TaskReviewManage.vue 14 KB

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