index.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. <template>
  2. <div class="container">
  3. <save-form
  4. inline
  5. :model="search"
  6. @submit="FetchList"
  7. @reset="reset"
  8. saveKey="/main/main/abnormal"
  9. >
  10. <el-form-item prop="organId">
  11. <el-select
  12. clearable
  13. filterable
  14. v-model="search.organId"
  15. placeholder="请选择分部"
  16. >
  17. <el-option
  18. v-for="(item, index) in selects.branchs"
  19. :key="index"
  20. :label="item.name"
  21. :value="item.id"
  22. ></el-option>
  23. </el-select>
  24. </el-form-item>
  25. <el-button native-type="submit" type="primary">搜索</el-button>
  26. <el-button native-type="reset" type="danger">重置</el-button>
  27. <el-button type="primary" @click="exportAbnormal">导出</el-button>
  28. </save-form>
  29. <div class="tags">
  30. <el-badge
  31. :hidden="!keyNames[item].num"
  32. is-dot
  33. v-for="(item, index) in permissionTags"
  34. :key="index"
  35. >
  36. <el-tag
  37. :effect="activeKey === item ? 'dark' : 'plain'"
  38. @click="changeTag(item)"
  39. >{{ keyNames[item].name }}</el-tag
  40. >
  41. </el-badge>
  42. </div>
  43. <empty desc="暂无需要处理异常" v-if="!activeList.length" />
  44. <el-button
  45. @click="handle(item)"
  46. style="width: 100%; color: #303133; margin-left: 0"
  47. v-else
  48. v-for="(item, index) in activeList"
  49. :key="index"
  50. :disabled="(item[0].result && !item[0].result.length) || !item[0].num"
  51. type="text"
  52. >
  53. <title-item
  54. :descss="descs"
  55. :type="item[0].isError ? 'error' : 'warning'"
  56. :data="
  57. item.map((title) => ({
  58. name: title.desc,
  59. num: title.num,
  60. num2: title.num2,
  61. errorType: title.errorType,
  62. }))
  63. "
  64. >
  65. <span
  66. style="color: var(--color-primary)"
  67. v-if="
  68. !errorType[item[0].errorType] ||
  69. (errorType[item[0].errorType] &&
  70. permission(errorType[item[0].errorType].permission))
  71. "
  72. >
  73. 立即处理<i class="el-icon-d-arrow-right" />
  74. </span>
  75. </title-item>
  76. </el-button>
  77. <!-- <title-item
  78. v-else
  79. :type="item[0].isError ? 'error' : 'warning'"
  80. v-for="(item, index) in activeList"
  81. :key="index"
  82. :data="item.map(title => ({name: title.desc, num: title.num}))"
  83. >
  84. <el-button
  85. type="text"
  86. v-if="item[0].url && item[0].result || item[0].always"
  87. @click="$router.push({
  88. path: item[0].url,
  89. query: {
  90. ...item[0].query,
  91. tag: $route.query.tag,
  92. filter_type: item[0].errorType,
  93. [item[0].resultKey]: item[0].resultKey ? (item[0].result || []).join(',') : undefined
  94. }
  95. })" :disabled="!item[0].result.length && !item[0].always"
  96. >立即处理<i class="el-icon-d-arrow-right"/></el-button>
  97. </title-item> -->
  98. </div>
  99. </template>
  100. <script>
  101. import { Searchs } from "@/helpers";
  102. import { getIndexError } from "@/views/main/api";
  103. import { createNotification } from "@/helpers/notification";
  104. import { errorType } from "@/views/main/constant";
  105. import { permission } from "@/utils/directivePage";
  106. import title from "./title";
  107. import { getSysTenantConfig } from "@/views/courseRulersManager/api";
  108. import { descs } from "../constant";
  109. import { Export } from "@/utils/downLoadFile";
  110. const initSearch = {
  111. organId: null,
  112. };
  113. export default {
  114. components: {
  115. "title-item": title,
  116. },
  117. data() {
  118. return {
  119. search: {
  120. ...initSearch,
  121. },
  122. listByType: {},
  123. infoByType: {},
  124. list: [],
  125. errorType: errorType,
  126. descs: { ...descs },
  127. };
  128. },
  129. computed: {
  130. keyNames() {
  131. const { status } = this.$store.state.app;
  132. return {
  133. MUSIC_PATROL: {
  134. name: "乐团巡查",
  135. num: status.musicPatrol || false,
  136. },
  137. STUDENT_INFO: {
  138. name: "学员处理",
  139. num: status.studentInfo || false,
  140. },
  141. TEACHER_INFO: {
  142. name: "日常行政",
  143. num: status.teacherInfo || false,
  144. },
  145. ATTENDANCE_SERVE: {
  146. name: "考勤及服务",
  147. num: status.attendanceServe || false,
  148. },
  149. };
  150. },
  151. permissionTags() {
  152. const url = "getIndexErrData?errorType=";
  153. const permissions = [
  154. "MUSIC_PATROL",
  155. "STUDENT_INFO",
  156. "TEACHER_INFO",
  157. "ATTENDANCE_SERVE",
  158. ];
  159. return permissions.filter((item) => {
  160. return this.permission(url + item);
  161. });
  162. },
  163. activeKey() {
  164. let key = "";
  165. const { tag } = this.$route.query;
  166. if (tag) {
  167. key = tag;
  168. } else if (this.permissionTags[0]) {
  169. key = this.permissionTags[0];
  170. }
  171. return key;
  172. },
  173. tags() {
  174. const tags = this.list.map((item) => ({
  175. name: item.desc,
  176. type: item.errorType,
  177. num: item.num,
  178. }));
  179. return tags;
  180. },
  181. activeList() {
  182. const list = this.listByType[this.activeKey] || [];
  183. return list;
  184. },
  185. },
  186. async mounted() {
  187. this.FetchList();
  188. await this.$store.dispatch("setBranchs");
  189. },
  190. methods: {
  191. permission,
  192. handle(item) {
  193. // 添加判断权限
  194. if (
  195. errorType[item[0].errorType] &&
  196. !this.permission(errorType[item[0].errorType].permission)
  197. ) {
  198. return;
  199. }
  200. // 单独对未缴费学员数
  201. if (item[0].errorType == "STUDENT_NOT_PAYMENT") {
  202. item[0].query["result"] = item[0].result
  203. ? (item[0].result || []).join(",")
  204. : undefined;
  205. }
  206. new Searchs().removeByKey(item[0].url);
  207. this.$router.push({
  208. path: item[0].url,
  209. query: {
  210. ...item[0].query,
  211. tag: this.$route.query.tag,
  212. filter_type: item[0].errorType,
  213. organId: this.search.organId || undefined,
  214. [item[0].resultKey]: item[0].resultKey
  215. ? (item[0].result || []).join(",")
  216. : undefined,
  217. },
  218. });
  219. },
  220. changeTag(type) {
  221. this.$router.replace({
  222. query: {
  223. ...this.$route.query,
  224. tag: type,
  225. },
  226. });
  227. this.FetchList();
  228. },
  229. async formatData(data) {
  230. const list = {};
  231. for (const item of data) {
  232. const row = errorType[item.errorType] || {};
  233. const key = row.parent || item.errorType;
  234. if (!list[key]) {
  235. list[key] = [];
  236. }
  237. list[key].push({
  238. ...item,
  239. ...row,
  240. });
  241. if (
  242. item.errorType == "COURSE_TIME_ERROR" ||
  243. item.errorType == "STUDENT_ERROR_LEAVE"
  244. ) {
  245. try {
  246. const res = await getSysTenantConfig({ group: "SERVER_ERROR" });
  247. let startStr = "";
  248. let endStr = "";
  249. let leaveStr = "";
  250. res.data.forEach((item) => {
  251. // this.form[item.paramName] = item.paranValue
  252. if (item.id == "195") {
  253. startStr = item.paranValue.substring(0, 5);
  254. }
  255. if (item.id == "196") {
  256. endStr = item.paranValue.substring(0, 5);
  257. }
  258. if (item.id == "194") {
  259. leaveStr = item.paranValue;
  260. }
  261. });
  262. if (startStr && endStr) {
  263. this.descs[
  264. "COURSE_TIME_ERROR"
  265. ] = `上课时间不在${startStr}~${endStr}时间段内为时间安排异常`;
  266. }
  267. if(leaveStr){
  268. this.descs[
  269. "STUDENT_ERROR_LEAVE"
  270. ] = `当月请假${leaveStr}次及以上`;
  271. }
  272. } catch (e) {
  273. console.log(e);
  274. }
  275. }
  276. }
  277. return Object.values(list);
  278. },
  279. async FetchList() {
  280. try {
  281. const res = await getIndexError({
  282. errorType: this.activeKey,
  283. ...this.search,
  284. });
  285. this.list = res.data.data;
  286. const data = {};
  287. const info = {};
  288. for (const item of this.list) {
  289. info[item.errorType] = item;
  290. data[item.errorType] = await this.formatData(item?.result || []);
  291. }
  292. this.infoByType = info;
  293. this.listByType = data;
  294. } catch (error) {}
  295. },
  296. reset() {
  297. this.search = { ...initSearch };
  298. this.FetchList();
  299. },
  300. send() {
  301. createNotification({
  302. title: "测试发送通知",
  303. body: "您有一条待处理通知,请及时处理",
  304. onClick: () => {
  305. this.$router.replace("/main/main");
  306. },
  307. });
  308. },
  309. exportAbnormal() {
  310. let params = this.search;
  311. Export(
  312. this,
  313. {
  314. method: "post",
  315. url: "/api-web/export/exportIndexErrData",
  316. params: this.$helpers.qs.stringify({
  317. ...params,
  318. }),
  319. },
  320. "是否确认导出报表?"
  321. );
  322. },
  323. },
  324. };
  325. </script>
  326. <style lang="less" scoped>
  327. .tags {
  328. margin-bottom: 20px;
  329. > div {
  330. margin-right: 20px;
  331. cursor: pointer;
  332. }
  333. }
  334. .container {
  335. /deep/ .is-disabled {
  336. .title {
  337. > span {
  338. color: #c0c4cc !important;
  339. }
  340. }
  341. }
  342. }
  343. </style>