zhangjie 4 vuotta sitten
vanhempi
commit
08c1eec656

+ 10 - 0
src/api.js

@@ -135,6 +135,13 @@ export const updateLevelParams = datas => {
 export const updateScoreParams = datas => {
   return $post("/api/param/score", datas, "json");
 };
+// export-paper
+export const exportScorePictures = datas => {
+  return $get("/api/file/image/exportScorePictures", datas);
+};
+export const exportDecryptPictures = datas => {
+  return $get("/api/file/image/exportDecryptPictures", datas);
+};
 
 // quality-analysis -------------------------->
 // 档位占比
@@ -278,6 +285,9 @@ export const paperSelectLevelOrScore = (taskId, result, stage) => {
   // stage => LEVEL or SCORE
   return $patch(`/api/marktasks/${taskId}`, { stage, result }, "json");
 };
+export const paperSelectLevelBatch = (taskIds, result, stage) => {
+  return $patch(`/api/marktasks/batch`, { taskIds, result, stage }, "json");
+};
 export const paperTaskPass = taskId => {
   return $post(`/api/marktasks/${taskId}/skip`, {});
 };

+ 24 - 0
src/assets/styles/base.less

@@ -188,6 +188,30 @@ body {
   &-navs {
     margin-bottom: 10px;
   }
+  &-reload {
+    position: fixed;
+    width: 35px;
+    height: 35px;
+    top: 140px;
+    right: 10px;
+    z-index: 999;
+    border-radius: 50%;
+    background-color: @white;
+    box-shadow: 0 0 5px #999;
+    color: @dark-color-lighter;
+    font-size: 22px;
+    line-height: 32px;
+    text-align: center;
+    cursor: pointer;
+    > i {
+      vertical-align: middle;
+    }
+
+    &:hover {
+      background-color: @primary-color;
+      color: @white;
+    }
+  }
 }
 /* table */
 .table {

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

@@ -401,6 +401,11 @@
     bottom: 32px;
     width: 80px;
   }
+  .ivu-form-inline {
+    .ivu-form-item {
+      margin-bottom: 26px;
+    }
+  }
 }
 
 // student-score

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

@@ -320,6 +320,9 @@
       display: inline-block;
       vertical-align: top;
       font-size: 14px;
+      &-split {
+        height: 40px;
+      }
     }
     &-list {
       display: inline-block;
@@ -332,6 +335,21 @@
       .image-view-list {
         margin: 0;
       }
+      .image-view-actions {
+        width: 30%;
+        border-radius: @box-border-radius-small;
+        background-color: @background-color;
+        height: 20px;
+        margin: 20px auto 0;
+        cursor: pointer;
+
+        &:hover {
+          background-color: shade(@background-color, 5%);
+        }
+        &.image-view-selected {
+          background-color: @sub-color;
+        }
+      }
       .part-page {
         position: absolute;
         bottom: 10px;

+ 2 - 2
src/components/UploadButton.vue

@@ -137,11 +137,11 @@ export default {
       this.loading = true;
       this.$refs.UploadComp.clearFiles();
     },
-    handleError(error) {
+    handleError(error, response) {
       this.loading = false;
       this.res = {
         success: false,
-        msg: error.message
+        msg: response.message
       };
     },
     handleSuccess(response) {

+ 4 - 4
src/constants/enumerate.js

@@ -84,13 +84,13 @@ export const IMAGE_NAME_TYPE = {
   1: "随机码命名"
 };
 export const EXPORT_IMAGE_NAME_TYPE = {
-  0: "考号+姓名",
-  1: "流水号"
+  1: "考号+姓名",
+  2: "流水号"
 };
 // image-type
 export const IMAGE_TYPE = {
-  0: "原图",
-  1: "裁切图"
+  1: "原图",
+  2: "裁切图"
 };
 
 // paper-level-known-type

+ 5 - 1
src/modules/grading-set/GradingRuleSet.vue

@@ -16,7 +16,11 @@
           style="width: 160px;"
         ></InputNumber>
       </FormItem>
-      <FormItem prop="cumulativeError" label="打回累计误差:">
+      <FormItem
+        prop="cumulativeError"
+        label="打回累计误差:"
+        v-if="modalForm.autoCallback"
+      >
         <InputNumber
           v-model="modalForm.cumulativeError"
           :min="1"

+ 82 - 0
src/modules/grading/GradingOperation.vue

@@ -47,6 +47,7 @@
               'detail-action',
               { 'detail-action-fullscreen': isFullscreenMarking }
             ]"
+            v-show="!multipleGradingList.length"
           >
             <grade-action
               :cur-paper-or-task="curPaper"
@@ -58,6 +59,32 @@
               v-if="curPaper.id"
             ></grade-action>
           </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>
           <!-- detail-papers -->
           <div :class="detailPapersClasses">
             <div class="detail-papers-carousel">
@@ -67,6 +94,7 @@
                 @on-paper-click="toViewCarouselPaper"
                 v-if="levels.length && filter.questionId"
               ></grade-standard-paper>
+              <div class="detail-papers-carousel-split"></div>
               <grade-history-paper
                 :question-id="filter.questionId"
                 @on-paper-click="toViewCarouselPaper"
@@ -92,6 +120,13 @@
                       @click="toReview(index)"
                     />
                   </div>
+                  <div
+                    :class="[
+                      'image-view-actions',
+                      { 'image-view-selected': image.selected }
+                    ]"
+                    @click="selectMultiplePaper(image)"
+                  ></div>
                 </div>
               </div>
               <div class="part-page">
@@ -148,6 +183,7 @@ import {
   workLevelList,
   subjectDetail,
   paperSelectLevelOrScore,
+  paperSelectLevelBatch,
   paperTaskPass
 } from "@/api";
 import SimpleImagePreview from "@/components/SimpleImagePreview";
@@ -207,6 +243,9 @@ export default {
       papers: [],
       curPaper: {},
       curPaperIndex: 0,
+      // multiple grading
+      multiplebtnClicked: false,
+      multipleGradingList: [],
       // carousel paper review,
       carouselPapers: [],
       curCarouselPaperIndex: 0,
@@ -238,6 +277,7 @@ export default {
       this.curSubject = await subjectDetail(this.subjectId);
     },
     async getList() {
+      this.multipleGradingList = [];
       const datas = {
         ...this.filter,
         ...this.typeFilter[this.curStep.type],
@@ -253,6 +293,7 @@ export default {
       const data = await markerTaskList(datas);
       this.papers = data.data.map(paper => {
         paper.title = `NO.${paper.sn}`;
+        paper.selected = false;
         return paper;
       });
       this.total = data.totalCount;
@@ -347,8 +388,49 @@ export default {
       this.getStepLevels();
       this.toPage(1);
     },
+    // selectMultiplePaper
+    selectMultiplePaper(paper) {
+      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 multipleGradingListCount = this.multipleGradingList.length;
+
+      let result = true;
+      await paperSelectLevelBatch(
+        this.multipleGradingList.map(item => item.id).join(), // is taskId
+        level.name,
+        "LEVEL"
+      ).catch(() => {
+        result = false;
+      });
+
+      this.multiplebtnClicked = false;
+      if (!result) return;
+
+      this.multipleGradingList = [];
+      this.getStepLevels();
+      this.updateHistory();
+
+      // update paper list
+      if (
+        this.current > 1 &&
+        this.current === this.pageCount &&
+        this.papers.length === multipleGradingListCount
+      ) {
+        this.current--;
+      }
+
+      await this.getList();
+      this.selectPaper(this.curPaperIndex);
+    },
+    // paper view action
     toReview(index) {
       this.isFullscreenMarking = true;
+      this.multipleGradingList = [];
       this.selectPaper(index);
       this.$refs.SimpleImagePreview.open();
     },

+ 55 - 40
src/modules/inspection/InspectionGrading.vue

@@ -148,18 +148,14 @@
     </div>
 
     <!-- image-preview -->
-    <image-preview
+    <simple-image-preview
       class="check-grade-image-preview"
-      :image-list="papers"
-      :init-index="curPaperIndex"
-      @on-paper-change="selectPaper"
-      @on-page-prev="prevPage"
-      @on-page-next="nextPage"
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
       @on-close="isFullscreenMarking = false"
-      header-hide
-      ref="ImagePreview"
-      v-if="papers.length"
-    ></image-preview>
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
   </div>
 </template>
 
@@ -170,12 +166,12 @@ import {
   workList,
   areaList
 } from "@/api";
-import ImagePreview from "@/components/common/ImagePreview";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
 import { CHANGE_LEVEL_STATUS } from "@/constants/enumerate";
 
 export default {
   name: "inspection-grading",
-  components: { ImagePreview },
+  components: { SimpleImagePreview },
   data() {
     return {
       filter: {
@@ -277,48 +273,67 @@ export default {
         id: this.curPaper.id,
         auditStatus
       });
-      this.$refs.ImagePreview.showNext();
-    },
-    selectPaper(index) {
-      this.curPaperIndex = index;
-      this.curPaper = { ...this.papers[index] };
+      this.toActionNextPaper();
     },
+    // paper view action
     toReview(index) {
       this.isFullscreenMarking = true;
       this.selectPaper(index);
-      this.$refs.ImagePreview.open();
-    },
-    paperPrev(index) {
-      this.curPaper = { ...this.papers[index] };
-      this.curPaperIndex = index;
+      this.$refs.SimpleImagePreview.open();
     },
-    paperNext(index) {
-      this.curPaper = { ...this.papers[index] };
-      this.curPaperIndex = index;
-    },
-    async prevPage() {
-      if (this.current === 1) {
-        this.$Message.warning("当前已经是第一条数据了");
-        return;
+    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.current--;
-      await this.getList();
-      this.selectPaper(this.papers.length - 1);
-      if (this.papers.length) this.$refs.ImagePreview.initData();
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
     },
-    async nextPage() {
-      if (this.current === this.totalPage) {
+    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("当前已经是最后一条数据了");
-          this.$refs.ImagePreview.cancel();
+          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();
-      this.selectPaper(0);
-      if (this.papers.length) this.$refs.ImagePreview.initData();
+      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
+      this.selectPaper(this.curPaperIndex);
     }
   }
 };

+ 79 - 4
src/modules/main/ClientMonitor.vue

@@ -1,6 +1,21 @@
 <template>
   <div class="client-monitor">
-    <image-action-list :data="papers" ref="ImageActionList"></image-action-list>
+    <div class="page-reload" @click="getList"><Icon type="md-refresh" /></div>
+
+    <div class="image-view-list image-view-list-5">
+      <div class="image-view" v-for="(image, index) in papers" :key="image.id">
+        <div class="image-view-container">
+          <h5 class="image-view-title">{{ image.title }}</h5>
+          <div class="image-view-contain" :style="image.styles">
+            <img
+              :src="image.thumbSrc"
+              :alt="image.title"
+              @click="toReview(index)"
+            />
+          </div>
+        </div>
+      </div>
+    </div>
 
     <div class="part-page" v-if="total > size">
       <Page
@@ -12,23 +27,34 @@
         @on-change="toPage"
       ></Page>
     </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
   </div>
 </template>
 
 <script>
 import { clientMonitorList } from "@/api";
-import ImageActionList from "./components/ImageActionList";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
 
 export default {
   name: "client-monitor",
-  components: { ImageActionList },
+  components: { SimpleImagePreview },
   data() {
     return {
       workId: this.$route.params.workId,
       current: 1,
       size: this.GLOBAL.pageSize,
       total: 0,
-      papers: []
+      totalPage: 0,
+      papers: [],
+      curPaper: {},
+      curPaperIndex: 0
     };
   },
   mounted() {
@@ -46,10 +72,59 @@ export default {
         return item;
       });
       this.total = data.totalCount;
+      this.totalPage = data.pageCount;
     },
     toPage(page) {
       this.current = page;
       this.getList();
+    },
+    toReview(index) {
+      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);
     }
   }
 };

+ 69 - 2
src/modules/main/PaperManage.vue

@@ -87,9 +87,11 @@
         </FormItem>
       </Form>
     </div>
+
     <image-action-list
       :data="papers"
       :actions="['rotate', 'absent']"
+      @on-review="toReview"
       ref="ImageActionList"
     ></image-action-list>
 
@@ -103,6 +105,14 @@
         @on-change="toPage"
       ></Page>
     </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
   </div>
 </template>
 
@@ -110,10 +120,11 @@
 import { paperPageList, subjectList, areaList } from "@/api";
 import { SORT_RULE_TYPE, CAFA_EXCEPTION_TYPE } from "@/constants/enumerate";
 import ImageActionList from "./components/ImageActionList";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
 
 export default {
   name: "papers",
-  components: { ImageActionList },
+  components: { ImageActionList, SimpleImagePreview },
   data() {
     return {
       filter: {
@@ -133,9 +144,12 @@ export default {
       current: 1,
       size: this.GLOBAL.pageSize,
       total: 0,
+      totalPage: 0,
       papers: [],
       subjects: [],
-      areas: []
+      areas: [],
+      curPaper: {},
+      curPaperIndex: 0
     };
   },
   mounted() {
@@ -162,6 +176,7 @@ export default {
         };
       });
       this.total = data.totalCount;
+      this.totalPage = data.pageCount;
     },
     toPage(page) {
       if (!this.filter.subject || !this.filter.areaCode) {
@@ -189,6 +204,9 @@ export default {
           areaCode: item.areaCode
         };
       });
+      if (this.areas.length === 1) {
+        this.filter.areaCode = this.areas[0].areaCode;
+      }
     },
     async getSubjects() {
       const data = await subjectList(this.filter.workId);
@@ -205,6 +223,55 @@ export default {
         this.filter.isManual = null;
         this.filter.missing = null;
       }
+    },
+    // paper view
+    toReview(index) {
+      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);
     }
   }
 };

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

@@ -58,6 +58,11 @@ export default {
             return h("div", param.index + 1 + "");
           }
         },
+        {
+          title: "ID",
+          key: "id",
+          minWidth: 100
+        },
         {
           title: "名称",
           key: "name",
@@ -66,6 +71,7 @@ export default {
         {
           title: "是否为当前工作",
           key: "active",
+          minWidth: 200,
           render: (h, param) => {
             return h("div", param.row.active ? "是" : "否");
           }

+ 2 - 25
src/modules/main/components/ImageActionList.vue

@@ -34,27 +34,14 @@
         </div>
       </div>
     </div>
-
-    <!-- image-preview -->
-    <image-preview
-      :class="imagePreviewCls"
-      :image-list="data"
-      :init-index="curImageIndex"
-      :loop="loop"
-      header-hide
-      ref="ImagePreview"
-      v-if="data.length"
-    ></image-preview>
   </div>
 </template>
 
 <script>
 import { rotatePaper, absentPaper } from "@/api";
-import ImagePreview from "@/components/common/ImagePreview";
 
 export default {
   name: "image-action-list",
-  components: { ImagePreview },
   props: {
     data: {
       type: Array,
@@ -71,20 +58,11 @@ export default {
     columnNumber: {
       type: Number,
       default: 5
-    },
-    loop: {
-      type: Boolean,
-      default: false
-    },
-    imagePreviewCls: {
-      type: String,
-      default: ""
     }
   },
   data() {
     return {
-      curImageIndex: 0,
-      imageList: []
+      curImageIndex: 0
     };
   },
   computed: {
@@ -121,8 +99,7 @@ export default {
       image.missing = !image.missing;
     },
     toReview(index) {
-      this.curImageIndex = index;
-      this.$refs.ImagePreview.open();
+      this.$emit("on-review", index);
     }
   }
 };

+ 82 - 31
src/modules/mark-set/ExportPaper.vue

@@ -6,8 +6,14 @@
           <div class="part-title">
             <h2>分数图片导出</h2>
           </div>
-          <Form label-position="left" inline>
-            <FormItem>
+          <Form
+            :rules="scoreRules"
+            :model="scoreFilter"
+            label-position="left"
+            inline
+            ref="scoreForm"
+          >
+            <FormItem prop="imageType">
               <Select v-model="scoreFilter.imageType" placeholder="图片类型">
                 <Option
                   v-for="(val, key) in IMAGE_TYPE"
@@ -17,9 +23,9 @@
                 >
               </Select>
             </FormItem>
-            <FormItem>
+            <FormItem prop="areaId">
               <Select
-                v-model="scoreFilter.areaCode"
+                v-model="scoreFilter.areaId"
                 @on-change="areaChange"
                 placeholder="考点"
               >
@@ -36,6 +42,7 @@
                 v-model="scoreFilter.school"
                 @on-change="schoolChange"
                 placeholder="学校"
+                clearable
               >
                 <Option
                   v-for="(item, index) in schools"
@@ -46,7 +53,11 @@
               </Select>
             </FormItem>
             <FormItem>
-              <Select v-model="scoreFilter.examRoom" placeholder="考场">
+              <Select
+                v-model="scoreFilter.examRoom"
+                placeholder="考场"
+                clearable
+              >
                 <Option
                   v-for="(room, index) in rooms"
                   :key="index"
@@ -55,7 +66,7 @@
                 ></Option>
               </Select>
             </FormItem>
-            <FormItem>
+            <FormItem prop="subject">
               <Select v-model="scoreFilter.subject" placeholder="科目">
                 <Option
                   v-for="(subject, index) in subjects"
@@ -65,7 +76,7 @@
                 ></Option>
               </Select>
             </FormItem>
-            <FormItem>
+            <FormItem prop="nameRule">
               <Select v-model="scoreFilter.nameRule" placeholder="命名规则">
                 <Option
                   v-for="(val, key) in EXPORT_IMAGE_NAME_TYPE"
@@ -77,7 +88,7 @@
             </FormItem>
             <FormItem>
               <InputNumber
-                v-model="scoreFilter.startNumber"
+                v-model="scoreFilter.startScore"
                 :min="1"
                 :precision="0"
                 placeholder="输入起始分数"
@@ -86,8 +97,8 @@
             </FormItem>
             <FormItem>
               <InputNumber
-                v-model="scoreFilter.endNumber"
-                :min="scoreFilter.startNumber"
+                v-model="scoreFilter.endScore"
+                :min="scoreFilter.startScore"
                 :precision="0"
                 placeholder="输入终止分数"
                 clearable
@@ -99,7 +110,7 @@
             class="export-paper-btn"
             type="primary"
             shape="circle"
-            @click="toExport('score')"
+            @click="toExportScore"
             >导出</Button
           >
         </div>
@@ -109,9 +120,15 @@
           <div class="part-title">
             <h2>图片解密、重命名导出</h2>
           </div>
-          <Form label-position="left" inline>
-            <FormItem>
-              <Select v-model="renameFilter.imageType" placeholder="图片类型">
+          <Form
+            :rules="decryptRules"
+            :model="decryptFilter"
+            label-position="left"
+            inline
+            ref="decryptForm"
+          >
+            <FormItem prop="imageType">
+              <Select v-model="decryptFilter.imageType" placeholder="图片类型">
                 <Option
                   v-for="(val, key) in IMAGE_TYPE"
                   :key="key"
@@ -120,8 +137,8 @@
                 >
               </Select>
             </FormItem>
-            <FormItem>
-              <Select v-model="renameFilter.areaCode" placeholder="考点">
+            <FormItem prop="areaId">
+              <Select v-model="decryptFilter.areaId" placeholder="考点">
                 <Option
                   v-for="area in cascadeList"
                   :key="area.areaCode"
@@ -130,8 +147,8 @@
                 ></Option>
               </Select>
             </FormItem>
-            <FormItem>
-              <Select v-model="renameFilter.subject" placeholder="科目">
+            <FormItem prop="subject">
+              <Select v-model="decryptFilter.subject" placeholder="科目">
                 <Option
                   v-for="(subject, index) in subjects"
                   :key="index"
@@ -146,7 +163,7 @@
             class="export-paper-btn"
             type="primary"
             shape="circle"
-            @click="toExport('rename')"
+            @click="toExportDecrypt"
             >导出</Button
           >
         </div>
@@ -156,8 +173,14 @@
 </template>
 
 <script>
-import { subjectList, areaSchoolRoomCascadeList } from "@/api";
+import {
+  subjectList,
+  areaSchoolRoomCascadeList,
+  exportScorePictures,
+  exportDecryptPictures
+} from "@/api";
 import { IMAGE_TYPE, EXPORT_IMAGE_NAME_TYPE } from "@/constants/enumerate";
+import { requiredValid } from "@/plugins/formRules";
 
 export default {
   name: "export-paper",
@@ -166,19 +189,30 @@ export default {
       workId: this.$route.params.workId,
       scoreFilter: {
         imageType: "",
-        areaCode: "",
+        areaId: "",
         examRoom: "",
         school: "",
         subject: "",
         nameRule: "",
-        startNumber: null,
-        endNumber: null
+        startScore: null,
+        endScore: null
       },
-      renameFilter: {
+      decryptFilter: {
         imageType: "",
-        areaCode: "",
+        areaId: "",
         subject: ""
       },
+      scoreRules: {
+        imageType: requiredValid("请选择图片类型"),
+        areaId: requiredValid("请选择考区"),
+        subject: requiredValid("请选择科目"),
+        nameRule: requiredValid("请选择命名规则")
+      },
+      decryptRules: {
+        imageType: requiredValid("请选择图片类型"),
+        areaId: requiredValid("请选择考区"),
+        subject: requiredValid("请选择科目")
+      },
       IMAGE_TYPE,
       EXPORT_IMAGE_NAME_TYPE,
       subjects: [],
@@ -201,13 +235,13 @@ export default {
     },
     areaChange() {
       const curArea = this.cascadeList.find(
-        item => item.areaCode === this.scoreFilter.areaCode
+        item => item.areaCode === this.scoreFilter.areaId
       );
-      this.schools = curArea.schools;
+      this.schools = curArea ? curArea.schools : [];
       this.rooms = [];
       this.scoreFilter.examRoom = null;
       this.scoreFilter.school = null;
-      if (curArea.schools.length === 1) {
+      if (curArea && curArea.schools.length === 1) {
         this.scoreFilter.school = curArea.schools[0].school;
         this.schoolChange();
       }
@@ -216,11 +250,28 @@ export default {
       const curSchool = this.schools.find(
         item => item.school === this.scoreFilter.school
       );
-      this.rooms = curSchool.rooms;
+      this.rooms = curSchool ? curSchool.rooms : [];
       this.scoreFilter.examRoom = null;
+      if (curSchool && curSchool.rooms.length === 1) {
+        this.scoreFilter.examRoom = curSchool.rooms[0];
+      }
+    },
+    async toExportScore() {
+      const valid = await this.$refs.scoreForm.validate();
+      if (!valid) return;
+
+      await exportScorePictures({ ...this.scoreFilter, workId: this.workId });
+      this.$Message.success("操作成功,后台正在导出!");
     },
-    toExport(type) {
-      console.log(this[`${type}Filter`]);
+    async toExportDecrypt() {
+      const valid = await this.$refs.decryptForm.validate();
+      if (!valid) return;
+
+      await exportDecryptPictures({
+        ...this.decryptFilter,
+        workId: this.workId
+      });
+      this.$Message.success("操作成功,后台正在导出!");
     }
   }
 };

+ 21 - 10
src/modules/mark/MarkOperation.vue

@@ -135,6 +135,7 @@
 
 <script>
 import {
+  getParamsSet,
   markerTaskList,
   markerChangeLevelPaperList,
   markerScoreStatData,
@@ -194,6 +195,7 @@ export default {
       subject: "",
       curSubject: {},
       curUserRoleType: "MARKER",
+      changeStage: 0, // 是否显示改档及改档打分
       current: 1,
       size: 6,
       total: 0,
@@ -231,11 +233,17 @@ export default {
 
       await this.getAreaList();
       this.filter.questionId = this.areas[0].id;
+      await this.getParamsSetInfo();
+
       this.getStepLevels();
     },
     async getSubjectDetail() {
       this.curSubject = await subjectDetail(this.subjectId);
     },
+    async getParamsSetInfo() {
+      const data = await getParamsSet(this.workId);
+      this.changeStage = data.changeStage;
+    },
     async getList() {
       const datas = {
         ...this.filter,
@@ -279,16 +287,19 @@ export default {
           count: undo.count,
           type: "undo"
         });
-        otherStep.push({
-          name: "改档",
-          count: undo.shift,
-          type: "shift"
-        });
-        otherStep.push({
-          name: "改档打分",
-          count: undo.shiftScore,
-          type: "shiftScore"
-        });
+
+        if (this.changeStage) {
+          otherStep.push({
+            name: "改档",
+            count: undo.shift,
+            type: "shift"
+          });
+          otherStep.push({
+            name: "改档打分",
+            count: undo.shiftScore,
+            type: "shiftScore"
+          });
+        }
       }
       let levelStep = data.map(item => {
         return {

+ 66 - 4
src/modules/quality/Quality.vue

@@ -111,6 +111,7 @@
           :data="papers"
           :column-number="4"
           :actions="imageListActions"
+          @on-review="toReview"
           ref="ImageActionList"
         ></image-action-list>
 
@@ -128,6 +129,14 @@
         <view-footer></view-footer>
       </div>
     </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
   </div>
 </template>
 
@@ -135,10 +144,11 @@
 import { workList, areaList, paperPageList } from "@/api";
 import { SORT_RULE_TYPE, CAFA_EXCEPTION_TYPE } from "@/constants/enumerate";
 import ImageActionList from "../main/components/ImageActionList";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
 
 export default {
   name: "quality",
-  components: { ImageActionList },
+  components: { ImageActionList, SimpleImagePreview },
   data() {
     return {
       filter: {
@@ -159,11 +169,13 @@ export default {
       current: 1,
       size: 8,
       total: 0,
+      totalPage: 0,
       papers: [],
-      curPaper: {},
       works: [],
       subjects: [],
-      areas: []
+      areas: [],
+      curPaper: {},
+      curPaperIndex: 0
     };
   },
   computed: {
@@ -210,7 +222,7 @@ export default {
         return {
           id: paper.id,
           title: paper.examNumber,
-          url: paper.imgSrc,
+          imgSrc: paper.imgSrc,
           thumbSrc: paper.thumbSrc,
           missing: paper.missing,
           stage: paper.stage,
@@ -219,6 +231,7 @@ export default {
         };
       });
       this.total = data.totalCount;
+      this.totalPage = data.pageCount;
       this.selectPaperType = this.paperType;
     },
     toPage(page) {
@@ -250,6 +263,55 @@ export default {
         this.filter.isManual = false;
         this.filter.missing = false;
       }
+    },
+    // paper view
+    toReview(index) {
+      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);
     }
   }
 };

+ 18 - 1
src/plugins/formRules.js

@@ -73,6 +73,22 @@ const numberValidator = message => {
   ];
 };
 
+const requiredValid = message => {
+  return [
+    {
+      required: true,
+      validator: (rule, value, callback) => {
+        if (value) {
+          callback();
+        } else {
+          callback(new Error(message));
+        }
+      },
+      trigger: "change"
+    }
+  ];
+};
+
 export {
   username,
   commonCode,
@@ -80,5 +96,6 @@ export {
   password,
   phone,
   smscode,
-  numberValidator
+  numberValidator,
+  requiredValid
 };