MarkAction.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. <template>
  2. <div class="mark-action grade-action">
  3. <!-- 头部信息 ------ -->
  4. <!-- 试卷状态 -->
  5. <!-- 状态:已评,待评,改档,改档打分 -->
  6. <div class="action-paper-state">
  7. <p class="paper-state-cont">{{ stepLabel }}</p>
  8. </div>
  9. <!-- 试卷信息 -->
  10. <div class="action-paper-info">
  11. <!-- <p v-if="IS_ADMIN">
  12. <span>试卷考号:</span><span>{{ curPaperOrTask.examNumber }}</span>
  13. </p> -->
  14. <p>
  15. <span v-if="IS_MARKER">任务密号:</span>
  16. <span v-else>试卷密号:</span>
  17. <span>NO.{{ curPaperOrTask.sn }}</span>
  18. </p>
  19. </div>
  20. <!-- 改档信息 -->
  21. <div class="action-grade-change" v-if="rights.gradeChange">
  22. <p>
  23. <span>原始档位:</span><span>{{ curPaperOrTask.originLevel }}</span>
  24. </p>
  25. <p>
  26. <span v-if="IS_MARKER">建议档位:</span>
  27. <span v-else>申请档位:</span>
  28. <span>{{ curPaperOrTask.redoLevel }}</span>
  29. </p>
  30. </div>
  31. <div
  32. :class="[
  33. 'action-grade-change-status',
  34. { 'action-grade-change-status-error': curPaperOrTask.auditStatus === 0 }
  35. ]"
  36. v-if="rights.gradeChange && IS_ADMIN"
  37. >
  38. <p>{{ curPaperOrTask.auditStatus === 1 ? "同意改档" : "不同意改档" }}</p>
  39. </div>
  40. <!-- 档位信息 -->
  41. <!-- 已评/待评(已评档位),改档打分(已评档位) -->
  42. <div class="action-grade-info" v-if="rights.gradeInfo">
  43. <h3 class="grade-info-name">
  44. {{ curPaperLevel }}
  45. </h3>
  46. <!-- <div class="grade-info-range">
  47. <p>分数范围</p>
  48. <p>
  49. <span>{{ curLevel.minScore }}</span>
  50. <span>~</span>
  51. <span>{{ curLevel.maxScore }}</span>
  52. </p>
  53. </div> -->
  54. </div>
  55. <!-- 打分信息 -->
  56. <div class="action-grade-info action-mark-info" v-if="rights.markInfo">
  57. <p class="grade-info-name" v-if="curPaperScore">
  58. {{ curPaperScore }}
  59. </p>
  60. <p class="grade-info-name grade-info-none" v-else>未打分</p>
  61. </div>
  62. <!-- 选择档位 -->
  63. <div class="action-grade-list" v-if="rights.gradeList">
  64. <div
  65. class="action-grade-item"
  66. v-for="(level, index) in levels"
  67. :key="index"
  68. >
  69. <div
  70. :class="[
  71. 'action-grade-item-content',
  72. { 'action-item-content-disabled': btnClicked }
  73. ]"
  74. @click="selectLevel(level)"
  75. >
  76. <p>{{ level.name }}</p>
  77. <p>{{ level.minScore }}~{{ level.maxScore }}</p>
  78. </div>
  79. </div>
  80. </div>
  81. <!-- 选择分数 -->
  82. <div class="action-mark-list" v-if="rights.levelList">
  83. <div
  84. class="action-mark-item"
  85. v-for="(score, index) in scores"
  86. :key="index"
  87. >
  88. <div
  89. :class="[
  90. 'action-mark-item-content',
  91. { 'action-item-content-disabled': btnClicked }
  92. ]"
  93. @click="selectScore(score)"
  94. >
  95. <p>{{ score }}</p>
  96. </div>
  97. </div>
  98. </div>
  99. <div class="action-grade-pass" v-if="rights.levelList" @click="toPass">
  100. 跳过
  101. </div>
  102. <!-- mark confirm grade change -->
  103. <div
  104. class="action-grade-change-confirm"
  105. v-if="IS_MARKER && stepType === 'shift'"
  106. >
  107. <Button type="primary" @click="gradeChangeConfirm">确认改档</Button>
  108. </div>
  109. <!-- 评卷记录 -->
  110. <div class="action-grade-history" v-if="rights.markHis">
  111. <h3>评卷记录</h3>
  112. <div class="grade-history-list">
  113. <div
  114. class="grade-history-item"
  115. v-for="(his, hindex) in gradingHistory"
  116. :key="hindex"
  117. >
  118. <p>{{ his.loginName }}</p>
  119. <p>{{ his.value }}</p>
  120. </div>
  121. </div>
  122. </div>
  123. <!-- 查询 -->
  124. <div class="action-search" v-if="rights.search">
  125. <Select
  126. class="search-select"
  127. v-model="filter.codeType"
  128. placeholder="密号类型"
  129. >
  130. <Option
  131. v-for="item in codeTypes"
  132. :key="item.key"
  133. :value="item.key"
  134. :label="item.val"
  135. ></Option>
  136. </Select>
  137. <Input
  138. class="search-input"
  139. v-model.trim="filter.code"
  140. placeholder="输入密号"
  141. clearable
  142. >
  143. </Input>
  144. <Button size="small" type="primary" class="search-btn" @click="searchCode"
  145. >查询</Button
  146. >
  147. </div>
  148. <!-- 改档处理状态查询 -->
  149. <div class="action-search" v-if="rights.gradeChangeSearch">
  150. <Select
  151. class="search-input"
  152. v-model="applyChangeLevelStatus"
  153. placeholder="类型"
  154. >
  155. <Option
  156. v-for="(val, key) in CHANGE_LEVEL_STATUS"
  157. :key="key"
  158. :value="key * 1"
  159. :label="val"
  160. ></Option>
  161. </Select>
  162. <Button
  163. size="small"
  164. type="primary"
  165. class="search-btn"
  166. @click="searchGradeChange"
  167. >查询</Button
  168. >
  169. </div>
  170. </div>
  171. </template>
  172. <script>
  173. import { markHistoryList } from "@/api";
  174. import { CODE_TYPE, CHANGE_LEVEL_STATUS } from "@/constants/enumerate";
  175. // 三种情况:
  176. // 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
  177. // 管理员:查询,头部信息,评卷记录
  178. // 科组长:查询,头部信息,选择档位,评卷记录
  179. // 评卷员:头部信息,选择分数
  180. /*
  181. [paper template]
  182. {
  183. "id": 42,
  184. "sn": "5314987744",
  185. "redoLevel": null,
  186. "level": "B",
  187. "score": null,
  188. "result": "88",
  189. "originLevel": null,
  190. "markerId": 52,
  191. "marker": "zj-pj-01",
  192. "updatedOn": 1595812145000,
  193. "imgSrc": "http://192.168.10.145:9000/images/34/SC/1/1901130046.jpg?random=f5549bb0-ba58-4cd3-a88e-0559be4e06e5",
  194. "thumbSrc": "http://192.168.10.145:9000/thumbs/34/SC/1/1901130046.jpg?random=e7f880b8-4cb6-4963-8e66-532f0f8bdeb0",
  195. "markByLeader": false,
  196. "oldRejected": false,
  197. "paperId": 116,
  198. "randomSeqNew": 4987744,
  199. "randomSeq": null,
  200. "serialNumber": "B1",
  201. "displayNumber": true,
  202. "shift": false,
  203. "shiftScore": false,
  204. "rejected": false,
  205. "sample": false
  206. }
  207. [marktask template]
  208. {
  209. "id": 38,
  210. "sn": "5314266469",
  211. "redoLevel": null,
  212. "level": "A",
  213. "score": null,
  214. "result": "96",
  215. "originLevel": null,
  216. "markerId": 52,
  217. "marker": "zj-pj-01",
  218. "updatedOn": 1595812012000,
  219. "imgSrc": "http://192.168.10.145:9000/images/34/SC/1/1901130043.jpg?random=bffc061c-7a80-42a4-ad56-36ec6eba0d45",
  220. "thumbSrc": "http://192.168.10.145:9000/thumbs/34/SC/1/1901130043.jpg?random=da743f9d-8d46-4499-bb6f-b9c26e003ba2",
  221. "markByLeader": true,
  222. "oldRejected": false,
  223. "paperId": 113,
  224. "randomSeqNew": 4266469,
  225. "randomSeq": null,
  226. "serialNumber": "A1",
  227. "displayNumber": true,
  228. "shift": false,
  229. "shiftScore": false,
  230. "rejected": false,
  231. "sample": true
  232. }
  233. */
  234. const initRights = {
  235. search: false,
  236. gradeChangeSearch: false,
  237. gradeChange: false,
  238. gradeInfo: false,
  239. markInfo: false,
  240. gradeList: false,
  241. levelList: false,
  242. markHis: false
  243. };
  244. export default {
  245. name: "mark-action",
  246. props: {
  247. curPaperOrTask: {
  248. type: Object,
  249. default() {
  250. return {};
  251. }
  252. },
  253. levels: {
  254. type: Array,
  255. default() {
  256. return [];
  257. }
  258. }
  259. },
  260. data() {
  261. return {
  262. curUserRoleType: this.$ls.get("user", { role: "" }).role,
  263. rights: {
  264. ...initRights
  265. },
  266. roleRight: {
  267. ADMIN: {
  268. done: ["search", "markHis", "gradeInfo", "markInfo"],
  269. shift: ["search", "gradeChangeSearch", "gradeChange"]
  270. },
  271. MARK_LEADER: {
  272. undo: ["gradeList", "gradeInfo", "markInfo"],
  273. done: ["gradeList", "markHis", "gradeInfo", "markInfo"],
  274. shift: ["gradeList", "gradeChange"]
  275. },
  276. MARKER: {
  277. done: ["levelList", "gradeInfo", "markInfo"],
  278. undo: ["levelList", "gradeInfo"],
  279. shift: ["gradeChange"],
  280. shiftScore: ["levelList", "gradeInfo"]
  281. }
  282. },
  283. filter: {
  284. codeType: "examNumber",
  285. code: ""
  286. },
  287. codeTypes: [],
  288. CHANGE_LEVEL_STATUS,
  289. applyChangeLevelStatus: null,
  290. stepDict: {
  291. undo: "待评",
  292. done: "已评",
  293. shift: "改档",
  294. shiftScore: "改档打分"
  295. },
  296. stepType: "",
  297. stepLabel: "",
  298. curPaperLevel: "",
  299. curPaperScore: "",
  300. scores: [],
  301. gradingHistory: [],
  302. curLevel: {},
  303. setT: null,
  304. btnClicked: false
  305. };
  306. },
  307. computed: {
  308. IS_ADMIN() {
  309. return this.curUserRoleType === "ADMIN";
  310. },
  311. IS_MARKER() {
  312. return this.curUserRoleType === "MARKER";
  313. },
  314. IS_MARK_LEADER() {
  315. return this.curUserRoleType === "MARK_LEADER";
  316. }
  317. },
  318. watch: {
  319. curPaperOrTask(val) {
  320. this.rebuildRight();
  321. }
  322. },
  323. mounted() {
  324. this.codeTypes = Object.entries(CODE_TYPE)
  325. .map(([key, val]) => {
  326. return {
  327. key,
  328. val
  329. };
  330. })
  331. .filter(item => item.key !== "examNumber");
  332. // .filter(item => this.IS_ADMIN || item.key !== "examNumber");
  333. this.rebuildRight();
  334. },
  335. methods: {
  336. getStepType() {
  337. const paper = this.curPaperOrTask;
  338. if (paper.shift && paper.shiftScore && !paper.level && !paper.result)
  339. return "shift";
  340. if (!paper.shift && paper.shiftScore && !paper.result)
  341. return "shiftScore";
  342. if (this.IS_MARKER) {
  343. if (!paper.result) return "undo";
  344. if (paper.result) return "done";
  345. } else {
  346. if (paper.score !== null) return "done";
  347. if (paper.score === null) return "undo";
  348. }
  349. },
  350. rebuildRight() {
  351. const curPaperScore = this.IS_MARKER
  352. ? this.curPaperOrTask.result
  353. : this.curPaperOrTask.score;
  354. this.curPaperScore = curPaperScore !== null ? curPaperScore + "" : "";
  355. this.stepType = this.getStepType();
  356. this.stepLabel = this.stepDict[this.stepType];
  357. this.rights = { ...initRights };
  358. const roleRights =
  359. this.roleRight[this.curUserRoleType][this.stepType] || [];
  360. roleRights.map(key => {
  361. this.rights[key] = true;
  362. });
  363. if (this.curPaperOrTask.level) {
  364. this.curLevel = this.levels.find(
  365. level => level.name === this.curPaperOrTask.level
  366. );
  367. this.curPaperLevel =
  368. this.curPaperOrTask["displayNumber"] && this.stepType !== "shiftScore"
  369. ? this.curPaperOrTask["serialNumber"]
  370. : this.curLevel.name;
  371. this.updateScoreList();
  372. }
  373. if (this.rights.markHis) {
  374. this.getMarkHistory();
  375. }
  376. this.btnClicked = false;
  377. },
  378. updateScoreList() {
  379. let scores = [];
  380. if (this.curLevel.levelType === "ADMITED") {
  381. const { minScore, maxScore, intervalScore } = this.curLevel;
  382. for (let i = minScore; i <= maxScore; i += intervalScore) {
  383. scores.push(i);
  384. }
  385. } else {
  386. scores = this.curLevel.scoreList.split(",").map(item => item * 1);
  387. }
  388. this.scores = scores;
  389. },
  390. async getMarkHistory() {
  391. const data = await markHistoryList(this.curPaperOrTask.id, "SCORE");
  392. this.gradingHistory = data.map(item => {
  393. return {
  394. id: item.markerId,
  395. name: item.marker,
  396. loginName: item.loginName,
  397. value: item.result || "未评"
  398. };
  399. });
  400. },
  401. selectLevel(level) {
  402. if (this.curPaperOrTask.level === level.name) return;
  403. if (this.btnClicked) return;
  404. this.btnClicked = true;
  405. this.setT = setTimeout(() => {
  406. this.btnClicked = false;
  407. }, 500);
  408. // 科组长改档 / 评卷同意改档:只使用selectedLevel
  409. this.$emit("on-leader-level", {
  410. paperId: this.curPaperOrTask.paperId,
  411. curLevel:
  412. this.stepType === "shift"
  413. ? this.curPaperOrTask.redoLevel
  414. : this.curPaperOrTask.level,
  415. selectedLevel: level.name
  416. });
  417. },
  418. gradeChangeConfirm() {
  419. this.selectLevel({ name: this.curPaperOrTask.redoLevel });
  420. },
  421. selectScore(score) {
  422. if (this.btnClicked) return;
  423. this.btnClicked = true;
  424. this.setT = setTimeout(() => {
  425. this.btnClicked = false;
  426. }, 500);
  427. // 评卷员打分
  428. this.$emit("on-select-score", score * 1);
  429. },
  430. toPass() {
  431. this.$emit("on-pass");
  432. },
  433. searchCode() {
  434. if (!this.filter.code || !this.filter.codeType) {
  435. this.$Message.error("请设置密号类型和密号!");
  436. return;
  437. }
  438. this.$emit("on-code-search", this.filter);
  439. },
  440. searchGradeChange() {
  441. this.$emit("on-grade-change-search", this.applyChangeLevelStatus);
  442. }
  443. }
  444. };
  445. </script>