zhangjie 4 ani în urmă
părinte
comite
1ece1bf668

+ 8 - 12
src/api.js

@@ -263,17 +263,17 @@ export const paperList = datas => {
   // ?questionId=64&level=A&page=0&size=6&sort=secretNumber&isSample=true
   return $get("/api/papers", datas);
 };
-export const markerPaperList = datas => {
+export const markerTaskList = datas => {
   // ?stage=LEVEL&markerId=49&size=6&page=0&sort=updatedOn,desc&questionId=73&isSample=false&level=C
   return $get("/api/marktasks", datas);
 };
 // grading or scoring
-export const paperSelectLevelOrScore = (paperId, result, stage) => {
+export const paperSelectLevelOrScore = (taskId, result, stage) => {
   // stage => LEVEL or SCORE
-  return $patch(`/api/marktasks/${paperId}`, { stage, result }, "json");
+  return $patch(`/api/marktasks/${taskId}`, { stage, result }, "json");
 };
-export const paperTaskPass = paperId => {
-  return $post(`/api/marktasks/${paperId}/skip`, {});
+export const paperTaskPass = taskId => {
+  return $post(`/api/marktasks/${taskId}/skip`, {});
 };
 // grade or mark history
 export const markHistoryList = (paperId, stage) => {
@@ -310,13 +310,9 @@ export const markStepChangeLevel = ({ subjectId, paperId, level }) => {
   return $post(`/api/changelevel/${subjectId}/changeLevel`, { paperId, level });
 };
 export const changeLevelPaperList = datas => {
-  // 非纪检人员和超级管理员查询改档列表
-  // status => 0:申请的,1:审核通过的,2:审核未通过
-  return $get("/api/changelevel/list", datas);
-};
-export const changeLevelPaperAllList = datas => {
-  // 纪检人员和超级管理员查询改档列表
+  // 纪检人员、超级管理员和科组长查询改档列表
   // status => 0:未审核,1:已审核
+  // 科组长默认查询审核通过的
   return $get("/api/changelevel/list", datas);
 };
 
@@ -336,7 +332,7 @@ export const markerScoreStatData = (userId, questionId) => {
   return $get(`/api/markers/${userId}/stat/scores`, { questionId });
 };
 // mark-operation
-export const markerStepChangeList = datas => {
+export const markerChangeLevelPaperList = datas => {
   // ?markerId=49&size=6&page=0&isShift=true&isShiftScore=false&questionId=10
   return $get(`/api/marktasks/shift`, datas);
 };

+ 7 - 0
src/assets/styles/main.less

@@ -532,6 +532,13 @@
     }
   }
 
+  &-none {
+    padding-top: 200px;
+    text-align: center;
+    font-size: 24px;
+    color: @dark-color-lighter;
+  }
+
   &-image-preview {
     .ivu-modal-mask,
     .ivu-modal-wrap {

+ 19 - 0
src/assets/styles/mark.less

@@ -525,6 +525,7 @@
     font-size: 20px;
     border-radius: @box-border-radius;
     line-height: 28px;
+    text-align: left;
 
     > p:first-child {
       margin-bottom: 10px;
@@ -765,3 +766,21 @@
     }
   }
 }
+.task-confirm-modal {
+  .ivu-modal-header {
+    padding: 20px 32px;
+    border: 0;
+  }
+  .ivu-modal-body {
+    padding: 10px 32px;
+  }
+  .ivu-modal-footer {
+    padding: 0 32px 32px;
+  }
+  .ivu-modal-header-inner {
+    text-align: left;
+  }
+  .ivu-modal-content {
+    background-color: @background-color;
+  }
+}

+ 229 - 0
src/components/SimpleImagePreview.vue

@@ -0,0 +1,229 @@
+<template>
+  <Modal
+    :class="prefixCls"
+    v-model="modalIsShow"
+    title="图片预览"
+    :mask-closable="false"
+    fullscreen
+    footer-hide
+    @on-visible-change="visibleChange"
+  >
+    <div slot="header"></div>
+    <div :class="[`${prefixCls}-close`]" @click="cancel">
+      <i class="el-icon-circle-close"></i>
+      <Icon type="ios-close" />
+    </div>
+
+    <div :class="[`${prefixCls}-body`]" ref="ReviewBody">
+      <div
+        :class="[`${prefixCls}-guide`, `${prefixCls}-guide-prev`]"
+        @click="showPrev"
+      >
+        <Icon type="ios-arrow-back" />
+      </div>
+      <div
+        :class="[`${prefixCls}-guide`, `${prefixCls}-guide-next`]"
+        @click="showNext"
+      >
+        <Icon type="ios-arrow-forward" />
+      </div>
+      <div
+        :class="[
+          `${prefixCls}-imgs`,
+          { [`${prefixCls}-imgs-nosition`]: nosition }
+        ]"
+        :style="styles"
+        v-show="!loading"
+      >
+        <img
+          :src="curImage.imgSrc"
+          :alt="curImage.name"
+          ref="PreviewImgDetail"
+        />
+      </div>
+    </div>
+
+    <div :class="[`${prefixCls}-footer`]">
+      <ul>
+        <li title="旋转" @click="toRotate">
+          <Icon type="ios-refresh-circle" />
+        </li>
+      </ul>
+    </div>
+
+    <div :class="[`${prefixCls}-loading`]" v-show="loading">
+      <Icon class="ivu-load-loop" type="ios-loading" />
+    </div>
+  </Modal>
+</template>
+
+<script>
+const prefixCls = "cc-image-preview";
+
+export default {
+  name: "simple-image-preview",
+  props: {
+    curImage: {
+      type: Object,
+      default() {
+        return {};
+      }
+    }
+  },
+  data() {
+    return {
+      prefixCls,
+      modalIsShow: false,
+      styles: { width: "", height: "", top: "", left: "", transform: "" },
+      initWidth: 500,
+      transform: {
+        scale: 1,
+        rotate: 0
+      },
+      loading: false,
+      loadingSetT: null,
+      nosition: false
+    };
+  },
+  mounted() {
+    this.registfileLoad();
+  },
+  methods: {
+    visibleChange(visible) {
+      if (!visible) return;
+      this.initData();
+    },
+    initData() {
+      this.nosition = true;
+      this.loadingSetT = setTimeout(() => {
+        this.loading = true;
+      }, 100);
+    },
+    registfileLoad() {
+      const imgDom = this.$refs.PreviewImgDetail;
+      imgDom.onload = () => {
+        const { naturalWidth, naturalHeight } = imgDom;
+        const imageSize = this.getImageSizePos({
+          win: {
+            width: this.$refs.ReviewBody.clientWidth,
+            height: this.$refs.ReviewBody.clientHeight
+          },
+          img: {
+            width: naturalWidth,
+            height: naturalHeight
+          },
+          rotate: 0
+        });
+
+        this.styles = Object.assign(this.styles, {
+          width: imageSize.width + "px",
+          height: imageSize.height + "px",
+          top: imageSize.top + "px",
+          left: imageSize.left + "px",
+          transform: ""
+        });
+        this.transform = {
+          scale: 1,
+          rotate: 0
+        };
+        if (this.loadingSetT) clearTimeout(this.loadingSetT);
+        this.loading = false;
+        setTimeout(() => {
+          this.nosition = false;
+        }, 100);
+      };
+    },
+    getImageSizePos({ win, img, rotate }) {
+      const imageSize = {
+        width: 0,
+        height: 0,
+        top: 0,
+        left: 0
+      };
+      const isHorizontal = !!(rotate % 180);
+
+      const rateWin = isHorizontal
+        ? win.height / win.width
+        : win.width / win.height;
+      const hwin = isHorizontal
+        ? {
+            width: win.height,
+            height: win.width
+          }
+        : win;
+
+      const rateImg = img.width / img.height;
+
+      if (rateImg <= rateWin) {
+        imageSize.height = Math.min(hwin.height, img.height);
+        imageSize.width = Math.floor(
+          (imageSize.height * img.width) / img.height
+        );
+      } else {
+        imageSize.width = Math.min(hwin.width, img.width);
+        imageSize.height = Math.floor(
+          (imageSize.width * img.height) / img.width
+        );
+      }
+      imageSize.left = (win.width - imageSize.width) / 2;
+      imageSize.top = (win.height - imageSize.height) / 2;
+      return imageSize;
+    },
+    cancel() {
+      this.modalIsShow = false;
+      this.$emit("on-close");
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    showPrev() {
+      this.$emit("on-prev");
+      this.initData();
+    },
+    showNext() {
+      this.$emit("on-next");
+      this.initData();
+    },
+    // dome-move
+    setStyleTransform() {
+      const { scale, rotate } = this.transform;
+      this.styles.transform = `scale(${scale}, ${scale}) rotate(${rotate}deg)`;
+    },
+    toRotate() {
+      this.transform.rotate = this.transform.rotate + 90;
+      this.setStyleTransform();
+      // 调整图片尺寸
+      const { naturalWidth, naturalHeight } = this.$refs.PreviewImgDetail;
+      const imageSize = this.getImageSizePos({
+        win: {
+          width: this.$refs.ReviewBody.clientWidth,
+          height: this.$refs.ReviewBody.clientHeight
+        },
+        img: {
+          width: naturalWidth,
+          height: naturalHeight
+        },
+        rotate: this.transform.rotate
+      });
+
+      this.styles = Object.assign(this.styles, {
+        width: imageSize.width + "px",
+        height: imageSize.height + "px",
+        top: imageSize.top + "px",
+        left: imageSize.left + "px"
+      });
+      // 360度无缝切换到0度
+      if (this.transform.rotate >= 360) {
+        setTimeout(() => {
+          this.nosition = true;
+          this.transform.rotate = 0;
+          this.setStyleTransform();
+          setTimeout(() => {
+            this.nosition = false;
+          }, 100);
+        }, 200);
+      }
+    }
+  }
+};
+</script>

+ 15 - 4
src/modules/grading/GradingDetail.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="grading-detail">
+  <div :class="compClasses">
     <div class="part-box-head grading-head">
       <div class="part-box-head-left">
         <Form ref="FilterForm" label-position="left" inline>
@@ -49,7 +49,7 @@
         ]"
       >
         <grade-action
-          :cur-paper="curPaper"
+          :cur-paper-or-task="curPaper"
           :levels="levels"
           :user-role="curUserRoleType"
           @on-leader-level="leaderSelectLevel"
@@ -121,7 +121,7 @@
 
     <!-- image-preview -->
     <image-preview
-      class="grading-detail-image-preview"
+      :class="imagePreviewClasses"
       :image-list="papers"
       :init-index="curPaperIndex"
       @on-paper-change="selectPaper"
@@ -134,7 +134,7 @@
     ></image-preview>
     <!-- carousel paper review -->
     <image-preview
-      class="grading-detail-image-preview"
+      :class="imagePreviewClasses"
       :image-list="carouselPapers"
       :init-index="curCarouselPaperIndex"
       @on-paper-change="selectCarouselPaper"
@@ -232,6 +232,9 @@ export default {
     };
   },
   computed: {
+    compClasses() {
+      return ["grading-detail", { "grading-operation": this.IS_MARK_LEADER }];
+    },
     detailPapersClasses() {
       return ["detail-papers", `detail-papers-col-${1 + this.size / 2}`];
     },
@@ -243,6 +246,11 @@ export default {
     },
     IS_MARK_LEADER() {
       return this.curUserRoleType === "MARK_LEADER";
+    },
+    imagePreviewClasses() {
+      return this.IS_ADMIN
+        ? "grading-detail-image-preview"
+        : "grading-operation-image-preview";
     }
   },
   mounted() {
@@ -378,6 +386,9 @@ export default {
           this.current--;
         } else {
           this.$Message.warning("当前已经是最后一条数据了");
+          this.$refs.ImagePreview.cancel();
+          this.$refs.CarouselPapersPreview &&
+            this.$refs.CarouselPapersPreview.cancel();
         }
       }
       // 下一页时,继续获取当前页数据。

+ 8 - 6
src/modules/grading/GradingOperation.vue

@@ -49,7 +49,7 @@
             ]"
           >
             <grade-action
-              :cur-paper="curPaper"
+              :cur-paper-or-task="curPaper"
               :levels="levels"
               :user-role="curUserRoleType"
               @on-select-level="gradeCurPaper"
@@ -148,7 +148,7 @@
 
 <script>
 import {
-  markerPaperList,
+  markerTaskList,
   markerLevelStatData,
   areaList,
   workLevelList,
@@ -239,8 +239,7 @@ export default {
 
       await this.getAreaList();
       this.filter.questionId = this.areas[0].id;
-      await this.getStepLevels();
-      this.getList();
+      this.getStepLevels();
     },
     async getSubjectDetail() {
       this.curSubject = await subjectDetail(this.subjectId);
@@ -257,7 +256,7 @@ export default {
         datas.sort = "updatedOn,desc";
       }
 
-      const data = await markerPaperList(datas);
+      const data = await markerTaskList(datas);
       this.papers = data.data.map(paper => {
         paper.title = `NO.${paper.sn}`;
         return paper;
@@ -378,6 +377,9 @@ export default {
           this.current--;
         } else {
           this.$Message.warning("当前已经是最后一条数据了");
+          this.$refs.ImagePreview.cancel();
+          this.$refs.CarouselPapersPreview &&
+            this.$refs.CarouselPapersPreview.cancel();
         }
       }
       // 下一页时,继续获取当前页数据。
@@ -387,7 +389,7 @@ export default {
     },
     async gradeCurPaper(level) {
       const data = await paperSelectLevelOrScore(
-        this.curPaper.id,
+        this.curPaper.id, // is taskId
         level.name,
         "LEVEL"
       );

+ 10 - 2
src/modules/grading/GradingProgress.vue

@@ -237,8 +237,16 @@ export default {
         }
       });
     },
-    toExportStandard() {},
-    toExportGrading() {}
+    toExportStandard() {
+      window.open(
+        `${this.GLOBAL.domain}/api/export/paper/${this.curSubject.workId}/${this.curSubject.subject}/sample`
+      );
+    },
+    toExportGrading() {
+      window.open(
+        `${this.GLOBAL.domain}/api/export/paper/${this.curSubject.workId}/${this.curSubject.subject}/oneClickLevel`
+      );
+    }
   }
 };
 </script>

+ 3 - 1
src/modules/grading/GradingUserManage.vue

@@ -171,7 +171,9 @@ export default {
       this.getList();
     },
     toExport() {
-      window.open(`${this.GLOBAL.domain}/export/users?workId=${this.workId}`);
+      window.open(
+        `${this.GLOBAL.domain}/api/export/users?workId=${this.workId}`
+      );
     }
   }
 };

+ 24 - 17
src/modules/grading/components/GradeAction.vue

@@ -33,15 +33,17 @@
     <!-- 试卷信息 -->
     <div class="action-paper-info">
       <p v-if="IS_ADMIN">
-        <span>试卷考号:</span><span>{{ curPaper.examNumber }}</span>
+        <span>试卷考号:</span><span>{{ curPaperOrTask.examNumber }}</span>
       </p>
       <p>
-        <span>试卷密号:</span><span>NO.{{ curPaper.sn }}</span>
+        <span>试卷密号:</span><span>NO.{{ curPaperOrTask.sn }}</span>
       </p>
     </div>
     <!-- 档位信息 -->
     <!-- 已评(已评档位),打回(建议档位) -->
-    <h3 class="action-grade-info-title" v-if="curPaper.rejected">建议档位:</h3>
+    <h3 class="action-grade-info-title" v-if="curPaperOrTask.rejected">
+      建议档位:
+    </h3>
     <div class="action-grade-info" v-if="rights.gradeInfo">
       <h3 class="grade-info-name">{{ curLevel.name }}</h3>
       <div class="grade-info-range">
@@ -95,6 +97,10 @@ import { CODE_TYPE } from "@/constants/enumerate";
 // 管理员:查询,头部信息,评卷记录
 // 科组长:查询,头部信息,选择档位,评卷记录
 // 评卷员:头部信息,选择档位
+
+// MARK_LEADER / ADMIN: curPaperOrTask => paper
+// MARKER: curPaperOrTask => task
+//
 /*
 [paper template]
 {
@@ -159,7 +165,7 @@ const initRights = {
 export default {
   name: "grade-action",
   props: {
-    curPaper: {
+    curPaperOrTask: {
       type: Object,
       default() {
         return {};
@@ -229,7 +235,7 @@ export default {
     }
   },
   watch: {
-    curPaper(val) {
+    curPaperOrTask(val) {
       this.rebuildRight();
     }
   },
@@ -238,12 +244,12 @@ export default {
   },
   methods: {
     getStepType() {
-      const paper = this.curPaper;
-      if (paper.sample) return "sample";
-      if (paper.level) return "done";
-      if (paper.arbitrated) return "arbitrate";
-      if (paper.rejected) return "reject";
-      if (!paper.rejected && !paper.arbitrated && !paper.level) return "undo";
+      const info = this.curinfoOrTask;
+      if (info.sample) return "sample";
+      if (info.level) return "done";
+      if (info.arbitrated) return "arbitrate";
+      if (info.rejected) return "reject";
+      if (!info.rejected && !info.arbitrated && !info.level) return "undo";
       return;
     },
     rebuildRight() {
@@ -265,15 +271,16 @@ export default {
       }
     },
     getCurLevel() {
-      const levelName = this.curPaper.rejected
-        ? this.curPaper.redoLevel
-        : this.curPaper.level;
+      const levelName = this.curPaperOrTask.rejected
+        ? this.curPaperOrTask.redoLevel
+        : this.curPaperOrTask.level;
       if (levelName) {
         this.curLevel = this.levels.find(item => item.name === levelName);
       }
     },
     async getMarkHistory() {
-      const data = await markHistoryList(this.curPaper.id, "LEVEL");
+      // 只有科组长和超管才会展示评卷记录
+      const data = await markHistoryList(this.curPaperOrTask.id, "LEVEL");
       this.gradingHistory = data.map(item => {
         return {
           id: item.id,
@@ -288,8 +295,8 @@ export default {
         this.$emit(
           "on-leader-level",
           {
-            curPaperId: this.curPaper.id,
-            curLevel: this.curPaper.level,
+            paperId: this.curPaperOrTask.id,
+            curLevel: this.curPaperOrTask.level,
             selectedLevel: level.name
           },
           this.gradingHistory.map(item => {

+ 2 - 2
src/modules/grading/components/ModifyLeaderGrading.vue

@@ -57,7 +57,7 @@ export default {
       type: Object,
       default() {
         return {
-          curPaperId: "",
+          paperId: "",
           curLevel: "",
           selectedLevel: ""
         };
@@ -123,7 +123,7 @@ export default {
       this.isSubmit = true;
       let result = true;
       const paper = await leaderGradingPaper(
-        this.LevelInfo.curPaperId,
+        this.LevelInfo.paperId,
         datas
       ).catch(() => {
         result = false;

+ 33 - 11
src/modules/inspection/InspectionGrading.vue

@@ -68,8 +68,14 @@
       </Form>
     </div>
 
-    <div class="check-grade">
-      <div class="check-grade-action" v-if="curPaper.id">
+    <div class="check-grade" v-if="papers.length">
+      <div
+        :class="[
+          'check-grade-action',
+          { 'check-grade-action-fullscreen': isFullscreenMarking }
+        ]"
+        v-if="curPaper.id"
+      >
         <div class="action-paper-info">
           <p>
             <span>试卷考号:</span><span>{{ curPaper.examNumber }}</span>
@@ -105,7 +111,7 @@
         </div>
       </div>
 
-      <div class="check-grade-body">
+      <div class="check-grade-body part-box">
         <div class="check-grade-list image-view-list image-view-list-4">
           <div class="image-view" v-for="(image, index) in papers" :key="index">
             <h5 class="image-view-title">{{ image.title }}</h5>
@@ -130,6 +136,9 @@
         </div>
       </div>
     </div>
+    <div class="check-grade" v-else>
+      <p class="check-grade-none">暂无数据</p>
+    </div>
 
     <!-- image-preview -->
     <image-preview
@@ -139,6 +148,7 @@
       @on-paper-change="selectPaper"
       @on-page-prev="prevPage"
       @on-page-next="nextPage"
+      @on-close="isFullscreenMarking = false"
       header-hide
       ref="ImagePreview"
       v-if="papers.length"
@@ -148,7 +158,7 @@
 
 <script>
 import {
-  changeLevelPaperAllList,
+  changeLevelPaperList,
   inspectionConfirmCheckGrade,
   workList,
   areaList
@@ -177,7 +187,8 @@ export default {
       totalPage: 1,
       papers: [],
       curPaper: {},
-      curPaperIndex: 0
+      curPaperIndex: 0,
+      isFullscreenMarking: false
     };
   },
   mounted() {
@@ -214,9 +225,13 @@ export default {
         current: this.current,
         size: this.size
       };
-      const data = await changeLevelPaperAllList(datas);
-      this.papers = data.data;
+      const data = await changeLevelPaperList(datas);
+      this.papers = data.data.map(item => {
+        item.title = `NO.${item.sn}`;
+        return item;
+      });
       this.total = data.totalCount;
+      this.totalPage = data.pageCount;
     },
     toPage(page) {
       this.current = page;
@@ -228,8 +243,10 @@ export default {
       const curWork = this.works.find(item => item.id === this.filter.workId);
       this.subjects = curWork.subjects;
       this.filter.subject = this.subjects[0].subject;
+      this.subjectChange();
     },
     subjectChange() {
+      this.areas = [];
       this.filter.questionId = null;
       this.getAreaList();
     },
@@ -259,6 +276,7 @@ export default {
       this.curPaper = { ...this.papers[index] };
     },
     toReview(index) {
+      this.isFullscreenMarking = true;
       this.selectPaper(index);
       this.$refs.ImagePreview.open();
     },
@@ -278,17 +296,21 @@ export default {
       this.current--;
       await this.getList();
       this.selectPaper(this.papers.length - 1);
-      this.$refs.ImagePreview.initData();
+      if (this.papers.length) this.$refs.ImagePreview.initData();
     },
     async nextPage() {
       if (this.current === this.totalPage) {
-        this.$Message.warning("当前已经是最后一条数据了");
-        return;
+        if (this.current > 1) {
+          this.current--;
+        } else {
+          this.$Message.warning("当前已经是最后一条数据了");
+          this.$refs.ImagePreview.cancel();
+        }
       }
       // 下一页时,继续获取当前页数据。
       await this.getList();
       this.selectPaper(0);
-      this.$refs.ImagePreview.initData();
+      if (this.papers.length) this.$refs.ImagePreview.initData();
     }
   }
 };

+ 0 - 1
src/modules/main/WorkManage.vue

@@ -55,7 +55,6 @@ export default {
           title: "序号",
           width: 80,
           render: (h, param) => {
-            console.log(param);
             return h("div", param.index + 1 + "");
           }
         },

+ 3 - 3
src/modules/main/WorkOverview.vue

@@ -96,15 +96,15 @@ export default {
   },
   mounted() {
     this.getDetail();
-    this.exportGradeScoreUrl = `${this.GLOBAL.domain}/export/score/exportLevelResult?workId=${this.workId}`;
-    this.exportScoreUrl = `${this.GLOBAL.domain}/export/score/exportScoreResult?workId=${this.workId}`;
+    this.exportGradeScoreUrl = `${this.GLOBAL.domain}/api/export/score/exportLevelResult?workId=${this.workId}`;
+    this.exportScoreUrl = `${this.GLOBAL.domain}/api/export/score/exportScoreResult?workId=${this.workId}`;
   },
   methods: {
     async getDetail() {
       const data = await workOverviewDetail(this.workId);
       data.subjectOverviews.map(item => {
         item.markStageName = SUBJECT_STAGE[item.markStage];
-        item.exportAbsentDataUrl = `${this.GLOBAL.domain}/export/users/${this.workId}/${item.subject}/export`;
+        item.exportAbsentDataUrl = `${this.GLOBAL.domain}/api/export/users/${this.workId}/${item.subject}/export`;
         item.progress =
           item.uploadedCount + item.leftCount
             ? (

+ 25 - 14
src/modules/mark/MarkDetail.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="mark-detail grading-detail">
+  <div :class="compClasses">
     <div class="part-box-head">
       <Form ref="FilterForm" label-position="left" inline>
         <FormItem>
@@ -44,7 +44,7 @@
         ]"
       >
         <mark-action
-          :cur-paper="curPaper"
+          :cur-paper-or-task="curPaper"
           :levels="levels"
           :user-role="curUserRoleType"
           @on-leader-level="leaderSelectLevel"
@@ -104,7 +104,7 @@
 
     <!-- image-preview -->
     <image-preview
-      class="grading-detail-image-preview"
+      :class="imagePreviewClasses"
       :image-list="papers"
       :init-index="curPaperIndex"
       @on-paper-change="selectPaper"
@@ -117,7 +117,7 @@
     ></image-preview>
     <!-- carousel paper review -->
     <image-preview
-      class="grading-detail-image-preview"
+      :class="imagePreviewClasses"
       :image-list="carouselPapers"
       :init-index="curCarouselPaperIndex"
       @on-paper-change="selectCarouselPaper"
@@ -134,7 +134,6 @@
 import {
   paperList,
   changeLevelPaperList,
-  changeLevelPaperAllList,
   levelStatData,
   areaList,
   workLevelList,
@@ -193,6 +192,13 @@ export default {
     };
   },
   computed: {
+    compClasses() {
+      return [
+        "mark-detail",
+        "grading-detail",
+        { "grading-operation": this.IS_MARK_LEADER }
+      ];
+    },
     bodyClasses() {
       return [
         "detail-body",
@@ -216,6 +222,11 @@ export default {
     },
     IS_MARK_LEADER() {
       return this.curUserRoleType === "MARK_LEADER";
+    },
+    imagePreviewClasses() {
+      return this.IS_ADMIN
+        ? "grading-detail-image-preview"
+        : "grading-operation-image-preview";
     }
   },
   mounted() {
@@ -230,8 +241,7 @@ export default {
 
       await this.getAreaList();
       this.filter.questionId = this.areas[0].id;
-      await this.getStepLevels();
-      this.getList();
+      this.getStepLevels();
     },
     async getList() {
       let data = [];
@@ -246,16 +256,14 @@ export default {
         data = await paperList(datas);
       } else {
         const datas = {
-          markerId: this.$ls.get("user", { id: "" }).id,
+          workId: this.workId,
+          subject: this.subject,
           questionId: this.filter.questionId,
           status: this.applyChangeLevelStatus,
           page: this.current - 1,
           size: this.size
         };
-        const requestAction = this.IS_ADMIN
-          ? changeLevelPaperAllList
-          : changeLevelPaperList;
-        data = await requestAction(datas);
+        data = await changeLevelPaperList(datas);
       }
       this.papers = data.data.map(paper => {
         paper.title = paper.examNumber;
@@ -316,6 +324,7 @@ export default {
       });
     },
     async stepChange(step) {
+      this.applyChangeLevelStatus = 1;
       this.curStep = step;
       this.current = 1;
       await this.getList();
@@ -354,6 +363,9 @@ export default {
           this.current--;
         } else {
           this.$Message.warning("当前已经是最后一条数据了");
+          this.$refs.ImagePreview.cancel();
+          this.$refs.CarouselPapersPreview &&
+            this.$refs.CarouselPapersPreview.cancel();
         }
       }
       // 下一页时,继续获取当前页数据。
@@ -388,7 +400,6 @@ export default {
     leaderSelectLevel(levelInfo) {
       const content = `确定申请由${levelInfo.curLevel}档改为${levelInfo.selectedLevel}并打回给所有老师吗?`;
       this.$Modal.confirm({
-        title: "改档",
         content,
         onOk: async () => {
           await markStepChangeLevel({
@@ -396,7 +407,7 @@ export default {
             paperId: levelInfo.paperId,
             level: levelInfo.selectedLevel
           });
-          this.$Message.success("改档成功!");
+          this.$Message.success("申请改档成功!");
           this.getStepLevels();
           this.updateHistory();
           this.toNext();

+ 23 - 11
src/modules/mark/MarkOperation.vue

@@ -47,9 +47,10 @@
             ]"
           >
             <mark-action
-              :cur-paper="curPaper"
+              :cur-paper-or-task="curPaper"
               :levels="levels"
               :user-role="curUserRoleType"
+              @on-leader-level="gradingCurPaper"
               @on-select-score="scoreCurPaper"
               @on-pass="passCurPaper"
               ref="GradeAction"
@@ -141,8 +142,8 @@
 
 <script>
 import {
-  markerPaperList,
-  markerStepChangeList,
+  markerTaskList,
+  markerChangeLevelPaperList,
   markerScoreStatData,
   areaList,
   workLevelList,
@@ -186,7 +187,7 @@ export default {
           sort: "updatedOn,desc",
           stage: "SCORE"
         },
-        shife: {
+        shift: {
           isShift: true,
           isShiftScore: false
         },
@@ -238,8 +239,7 @@ export default {
 
       await this.getAreaList();
       this.filter.questionId = this.areas[0].id;
-      await this.getStepLevels();
-      this.getList();
+      this.getStepLevels();
     },
     async getSubjectDetail() {
       this.curSubject = await subjectDetail(this.subjectId);
@@ -255,8 +255,8 @@ export default {
         datas.level = this.curStep.name;
       }
       const requestAction = this.curStep.type.includes("shift")
-        ? markerStepChangeList
-        : markerPaperList;
+        ? markerChangeLevelPaperList
+        : markerTaskList;
 
       const data = await requestAction(datas);
       this.papers = data.data.map(paper => {
@@ -378,13 +378,14 @@ export default {
       if (this.papers.length) this.$refs.ImagePreview.initData();
     },
     async nextPage() {
-      console.log(this.current, this.totalPage);
       if (this.current === this.totalPage) {
         if (this.current > 1) {
           this.current--;
         } else {
-          console.log("122");
           this.$Message.warning("当前已经是最后一条数据了");
+          this.$refs.ImagePreview.cancel();
+          this.$refs.CarouselPapersPreview &&
+            this.$refs.CarouselPapersPreview.cancel();
         }
       }
       // 下一页时,继续获取当前页数据。
@@ -392,9 +393,20 @@ export default {
       this.selectPaper(0);
       if (this.papers.length) this.$refs.ImagePreview.initData();
     },
+    async gradingCurPaper({ selectedLevel }) {
+      const data = await paperSelectLevelOrScore(
+        this.curPaper.id, // is taskId
+        selectedLevel,
+        "LEVEL"
+      );
+      this.updatePaperList(data);
+      this.getStepLevels();
+      this.updateHistory();
+      this.toNext();
+    },
     async scoreCurPaper(score) {
       const data = await paperSelectLevelOrScore(
-        this.curPaper.id,
+        this.curPaper.id, // is taskId
         score,
         "SCORE"
       );

+ 83 - 3
src/modules/mark/MarkTaskManage.vue

@@ -32,7 +32,7 @@
           shape="circle"
           type="success"
           icon="upload-white icon"
-          @click="submit"
+          @click="toSubmit"
           :disabled="isSubmit || !canSubmitTask"
           >发布评卷任务</Button
         >
@@ -88,6 +88,35 @@
     <p class="tips-info tips-error" v-if="!canSubmitTask">
       警告:当前考区还有未完成的任务,无法发布新任务!
     </p>
+
+    <!-- task info confirm modal -->
+    <Modal
+      class="task-confirm-modal"
+      v-model="modalIsShow"
+      :title="modalTitle"
+      :width="800"
+      :mask-closable="false"
+      :closable="false"
+    >
+      <Table
+        ref="TableList"
+        :columns="columns"
+        :data="taskList"
+        disabled-hover
+        border
+      ></Table>
+
+      <div slot="footer">
+        <Button
+          shape="circle"
+          type="primary"
+          :disabled="isSubmit || !canSubmitTask"
+          @click="submit"
+          >确认</Button
+        >
+        <Button shape="circle" @click="cancel">取消</Button>
+      </div>
+    </Modal>
   </div>
 </template>
 
@@ -114,13 +143,58 @@ export default {
       canSubmitTask: true,
       isSubmit: false,
       taskList: [],
-      areas: []
+      areas: [],
+      // modal
+      modalIsShow: false,
+      columns: [
+        {
+          title: "档位",
+          key: "code",
+          width: 70
+        },
+        {
+          title: "总数量",
+          key: "totalCount"
+        },
+        {
+          title: "已评",
+          key: "successCount"
+        },
+        {
+          title: "未评",
+          key: "waitCount"
+        },
+        {
+          title: "排序规则",
+          key: "sortRule",
+          width: 100,
+          render: (h, param) => {
+            return h("div", SORT_ORDER_TYPE[param.row.sortRule]);
+          }
+        },
+        {
+          title: "是否显示档内序号",
+          key: "displayNumber",
+          width: 200,
+          render: (h, param) => {
+            return h("div", BOOLEAN_TYPE[param.row.displayNumber]);
+          }
+        },
+        {
+          title: "本次任务数",
+          key: "taskCount",
+          width: 120
+        }
+      ]
     };
   },
   computed: {
     curTaskCount() {
       let nums = this.taskList.map(item => item.taskCount);
       return calcSum(nums);
+    },
+    modalTitle() {
+      return `已选试卷数量:${this.curTaskCount}`;
     }
   },
   mounted() {
@@ -173,7 +247,10 @@ export default {
     sortRuleChange(task) {
       if (!task.sortRule) task.displayNumber = 0;
     },
-    async submit() {
+    cancel() {
+      this.modalIsShow = false;
+    },
+    toSubmit() {
       if (!this.canSubmitTask) {
         this.$Message.error("当前考区还有未完成的任务,无法发布新任务!");
         return;
@@ -182,6 +259,9 @@ export default {
         this.$Message.error("请设置任务数量!");
         return;
       }
+      this.modalIsShow = true;
+    },
+    async submit() {
       if (this.isSubmit) return;
       this.isSubmit = true;
       let result = true;

+ 86 - 70
src/modules/mark/components/MarkAction.vue

@@ -55,53 +55,55 @@
     <!-- 试卷信息 -->
     <div class="action-paper-info">
       <p v-if="IS_ADMIN">
-        <span>试卷考号:</span><span>{{ curPaper.examNumber }}</span>
+        <span>试卷考号:</span><span>{{ curPaperOrTask.examNumber }}</span>
       </p>
       <p>
-        <span>试卷密号:</span><span>NO.{{ curPaper.sn }}</span>
+        <span>试卷密号:</span><span>NO.{{ curPaperOrTask.sn }}</span>
       </p>
     </div>
     <!-- 改档信息 -->
     <div class="action-grade-change" v-if="rights.gradeChange">
       <p>
-        <span>原始档位:</span><span>{{ curPaper.originLevel }}</span>
+        <span>原始档位:</span><span>{{ curPaperOrTask.originLevel }}</span>
       </p>
       <p>
-        <span>申请档位:</span><span>{{ curPaper.redoLevel }}</span>
+        <span>申请档位:</span><span>{{ curPaperOrTask.redoLevel }}</span>
       </p>
     </div>
     <div
       :class="[
         'action-grade-change-status',
-        { 'action-grade-change-status-error': curPaper.auditStatus === 0 }
+        { 'action-grade-change-status-error': curPaperOrTask.auditStatus === 0 }
       ]"
-      v-if="rights.gradeChange"
+      v-if="rights.gradeChange && IS_ADMIN"
     >
-      <p>{{ curPaper.auditStatus === 1 ? "同意改档" : "不同意改档" }}</p>
+      <p>{{ curPaperOrTask.auditStatus === 1 ? "同意改档" : "不同意改档" }}</p>
     </div>
 
     <!-- 档位信息 -->
     <!-- 已评/待评(已评档位),改档打分(已评档位) -->
     <div class="action-grade-info" v-if="rights.gradeInfo">
-      <h3 class="grade-info-name">{{ curLevel.name }}</h3>
-      <div class="grade-info-range">
+      <h3 class="grade-info-name">
+        {{ curPaperLevel }}
+      </h3>
+      <!-- <div class="grade-info-range">
         <p>分数范围</p>
         <p>
           <span>{{ curLevel.minScore }}</span>
           <span>~</span>
           <span>{{ curLevel.maxScore }}</span>
         </p>
-      </div>
+      </div> -->
     </div>
     <!-- 打分信息 -->
     <div class="action-grade-info action-mark-info" v-if="rights.markInfo">
-      <p class="grade-info-name" v-if="curPaper.result">
-        {{ curPaper.result }}
+      <p class="grade-info-name" v-if="curPaperScore">
+        {{ curPaperScore }}
       </p>
       <p class="grade-info-name grade-info-none" v-else>未打分</p>
     </div>
-    <!-- 选择分数 / 档位 -->
-    <div class="action-grade-list" v-if="rights.gradeList && IS_MARK_LEADER">
+    <!-- 选择档位 -->
+    <div class="action-grade-list" v-if="rights.gradeList">
       <div
         class="action-grade-item"
         v-for="(level, index) in levels"
@@ -113,7 +115,8 @@
         </div>
       </div>
     </div>
-    <div class="action-mark-list" v-if="rights.gradeList && !IS_MARK_LEADER">
+    <!-- 选择分数  -->
+    <div class="action-mark-list" v-if="rights.levelList">
       <div
         class="action-mark-item"
         v-for="(score, index) in scores"
@@ -124,10 +127,7 @@
         </div>
       </div>
     </div>
-    <div
-      class="action-grade-pass"
-      v-if="rights.gradeList && IS_MARKER && stepType === 'undo'"
-    >
+    <div class="action-grade-pass" v-if="rights.levelList">
       <Button @click="toPass">跳过</Button>
     </div>
 
@@ -159,52 +159,53 @@ import { CODE_TYPE, CHANGE_LEVEL_STATUS } from "@/constants/enumerate";
 /*
 [paper template]
 {
-  "id": 165,
-  "sn": "029947536",
-  "examNumber": "1901040084",
-  "level": "A",
-  "score": null,
+  "id": 42,
+  "sn": "5314987744",
   "redoLevel": null,
-  "updatedOn": 1591767742000,
-  "imgSrc": "",
-  "thumbSrc": "",
+  "level": "B",
+  "score": null,
+  "result": "88",
+  "originLevel": null,
+  "markerId": 52,
+  "marker": "zj-pj-01",
+  "updatedOn": 1595812145000,
+  "imgSrc": "http://192.168.10.145:9000/images/34/SC/1/1901130046.jpg?random=f5549bb0-ba58-4cd3-a88e-0559be4e06e5",
+  "thumbSrc": "http://192.168.10.145:9000/thumbs/34/SC/1/1901130046.jpg?random=e7f880b8-4cb6-4963-8e66-532f0f8bdeb0",
   "markByLeader": false,
-  "markedLogic": true,
-  "areaCode": "2",
-  "inspectScore": null,
-  "inspectLevel": null,
-  "inspector": null,
-  "sheetSrc": null,
-  "stage": "LEVEL",
-  "test": 0,
-  "paperTest": 0,
-  "markResults": [],
+  "oldRejected": false,
+  "paperId": 116,
+  "randomSeqNew": 4987744,
+  "randomSeq": null,
+  "serialNumber": "B1",
+  "displayNumber": true,
+  "shift": false,
+  "shiftScore": false,
   "rejected": false,
-  "arbitrated": false,
-  "sample": false,
-  "tagged": false,
-  "missing": false,
-  "manual": false
+  "sample": false
 }
 [marktask template]
 {
-  "id": 511,
-  "sn": "4929446110",
+  "id": 38,
+  "sn": "5314266469",
   "redoLevel": null,
   "level": "A",
   "score": null,
-  "result": "100",
+  "result": "96",
   "originLevel": null,
-  "markerId": 49,
-  "marker": "pj061001",
-  "updatedOn": 1594775592000,
-  "imgSrc": "",
-  "thumbSrc": "",
+  "markerId": 52,
+  "marker": "zj-pj-01",
+  "updatedOn": 1595812012000,
+  "imgSrc": "http://192.168.10.145:9000/images/34/SC/1/1901130043.jpg?random=bffc061c-7a80-42a4-ad56-36ec6eba0d45",
+  "thumbSrc": "http://192.168.10.145:9000/thumbs/34/SC/1/1901130043.jpg?random=da743f9d-8d46-4499-bb6f-b9c26e003ba2",
   "markByLeader": true,
   "oldRejected": false,
-  "paperId": 168,
-  "randomSeqNew": 9446110,
+  "paperId": 113,
+  "randomSeqNew": 4266469,
   "randomSeq": null,
+  "serialNumber": "A1",
+  "displayNumber": true,
+  "shift": false,
+  "shiftScore": false,
   "rejected": false,
   "sample": true
 }
@@ -217,13 +218,14 @@ const initRights = {
   gradeInfo: false,
   markInfo: false,
   gradeList: false,
+  levelList: false,
   markHis: false
 };
 
 export default {
   name: "mark-action",
   props: {
-    curPaper: {
+    curPaperOrTask: {
       type: Object,
       default() {
         return {};
@@ -251,14 +253,15 @@ export default {
           shift: ["search", "gradeChangeSearch", "gradeChange"]
         },
         MARK_LEADER: {
+          undo: ["search", "gradeList", "gradeInfo", "markInfo"],
           done: ["search", "gradeList", "gradeHis", "gradeInfo", "markInfo"],
           shift: ["search", "gradeList", "gradeChange"]
         },
         MARKER: {
-          done: ["gradeList", "gradeInfo", "markInfo"],
-          undo: ["gradeList", "gradeInfo"],
+          done: ["levelList", "gradeInfo", "markInfo"],
+          undo: ["levelList", "gradeInfo"],
           shift: ["gradeList", "gradeChange"],
-          shiftScore: ["gradeList", "gradeInfo"]
+          shiftScore: ["levelList", "gradeInfo"]
         }
       },
       filter: {
@@ -276,6 +279,8 @@ export default {
       },
       stepType: "",
       stepLabel: "",
+      curPaperLevel: "",
+      curPaperScore: "",
       scores: [],
       gradingHistory: [],
       curLevel: {}
@@ -293,7 +298,7 @@ export default {
     }
   },
   watch: {
-    curPaper(val) {
+    curPaperOrTask(val) {
       this.rebuildRight();
     }
   },
@@ -302,16 +307,22 @@ export default {
   },
   methods: {
     getStepType() {
-      const paper = this.curPaper;
-      if (!paper.result) return "undo";
-      if (paper.result) return "done";
-      // TODO:
-      if (paper.arbitrated) return "arbitrate";
-      if (paper.rejected) return "reject";
-      if (!paper.rejected && !paper.arbitrated && !paper.level) return "undo";
-      return;
+      const paper = this.curPaperOrTask;
+      if (paper.shift && paper.shiftScore && !paper.level) return "shift";
+      if (!paper.shift && paper.shiftScore) return "shiftScore";
+      if (this.IS_MARKER) {
+        if (!paper.result) return "undo";
+        if (paper.result) return "done";
+      } else {
+        if (paper.score !== null) return "done";
+        if (paper.score === null) return "undo";
+      }
     },
     rebuildRight() {
+      const curPaperScore = this.IS_MARKER
+        ? this.curPaperOrTask.result
+        : this.curPaperOrTask.score;
+      this.curPaperScore = curPaperScore !== null ? curPaperScore + "" : "";
       this.stepType = this.getStepType();
       this.stepLabel = this.stepDict[this.stepType];
       this.rights = { ...initRights };
@@ -320,10 +331,14 @@ export default {
         this.rights[key] = true;
       });
 
-      if (this.curPaper.level) {
+      if (this.curPaperOrTask.level) {
         this.curLevel = this.levels.find(
-          level => level.name === this.curPaper.level
+          level => level.name === this.curPaperOrTask.level
         );
+        this.curPaperLevel =
+          this.curPaperOrTask["displayNumber"] && this.stepType !== "shiftScore"
+            ? this.curPaperOrTask["serialNumber"]
+            : this.curLevel.name;
         this.updateScoreList();
       }
       if (this.rights.gradeHis) {
@@ -339,7 +354,7 @@ export default {
       this.scores = scores;
     },
     async getMarkHistory() {
-      const data = await markHistoryList(this.curPaper.id, "SCORE");
+      const data = await markHistoryList(this.curPaperOrTask.id, "SCORE");
       this.gradingHistory = data.map(item => {
         return {
           id: item.markerId,
@@ -349,10 +364,11 @@ export default {
       });
     },
     selectLevel(level) {
+      if (this.curPaperOrTask.level === level.name) return;
       // 科组长改档
       this.$emit("on-leader-level", {
-        curPaperId: this.curPaper.id,
-        curLevel: this.curPaper.level,
+        paperId: this.curPaperOrTask.id,
+        curLevel: this.curPaperOrTask.level,
         selectedLevel: level.name
       });
     },

+ 2 - 0
src/modules/quality/Quality.vue

@@ -232,8 +232,10 @@ export default {
       const curWork = this.works.find(item => item.id === this.filter.workId);
       this.subjects = curWork.subjects;
       this.filter.subject = this.subjects[0].subject;
+      this.subjectChange();
     },
     subjectChange() {
+      this.areas = [];
       this.filter.areaCode = null;
       this.getAreaList();
     },