MarkAction.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. <template>
  2. <div class="mark-action grade-action">
  3. <!-- 查询 -->
  4. <div class="action-search" v-if="rights.search">
  5. <Select
  6. class="search-select"
  7. v-model="filter.codeType"
  8. placeholder="密号类型"
  9. >
  10. <Option
  11. v-for="(val, key) in CODE_TYPE"
  12. :key="key"
  13. :value="key"
  14. :label="val"
  15. ></Option>
  16. </Select>
  17. <Input
  18. class="search-input"
  19. v-model.trim="filter.code"
  20. placeholder="输入密号"
  21. >
  22. </Input>
  23. <Button size="small" type="primary" class="search-btn" @click="searchCode"
  24. >查询</Button
  25. >
  26. </div>
  27. <!-- 改档处理状态查询 -->
  28. <div class="action-grade-change-search" v-if="rights.gradeChangeSearch">
  29. <Select
  30. v-model="applyChangeLevelStatus"
  31. placeholder="类型"
  32. style="width: 100px"
  33. >
  34. <Option
  35. v-for="(val, key) in CHANGE_LEVEL_STATUS"
  36. :key="key"
  37. :value="key * 1"
  38. :label="val"
  39. ></Option>
  40. </Select>
  41. <Button
  42. size="small"
  43. type="primary"
  44. class="search-btn"
  45. @click="searchGradeChange"
  46. >查询</Button
  47. >
  48. </div>
  49. <!-- 头部信息 ------ -->
  50. <!-- 试卷状态 -->
  51. <!-- 状态:已评,待评,改档,改档打分 -->
  52. <div class="action-paper-state">
  53. <p class="paper-state-cont">{{ stepLabel }}</p>
  54. </div>
  55. <!-- 试卷信息 -->
  56. <div class="action-paper-info">
  57. <p v-if="IS_ADMIN">
  58. <span>试卷考号:</span><span>{{ curPaper.examNumber }}</span>
  59. </p>
  60. <p>
  61. <span>试卷密号:</span><span>NO.{{ curPaper.sn }}</span>
  62. </p>
  63. </div>
  64. <!-- 改档信息 -->
  65. <div class="action-grade-change" v-if="rights.gradeChange">
  66. <p>
  67. <span>原始档位:</span><span>{{ curPaper.originLevel }}</span>
  68. </p>
  69. <p>
  70. <span>申请档位:</span><span>{{ curPaper.redoLevel }}</span>
  71. </p>
  72. </div>
  73. <div
  74. :class="[
  75. 'action-grade-change-status',
  76. { 'action-grade-change-status-error': curPaper.auditStatus === 0 }
  77. ]"
  78. v-if="rights.gradeChange"
  79. >
  80. <p>{{ curPaper.auditStatus === 1 ? "同意改档" : "不同意改档" }}</p>
  81. </div>
  82. <!-- 档位信息 -->
  83. <!-- 已评/待评(已评档位),改档打分(已评档位) -->
  84. <div class="action-grade-info" v-if="rights.gradeInfo">
  85. <h3 class="grade-info-name">{{ curLevel.name }}</h3>
  86. <div class="grade-info-range">
  87. <p>分数范围</p>
  88. <p>
  89. <span>{{ curLevel.minScore }}</span>
  90. <span>~</span>
  91. <span>{{ curLevel.maxScore }}</span>
  92. </p>
  93. </div>
  94. </div>
  95. <!-- 打分信息 -->
  96. <div class="action-grade-info action-mark-info" v-if="rights.markInfo">
  97. <p class="grade-info-name" v-if="curPaper.result">
  98. {{ curPaper.result }}
  99. </p>
  100. <p class="grade-info-name grade-info-none" v-else>未打分</p>
  101. </div>
  102. <!-- 选择分数 / 档位 -->
  103. <div class="action-grade-list" v-if="rights.gradeList && IS_MARK_LEADER">
  104. <div
  105. class="action-grade-item"
  106. v-for="(level, index) in levels"
  107. :key="index"
  108. >
  109. <div class="action-grade-item-content" @click="selectLevel(level)">
  110. <p>{{ level.name }}</p>
  111. <p>{{ level.minScore }}~{{ level.maxScore }}</p>
  112. </div>
  113. </div>
  114. </div>
  115. <div class="action-mark-list" v-if="rights.gradeList && !IS_MARK_LEADER">
  116. <div
  117. class="action-mark-item"
  118. v-for="(score, index) in scores"
  119. :key="index"
  120. >
  121. <div class="action-mark-item-content">
  122. <p @click="selectScore(score)">{{ score }}</p>
  123. </div>
  124. </div>
  125. </div>
  126. <div
  127. class="action-grade-pass"
  128. v-if="rights.gradeList && IS_MARKER && stepType === 'undo'"
  129. >
  130. <Button @click="toPass">跳过</Button>
  131. </div>
  132. <!-- 评卷记录 -->
  133. <div class="action-grade-history" v-if="rights.markHis">
  134. <h3>评卷记录</h3>
  135. <div class="grade-history-list">
  136. <div
  137. class="grade-history-item"
  138. v-for="(his, hindex) in gradingHistory"
  139. :key="hindex"
  140. >
  141. <p>{{ his.name }}</p>
  142. <p>{{ his.value }}</p>
  143. </div>
  144. </div>
  145. </div>
  146. </div>
  147. </template>
  148. <script>
  149. import { markHistoryList } from "@/api";
  150. import { CODE_TYPE, CHANGE_LEVEL_STATUS } from "@/constants/enumerate";
  151. // 三种情况:
  152. // 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
  153. // 管理员:查询,头部信息,评卷记录
  154. // 科组长:查询,头部信息,选择档位,评卷记录
  155. // 评卷员:头部信息,选择分数
  156. /*
  157. [paper template]
  158. {
  159. "id": 165,
  160. "sn": "029947536",
  161. "examNumber": "1901040084",
  162. "level": "A",
  163. "score": null,
  164. "redoLevel": null,
  165. "updatedOn": 1591767742000,
  166. "imgSrc": "",
  167. "thumbSrc": "",
  168. "markByLeader": false,
  169. "markedLogic": true,
  170. "areaCode": "2",
  171. "inspectScore": null,
  172. "inspectLevel": null,
  173. "inspector": null,
  174. "sheetSrc": null,
  175. "stage": "LEVEL",
  176. "test": 0,
  177. "paperTest": 0,
  178. "markResults": [],
  179. "rejected": false,
  180. "arbitrated": false,
  181. "sample": false,
  182. "tagged": false,
  183. "missing": false,
  184. "manual": false
  185. }
  186. [marktask template]
  187. {
  188. "id": 511,
  189. "sn": "4929446110",
  190. "redoLevel": null,
  191. "level": "A",
  192. "score": null,
  193. "result": "100",
  194. "originLevel": null,
  195. "markerId": 49,
  196. "marker": "pj061001",
  197. "updatedOn": 1594775592000,
  198. "imgSrc": "",
  199. "thumbSrc": "",
  200. "markByLeader": true,
  201. "oldRejected": false,
  202. "paperId": 168,
  203. "randomSeqNew": 9446110,
  204. "randomSeq": null,
  205. "rejected": false,
  206. "sample": true
  207. }
  208. */
  209. const initRights = {
  210. search: false,
  211. gradeChangeSearch: false,
  212. gradeChange: false,
  213. gradeInfo: false,
  214. markInfo: false,
  215. gradeList: false,
  216. markHis: false
  217. };
  218. export default {
  219. name: "mark-action",
  220. props: {
  221. curPaper: {
  222. type: Object,
  223. default() {
  224. return {};
  225. }
  226. },
  227. levels: {
  228. type: Array,
  229. default() {
  230. return [];
  231. }
  232. },
  233. userRole: {
  234. type: String,
  235. default: "MARKER"
  236. }
  237. },
  238. data() {
  239. return {
  240. rights: {
  241. ...initRights
  242. },
  243. roleRight: {
  244. ADMIN: {
  245. done: ["search", "gradeHis", "gradeInfo", "markInfo"],
  246. shift: ["search", "gradeChangeSearch", "gradeChange"]
  247. },
  248. MARK_LEADER: {
  249. done: ["search", "gradeList", "gradeHis", "gradeInfo", "markInfo"],
  250. shift: ["search", "gradeList", "gradeChange"]
  251. },
  252. MARKER: {
  253. done: ["gradeList", "gradeInfo", "markInfo"],
  254. undo: ["gradeList", "gradeInfo"],
  255. shift: ["gradeList", "gradeChange"],
  256. shiftScore: ["gradeList", "gradeInfo"]
  257. }
  258. },
  259. filter: {
  260. codeType: "examNumber",
  261. code: ""
  262. },
  263. CODE_TYPE,
  264. CHANGE_LEVEL_STATUS,
  265. applyChangeLevelStatus: null,
  266. stepDict: {
  267. undo: "待评",
  268. done: "已评",
  269. shift: "改档",
  270. shiftScore: "改档打分"
  271. },
  272. stepType: "",
  273. stepLabel: "",
  274. scores: [],
  275. gradingHistory: [],
  276. curLevel: {}
  277. };
  278. },
  279. computed: {
  280. IS_ADMIN() {
  281. return this.userRole === "ADMIN";
  282. },
  283. IS_MARKER() {
  284. return this.userRole === "MARKER";
  285. },
  286. IS_MARK_LEADER() {
  287. return this.userRole === "MARK_LEADER";
  288. }
  289. },
  290. watch: {
  291. curPaper(val) {
  292. this.rebuildRight();
  293. }
  294. },
  295. mounted() {
  296. this.rebuildRight();
  297. },
  298. methods: {
  299. getStepType() {
  300. const paper = this.curPaper;
  301. if (!paper.result) return "undo";
  302. if (paper.result) return "done";
  303. // TODO:
  304. if (paper.arbitrated) return "arbitrate";
  305. if (paper.rejected) return "reject";
  306. if (!paper.rejected && !paper.arbitrated && !paper.level) return "undo";
  307. return;
  308. },
  309. rebuildRight() {
  310. this.stepType = this.getStepType();
  311. this.stepLabel = this.stepDict[this.stepType];
  312. this.rights = { ...initRights };
  313. const roleRights = this.roleRight[this.userRole][this.stepType] || [];
  314. roleRights.map(key => {
  315. this.rights[key] = true;
  316. });
  317. if (this.curPaper.level) {
  318. this.curLevel = this.levels.find(
  319. level => level.name === this.curPaper.level
  320. );
  321. this.updateScoreList();
  322. }
  323. if (this.rights.gradeHis) {
  324. this.getMarkHistory();
  325. }
  326. },
  327. updateScoreList() {
  328. let scores = [];
  329. const { minScore, maxScore } = this.curLevel;
  330. for (let i = minScore; i <= maxScore; i++) {
  331. scores.push(i);
  332. }
  333. this.scores = scores;
  334. },
  335. async getMarkHistory() {
  336. const data = await markHistoryList(this.curPaper.id, "SCORE");
  337. this.gradingHistory = data.map(item => {
  338. return {
  339. id: item.markerId,
  340. name: item.marker,
  341. value: item.result || "未评"
  342. };
  343. });
  344. },
  345. selectLevel(level) {
  346. // 科组长改档
  347. this.$emit("on-leader-level", {
  348. curPaperId: this.curPaper.id,
  349. curLevel: this.curPaper.level,
  350. selectedLevel: level.name
  351. });
  352. },
  353. selectScore(score) {
  354. // 评卷员打分
  355. this.$emit("on-select-score", score * 1);
  356. },
  357. toPass() {
  358. this.$emit("on-pass");
  359. },
  360. searchCode() {
  361. this.$emit("on-code-search", this.filter);
  362. },
  363. searchGradeChange() {
  364. this.$emit("on-grade-change-search", this.applyChangeLevelStatus);
  365. }
  366. }
  367. };
  368. </script>