zhangjie %!s(int64=3) %!d(string=hai) anos
pai
achega
911e2388a7

+ 2 - 2
src/App.vue

@@ -12,8 +12,8 @@ export default {
   mixins: [timeMixin],
   mixins: [timeMixin],
   data() {
   data() {
     return {
     return {
-      // unactiveTime: 0,
-      unactiveTime: 10 * 60 * 1000,
+      unactiveTime: 0,
+      // unactiveTime: 10 * 60 * 1000,
       timeIsOut: false
       timeIsOut: false
     };
     };
   },
   },

+ 620 - 619
src/modules/grading/GradingDetail.vue

@@ -1,619 +1,620 @@
-<template>
-  <div :class="compClasses">
-    <grade-filter
-      ref="GradeFilter"
-      :data="workSubject"
-      @change="areaChange"
-    ></grade-filter>
-    <grade-step
-      :steps="steps"
-      :init-step="curStep"
-      @on-change="stepChange"
-      ref="GradeStep"
-      v-if="steps.levelStep"
-    ></grade-step>
-    <div class="detail-body">
-      <!-- detail-papers -->
-      <div :class="detailPapersClasses">
-        <div class="detail-papers-carousel">
-          <grade-standard-paper
-            :levels="levels"
-            :question-id="filter.questionId"
-            @on-paper-click="
-              (index, papers) => {
-                toViewCarouselPaper(index, papers, 'sample');
-              }
-            "
-            @on-paper-change="standardPaperChange"
-            v-if="levels.length && filter.questionId"
-            ref="GradeStandardPaper"
-          ></grade-standard-paper>
-          <grade-history-paper
-            :question-id="filter.questionId"
-            @on-paper-click="
-              (index, papers) => {
-                toViewCarouselPaper(index, papers, 'history');
-              }
-            "
-            v-if="filter.questionId && !IS_ADMIN"
-            ref="GradeHistoryPaper"
-          ></grade-history-paper>
-        </div>
-        <div class="detail-papers-list" v-if="papers.length">
-          <div :class="imageViewClasses">
-            <div
-              :class="[
-                'image-view',
-                { 'image-view-act': curPaperIndex === index || image.selected }
-              ]"
-              v-for="(image, index) in papers"
-              :key="index"
-            >
-              <div class="image-view-container">
-                <h5 class="image-view-title">{{ image.title }}</h5>
-                <div class="image-view-contain">
-                  <img
-                    :src="image.thumbSrc"
-                    :alt="image.title"
-                    @click="toReview(index)"
-                  />
-                </div>
-                <div class="image-view-actions" v-if="ACTION_CAN_BATCH">
-                  <div
-                    :class="[
-                      'image-view-multibar',
-                      { 'image-view-selected': image.selected },
-                      { 'image-view-disabled': image.sample }
-                    ]"
-                    :title="image.sample ? '标准卷' : '选中批量操作'"
-                    @click="selectMultiplePaper(image)"
-                  ></div>
-                </div>
-              </div>
-            </div>
-          </div>
-          <div class="part-page" v-if="total > size">
-            <Page
-              :current="current"
-              :total="total"
-              :page-size="size"
-              show-total
-              show-elevator
-              @on-change="toPage"
-            ></Page>
-          </div>
-        </div>
-        <div class="detail-papers-list" v-else>
-          <p class="detail-papers-none">暂无数据</p>
-        </div>
-      </div>
-      <!-- detail-aciton -->
-      <div
-        :class="[
-          'detail-action',
-          { 'detail-action-fullscreen': isFullscreenMarking }
-        ]"
-        v-show="!multipleGradingList.length"
-      >
-        <grade-action
-          :cur-paper-or-task="curPaper"
-          :levels="levels"
-          :params-set="paramsSet"
-          @on-leader-level="leaderSelectLevel"
-          @on-code-search="serachPaperByCode"
-          ref="GradeAction"
-          v-if="curPaper.id"
-        ></grade-action>
-      </div>
-      <!-- 占位 -->
-      <div class="detail-action" v-if="isFullscreenMarking"></div>
-      <!-- multiple grading action -->
-      <div class="detail-action" v-show="multipleGradingList.length">
-        <div class="grade-action">
-          <div class="action-paper-state">
-            <p class="paper-state-cont">批量操作</p>
-          </div>
-          <div class="action-grade-list">
-            <div
-              class="action-grade-item"
-              v-for="(level, index) in levels"
-              :key="index"
-            >
-              <div
-                :class="[
-                  'action-grade-item-content',
-                  { 'action-item-content-disabled': multiplebtnClicked }
-                ]"
-                @click="multipleSelectLevel(level)"
-              >
-                <p>{{ level.name }}</p>
-                <p>{{ level.minScore }}~{{ level.maxScore }}</p>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <!-- image-preview -->
-    <simple-image-preview
-      :class="imagePreviewClasses"
-      :cur-image="curPaper"
-      @on-prev="toPrevPaper"
-      @on-next="toNextPaper"
-      @on-close="isFullscreenMarking = false"
-      ref="SimpleImagePreview"
-    ></simple-image-preview>
-    <!-- carousel paper review -->
-    <simple-image-preview
-      :class="imagePreviewClasses"
-      :cur-image="curPaper"
-      @on-prev="toCarousePaper('prev')"
-      @on-next="toCarousePaper('next')"
-      @on-close="carouseImagePreviewClose"
-      ref="CarouselPapersPreview"
-    ></simple-image-preview>
-    <!-- modify-leader-grading -->
-    <modify-leader-grading
-      :level-info="levelInfo"
-      :markers="markers"
-      @modified="leaderGradingSuccess"
-      @canceled="leaderGradingCancel"
-      ref="ModifyLeaderGrading"
-    ></modify-leader-grading>
-  </div>
-</template>
-
-<script>
-import {
-  paperList,
-  levelStatData,
-  workLevelList,
-  taskSnSearch,
-  subjectDetail,
-  markHistoryList,
-  getParamsSet,
-  leaderGradingPaper
-} from "@/api";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-import GradeFilter from "./components/GradeFilter";
-import GradeStep from "./components/GradeStep";
-import GradeStandardPaper from "./components/GradeStandardPaper";
-import GradeHistoryPaper from "./components/GradeHistoryPaper";
-import GradeAction from "./components/GradeAction";
-import ModifyLeaderGrading from "./components/ModifyLeaderGrading";
-// 三种情况:
-// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
-// 管理员:标准卷,试卷列表,操作盘
-// 科组长:标准卷,操作记录,试卷列表,操作盘(定档,标准卷,打回)
-
-// TIP:不考虑评卷员的情况
-// 评卷员:标准卷,操作记录,试卷列表,操作盘(只分档)
-
-export default {
-  name: "grading-detail",
-  components: {
-    SimpleImagePreview,
-    GradeFilter,
-    GradeStep,
-    GradeHistoryPaper,
-    GradeStandardPaper,
-    GradeAction,
-    ModifyLeaderGrading
-  },
-  data() {
-    return {
-      filter: {
-        questionId: "",
-        sort: "secretNumber"
-      },
-      typeFilter: {
-        done: {
-          level: ""
-        },
-        reject: {
-          reject: true
-        },
-        arbitrate: {
-          arbi: true
-        }
-      },
-      workId: this.$route.params.workId,
-      subjectId: this.$route.params.subjectId,
-      subject: "",
-      workSubject: {},
-      curSubject: {},
-      curUserRoleType: "MARKER",
-      current: 1,
-      size: 6,
-      total: 0,
-      totalPage: 1,
-      curStep: { type: "", name: "" },
-      steps: {},
-      levels: [],
-      curArea: {},
-      papers: [],
-      curPaper: {},
-      curPaperIndex: 0,
-      paramsSet: {},
-      // leader-grade
-      levelInfo: {},
-      markers: [],
-      // carousel paper review,
-      carouselType: "",
-      carouselPapers: [],
-      curCarouselPaperIndex: 0,
-      isFullscreenMarking: false,
-      // multiple grading
-      multiplebtnClicked: false,
-      multipleGradingList: []
-    };
-  },
-  computed: {
-    compClasses() {
-      return [
-        "page-container-flex",
-        "grading-detail",
-        { "grading-operation": this.IS_MARK_LEADER }
-      ];
-    },
-    detailPapersClasses() {
-      return ["detail-papers", `detail-papers-col-${1 + this.size / 2}`];
-    },
-    imageViewClasses() {
-      return ["image-view-list", `image-view-list-${this.size / 2}`];
-    },
-    IS_ADMIN() {
-      return this.curUserRoleType === "ADMIN";
-    },
-    IS_MARK_LEADER() {
-      return this.curUserRoleType === "MARK_LEADER";
-    },
-    IS_TEST() {
-      return this.curSubject.test === 2;
-    },
-    ACTION_CAN_BATCH() {
-      return (
-        this.curStep.type === "done" &&
-        this.IS_MARK_LEADER &&
-        !this.paramsSet.paperStage
-      );
-    },
-    imagePreviewClasses() {
-      return this.IS_ADMIN
-        ? "grading-detail-image-preview"
-        : "grading-operation-image-preview";
-    }
-  },
-  created() {
-    this.subject = this.subjectId.split("-")[1];
-    this.workSubject = {
-      workId: this.workId,
-      subject: this.subject
-    };
-    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
-    this.initData();
-  },
-  methods: {
-    async initData() {
-      await this.getParamsSetInfo();
-      await this.getSubjectDetail();
-      // 获取档位列表
-      this.getWorkLevels();
-    },
-    async getParamsSetInfo() {
-      this.paramsSet = await getParamsSet(this.workId);
-    },
-    async getList() {
-      this.multipleGradingList = [];
-      const datas = {
-        ...this.filter,
-        ...this.typeFilter[this.curStep.type],
-        page: this.current - 1,
-        size: this.size
-      };
-      if (this.curStep.type === "done") datas.level = this.curStep.name;
-
-      const data = await paperList(datas);
-      this.papers = data.data.map(paper => {
-        paper.title = `NO.${paper.sn}`;
-        // paper.title = this.IS_ADMIN ? paper.examNumber : `NO.${paper.sn}`;
-        paper.selected = false;
-        return paper;
-      });
-      this.total = data.totalCount;
-      this.totalPage = data.pageCount;
-    },
-    async toPage(page) {
-      this.current = page;
-      await this.getList();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async getSubjectDetail() {
-      this.curSubject = await subjectDetail(this.subjectId);
-    },
-    async getStepLevels() {
-      const data = await levelStatData(this.subjectId, this.filter.questionId);
-      const undoIndex = data.findIndex(item => item.id === null);
-      let otherStep = [];
-      let undo = {
-        count: 0,
-        rejected: 0,
-        arbitrated: 0
-      };
-      if (undoIndex !== -1) {
-        undo = { ...data[undoIndex] };
-        data.splice(undoIndex, 1);
-      }
-
-      if (this.IS_MARK_LEADER && this.IS_TEST) {
-        otherStep.push({
-          name: "待评",
-          count: undo.count,
-          type: "undo"
-        });
-      }
-      otherStep.push({
-        name: "打回",
-        count: undo.rejected,
-        type: "reject"
-      });
-      otherStep.push({
-        name: "仲裁",
-        count: undo.arbitrated,
-        type: "arbitrate"
-      });
-
-      let levelStep = data.map(item => {
-        return {
-          ...item,
-          name: item.id,
-          type: "done"
-        };
-      });
-      this.steps = { levelStep, otherStep };
-
-      if (!this.curStep.type) {
-        this.curStep = levelStep[0];
-      }
-    },
-    async getWorkLevels() {
-      const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          id: item.id,
-          name: item.code,
-          minScore: item.minScore,
-          maxScore: item.maxScore
-        };
-      });
-    },
-    async stepChange(step) {
-      this.curStep = step;
-
-      this.current = 1;
-      await this.getList();
-      if (this.papers.length) {
-        this.selectPaper(0);
-      } else {
-        this.curPaper = {};
-      }
-    },
-    async areaChange(curArea) {
-      this.curArea = curArea;
-      this.filter.questionId = curArea.id;
-      await this.getStepLevels();
-      this.toPage(1);
-    },
-    // selectMultiplePaper
-    selectMultiplePaper(paper) {
-      if (paper.sample) return;
-      paper.selected = !paper.selected;
-      this.multipleGradingList = this.papers.filter(paper => paper.selected);
-    },
-    async multipleSelectLevel(level) {
-      if (!this.multipleGradingList.length) return;
-      if (this.multiplebtnClicked) return;
-      this.multiplebtnClicked = true;
-
-      const data = await markHistoryList(
-        this.multipleGradingList[0].id,
-        "LEVEL"
-      ).catch(() => {});
-      this.multiplebtnClicked = false;
-      if (!data) return;
-
-      this.markers = data.map(item => {
-        return {
-          id: item.markerId,
-          name: item.marker
-        };
-      });
-      this.levelInfo = {
-        paperIds: this.multipleGradingList.map(item => item.id).join(),
-        curLevel: this.curStep.name,
-        selectedLevel: level.name
-      };
-      this.$refs.ModifyLeaderGrading.open();
-    },
-    // to review
-    toReview(index) {
-      this.isFullscreenMarking = true;
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        if (this.current > 1) {
-          this.current--;
-          this.curPaperIndex = this.size - 1;
-          await this.getList();
-        } else {
-          this.$Message.warning("当前已经是第一条数据了");
-          return;
-        }
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        if (this.current === this.totalPage) {
-          this.$Message.warning("当前已经是最后一条数据了");
-          return;
-        } else {
-          this.current++;
-          this.curPaperIndex = 0;
-          await this.getList();
-        }
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toActionNextPaper() {
-      if (this.current > 1 && this.papers.length === 1) {
-        this.current--;
-        this.curPaperIndex = this.size;
-      }
-
-      await this.getList();
-      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
-      this.selectPaper(this.curPaperIndex);
-    },
-    updateHistory() {
-      this.$refs.GradeHistoryPaper.updatePapers();
-    },
-    async serachPaperByCode(params) {
-      const data = await taskSnSearch(
-        params.codeType,
-        params.code,
-        this.filter.questionId
-      );
-      if (!data) {
-        this.$Message.error("没有查找到结果!");
-        return;
-      }
-      data.title = `NO.${data.sn}`;
-      // data.title = this.IS_ADMIN ? data.examNumber : `NO.${data.sn}`;
-      this.papers = [data];
-      this.total = 1;
-      this.selectPaper(0);
-    },
-    async leaderSelectLevel(levelInfo, markers) {
-      // 唯一权限时,直接操作
-      if (levelInfo.markLeaderOnlyRight && !this.paramsSet.leaderConfirm) {
-        const datas = {
-          action: levelInfo.markLeaderOnlyRight.action,
-          level: levelInfo.selectedLevel,
-          originLevel: levelInfo.curLevel,
-          paperIds: levelInfo.paperIds
-        };
-        if (datas.action === "reject") {
-          datas.range = markers.map(item => item.id).join();
-        }
-        let result = true;
-        const paper = await leaderGradingPaper(datas).catch(() => {
-          result = false;
-        });
-        if (!result) return;
-
-        this.leaderGradingSuccess(datas, paper);
-        return;
-      }
-
-      this.levelInfo = levelInfo;
-      this.markers = markers;
-      this.$refs.ModifyLeaderGrading.open();
-    },
-    async leaderGradingSuccess(datas, paper) {
-      if (datas.action === "sampling" && this.$refs.GradeStandardPaper) {
-        this.$refs.GradeStandardPaper.updateLevelPapers(datas.level);
-      }
-      this.getStepLevels();
-      this.updateHistory();
-
-      if (this.multipleGradingList && this.multipleGradingList.length) {
-        // 批量处理逻辑
-        if (
-          this.current > 1 &&
-          this.current === this.pageCount &&
-          this.papers.length === this.multipleGradingList.length
-        ) {
-          this.current--;
-        }
-
-        this.multipleGradingList = [];
-        await this.getList();
-        this.selectPaper(this.curPaperIndex);
-      } else {
-        // 单张处理逻辑
-        this.toActionNextPaper();
-      }
-    },
-    leaderGradingCancel() {
-      this.$refs.GradeAction.btnClicked = false;
-    },
-    // paper carousel
-    toViewCarouselPaper(paperIndex, papers, type) {
-      this.carouselType = type;
-      this.isFullscreenMarking = true;
-      this.carouselPapers = papers;
-      this.selectCarouselPaper(paperIndex);
-      this.$nextTick(() => {
-        this.$refs.CarouselPapersPreview.open();
-      });
-    },
-    selectCarouselPaper(index) {
-      this.curCarouselPaperIndex = index;
-      this.curPaper = { ...this.carouselPapers[index] };
-    },
-    toCarousePaper(type) {
-      if (this.carouselType === "sample") {
-        this.toSampleCarousePaper(type);
-        return;
-      }
-      if (type === "prev" && this.curCarouselPaperIndex > 0) {
-        this.curCarouselPaperIndex--;
-      } else if (
-        type === "next" &&
-        this.curCarouselPaperIndex < this.carouselPapers.length - 1
-      ) {
-        this.curCarouselPaperIndex++;
-      }
-      this.selectCarouselPaper(this.curCarouselPaperIndex);
-    },
-    toSampleCarousePaper(type) {
-      if (type === "prev") {
-        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleLeft();
-      } else if (type === "next") {
-        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleRight();
-      }
-    },
-    carouseImagePreviewClose() {
-      this.isFullscreenMarking = false;
-      this.carouselType = "";
-      this.selectPaper(this.curPaperIndex);
-    },
-    standardPaperChange(curPaper) {
-      if (!this.isFullscreenMarking) return;
-      this.curPaper = { ...curPaper };
-    }
-  }
-};
-</script>
+<template>
+  <div :class="compClasses">
+    <grade-filter
+      ref="GradeFilter"
+      :data="workSubject"
+      @change="areaChange"
+    ></grade-filter>
+    <grade-step
+      :steps="steps"
+      :init-step="curStep"
+      @on-change="stepChange"
+      ref="GradeStep"
+      v-if="steps.levelStep"
+    ></grade-step>
+    <div class="detail-body">
+      <!-- detail-papers -->
+      <div :class="detailPapersClasses">
+        <div class="detail-papers-carousel">
+          <grade-standard-paper
+            :levels="levels"
+            :question-id="filter.questionId"
+            @on-paper-click="
+              (index, papers) => {
+                toViewCarouselPaper(index, papers, 'sample');
+              }
+            "
+            @on-paper-change="standardPaperChange"
+            v-if="levels.length && filter.questionId"
+            ref="GradeStandardPaper"
+          ></grade-standard-paper>
+          <grade-history-paper
+            :question-id="filter.questionId"
+            @on-paper-click="
+              (index, papers) => {
+                toViewCarouselPaper(index, papers, 'history');
+              }
+            "
+            v-if="filter.questionId && !IS_ADMIN"
+            ref="GradeHistoryPaper"
+          ></grade-history-paper>
+        </div>
+        <div class="detail-papers-list" v-if="papers.length">
+          <div :class="imageViewClasses">
+            <div
+              :class="[
+                'image-view',
+                { 'image-view-act': curPaperIndex === index || image.selected }
+              ]"
+              v-for="(image, index) in papers"
+              :key="index"
+            >
+              <div class="image-view-container">
+                <h5 class="image-view-title">{{ image.title }}</h5>
+                <div class="image-view-contain">
+                  <img
+                    :src="image.thumbSrc"
+                    :alt="image.title"
+                    @click="toReview(index)"
+                  />
+                </div>
+                <div class="image-view-actions" v-if="ACTION_CAN_BATCH">
+                  <div
+                    :class="[
+                      'image-view-multibar',
+                      { 'image-view-selected': image.selected },
+                      { 'image-view-disabled': image.sample }
+                    ]"
+                    :title="image.sample ? '标准卷' : '选中批量操作'"
+                    @click="selectMultiplePaper(image)"
+                  ></div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="part-page" v-if="total > size">
+            <Page
+              :current="current"
+              :total="total"
+              :page-size="size"
+              show-total
+              show-elevator
+              @on-change="toPage"
+            ></Page>
+          </div>
+        </div>
+        <div class="detail-papers-list" v-else>
+          <p class="detail-papers-none">暂无数据</p>
+        </div>
+      </div>
+      <!-- detail-aciton -->
+      <div
+        :class="[
+          'detail-action',
+          { 'detail-action-fullscreen': isFullscreenMarking }
+        ]"
+        v-show="!multipleGradingList.length"
+      >
+        <grade-action
+          :cur-paper-or-task="curPaper"
+          :levels="levels"
+          :params-set="paramsSet"
+          @on-leader-level="leaderSelectLevel"
+          @on-code-search="serachPaperByCode"
+          ref="GradeAction"
+          v-if="curPaper.id"
+        ></grade-action>
+      </div>
+      <!-- 占位 -->
+      <div class="detail-action" v-if="isFullscreenMarking"></div>
+      <!-- multiple grading action -->
+      <div class="detail-action" v-show="multipleGradingList.length">
+        <div class="grade-action">
+          <div class="action-paper-state">
+            <p class="paper-state-cont">批量操作</p>
+          </div>
+          <div class="action-grade-list">
+            <div
+              class="action-grade-item"
+              v-for="(level, index) in levels"
+              :key="index"
+            >
+              <div
+                :class="[
+                  'action-grade-item-content',
+                  { 'action-item-content-disabled': multiplebtnClicked }
+                ]"
+                @click="multipleSelectLevel(level)"
+              >
+                <p>{{ level.name }}</p>
+                <p>{{ level.minScore }}~{{ level.maxScore }}</p>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      :class="imagePreviewClasses"
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      @on-close="isFullscreenMarking = false"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
+    <!-- carousel paper review -->
+    <simple-image-preview
+      :class="imagePreviewClasses"
+      :cur-image="curPaper"
+      @on-prev="toCarousePaper('prev')"
+      @on-next="toCarousePaper('next')"
+      @on-close="carouseImagePreviewClose"
+      ref="CarouselPapersPreview"
+    ></simple-image-preview>
+    <!-- modify-leader-grading -->
+    <modify-leader-grading
+      :level-info="levelInfo"
+      :markers="markers"
+      @modified="leaderGradingSuccess"
+      @canceled="leaderGradingCancel"
+      ref="ModifyLeaderGrading"
+    ></modify-leader-grading>
+  </div>
+</template>
+
+<script>
+import {
+  paperList,
+  levelStatData,
+  workLevelList,
+  taskSnSearch,
+  subjectDetail,
+  markHistoryList,
+  getParamsSet,
+  leaderGradingPaper
+} from "@/api";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+import GradeFilter from "./components/GradeFilter";
+import GradeStep from "./components/GradeStep";
+import GradeStandardPaper from "./components/GradeStandardPaper";
+import GradeHistoryPaper from "./components/GradeHistoryPaper";
+import GradeAction from "./components/GradeAction";
+import ModifyLeaderGrading from "./components/ModifyLeaderGrading";
+// 三种情况:
+// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
+// 管理员:标准卷,试卷列表,操作盘
+// 科组长:标准卷,操作记录,试卷列表,操作盘(定档,标准卷,打回)
+
+// TIP:不考虑评卷员的情况
+// 评卷员:标准卷,操作记录,试卷列表,操作盘(只分档)
+
+export default {
+  name: "grading-detail",
+  components: {
+    SimpleImagePreview,
+    GradeFilter,
+    GradeStep,
+    GradeHistoryPaper,
+    GradeStandardPaper,
+    GradeAction,
+    ModifyLeaderGrading
+  },
+  data() {
+    return {
+      filter: {
+        questionId: "",
+        sort: "secretNumber"
+      },
+      typeFilter: {
+        done: {
+          level: ""
+        },
+        reject: {
+          reject: true
+        },
+        arbitrate: {
+          arbi: true
+        }
+      },
+      workId: this.$route.params.workId,
+      subjectId: this.$route.params.subjectId,
+      subject: "",
+      workSubject: {},
+      curSubject: {},
+      curUserRoleType: "MARKER",
+      current: 1,
+      size: 6,
+      total: 0,
+      totalPage: 1,
+      curStep: { type: "", name: "" },
+      steps: {},
+      levels: [],
+      curArea: {},
+      papers: [],
+      curPaper: {},
+      curPaperIndex: 0,
+      paramsSet: {},
+      // leader-grade
+      levelInfo: {},
+      markers: [],
+      // carousel paper review,
+      carouselType: "",
+      carouselPapers: [],
+      curCarouselPaperIndex: 0,
+      isFullscreenMarking: false,
+      // multiple grading
+      multiplebtnClicked: false,
+      multipleGradingList: []
+    };
+  },
+  computed: {
+    compClasses() {
+      return [
+        "page-container-flex",
+        "grading-detail",
+        { "grading-operation": this.IS_MARK_LEADER }
+      ];
+    },
+    detailPapersClasses() {
+      return ["detail-papers", `detail-papers-col-${1 + this.size / 2}`];
+    },
+    imageViewClasses() {
+      return ["image-view-list", `image-view-list-${this.size / 2}`];
+    },
+    IS_ADMIN() {
+      return this.curUserRoleType === "ADMIN";
+    },
+    IS_MARK_LEADER() {
+      return this.curUserRoleType === "MARK_LEADER";
+    },
+    IS_TEST() {
+      return this.curSubject.test === 2;
+    },
+    ACTION_CAN_BATCH() {
+      return (
+        this.curStep.type === "done" &&
+        this.IS_MARK_LEADER &&
+        !this.paramsSet.paperStage
+      );
+    },
+    imagePreviewClasses() {
+      return this.IS_ADMIN
+        ? "grading-detail-image-preview"
+        : "grading-operation-image-preview";
+    }
+  },
+  created() {
+    this.subject = this.subjectId.split("-")[1];
+    this.workSubject = {
+      workId: this.workId,
+      subject: this.subject
+    };
+    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
+    this.initData();
+  },
+  methods: {
+    async initData() {
+      await this.getParamsSetInfo();
+      await this.getSubjectDetail();
+      // 获取档位列表
+      this.getWorkLevels();
+    },
+    async getParamsSetInfo() {
+      this.paramsSet = await getParamsSet(this.workId);
+    },
+    async getList() {
+      this.multipleGradingList = [];
+      const datas = {
+        ...this.filter,
+        ...this.typeFilter[this.curStep.type],
+        page: this.current - 1,
+        size: this.size
+      };
+      if (this.curStep.type === "done") datas.level = this.curStep.name;
+
+      const data = await paperList(datas);
+      this.papers = data.data.map(paper => {
+        paper.title = `NO.${paper.sn}`;
+        // paper.title = this.IS_ADMIN ? paper.examNumber : `NO.${paper.sn}`;
+        paper.selected = false;
+        return paper;
+      });
+      this.total = data.totalCount;
+      this.totalPage = data.pageCount;
+    },
+    async toPage(page) {
+      this.current = page;
+      await this.getList();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async getSubjectDetail() {
+      this.curSubject = await subjectDetail(this.subjectId);
+    },
+    async getStepLevels() {
+      const data = await levelStatData(this.subjectId, this.filter.questionId);
+      const undoIndex = data.findIndex(item => item.id === null);
+      let otherStep = [];
+      let undo = {
+        count: 0,
+        rejected: 0,
+        arbitrated: 0
+      };
+      if (undoIndex !== -1) {
+        undo = { ...data[undoIndex] };
+        data.splice(undoIndex, 1);
+      }
+
+      if (this.IS_MARK_LEADER && this.IS_TEST) {
+        otherStep.push({
+          name: "待评",
+          count: undo.count,
+          type: "undo"
+        });
+      }
+      otherStep.push({
+        name: "打回",
+        count: undo.rejected,
+        type: "reject"
+      });
+      otherStep.push({
+        name: "仲裁",
+        count: undo.arbitrated,
+        type: "arbitrate"
+      });
+
+      let levelStep = data.map(item => {
+        return {
+          ...item,
+          name: item.id,
+          type: "done"
+        };
+      });
+      this.steps = { levelStep, otherStep };
+
+      if (!this.curStep.type) {
+        this.curStep = levelStep[0];
+      }
+    },
+    async getWorkLevels() {
+      const data = await workLevelList(this.workId);
+      this.levels = data.map(item => {
+        return {
+          id: item.id,
+          name: item.code,
+          minScore: item.minScore,
+          maxScore: item.maxScore
+        };
+      });
+    },
+    async stepChange(step) {
+      this.curStep = step;
+
+      this.current = 1;
+      await this.getList();
+      if (this.papers.length) {
+        this.selectPaper(0);
+      } else {
+        this.curPaper = {};
+      }
+    },
+    async areaChange(curArea) {
+      this.curArea = curArea;
+      this.filter.questionId = curArea.id;
+      await this.getStepLevels();
+      this.toPage(1);
+    },
+    // selectMultiplePaper
+    selectMultiplePaper(paper) {
+      if (paper.sample) return;
+      paper.selected = !paper.selected;
+      this.multipleGradingList = this.papers.filter(paper => paper.selected);
+    },
+    async multipleSelectLevel(level) {
+      if (!this.multipleGradingList.length) return;
+      if (this.multiplebtnClicked) return;
+      this.multiplebtnClicked = true;
+
+      const data = await markHistoryList(
+        this.multipleGradingList[0].id,
+        "LEVEL"
+      ).catch(() => {});
+      this.multiplebtnClicked = false;
+      if (!data) return;
+
+      this.markers = data.map(item => {
+        return {
+          id: item.markerId,
+          name: item.marker
+        };
+      });
+      this.levelInfo = {
+        paperIds: this.multipleGradingList.map(item => item.id).join(),
+        curLevel: this.curStep.name,
+        selectedLevel: level.name
+      };
+      this.$refs.ModifyLeaderGrading.open();
+    },
+    // to review
+    toReview(index) {
+      this.isFullscreenMarking = true;
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        if (this.current > 1) {
+          this.current--;
+          this.curPaperIndex = this.size - 1;
+          await this.getList();
+        } else {
+          this.$Message.warning("当前已经是第一条数据了");
+          return;
+        }
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        if (this.current === this.totalPage) {
+          this.$Message.warning("当前已经是最后一条数据了");
+          return;
+        } else {
+          this.current++;
+          this.curPaperIndex = 0;
+          await this.getList();
+        }
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toActionNextPaper() {
+      if (this.current > 1 && this.papers.length === 1) {
+        this.current--;
+        this.curPaperIndex = this.size;
+      }
+
+      await this.getList();
+      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
+      this.selectPaper(this.curPaperIndex);
+    },
+    updateHistory() {
+      this.$refs.GradeHistoryPaper.updatePapers();
+    },
+    async serachPaperByCode(params) {
+      const data = await taskSnSearch(
+        params.codeType,
+        params.code,
+        this.filter.questionId
+      );
+      if (!data) {
+        this.$Message.error("没有查找到结果!");
+        return;
+      }
+      data.title = `NO.${data.sn}`;
+      data.key = this.$randomCode();
+      // data.title = this.IS_ADMIN ? data.examNumber : `NO.${data.sn}`;
+      this.papers = [data];
+      this.total = 1;
+      this.selectPaper(0);
+    },
+    async leaderSelectLevel(levelInfo, markers) {
+      // 唯一权限时,直接操作
+      if (levelInfo.markLeaderOnlyRight && !this.paramsSet.leaderConfirm) {
+        const datas = {
+          action: levelInfo.markLeaderOnlyRight.action,
+          level: levelInfo.selectedLevel,
+          originLevel: levelInfo.curLevel,
+          paperIds: levelInfo.paperIds
+        };
+        if (datas.action === "reject") {
+          datas.range = markers.map(item => item.id).join();
+        }
+        let result = true;
+        const paper = await leaderGradingPaper(datas).catch(() => {
+          result = false;
+        });
+        if (!result) return;
+
+        this.leaderGradingSuccess(datas, paper);
+        return;
+      }
+
+      this.levelInfo = levelInfo;
+      this.markers = markers;
+      this.$refs.ModifyLeaderGrading.open();
+    },
+    async leaderGradingSuccess(datas, paper) {
+      if (datas.action === "sampling" && this.$refs.GradeStandardPaper) {
+        this.$refs.GradeStandardPaper.updateLevelPapers(datas.level);
+      }
+      this.getStepLevels();
+      this.updateHistory();
+
+      if (this.multipleGradingList && this.multipleGradingList.length) {
+        // 批量处理逻辑
+        if (
+          this.current > 1 &&
+          this.current === this.pageCount &&
+          this.papers.length === this.multipleGradingList.length
+        ) {
+          this.current--;
+        }
+
+        this.multipleGradingList = [];
+        await this.getList();
+        this.selectPaper(this.curPaperIndex);
+      } else {
+        // 单张处理逻辑
+        this.toActionNextPaper();
+      }
+    },
+    leaderGradingCancel() {
+      this.$refs.GradeAction.btnClicked = false;
+    },
+    // paper carousel
+    toViewCarouselPaper(paperIndex, papers, type) {
+      this.carouselType = type;
+      this.isFullscreenMarking = true;
+      this.carouselPapers = papers;
+      this.selectCarouselPaper(paperIndex);
+      this.$nextTick(() => {
+        this.$refs.CarouselPapersPreview.open();
+      });
+    },
+    selectCarouselPaper(index) {
+      this.curCarouselPaperIndex = index;
+      this.curPaper = { ...this.carouselPapers[index] };
+    },
+    toCarousePaper(type) {
+      if (this.carouselType === "sample") {
+        this.toSampleCarousePaper(type);
+        return;
+      }
+      if (type === "prev" && this.curCarouselPaperIndex > 0) {
+        this.curCarouselPaperIndex--;
+      } else if (
+        type === "next" &&
+        this.curCarouselPaperIndex < this.carouselPapers.length - 1
+      ) {
+        this.curCarouselPaperIndex++;
+      }
+      this.selectCarouselPaper(this.curCarouselPaperIndex);
+    },
+    toSampleCarousePaper(type) {
+      if (type === "prev") {
+        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleLeft();
+      } else if (type === "next") {
+        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleRight();
+      }
+    },
+    carouseImagePreviewClose() {
+      this.isFullscreenMarking = false;
+      this.carouselType = "";
+      this.selectPaper(this.curPaperIndex);
+    },
+    standardPaperChange(curPaper) {
+      if (!this.isFullscreenMarking) return;
+      this.curPaper = { ...curPaper };
+    }
+  }
+};
+</script>

+ 1 - 0
src/modules/grading/leader/LeaderGrading.vue

@@ -542,6 +542,7 @@ export default {
         return;
         return;
       }
       }
       data.title = `NO.${data.sn}`;
       data.title = `NO.${data.sn}`;
+      data.key = this.$randomCode();
       this.papers = [data];
       this.papers = [data];
       this.setPage({ current: 1, total: 1, totalPage: 1 });
       this.setPage({ current: 1, total: 1, totalPage: 1 });
       this.selectPaper(0);
       this.selectPaper(0);

+ 1 - 1
src/modules/grading/marker/MarkerHeader.vue

@@ -126,7 +126,7 @@
         <div class="header-part header-filter">
         <div class="header-part header-filter">
           筛选 <Icon type="ios-arrow-down"></Icon>
           筛选 <Icon type="ios-arrow-down"></Icon>
         </div>
         </div>
-        <div class="header-filter-body dark-mark" slot="content">
+        <div class="header-filter-body dark-mark" slot="content" @keydown.stop>
           <!-- 查询标记 -->
           <!-- 查询标记 -->
           <div class="filter-part">
           <div class="filter-part">
             <h4 class="filter-part-title">查询标记试卷</h4>
             <h4 class="filter-part-title">查询标记试卷</h4>

+ 462 - 461
src/modules/mark/MarkDetail.vue

@@ -1,461 +1,462 @@
-<template>
-  <div :class="compClasses">
-    <grade-filter
-      ref="GradeFilter"
-      :data="workSubject"
-      @change="areaChange"
-    ></grade-filter>
-    <mark-step
-      :steps="steps"
-      :init-step="curStep"
-      :show-top-number="false"
-      @on-change="stepChange"
-      ref="MarkStep"
-      v-if="steps.levelStep"
-    ></mark-step>
-    <div class="detail-body clear-float">
-      <!-- detail-papers -->
-      <div :class="detailPapersClasses">
-        <div class="detail-papers-carousel" v-if="!IS_ADMIN">
-          <grade-history-paper
-            :question-id="filter.questionId"
-            stage="SCORE"
-            @on-paper-click="toViewCarouselPaper"
-            v-if="filter.questionId"
-            ref="GradeHistoryPaper"
-          ></grade-history-paper>
-        </div>
-        <div class="detail-papers-list" v-if="papers.length">
-          <div :class="imageViewClasses">
-            <div
-              :class="[
-                'image-view',
-                { 'image-view-act': curPaperIndex === index }
-              ]"
-              v-for="(image, index) in papers"
-              :key="index"
-            >
-              <div class="image-view-container">
-                <h5 class="image-view-title">{{ image.title }}</h5>
-                <div class="image-view-contain">
-                  <img
-                    :src="image.thumbSrc"
-                    :alt="image.title"
-                    @click="toReview(index)"
-                  />
-                  <span
-                    class="image-info"
-                    v-if="image.score || image.score === 0"
-                    >{{ image.score }}分</span
-                  >
-                </div>
-              </div>
-            </div>
-          </div>
-          <div class="part-page" v-if="total > size">
-            <Page
-              :current="current"
-              :total="total"
-              :page-size="size"
-              show-total
-              show-elevator
-              @on-change="toPage"
-            ></Page>
-          </div>
-        </div>
-        <div class="detail-papers-list" v-else>
-          <p class="detail-papers-none">暂无数据</p>
-        </div>
-      </div>
-      <!-- detail-aciton -->
-      <div
-        :class="[
-          'detail-action',
-          { 'detail-action-fullscreen': isFullscreenMarking }
-        ]"
-      >
-        <mark-action
-          :cur-paper-or-task="curPaper"
-          :levels="levels"
-          @on-leader-level="leaderSelectLevel"
-          @on-code-search="serachPaperByCode"
-          @on-grade-change-search="searchGradeChangeList"
-          v-if="curPaper.id"
-          ref="MarkAction"
-        ></mark-action>
-      </div>
-      <!-- 占位 -->
-      <div class="detail-action" v-if="isFullscreenMarking"></div>
-    </div>
-
-    <!-- image-preview -->
-    <simple-image-preview
-      :class="imagePreviewClasses"
-      :cur-image="curPaper"
-      @on-prev="toPrevPaper"
-      @on-next="toNextPaper"
-      @on-close="isFullscreenMarking = false"
-      ref="SimpleImagePreview"
-    ></simple-image-preview>
-    <!-- carousel paper review -->
-    <simple-image-preview
-      :class="imagePreviewClasses"
-      :cur-image="curPaper"
-      @on-prev="toCarousePaper('prev')"
-      @on-next="toCarousePaper('next')"
-      @on-close="carouseImagePreviewClose"
-      ref="CarouselPapersPreview"
-    ></simple-image-preview>
-  </div>
-</template>
-
-<script>
-import {
-  paperList,
-  changeLevelPaperList,
-  scoreStatData,
-  workLevelList,
-  taskSnSearch,
-  markStepChangeLevel
-} from "@/api";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-import MarkStep from "./components/MarkStep";
-import GradeFilter from "../grading/components/GradeFilter";
-import GradeHistoryPaper from "../grading/components/GradeHistoryPaper";
-import MarkAction from "./components/MarkAction";
-// 三种情况:
-// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
-// 管理员:试卷列表,操作盘
-// 科组长:操作记录,试卷列表,操作盘(改档)
-
-// TIP:不考虑评卷员的情况
-// 评卷员:操作记录,试卷列表,操作盘(打分)
-
-export default {
-  name: "mark-detail",
-  components: {
-    SimpleImagePreview,
-    MarkStep,
-    GradeFilter,
-    GradeHistoryPaper,
-    MarkAction
-  },
-  data() {
-    return {
-      filter: {
-        questionId: "",
-        sort: "score,desc"
-      },
-      workId: this.$route.params.workId,
-      subjectId: this.$route.params.subjectId,
-      subject: "",
-      workSubject: {},
-      curUserRoleType: "",
-      applyChangeLevelStatus: 1, // 改档申请处理状态
-      current: 1,
-      size: 6,
-      total: 0,
-      totalPage: 1,
-      curStep: { type: "", name: "" },
-      steps: [],
-      levels: [],
-      curArea: {},
-      papers: [],
-      curPaper: {},
-      curPaperIndex: 0,
-      // carousel paper review,
-      carouselPapers: [],
-      curCarouselPaperIndex: 0,
-      isFullscreenMarking: false
-    };
-  },
-  computed: {
-    compClasses() {
-      return [
-        "page-container-flex",
-        "mark-detail",
-        "grading-detail",
-        { "grading-operation": this.IS_MARK_LEADER }
-      ];
-    },
-    bodyClasses() {
-      return [
-        "detail-body",
-        { "detail-body-2": this.curUserRoleType === "ADMIN" }
-      ];
-    },
-    detailPapersClasses() {
-      return [
-        "detail-papers",
-        {
-          [`detail-papers-col-${1 + this.size / 2}`]:
-            this.curUserRoleType !== "ADMIN"
-        }
-      ];
-    },
-    imageViewClasses() {
-      return ["image-view-list", `image-view-list-${this.size / 2}`];
-    },
-    IS_ADMIN() {
-      return this.curUserRoleType === "ADMIN";
-    },
-    IS_MARK_LEADER() {
-      return this.curUserRoleType === "MARK_LEADER";
-    },
-    imagePreviewClasses() {
-      return this.IS_ADMIN
-        ? "grading-detail-image-preview"
-        : "grading-operation-image-preview";
-    }
-  },
-  created() {
-    this.subject = this.subjectId.split("-")[1];
-    this.workSubject = {
-      workId: this.workId,
-      subject: this.subject
-    };
-    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
-    if (this.curUserRoleType === "ADMIN") this.size = 8;
-    this.initData();
-  },
-  methods: {
-    initData() {
-      this.getWorkLevels();
-    },
-    async getList() {
-      let data = [];
-      if (this.curStep.type === "shift") {
-        const datas = {
-          workId: this.workId,
-          subject: this.subject,
-          questionId: this.filter.questionId,
-          status: this.applyChangeLevelStatus,
-          page: this.current - 1,
-          size: this.size
-        };
-        data = await changeLevelPaperList(datas);
-      } else {
-        const datas = {
-          ...this.filter,
-          isScore: true,
-          page: this.current - 1,
-          size: this.size
-        };
-        if (this.curStep.type === "done") datas.level = this.curStep.name;
-
-        data = await paperList(datas);
-      }
-      this.papers = data.data.map(paper => {
-        paper.title = `NO.${paper.sn}`;
-        // paper.title = this.IS_ADMIN ? paper.examNumber : `NO.${paper.sn}`;
-        return paper;
-      });
-      this.total = data.totalCount;
-      this.totalPage = data.pageCount;
-    },
-    async toPage(page) {
-      this.current = page;
-      await this.getList();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async getStepLevels() {
-      const data = await scoreStatData(this.subjectId, this.filter.questionId);
-      const undoIndex = data.findIndex(item => item.id === null);
-      let otherStep = [];
-      let undo = {
-        count: 0,
-        shift: 0
-      };
-      if (undoIndex !== -1) {
-        undo = { ...data[undoIndex] };
-        data.splice(undoIndex, 1);
-      }
-      otherStep.push({
-        name: "待评",
-        count: undo.count,
-        type: "undo"
-      });
-      otherStep.push({
-        name: "改档",
-        count: undo.shift,
-        type: "shift"
-      });
-      let levelStep = data.map(item => {
-        return {
-          ...item,
-          name: item.id,
-          type: "done"
-        };
-      });
-      this.steps = { levelStep, otherStep };
-      if (!this.curStep.type) {
-        this.curStep = levelStep[0];
-      }
-    },
-    async getWorkLevels() {
-      const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          ...item,
-          name: item.code
-        };
-      });
-    },
-    async stepChange(step) {
-      this.applyChangeLevelStatus = 1;
-      this.curStep = step;
-      this.current = 1;
-      await this.getList();
-      if (this.papers.length) {
-        this.selectPaper(0);
-      } else {
-        this.curPaper = {};
-      }
-    },
-    async areaChange(curArea) {
-      this.curArea = curArea;
-      this.filter.questionId = curArea.id;
-      await this.getStepLevels();
-      this.toPage(1);
-    },
-    toReview(index) {
-      this.isFullscreenMarking = true;
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    toExport() {
-      window.open(
-        this.urlAddAuthor(
-          `${this.GLOBAL.domain}/api/export/paper/${this.workId}/${this.subject}/changeLevel`
-        )
-      );
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        if (this.current > 1) {
-          this.current--;
-          this.curPaperIndex = this.size - 1;
-          await this.getList();
-        } else {
-          this.$Message.warning("当前已经是第一条数据了");
-          return;
-        }
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        if (this.current === this.totalPage) {
-          this.$Message.warning("当前已经是最后一条数据了");
-          return;
-        } else {
-          this.current++;
-          this.curPaperIndex = 0;
-          await this.getList();
-        }
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toActionNextPaper() {
-      if (this.current > 1 && this.papers.length === 1) {
-        this.current--;
-        this.curPaperIndex = this.size;
-      }
-
-      await this.getList();
-      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
-      this.selectPaper(this.curPaperIndex);
-    },
-    updateHistory() {
-      this.$refs.GradeHistoryPaper.updatePapers();
-    },
-    async serachPaperByCode(params) {
-      const data = await taskSnSearch(
-        params.codeType,
-        params.code,
-        this.filter.questionId
-      );
-      if (!data) {
-        this.$Message.error("没有查找到结果!");
-        return;
-      }
-      data.title = `NO.${data.sn}`;
-      // data.title = this.IS_ADMIN ? data.examNumber : `NO.${data.sn}`;
-      this.papers = [data];
-      this.total = 1;
-      this.selectPaper(0);
-    },
-    searchGradeChangeList(applyChangeLevelStatus) {
-      this.applyChangeLevelStatus = applyChangeLevelStatus;
-      this.toPage(1);
-    },
-    leaderSelectLevel(levelInfo) {
-      const content = `确定申请由${levelInfo.curLevel}档改为${levelInfo.selectedLevel}并打回给所有老师吗?`;
-      this.$Modal.confirm({
-        content,
-        onOk: async () => {
-          await markStepChangeLevel({
-            subjectId: this.subjectId,
-            paperId: levelInfo.paperId,
-            level: levelInfo.selectedLevel,
-            userId: this.$ls.get("user", { id: "" }).id
-          });
-          this.$Message.success("申请改档成功!");
-          this.getStepLevels();
-          // this.updateHistory();
-          this.toActionNextPaper();
-        },
-        onCancel: () => {
-          this.$refs.MarkAction.btnClicked = false;
-        }
-      });
-    },
-    // paper carousel
-    toViewCarouselPaper(paperIndex, papers) {
-      this.isFullscreenMarking = true;
-      this.carouselPapers = papers;
-      this.selectCarouselPaper(paperIndex);
-      this.$nextTick(() => {
-        this.$refs.CarouselPapersPreview.open();
-      });
-    },
-    selectCarouselPaper(index) {
-      this.curCarouselPaperIndex = index;
-      this.curPaper = { ...this.carouselPapers[index] };
-    },
-    toCarousePaper(type) {
-      if (type === "prev" && this.curCarouselPaperIndex > 0) {
-        this.curCarouselPaperIndex--;
-      } else if (
-        type === "next" &&
-        this.curCarouselPaperIndex < this.carouselPapers.length - 1
-      ) {
-        this.curCarouselPaperIndex++;
-      }
-      this.selectCarouselPaper(this.curCarouselPaperIndex);
-    },
-    carouseImagePreviewClose() {
-      this.isFullscreenMarking = false;
-      this.selectPaper(this.curPaperIndex);
-    }
-  }
-};
-</script>
+<template>
+  <div :class="compClasses">
+    <grade-filter
+      ref="GradeFilter"
+      :data="workSubject"
+      @change="areaChange"
+    ></grade-filter>
+    <mark-step
+      :steps="steps"
+      :init-step="curStep"
+      :show-top-number="false"
+      @on-change="stepChange"
+      ref="MarkStep"
+      v-if="steps.levelStep"
+    ></mark-step>
+    <div class="detail-body clear-float">
+      <!-- detail-papers -->
+      <div :class="detailPapersClasses">
+        <div class="detail-papers-carousel" v-if="!IS_ADMIN">
+          <grade-history-paper
+            :question-id="filter.questionId"
+            stage="SCORE"
+            @on-paper-click="toViewCarouselPaper"
+            v-if="filter.questionId"
+            ref="GradeHistoryPaper"
+          ></grade-history-paper>
+        </div>
+        <div class="detail-papers-list" v-if="papers.length">
+          <div :class="imageViewClasses">
+            <div
+              :class="[
+                'image-view',
+                { 'image-view-act': curPaperIndex === index }
+              ]"
+              v-for="(image, index) in papers"
+              :key="index"
+            >
+              <div class="image-view-container">
+                <h5 class="image-view-title">{{ image.title }}</h5>
+                <div class="image-view-contain">
+                  <img
+                    :src="image.thumbSrc"
+                    :alt="image.title"
+                    @click="toReview(index)"
+                  />
+                  <span
+                    class="image-info"
+                    v-if="image.score || image.score === 0"
+                    >{{ image.score }}分</span
+                  >
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="part-page" v-if="total > size">
+            <Page
+              :current="current"
+              :total="total"
+              :page-size="size"
+              show-total
+              show-elevator
+              @on-change="toPage"
+            ></Page>
+          </div>
+        </div>
+        <div class="detail-papers-list" v-else>
+          <p class="detail-papers-none">暂无数据</p>
+        </div>
+      </div>
+      <!-- detail-aciton -->
+      <div
+        :class="[
+          'detail-action',
+          { 'detail-action-fullscreen': isFullscreenMarking }
+        ]"
+      >
+        <mark-action
+          :cur-paper-or-task="curPaper"
+          :levels="levels"
+          @on-leader-level="leaderSelectLevel"
+          @on-code-search="serachPaperByCode"
+          @on-grade-change-search="searchGradeChangeList"
+          v-if="curPaper.id"
+          ref="MarkAction"
+        ></mark-action>
+      </div>
+      <!-- 占位 -->
+      <div class="detail-action" v-if="isFullscreenMarking"></div>
+    </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      :class="imagePreviewClasses"
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      @on-close="isFullscreenMarking = false"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
+    <!-- carousel paper review -->
+    <simple-image-preview
+      :class="imagePreviewClasses"
+      :cur-image="curPaper"
+      @on-prev="toCarousePaper('prev')"
+      @on-next="toCarousePaper('next')"
+      @on-close="carouseImagePreviewClose"
+      ref="CarouselPapersPreview"
+    ></simple-image-preview>
+  </div>
+</template>
+
+<script>
+import {
+  paperList,
+  changeLevelPaperList,
+  scoreStatData,
+  workLevelList,
+  taskSnSearch,
+  markStepChangeLevel
+} from "@/api";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+import MarkStep from "./components/MarkStep";
+import GradeFilter from "../grading/components/GradeFilter";
+import GradeHistoryPaper from "../grading/components/GradeHistoryPaper";
+import MarkAction from "./components/MarkAction";
+// 三种情况:
+// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
+// 管理员:试卷列表,操作盘
+// 科组长:操作记录,试卷列表,操作盘(改档)
+
+// TIP:不考虑评卷员的情况
+// 评卷员:操作记录,试卷列表,操作盘(打分)
+
+export default {
+  name: "mark-detail",
+  components: {
+    SimpleImagePreview,
+    MarkStep,
+    GradeFilter,
+    GradeHistoryPaper,
+    MarkAction
+  },
+  data() {
+    return {
+      filter: {
+        questionId: "",
+        sort: "score,desc"
+      },
+      workId: this.$route.params.workId,
+      subjectId: this.$route.params.subjectId,
+      subject: "",
+      workSubject: {},
+      curUserRoleType: "",
+      applyChangeLevelStatus: 1, // 改档申请处理状态
+      current: 1,
+      size: 6,
+      total: 0,
+      totalPage: 1,
+      curStep: { type: "", name: "" },
+      steps: [],
+      levels: [],
+      curArea: {},
+      papers: [],
+      curPaper: {},
+      curPaperIndex: 0,
+      // carousel paper review,
+      carouselPapers: [],
+      curCarouselPaperIndex: 0,
+      isFullscreenMarking: false
+    };
+  },
+  computed: {
+    compClasses() {
+      return [
+        "page-container-flex",
+        "mark-detail",
+        "grading-detail",
+        { "grading-operation": this.IS_MARK_LEADER }
+      ];
+    },
+    bodyClasses() {
+      return [
+        "detail-body",
+        { "detail-body-2": this.curUserRoleType === "ADMIN" }
+      ];
+    },
+    detailPapersClasses() {
+      return [
+        "detail-papers",
+        {
+          [`detail-papers-col-${1 + this.size / 2}`]:
+            this.curUserRoleType !== "ADMIN"
+        }
+      ];
+    },
+    imageViewClasses() {
+      return ["image-view-list", `image-view-list-${this.size / 2}`];
+    },
+    IS_ADMIN() {
+      return this.curUserRoleType === "ADMIN";
+    },
+    IS_MARK_LEADER() {
+      return this.curUserRoleType === "MARK_LEADER";
+    },
+    imagePreviewClasses() {
+      return this.IS_ADMIN
+        ? "grading-detail-image-preview"
+        : "grading-operation-image-preview";
+    }
+  },
+  created() {
+    this.subject = this.subjectId.split("-")[1];
+    this.workSubject = {
+      workId: this.workId,
+      subject: this.subject
+    };
+    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
+    if (this.curUserRoleType === "ADMIN") this.size = 8;
+    this.initData();
+  },
+  methods: {
+    initData() {
+      this.getWorkLevels();
+    },
+    async getList() {
+      let data = [];
+      if (this.curStep.type === "shift") {
+        const datas = {
+          workId: this.workId,
+          subject: this.subject,
+          questionId: this.filter.questionId,
+          status: this.applyChangeLevelStatus,
+          page: this.current - 1,
+          size: this.size
+        };
+        data = await changeLevelPaperList(datas);
+      } else {
+        const datas = {
+          ...this.filter,
+          isScore: true,
+          page: this.current - 1,
+          size: this.size
+        };
+        if (this.curStep.type === "done") datas.level = this.curStep.name;
+
+        data = await paperList(datas);
+      }
+      this.papers = data.data.map(paper => {
+        paper.title = `NO.${paper.sn}`;
+        // paper.title = this.IS_ADMIN ? paper.examNumber : `NO.${paper.sn}`;
+        return paper;
+      });
+      this.total = data.totalCount;
+      this.totalPage = data.pageCount;
+    },
+    async toPage(page) {
+      this.current = page;
+      await this.getList();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async getStepLevels() {
+      const data = await scoreStatData(this.subjectId, this.filter.questionId);
+      const undoIndex = data.findIndex(item => item.id === null);
+      let otherStep = [];
+      let undo = {
+        count: 0,
+        shift: 0
+      };
+      if (undoIndex !== -1) {
+        undo = { ...data[undoIndex] };
+        data.splice(undoIndex, 1);
+      }
+      otherStep.push({
+        name: "待评",
+        count: undo.count,
+        type: "undo"
+      });
+      otherStep.push({
+        name: "改档",
+        count: undo.shift,
+        type: "shift"
+      });
+      let levelStep = data.map(item => {
+        return {
+          ...item,
+          name: item.id,
+          type: "done"
+        };
+      });
+      this.steps = { levelStep, otherStep };
+      if (!this.curStep.type) {
+        this.curStep = levelStep[0];
+      }
+    },
+    async getWorkLevels() {
+      const data = await workLevelList(this.workId);
+      this.levels = data.map(item => {
+        return {
+          ...item,
+          name: item.code
+        };
+      });
+    },
+    async stepChange(step) {
+      this.applyChangeLevelStatus = 1;
+      this.curStep = step;
+      this.current = 1;
+      await this.getList();
+      if (this.papers.length) {
+        this.selectPaper(0);
+      } else {
+        this.curPaper = {};
+      }
+    },
+    async areaChange(curArea) {
+      this.curArea = curArea;
+      this.filter.questionId = curArea.id;
+      await this.getStepLevels();
+      this.toPage(1);
+    },
+    toReview(index) {
+      this.isFullscreenMarking = true;
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    toExport() {
+      window.open(
+        this.urlAddAuthor(
+          `${this.GLOBAL.domain}/api/export/paper/${this.workId}/${this.subject}/changeLevel`
+        )
+      );
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        if (this.current > 1) {
+          this.current--;
+          this.curPaperIndex = this.size - 1;
+          await this.getList();
+        } else {
+          this.$Message.warning("当前已经是第一条数据了");
+          return;
+        }
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        if (this.current === this.totalPage) {
+          this.$Message.warning("当前已经是最后一条数据了");
+          return;
+        } else {
+          this.current++;
+          this.curPaperIndex = 0;
+          await this.getList();
+        }
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toActionNextPaper() {
+      if (this.current > 1 && this.papers.length === 1) {
+        this.current--;
+        this.curPaperIndex = this.size;
+      }
+
+      await this.getList();
+      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
+      this.selectPaper(this.curPaperIndex);
+    },
+    updateHistory() {
+      this.$refs.GradeHistoryPaper.updatePapers();
+    },
+    async serachPaperByCode(params) {
+      const data = await taskSnSearch(
+        params.codeType,
+        params.code,
+        this.filter.questionId
+      );
+      if (!data) {
+        this.$Message.error("没有查找到结果!");
+        return;
+      }
+      data.title = `NO.${data.sn}`;
+      data.key = this.$randomCode();
+      // data.title = this.IS_ADMIN ? data.examNumber : `NO.${data.sn}`;
+      this.papers = [data];
+      this.total = 1;
+      this.selectPaper(0);
+    },
+    searchGradeChangeList(applyChangeLevelStatus) {
+      this.applyChangeLevelStatus = applyChangeLevelStatus;
+      this.toPage(1);
+    },
+    leaderSelectLevel(levelInfo) {
+      const content = `确定申请由${levelInfo.curLevel}档改为${levelInfo.selectedLevel}并打回给所有老师吗?`;
+      this.$Modal.confirm({
+        content,
+        onOk: async () => {
+          await markStepChangeLevel({
+            subjectId: this.subjectId,
+            paperId: levelInfo.paperId,
+            level: levelInfo.selectedLevel,
+            userId: this.$ls.get("user", { id: "" }).id
+          });
+          this.$Message.success("申请改档成功!");
+          this.getStepLevels();
+          // this.updateHistory();
+          this.toActionNextPaper();
+        },
+        onCancel: () => {
+          this.$refs.MarkAction.btnClicked = false;
+        }
+      });
+    },
+    // paper carousel
+    toViewCarouselPaper(paperIndex, papers) {
+      this.isFullscreenMarking = true;
+      this.carouselPapers = papers;
+      this.selectCarouselPaper(paperIndex);
+      this.$nextTick(() => {
+        this.$refs.CarouselPapersPreview.open();
+      });
+    },
+    selectCarouselPaper(index) {
+      this.curCarouselPaperIndex = index;
+      this.curPaper = { ...this.carouselPapers[index] };
+    },
+    toCarousePaper(type) {
+      if (type === "prev" && this.curCarouselPaperIndex > 0) {
+        this.curCarouselPaperIndex--;
+      } else if (
+        type === "next" &&
+        this.curCarouselPaperIndex < this.carouselPapers.length - 1
+      ) {
+        this.curCarouselPaperIndex++;
+      }
+      this.selectCarouselPaper(this.curCarouselPaperIndex);
+    },
+    carouseImagePreviewClose() {
+      this.isFullscreenMarking = false;
+      this.selectPaper(this.curPaperIndex);
+    }
+  }
+};
+</script>

+ 1 - 0
src/modules/mark/leader/LeaderMarking.vue

@@ -424,6 +424,7 @@ export default {
         return;
         return;
       }
       }
       data.title = this.IS_ADMIN ? data.examNumber : `NO.${data.sn}`;
       data.title = this.IS_ADMIN ? data.examNumber : `NO.${data.sn}`;
+      data.key = this.$randomCode();
       this.papers = [data];
       this.papers = [data];
       this.setPage({ current: 1, total: 1, totalPage: 1 });
       this.setPage({ current: 1, total: 1, totalPage: 1 });
       this.selectPaper(0);
       this.selectPaper(0);