MarkDetail.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. <template>
  2. <div :class="compClasses">
  3. <div class="part-box-head">
  4. <Form ref="FilterForm" label-position="left" inline>
  5. <FormItem>
  6. <Select
  7. v-model="filter.questionId"
  8. @on-change="areaChange"
  9. placeholder="请选择考区"
  10. >
  11. <Option
  12. v-for="area in areas"
  13. :key="area.id"
  14. :value="area.id"
  15. :label="area.areaName"
  16. ></Option>
  17. </Select>
  18. </FormItem>
  19. <FormItem>
  20. <Button
  21. size="small"
  22. class="btn-form-search"
  23. type="primary"
  24. @click="toPage(1)"
  25. >查询</Button
  26. >
  27. </FormItem>
  28. </Form>
  29. </div>
  30. <grade-step
  31. :steps="steps"
  32. :init-step="curStep"
  33. :show-analysis="false"
  34. @on-change="stepChange"
  35. ref="GradeStep"
  36. v-if="steps.levelStep"
  37. ></grade-step>
  38. <div class="detail-body clear-float">
  39. <!-- detail-aciton -->
  40. <div
  41. :class="[
  42. 'detail-action',
  43. { 'detail-action-fullscreen': isFullscreenMarking }
  44. ]"
  45. >
  46. <mark-action
  47. :cur-paper-or-task="curPaper"
  48. :levels="levels"
  49. :user-role="curUserRoleType"
  50. @on-leader-level="leaderSelectLevel"
  51. @on-code-search="serachPaperByCode"
  52. @on-grade-change-search="searchGradeChangeList"
  53. v-if="curPaper.id"
  54. ref="GradeAction"
  55. ></mark-action>
  56. </div>
  57. <!-- detail-papers -->
  58. <div :class="detailPapersClasses">
  59. <div class="detail-papers-carousel" v-if="!IS_ADMIN">
  60. <grade-history-paper
  61. :question-id="filter.questionId"
  62. stage="SCORE"
  63. @on-paper-click="toViewCarouselPaper"
  64. v-if="filter.questionId"
  65. ref="GradeHistoryPaper"
  66. ></grade-history-paper>
  67. </div>
  68. <div class="detail-papers-list" v-if="papers.length">
  69. <div :class="imageViewClasses">
  70. <div
  71. :class="[
  72. 'image-view',
  73. { 'image-view-act': curPaperIndex === index }
  74. ]"
  75. v-for="(image, index) in papers"
  76. :key="index"
  77. >
  78. <h5 class="image-view-title">{{ image.title }}</h5>
  79. <div class="image-view-contain">
  80. <img
  81. :src="image.thumbSrc"
  82. :alt="image.title"
  83. @click="toReview(index)"
  84. />
  85. </div>
  86. </div>
  87. </div>
  88. <div class="part-page" v-if="total > size">
  89. <Page
  90. :current="current"
  91. :total="total"
  92. :page-size="size"
  93. show-total
  94. show-elevator
  95. @on-change="toPage"
  96. ></Page>
  97. </div>
  98. </div>
  99. <div class="detail-papers-list" v-else>
  100. <p class="detail-papers-none">暂无数据</p>
  101. </div>
  102. </div>
  103. </div>
  104. <!-- image-preview -->
  105. <image-preview
  106. :class="imagePreviewClasses"
  107. :image-list="papers"
  108. :init-index="curPaperIndex"
  109. @on-paper-change="selectPaper"
  110. @on-page-prev="prevPage"
  111. @on-page-next="nextPage"
  112. @on-close="isFullscreenMarking = false"
  113. header-hide
  114. ref="ImagePreview"
  115. v-if="papers.length"
  116. ></image-preview>
  117. <!-- carousel paper review -->
  118. <image-preview
  119. :class="imagePreviewClasses"
  120. :image-list="carouselPapers"
  121. :init-index="curCarouselPaperIndex"
  122. @on-paper-change="selectCarouselPaper"
  123. @on-close="carouseImagePreviewClose"
  124. loop
  125. header-hide
  126. ref="CarouselPapersPreview"
  127. v-if="carouselPapers.length"
  128. ></image-preview>
  129. </div>
  130. </template>
  131. <script>
  132. import {
  133. paperList,
  134. changeLevelPaperList,
  135. levelStatData,
  136. areaList,
  137. workLevelList,
  138. taskSnSearch,
  139. markStepChangeLevel
  140. } from "@/api";
  141. import ImagePreview from "@/components/common/ImagePreview";
  142. import GradeStep from "../grading/components/GradeStep";
  143. import GradeHistoryPaper from "../grading/components/GradeHistoryPaper";
  144. import MarkAction from "./components/MarkAction";
  145. // 三种情况:
  146. // 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
  147. // 管理员:试卷列表,操作盘
  148. // 科组长:操作记录,试卷列表,操作盘(改档)
  149. // TIP:不考虑评卷员的情况
  150. // 评卷员:操作记录,试卷列表,操作盘(打分)
  151. export default {
  152. name: "mark-detail",
  153. components: {
  154. ImagePreview,
  155. GradeStep,
  156. GradeHistoryPaper,
  157. MarkAction
  158. },
  159. data() {
  160. return {
  161. filter: {
  162. questionId: "",
  163. sort: "score,desc",
  164. level: "",
  165. isSample: false
  166. },
  167. workId: this.$route.params.workId,
  168. subjectId: this.$route.params.subjectId,
  169. subject: "",
  170. curUserRoleType: "",
  171. applyChangeLevelStatus: 1, // 改档申请处理状态
  172. current: 1,
  173. size: 6,
  174. total: 0,
  175. totalPage: 1,
  176. curStep: null,
  177. steps: [],
  178. levels: [],
  179. areas: [],
  180. papers: [],
  181. curPaper: {},
  182. curPaperIndex: 0,
  183. // carousel paper review,
  184. carouselPapers: [],
  185. curCarouselPaperIndex: 0,
  186. beforeCarouselCurPaperIndex: 0,
  187. isFullscreenMarking: false
  188. };
  189. },
  190. computed: {
  191. compClasses() {
  192. return [
  193. "mark-detail",
  194. "grading-detail",
  195. { "grading-operation": this.IS_MARK_LEADER }
  196. ];
  197. },
  198. bodyClasses() {
  199. return [
  200. "detail-body",
  201. { "detail-body-2": this.curUserRoleType === "ADMIN" }
  202. ];
  203. },
  204. detailPapersClasses() {
  205. return [
  206. "detail-papers",
  207. {
  208. [`detail-papers-col-${1 + this.size / 2}`]:
  209. this.curUserRoleType !== "ADMIN"
  210. }
  211. ];
  212. },
  213. imageViewClasses() {
  214. return ["image-view-list", `image-view-list-${this.size / 2}`];
  215. },
  216. IS_ADMIN() {
  217. return this.curUserRoleType === "ADMIN";
  218. },
  219. IS_MARK_LEADER() {
  220. return this.curUserRoleType === "MARK_LEADER";
  221. },
  222. imagePreviewClasses() {
  223. return this.IS_ADMIN
  224. ? "grading-detail-image-preview"
  225. : "grading-operation-image-preview";
  226. }
  227. },
  228. mounted() {
  229. this.subject = this.subjectId.split("-")[1];
  230. this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
  231. if (this.curUserRoleType === "ADMIN") this.size = 8;
  232. this.initData();
  233. },
  234. methods: {
  235. async initData() {
  236. this.getWorkLevels();
  237. await this.getAreaList();
  238. this.filter.questionId = this.areas[0].id;
  239. this.getStepLevels();
  240. },
  241. async getList() {
  242. let data = [];
  243. if (this.curStep.type === "done") {
  244. const datas = {
  245. ...this.filter,
  246. level: this.curStep.name,
  247. page: this.current - 1,
  248. size: this.size
  249. };
  250. data = await paperList(datas);
  251. } else {
  252. const datas = {
  253. workId: this.workId,
  254. subject: this.subject,
  255. questionId: this.filter.questionId,
  256. status: this.applyChangeLevelStatus,
  257. page: this.current - 1,
  258. size: this.size
  259. };
  260. data = await changeLevelPaperList(datas);
  261. }
  262. this.papers = data.data.map(paper => {
  263. paper.title = paper.examNumber;
  264. return paper;
  265. });
  266. this.total = data.totalCount;
  267. this.totalPage = data.pageCount;
  268. },
  269. toPage(page) {
  270. this.current = page;
  271. this.getList();
  272. },
  273. async getStepLevels() {
  274. const data = await levelStatData(this.subjectId, this.filter.questionId);
  275. const undoIndex = data.findIndex(item => item.id === null);
  276. let otherStep = [];
  277. if (undoIndex !== -1) {
  278. const undo = { ...data[undoIndex] };
  279. data.splice(undoIndex, 1);
  280. otherStep.push({
  281. name: "改档",
  282. count: undo.shift,
  283. type: "shift"
  284. });
  285. }
  286. let levelStep = data.map(item => {
  287. return {
  288. ...item,
  289. name: item.id,
  290. type: "done"
  291. };
  292. });
  293. this.steps = { levelStep, otherStep };
  294. if (!this.curStep) this.curStep = levelStep[0];
  295. },
  296. async getWorkLevels() {
  297. const data = await workLevelList(this.workId);
  298. this.levels = data.map(item => {
  299. return {
  300. id: item.id,
  301. name: item.code,
  302. minScore: item.minScore,
  303. maxScore: item.maxScore
  304. };
  305. });
  306. },
  307. async getAreaList() {
  308. const data = await areaList({
  309. workId: this.workId,
  310. subject: this.subject
  311. });
  312. this.areas = data.map(item => {
  313. return {
  314. id: item.id,
  315. areaName: item.areaName,
  316. areaCode: item.areaCode
  317. };
  318. });
  319. },
  320. async stepChange(step) {
  321. this.applyChangeLevelStatus = 1;
  322. this.curStep = step;
  323. this.current = 1;
  324. await this.getList();
  325. if (this.papers.length) {
  326. this.selectPaper(0);
  327. } else {
  328. this.curPaper = {};
  329. }
  330. },
  331. areaChange() {
  332. this.getStepLevels();
  333. this.toPage(1);
  334. },
  335. selectPaper(index) {
  336. this.curPaperIndex = index;
  337. this.curPaper = { ...this.papers[index] };
  338. },
  339. toReview(index) {
  340. this.isFullscreenMarking = true;
  341. this.selectPaper(index);
  342. this.$refs.ImagePreview.open();
  343. },
  344. async prevPage() {
  345. if (this.current === 1) {
  346. this.$Message.warning("当前已经是第一条数据了");
  347. return;
  348. }
  349. this.current--;
  350. await this.getList();
  351. this.selectPaper(this.papers.length - 1);
  352. if (this.papers.length) this.$refs.ImagePreview.initData();
  353. },
  354. async nextPage() {
  355. if (this.current === this.totalPage) {
  356. if (this.current > 1) {
  357. this.current--;
  358. } else {
  359. this.$Message.warning("当前已经是最后一条数据了");
  360. this.$refs.ImagePreview.cancel();
  361. this.$refs.CarouselPapersPreview &&
  362. this.$refs.CarouselPapersPreview.cancel();
  363. }
  364. }
  365. // 下一页时,继续获取当前页数据。
  366. await this.getList();
  367. this.selectPaper(0);
  368. if (this.papers.length) this.$refs.ImagePreview.initData();
  369. },
  370. toNext() {
  371. this.$refs.ImagePreview.showNext();
  372. },
  373. updateHistory() {
  374. this.$refs.GradeHistoryPaper.updatePapers();
  375. },
  376. async serachPaperByCode(params) {
  377. const data = await taskSnSearch(
  378. params.codeType,
  379. params.code,
  380. this.filter.questionId
  381. );
  382. if (!data) {
  383. this.$Message.error("没有查找到结果!");
  384. return;
  385. }
  386. data.title = data.examNumber;
  387. this.papers = [data];
  388. this.total = 1;
  389. },
  390. searchGradeChangeList(applyChangeLevelStatus) {
  391. this.applyChangeLevelStatus = applyChangeLevelStatus;
  392. this.toPage(1);
  393. },
  394. leaderSelectLevel(levelInfo) {
  395. const content = `确定申请由${levelInfo.curLevel}档改为${levelInfo.selectedLevel}并打回给所有老师吗?`;
  396. this.$Modal.confirm({
  397. content,
  398. onOk: async () => {
  399. await markStepChangeLevel({
  400. subjectId: this.subjectId,
  401. paperId: levelInfo.paperId,
  402. level: levelInfo.selectedLevel
  403. });
  404. this.$Message.success("申请改档成功!");
  405. this.getStepLevels();
  406. this.updateHistory();
  407. this.toNext();
  408. }
  409. });
  410. },
  411. // paper carousel
  412. toViewCarouselPaper(paperIndex, papers) {
  413. this.isFullscreenMarking = true;
  414. this.beforeCarouselCurPaperIndex = this.curPaperIndex;
  415. this.curPaperIndex = null;
  416. this.carouselPapers = papers;
  417. this.selectCarouselPaper(paperIndex);
  418. this.$nextTick(() => {
  419. this.$refs.CarouselPapersPreview.open();
  420. });
  421. },
  422. selectCarouselPaper(index) {
  423. this.curCarouselPaperIndex = index;
  424. this.curPaper = { ...this.carouselPapers[index] };
  425. },
  426. carouseImagePreviewClose() {
  427. this.isFullscreenMarking = false;
  428. this.selectPaper(this.beforeCarouselCurPaperIndex);
  429. }
  430. }
  431. };
  432. </script>