GradeAction.vue 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. <template>
  2. <div class="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. <!-- 试卷状态 -->
  29. <!-- 状态:已评,待评,打回,仲裁 -->
  30. <div class="action-paper-state">
  31. <p class="paper-state-cont">{{ stepLabel }}</p>
  32. </div>
  33. <!-- 试卷信息 -->
  34. <div class="action-paper-info">
  35. <p v-if="IS_ADMIN">
  36. <span>试卷考号:</span><span>{{ curPaperOrTask.examNumber }}</span>
  37. </p>
  38. <p>
  39. <span>试卷密号:</span><span>NO.{{ curPaperOrTask.sn }}</span>
  40. </p>
  41. </div>
  42. <!-- 档位信息 -->
  43. <!-- 已评(已评档位),打回(建议档位) -->
  44. <h3 class="action-grade-info-title" v-if="curPaperOrTask.rejected">
  45. 建议档位:
  46. </h3>
  47. <div class="action-grade-info" v-if="rights.gradeInfo">
  48. <h3 class="grade-info-name">{{ curLevel.name }}</h3>
  49. <div class="grade-info-range">
  50. <p>分数范围</p>
  51. <p>
  52. <span>{{ curLevel.minScore }}</span>
  53. <span>~</span>
  54. <span>{{ curLevel.maxScore }}</span>
  55. </p>
  56. </div>
  57. </div>
  58. <!-- 选择档位 -->
  59. <div class="action-grade-list" v-if="rights.gradeList">
  60. <div
  61. class="action-grade-item"
  62. v-for="(level, index) in levels"
  63. :key="index"
  64. >
  65. <div
  66. :class="[
  67. 'action-grade-item-content',
  68. { 'action-item-content-disabled': btnClicked }
  69. ]"
  70. @click="selectLevel(level)"
  71. >
  72. <p>{{ level.name }}</p>
  73. <p>{{ level.minScore }}~{{ level.maxScore }}</p>
  74. </div>
  75. </div>
  76. </div>
  77. <div class="action-grade-pass" v-if="rights.gradeList && IS_MARKER">
  78. <Button @click="toPass">跳过</Button>
  79. </div>
  80. <!-- 评卷记录 -->
  81. <div class="action-grade-history" v-if="rights.gradeHis">
  82. <h3>评卷记录</h3>
  83. <div class="grade-history-list">
  84. <div
  85. class="grade-history-item"
  86. v-for="his in gradingHistory"
  87. :key="his.id"
  88. >
  89. <p>{{ his.name }}</p>
  90. <p>{{ his.value }}</p>
  91. </div>
  92. </div>
  93. </div>
  94. </div>
  95. </template>
  96. <script>
  97. import { markHistoryList } from "@/api";
  98. import { CODE_TYPE } from "@/constants/enumerate";
  99. // 三种情况:
  100. // 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
  101. // 管理员:查询,头部信息,评卷记录
  102. // 科组长:查询,头部信息,选择档位,评卷记录
  103. // 评卷员:头部信息,选择档位
  104. // MARK_LEADER / ADMIN: curPaperOrTask => paper
  105. // MARKER: curPaperOrTask => task
  106. //
  107. /*
  108. [paper template]
  109. {
  110. "id": 165,
  111. "sn": "029947536",
  112. "examNumber": "1901040084",
  113. "level": "A",
  114. "score": null,
  115. "redoLevel": null,
  116. "updatedOn": 1591767742000,
  117. "imgSrc": "",
  118. "thumbSrc": "",
  119. "markByLeader": false,
  120. "markedLogic": true,
  121. "areaCode": "2",
  122. "inspectScore": null,
  123. "inspectLevel": null,
  124. "inspector": null,
  125. "sheetSrc": null,
  126. "stage": "LEVEL",
  127. "test": 0,
  128. "paperTest": 0,
  129. "markResults": [],
  130. "rejected": false,
  131. "arbitrated": false,
  132. "sample": false,
  133. "tagged": false,
  134. "missing": false,
  135. "manual": false
  136. }
  137. [marktask template]
  138. {
  139. "id": 511,
  140. "sn": "4929446110",
  141. "redoLevel": null,
  142. "level": "A",
  143. "score": null,
  144. "result": "100",
  145. "originLevel": null,
  146. "markerId": 49,
  147. "marker": "pj061001",
  148. "updatedOn": 1594775592000,
  149. "imgSrc": "",
  150. "thumbSrc": "",
  151. "markByLeader": true,
  152. "oldRejected": false,
  153. "paperId": 168,
  154. "randomSeqNew": 9446110,
  155. "randomSeq": null,
  156. "rejected": false,
  157. "sample": true
  158. }
  159. */
  160. const initRights = {
  161. search: false,
  162. gradeInfo: false,
  163. gradeList: false,
  164. gradeHis: false
  165. };
  166. export default {
  167. name: "grade-action",
  168. props: {
  169. curPaperOrTask: {
  170. type: Object,
  171. default() {
  172. return {};
  173. }
  174. },
  175. levels: {
  176. type: Array,
  177. default() {
  178. return [];
  179. }
  180. },
  181. userRole: {
  182. type: String,
  183. default: "MARKER"
  184. }
  185. },
  186. data() {
  187. return {
  188. rights: {
  189. ...initRights
  190. },
  191. roleRight: {
  192. ADMIN: {
  193. done: ["search", "gradeHis", "gradeInfo"],
  194. reject: ["search", "gradeInfo", "gradeHis"],
  195. arbitrate: ["search", "gradeHis"]
  196. },
  197. MARK_LEADER: {
  198. done: ["search", "gradeList", "gradeHis", "gradeInfo"],
  199. reject: ["search", "gradeList", "gradeInfo", "gradeHis"],
  200. arbitrate: ["search", "gradeList", "gradeHis"]
  201. },
  202. MARKER: {
  203. done: ["gradeList", "gradeInfo"],
  204. undo: ["gradeList"],
  205. reject: ["gradeList", "gradeInfo"]
  206. },
  207. STANDARD: ["gradeInfo"]
  208. },
  209. filter: {
  210. codeType: "examNumber",
  211. code: ""
  212. },
  213. CODE_TYPE,
  214. stepDict: {
  215. undo: "待评",
  216. done: "已评",
  217. reject: "打回",
  218. arbitrate: "待仲裁",
  219. sample: "标准卷"
  220. },
  221. stepType: "",
  222. stepLabel: "",
  223. gradingHistory: [],
  224. curLevel: {},
  225. setT: null,
  226. btnClicked: false
  227. };
  228. },
  229. computed: {
  230. IS_ADMIN() {
  231. return this.userRole === "ADMIN";
  232. },
  233. IS_MARKER() {
  234. return this.userRole === "MARKER";
  235. },
  236. IS_MARK_LEADER() {
  237. return this.userRole === "MARK_LEADER";
  238. }
  239. },
  240. watch: {
  241. curPaperOrTask(val) {
  242. this.rebuildRight();
  243. }
  244. },
  245. mounted() {
  246. this.rebuildRight();
  247. },
  248. methods: {
  249. getStepType() {
  250. const info = this.curPaperOrTask;
  251. if (info.sample) return "sample";
  252. if (info.level) return "done";
  253. if (info.arbitrated) return "arbitrate";
  254. if (info.rejected) return "reject";
  255. if (!info.rejected && !info.arbitrated && !info.level) return "undo";
  256. return;
  257. },
  258. rebuildRight() {
  259. let roleRights = [];
  260. this.stepType = this.getStepType();
  261. this.stepLabel = this.stepDict[this.stepType];
  262. if (this.stepType === "sample") {
  263. roleRights = this.roleRight.STANDARD;
  264. } else {
  265. roleRights = this.roleRight[this.userRole][this.stepType] || [];
  266. }
  267. this.rights = { ...initRights };
  268. roleRights.map(key => {
  269. this.rights[key] = true;
  270. });
  271. this.getCurLevel();
  272. if (this.rights.gradeHis) {
  273. this.getMarkHistory();
  274. }
  275. },
  276. getCurLevel() {
  277. const levelName = this.curPaperOrTask.rejected
  278. ? this.curPaperOrTask.redoLevel
  279. : this.curPaperOrTask.level;
  280. if (levelName) {
  281. this.curLevel = this.levels.find(item => item.name === levelName);
  282. }
  283. },
  284. async getMarkHistory() {
  285. // 只有科组长和超管才会展示评卷记录
  286. const data = await markHistoryList(this.curPaperOrTask.id, "LEVEL");
  287. this.gradingHistory = data.map(item => {
  288. return {
  289. id: item.id,
  290. markerId: item.markerId,
  291. name: item.marker,
  292. value: item.result || "未评"
  293. };
  294. });
  295. },
  296. selectLevel(level) {
  297. if (this.btnClicked) return;
  298. this.btnClicked = true;
  299. this.setT = setTimeout(() => {
  300. this.btnClicked = false;
  301. }, 500);
  302. if (this.IS_MARK_LEADER) {
  303. this.$emit(
  304. "on-leader-level",
  305. {
  306. paperId: this.curPaperOrTask.id,
  307. curLevel: this.curPaperOrTask.level,
  308. selectedLevel: level.name
  309. },
  310. this.gradingHistory.map(item => {
  311. return {
  312. id: item.markerId,
  313. name: item.name
  314. };
  315. })
  316. );
  317. return;
  318. }
  319. this.$emit("on-select-level", level);
  320. },
  321. toPass() {
  322. this.$emit("on-pass");
  323. },
  324. searchCode() {
  325. this.$emit("on-code-search", this.filter);
  326. }
  327. },
  328. beforeDestroy() {
  329. if (this.setT) clearTimeout(this.setT);
  330. }
  331. };
  332. </script>