TaskReviewManage.vue 13 KB

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