TaskReviewManage.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. <template>
  2. <div class="task-review-manage">
  3. <div class="mb-4">
  4. <el-button
  5. v-for="(val, key) in AUDITING_STATUS"
  6. :key="key"
  7. :type="auditStatus == key ? 'primary' : 'default'"
  8. @click="selectMenu(key)"
  9. >{{ val }}</el-button
  10. >
  11. </div>
  12. <div class="part-box part-box-filter part-box-flex">
  13. <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
  14. <template
  15. v-if="
  16. (AUDITED && checkPrivilege('condition', 'reviewCondition')) ||
  17. (!AUDITED && checkPrivilege('condition', 'notReviewCondition'))
  18. "
  19. >
  20. <el-form-item label="题卡规则:">
  21. <card-rule-select
  22. ref="CardRuleSelect"
  23. v-model.trim="filter.cardRuleId"
  24. placeholder="请选择"
  25. clearable
  26. ></card-rule-select>
  27. </el-form-item>
  28. <el-form-item label="课程(代码):" label-width="110px">
  29. <course-select
  30. ref="CourseSelect"
  31. v-model.trim="filter.courseCode"
  32. placeholder="请选择"
  33. clearable
  34. ></course-select>
  35. </el-form-item>
  36. <el-form-item label="试卷编号:">
  37. <paper-number-select
  38. ref="PaperNumberSelect"
  39. v-model="filter.paperNumber"
  40. placeholder="请选择"
  41. clearable
  42. ></paper-number-select>
  43. </el-form-item>
  44. <el-form-item label="命题老师:">
  45. <question-teacher-select
  46. ref="QuestionTeacherSelect"
  47. v-model="filter.userId"
  48. :course-code="filter.courseCode"
  49. placeholder="请选择"
  50. ></question-teacher-select>
  51. </el-form-item>
  52. <el-form-item label="命题时间:">
  53. <el-date-picker
  54. v-model="createTime"
  55. type="datetimerange"
  56. :picker-options="pickerOptions"
  57. range-separator="至"
  58. start-placeholder="开始日期"
  59. end-placeholder="结束日期"
  60. value-format="timestamp"
  61. align="right"
  62. unlink-panels
  63. >
  64. </el-date-picker>
  65. </el-form-item>
  66. <el-form-item label="审核结果:" v-if="AUDITED">
  67. <el-select
  68. v-model="filter.reviewStatus"
  69. style="width: 142px;"
  70. placeholder="请选择"
  71. clearable
  72. >
  73. <el-option
  74. v-for="(val, key) in AUDITING_RESULT"
  75. :key="key"
  76. :value="key"
  77. :label="val"
  78. ></el-option>
  79. </el-select>
  80. </el-form-item>
  81. </template>
  82. <el-form-item label-width="0px">
  83. <el-button
  84. v-if="
  85. (AUDITED && checkPrivilege('button', 'reviewSelect')) ||
  86. (!AUDITED && checkPrivilege('button', 'notReviewSelect'))
  87. "
  88. type="primary"
  89. icon="el-icon-search"
  90. @click="toPage(1)"
  91. >查询</el-button
  92. >
  93. </el-form-item>
  94. </el-form>
  95. <div class="part-box-action" v-if="!AUDITED">
  96. <el-button
  97. v-if="checkPrivilege('button', 'notReviewExport')"
  98. icon="el-icon-download"
  99. type="primary"
  100. :disabled="loading"
  101. @click="toExport"
  102. >
  103. 导出审核样本
  104. </el-button>
  105. <el-button
  106. v-if="checkPrivilege('button', 'notReviewBatchNotPass')"
  107. icon="el-icon-coordinate"
  108. type="danger"
  109. @click="toBatchAudit(0)"
  110. >
  111. 批量不通过
  112. </el-button>
  113. <el-button
  114. v-if="checkPrivilege('button', 'notReviewBatchPass')"
  115. icon="el-icon-coordinate"
  116. type="primary"
  117. @click="toBatchAudit(1)"
  118. >
  119. 批量通过
  120. </el-button>
  121. </div>
  122. </div>
  123. <div class="part-box">
  124. <el-table
  125. ref="TableList"
  126. :data="examTasks"
  127. border
  128. stripe
  129. @selection-change="handleSelectionChange"
  130. >
  131. <el-table-column
  132. v-if="!AUDITED"
  133. type="selection"
  134. width="55"
  135. :selectable="checkAbleSelected"
  136. ></el-table-column>
  137. <el-table-column
  138. type="index"
  139. label="序号"
  140. width="70"
  141. align="center"
  142. :index="indexMethod"
  143. ></el-table-column>
  144. <el-table-column prop="paperNumber" label="试卷编号"></el-table-column>
  145. <el-table-column prop="courseName" label="课程(代码)">
  146. <template slot-scope="scope">
  147. {{ scope.row.courseName }}({{ scope.row.courseCode }})
  148. </template>
  149. </el-table-column>
  150. <el-table-column prop="cardRuleName" label="题卡规则"></el-table-column>
  151. <el-table-column
  152. prop="userName"
  153. label="命题老师"
  154. width="100"
  155. ></el-table-column>
  156. <el-table-column prop="startTime" label="命题开始时间">
  157. <span slot-scope="scope">{{
  158. scope.row.startTime | timestampFilter
  159. }}</span>
  160. </el-table-column>
  161. <el-table-column prop="endTime" label="命题结束时间">
  162. <span slot-scope="scope">{{
  163. scope.row.endTime | timestampFilter
  164. }}</span>
  165. </el-table-column>
  166. <el-table-column prop="createTime" label="申请时间">
  167. <template slot-scope="scope">
  168. {{ scope.row.createTime | timestampFilter }}
  169. </template>
  170. </el-table-column>
  171. <el-table-column prop="createName" label="创建人"></el-table-column>
  172. <el-table-column
  173. class-name="action-column"
  174. label="操作"
  175. align="center"
  176. width="80px"
  177. >
  178. <template slot-scope="scope">
  179. <el-button
  180. v-if="AUDITED && checkPrivilege('link', 'reviewPreview')"
  181. class="btn-table-icon"
  182. type="text"
  183. icon="icon icon-circle-right"
  184. @click="toPreview(scope.row)"
  185. title="查看详情"
  186. ></el-button>
  187. <el-button
  188. v-if="!AUDITED && checkPrivilege('link', 'notReviewEdit')"
  189. class="btn-table-icon"
  190. type="text"
  191. icon="icon icon-edit"
  192. @click="toEdit(scope.row)"
  193. title="审核"
  194. ></el-button>
  195. </template>
  196. </el-table-column>
  197. </el-table>
  198. <div class="part-page">
  199. <el-pagination
  200. background
  201. layout="total,prev, pager, next"
  202. :current-page="current"
  203. :total="total"
  204. :page-size="size"
  205. @current-change="toPage"
  206. >
  207. </el-pagination>
  208. </div>
  209. </div>
  210. <!-- ModifyTaskApply -->
  211. <modify-task-apply
  212. ref="ModifyTaskApply"
  213. :edit-type="editType"
  214. :instance="curExamTask"
  215. @modified="taskModified"
  216. ></modify-task-apply>
  217. <!-- audit-dialog-->
  218. <el-dialog
  219. :visible.sync="auditDialogShow"
  220. title="审核不通过"
  221. width="500px"
  222. :close-on-click-modal="false"
  223. :close-on-press-escape="false"
  224. append-to-body
  225. >
  226. <el-form ref="AuditForm" :rules="auditRules" :model="auditModal">
  227. <el-form-item prop="reason">
  228. <el-input
  229. class="mb-2"
  230. v-model="auditModal.reason"
  231. type="textarea"
  232. resize="none"
  233. :rows="5"
  234. :maxlength="1000"
  235. clearable
  236. show-word-limit
  237. placeholder="建议不超过1000个字"
  238. ></el-input>
  239. </el-form-item>
  240. </el-form>
  241. <div slot="footer">
  242. <el-button type="primary" @click="auditNotPass">确认</el-button>
  243. <el-button type="danger" @click="auditDialogShow = false" plain
  244. >取消</el-button
  245. >
  246. </div>
  247. </el-dialog>
  248. </div>
  249. </template>
  250. <script>
  251. import ModifyTaskApply from "../components/ModifyTaskApply";
  252. import { AUDITING_RESULT, AUDITING_STATUS } from "@/constants/enumerate";
  253. import pickerOptions from "@/constants/datePickerOptions";
  254. import {
  255. taskReviewAuditedListPage,
  256. taskReviewUnauditedListPage,
  257. batchUpdateTaskReview,
  258. reviewSampleDataExport
  259. } from "../api";
  260. import { mapActions } from "vuex";
  261. export default {
  262. name: "task-review-manage",
  263. components: {
  264. ModifyTaskApply
  265. },
  266. data() {
  267. return {
  268. auditStatus: "NOT_AUDITED",
  269. filter: {
  270. userId: "",
  271. cardRuleId: "",
  272. courseCode: "",
  273. paperNumber: "",
  274. startTime: null,
  275. endTime: null
  276. },
  277. current: 1,
  278. size: this.GLOBAL.pageSize,
  279. total: 0,
  280. editType: "APPLY",
  281. AUDITING_RESULT,
  282. AUDITING_STATUS,
  283. caches: {},
  284. examTasks: [],
  285. curExamTask: {},
  286. multipleSelection: [],
  287. loading: false,
  288. curUserId: this.$ls.get("user", { id: "" }).id,
  289. // audit-dialog
  290. auditDialogShow: false,
  291. auditModal: { reason: "" },
  292. auditRules: {
  293. reason: [
  294. { required: true, message: "请输入审核意见", trigger: "change" }
  295. ]
  296. },
  297. // date-picker
  298. createTime: [],
  299. pickerOptions
  300. };
  301. },
  302. computed: {
  303. AUDITED() {
  304. return this.auditStatus === "AUDITED";
  305. }
  306. },
  307. mounted() {
  308. this.toPage(1);
  309. },
  310. methods: {
  311. ...mapActions("exam", ["updateWaitTaskCount"]),
  312. async getList() {
  313. const valid =
  314. (this.AUDITED && this.checkPrivilege("list", "reviewList")) ||
  315. (!this.AUDITED && this.checkPrivilege("list", "notReviewList"));
  316. if (!valid) return;
  317. const datas = {
  318. ...this.filter,
  319. pageNumber: this.current,
  320. pageSize: this.size
  321. };
  322. if (this.createTime) {
  323. datas.startTime = this.createTime[0];
  324. datas.endTime = this.createTime[1];
  325. }
  326. const func = this.AUDITED
  327. ? taskReviewAuditedListPage
  328. : taskReviewUnauditedListPage;
  329. const data = await func(datas);
  330. this.examTasks = data.records;
  331. this.total = data.total;
  332. },
  333. toPage(page) {
  334. this.current = page;
  335. this.getList();
  336. this.multipleSelection = [];
  337. },
  338. handleSelectionChange(val) {
  339. this.multipleSelection = val.map(item => item.id);
  340. console.log(this.multipleSelection);
  341. },
  342. checkAbleSelected(row) {
  343. return row.createId === this.curUserId;
  344. },
  345. selectMenu(val) {
  346. if (this.auditStatus === val) return;
  347. this.caches[this.auditStatus] = {
  348. current: this.current,
  349. examTasks: this.examTasks,
  350. total: this.total
  351. };
  352. this.auditStatus = val;
  353. if (this.caches[val] && this.caches[val].examTasks) {
  354. this.current = this.caches[val].current;
  355. this.total = this.caches[val].total;
  356. this.examTasks = this.caches[val].examTasks;
  357. } else {
  358. this.toPage(1);
  359. }
  360. },
  361. toBatchAudit(isPass) {
  362. if (!this.multipleSelection.length) {
  363. this.$message.error("请选择要审核的记录!");
  364. return;
  365. }
  366. const actionName = isPass ? "通过" : "不通过";
  367. this.$confirm(`确定${actionName}这些申请吗?`, "提示", {
  368. cancelButtonClass: "el-button--danger is-plain",
  369. confirmButtonClass: "el-button--primary",
  370. type: "warning"
  371. })
  372. .then(() => {
  373. this.auditModal.reason = "";
  374. if (isPass) {
  375. this.auditApply("PASS", this.multipleSelection);
  376. } else {
  377. this.auditDialogShow = true;
  378. }
  379. })
  380. .catch(() => {});
  381. },
  382. async auditNotPass() {
  383. const valid = await this.$refs.AuditForm.validate().catch(() => {});
  384. if (!valid) return;
  385. await this.auditApply("NOT_PASS", this.multipleSelection);
  386. this.auditDialogShow = false;
  387. },
  388. async auditApply(type, ids) {
  389. const data = await batchUpdateTaskReview({
  390. reviewStatus: type,
  391. examTaskIds: ids,
  392. reason: this.auditModal.reason
  393. }).catch(() => {});
  394. if (!data) return;
  395. this.$message.success("审核成功!");
  396. this.taskModified();
  397. },
  398. async toExport() {
  399. if (!this.multipleSelection.length) {
  400. this.$message.error("请选择要导出的记录!");
  401. return;
  402. }
  403. if (this.loading) return;
  404. this.loading = true;
  405. const res = await reviewSampleDataExport({
  406. ids: this.multipleSelection
  407. }).catch(() => {});
  408. this.loading = false;
  409. if (res) {
  410. this.$message.success(
  411. "导出任务已提交,请在数据管理-任务管理中下载文件!"
  412. );
  413. } else {
  414. this.$message.error("导出任务提交失败,请重新尝试!");
  415. }
  416. },
  417. toEdit(row) {
  418. this.curExamTask = { ...row, source: "REVIEW" };
  419. this.editType = "AUDIT";
  420. this.$refs.ModifyTaskApply.open();
  421. },
  422. toPreview(row) {
  423. this.curExamTask = { ...row, source: "REVIEW" };
  424. this.editType = "PREVIEW";
  425. this.$refs.ModifyTaskApply.open();
  426. },
  427. taskModified() {
  428. this.getList();
  429. this.updateWaitTaskCount();
  430. }
  431. }
  432. };
  433. </script>