MarkDetail.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. <template>
  2. <div class="mark-detail grading-detail">
  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="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="grading-detail-image-preview"
  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="grading-detail-image-preview"
  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. changeLevelPaperAllList,
  136. levelStatData,
  137. areaList,
  138. workLevelList,
  139. taskSnSearch,
  140. markStepChangeLevel
  141. } from "@/api";
  142. import ImagePreview from "@/components/common/ImagePreview";
  143. import GradeStep from "../grading/components/GradeStep";
  144. import GradeHistoryPaper from "../grading/components/GradeHistoryPaper";
  145. import MarkAction from "./components/MarkAction";
  146. // 三种情况:
  147. // 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
  148. // 管理员:试卷列表,操作盘
  149. // 科组长:操作记录,试卷列表,操作盘(改档)
  150. // TIP:不考虑评卷员的情况
  151. // 评卷员:操作记录,试卷列表,操作盘(打分)
  152. export default {
  153. name: "mark-detail",
  154. components: {
  155. ImagePreview,
  156. GradeStep,
  157. GradeHistoryPaper,
  158. MarkAction
  159. },
  160. data() {
  161. return {
  162. filter: {
  163. questionId: "",
  164. sort: "score,desc",
  165. level: "",
  166. isSample: false
  167. },
  168. workId: this.$route.params.workId,
  169. subjectId: this.$route.params.subjectId,
  170. subject: "",
  171. curUserRoleType: "",
  172. applyChangeLevelStatus: 1, // 改档申请处理状态
  173. current: 1,
  174. size: 6,
  175. total: 0,
  176. totalPage: 1,
  177. curStep: null,
  178. steps: [],
  179. levels: [],
  180. areas: [],
  181. papers: [],
  182. curPaper: {},
  183. curPaperIndex: 0,
  184. // carousel paper review,
  185. carouselPapers: [],
  186. curCarouselPaperIndex: 0,
  187. beforeCarouselCurPaperIndex: 0,
  188. isFullscreenMarking: false
  189. };
  190. },
  191. computed: {
  192. bodyClasses() {
  193. return [
  194. "detail-body",
  195. { "detail-body-2": this.curUserRoleType === "ADMIN" }
  196. ];
  197. },
  198. detailPapersClasses() {
  199. return [
  200. "detail-papers",
  201. {
  202. [`detail-papers-col-${1 + this.size / 2}`]:
  203. this.curUserRoleType !== "ADMIN"
  204. }
  205. ];
  206. },
  207. imageViewClasses() {
  208. return ["image-view-list", `image-view-list-${this.size / 2}`];
  209. },
  210. IS_ADMIN() {
  211. return this.curUserRoleType === "ADMIN";
  212. },
  213. IS_MARK_LEADER() {
  214. return this.curUserRoleType === "MARK_LEADER";
  215. }
  216. },
  217. mounted() {
  218. this.subject = this.subjectId.split("-")[1];
  219. this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
  220. if (this.curUserRoleType === "ADMIN") this.size = 8;
  221. this.initData();
  222. },
  223. methods: {
  224. async initData() {
  225. this.getWorkLevels();
  226. await this.getAreaList();
  227. this.filter.questionId = this.areas[0].id;
  228. await this.getStepLevels();
  229. this.getList();
  230. },
  231. async getList() {
  232. let data = [];
  233. if (this.curStep.type === "done") {
  234. const datas = {
  235. ...this.filter,
  236. level: this.curStep.name,
  237. page: this.current - 1,
  238. size: this.size
  239. };
  240. data = await paperList(datas);
  241. } else {
  242. const datas = {
  243. markerId: this.$ls.get("user", { id: "" }).id,
  244. questionId: this.filter.questionId,
  245. status: this.applyChangeLevelStatus,
  246. page: this.current - 1,
  247. size: this.size
  248. };
  249. const requestAction = this.IS_ADMIN
  250. ? changeLevelPaperAllList
  251. : changeLevelPaperList;
  252. data = await requestAction(datas);
  253. }
  254. this.papers = data.data.map(paper => {
  255. paper.title = paper.examNumber;
  256. return paper;
  257. });
  258. this.total = data.totalCount;
  259. this.totalPage = data.pageCount;
  260. },
  261. toPage(page) {
  262. this.current = page;
  263. this.getList();
  264. },
  265. async getStepLevels() {
  266. const data = await levelStatData(this.subjectId, this.filter.questionId);
  267. const undoIndex = data.findIndex(item => item.id === null);
  268. let otherStep = [];
  269. if (undoIndex !== -1) {
  270. const undo = { ...data[undoIndex] };
  271. data.splice(undoIndex, 1);
  272. otherStep.push({
  273. name: "改档",
  274. count: undo.shift,
  275. type: "shift"
  276. });
  277. }
  278. let levelStep = data.map(item => {
  279. return {
  280. ...item,
  281. name: item.id,
  282. type: "done"
  283. };
  284. });
  285. this.steps = { levelStep, otherStep };
  286. if (!this.curStep) this.curStep = levelStep[0];
  287. },
  288. async getWorkLevels() {
  289. const data = await workLevelList(this.workId);
  290. this.levels = data.map(item => {
  291. return {
  292. id: item.id,
  293. name: item.code,
  294. minScore: item.minScore,
  295. maxScore: item.maxScore
  296. };
  297. });
  298. },
  299. async getAreaList() {
  300. const data = await areaList({
  301. workId: this.workId,
  302. subject: this.subject
  303. });
  304. this.areas = data.map(item => {
  305. return {
  306. id: item.id,
  307. areaName: item.areaName,
  308. areaCode: item.areaCode
  309. };
  310. });
  311. },
  312. async stepChange(step) {
  313. this.curStep = step;
  314. this.current = 1;
  315. await this.getList();
  316. if (this.papers.length) {
  317. this.selectPaper(0);
  318. } else {
  319. this.curPaper = {};
  320. }
  321. },
  322. areaChange() {
  323. this.getStepLevels();
  324. this.toPage(1);
  325. },
  326. selectPaper(index) {
  327. this.curPaperIndex = index;
  328. this.curPaper = { ...this.papers[index] };
  329. },
  330. toReview(index) {
  331. this.isFullscreenMarking = true;
  332. this.selectPaper(index);
  333. this.$refs.ImagePreview.open();
  334. },
  335. async prevPage() {
  336. if (this.current === 1) {
  337. this.$Message.warning("当前已经是第一条数据了");
  338. return;
  339. }
  340. this.current--;
  341. await this.getList();
  342. this.selectPaper(this.papers.length - 1);
  343. if (this.papers.length) this.$refs.ImagePreview.initData();
  344. },
  345. async nextPage() {
  346. if (this.current === this.totalPage) {
  347. if (this.current > 1) {
  348. this.current--;
  349. } else {
  350. this.$Message.warning("当前已经是最后一条数据了");
  351. }
  352. }
  353. // 下一页时,继续获取当前页数据。
  354. await this.getList();
  355. this.selectPaper(0);
  356. if (this.papers.length) this.$refs.ImagePreview.initData();
  357. },
  358. toNext() {
  359. this.$refs.ImagePreview.showNext();
  360. },
  361. updateHistory() {
  362. this.$refs.GradeHistoryPaper.updatePapers();
  363. },
  364. async serachPaperByCode(params) {
  365. const data = await taskSnSearch(
  366. params.codeType,
  367. params.code,
  368. this.filter.questionId
  369. );
  370. if (!data) {
  371. this.$Message.error("没有查找到结果!");
  372. return;
  373. }
  374. data.title = data.examNumber;
  375. this.papers = [data];
  376. this.total = 1;
  377. },
  378. searchGradeChangeList(applyChangeLevelStatus) {
  379. this.applyChangeLevelStatus = applyChangeLevelStatus;
  380. this.toPage(1);
  381. },
  382. leaderSelectLevel(levelInfo) {
  383. const content = `确定申请由${levelInfo.curLevel}档改为${levelInfo.selectedLevel}并打回给所有老师吗?`;
  384. this.$Modal.confirm({
  385. title: "改档",
  386. content,
  387. onOk: async () => {
  388. await markStepChangeLevel({
  389. subjectId: this.subjectId,
  390. paperId: levelInfo.paperId,
  391. level: levelInfo.selectedLevel
  392. });
  393. this.$Message.success("改档成功!");
  394. this.getStepLevels();
  395. this.updateHistory();
  396. this.toNext();
  397. }
  398. });
  399. },
  400. // paper carousel
  401. toViewCarouselPaper(paperIndex, papers) {
  402. this.isFullscreenMarking = true;
  403. this.beforeCarouselCurPaperIndex = this.curPaperIndex;
  404. this.curPaperIndex = null;
  405. this.carouselPapers = papers;
  406. this.selectCarouselPaper(paperIndex);
  407. this.$nextTick(() => {
  408. this.$refs.CarouselPapersPreview.open();
  409. });
  410. },
  411. selectCarouselPaper(index) {
  412. this.curCarouselPaperIndex = index;
  413. this.curPaper = { ...this.carouselPapers[index] };
  414. },
  415. carouseImagePreviewClose() {
  416. this.isFullscreenMarking = false;
  417. this.selectPaper(this.beforeCarouselCurPaperIndex);
  418. }
  419. }
  420. };
  421. </script>