zhangjie 5 years ago
parent
commit
5117429db9

+ 23 - 3
src/api.js

@@ -202,8 +202,12 @@ export const areaStatProgress = subjectId => {
   return $get(`/api/marksubjects/${subjectId}/areaProgress`);
 };
 export const createTryGradingTask = datas => {
-  // TODO:
-  return $post(`/api/marksubjects/${datas.subjectId}/markergroups`, datas);
+  // workId, subject
+  return $get(`/api/trial/startTrial`, datas);
+};
+export const finishTryGradingTask = datas => {
+  // workId, subject
+  return $get(`/api/trial/finishTrial`, datas);
 };
 // grade-task
 export const checkMissionStatus = ({ workId, subject }) => {
@@ -255,7 +259,23 @@ export const markerDetail = userId => {
 // leader mark paper
 export const leaderGradingPaper = (paperId, datas) => {
   // datas:{value: ,level:,range?}
-  return $patch(`/api/papers/${paperId}`, datas);
+  return $patch(`/api/papers/${paperId}`, datas, "json");
+};
+// review action history
+export const actionHistory = datas => {
+  return $get("/api/marktasks/reviewPaper", datas);
+};
+// sn search
+export const taskSnSearch = (type, code, questionId) => {
+  if (type === "task") {
+    return $get(`/api/papers/search/byTaskSecretNumber`, {
+      sn: code,
+      questionId
+    });
+  } else {
+    const paramName = type === "examNumber" ? "examNumber" : "sn";
+    return $get(`/api/papers/one`, { [paramName]: code, questionId });
+  }
 };
 
 // mark -------------------------->

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

@@ -152,6 +152,50 @@
   }
 }
 
+/* paper-carousel */
+.paper-carousel {
+  position: relative;
+  min-height: 40px;
+
+  .carousel-none {
+    font-size: 14px;
+    text-align: center;
+    position: absolute;
+    width: 100%;
+    top: 50%;
+    left: 0;
+    transform: translateY(-50%);
+    z-index: 8;
+    > i {
+      font-size: 30px;
+    }
+  }
+  .carousel-btn {
+    position: absolute;
+    width: 40px;
+    height: 40px;
+    top: 50%;
+    z-index: 9;
+    margin-top: -20px;
+    text-align: center;
+    line-height: 40px;
+    font-size: 36px;
+    color: @gray;
+    cursor: pointer;
+
+    &:hover {
+      color: @mainColor;
+    }
+
+    &-left {
+      left: 0;
+    }
+    &-right {
+      right: 0;
+    }
+  }
+}
+
 // client-param-set
 .client-param {
   &-set {

+ 23 - 2
src/assets/styles/mark.less

@@ -227,8 +227,8 @@
   }
 }
 
-// .paper-carousel
-.paper-carousel {
+// .grade-history-paper
+.grade-history-paper {
   width: 100%;
   padding: 10px;
 
@@ -244,7 +244,11 @@
 }
 // grade-standard-paper
 .grade-standard-paper {
+  position: relative;
   .carousel-title {
+    text-align: center;
+    margin-bottom: 5px;
+
     > h3 {
       display: inline-block;
       vertical-align: middle;
@@ -254,6 +258,23 @@
       width: 80px;
     }
   }
+  .carousel-loading {
+    position: absolute;
+    top: 32px;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    z-index: 99;
+    background-color: rgba(255, 255, 255, 0.3);
+    text-align: center;
+
+    > i {
+      font-size: 24px;
+      position: relative;
+      top: 50%;
+      margin-top: -15px;
+    }
+  }
 }
 
 // .grade-action

+ 104 - 0
src/components/PaperCarousel.vue

@@ -0,0 +1,104 @@
+<template>
+  <div class="paper-carousel">
+    <div class="carousel-body image-view-contain">
+      <img
+        :src="curPaper.thumbSrc"
+        :alt="curPaper.title"
+        v-if="curPaper.thumbSrc"
+        @click="clickHandle"
+      />
+      <div class="carousel-none" v-else>
+        <Icon type="md-image" />
+        <p>暂无数据</p>
+      </div>
+    </div>
+    <div class="carousel-action">
+      <div class="carousel-btn carousel-btn-left" @click="handleLeft">
+        <Icon type="ios-arrow-dropleft-circle" />
+      </div>
+      <div class="carousel-btn carousel-btn-right" @click="handleRight">
+        <Icon type="ios-arrow-dropright-circle" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "paper-carousel",
+  props: {
+    papers: {
+      type: Array,
+      default() {
+        return [];
+      }
+    },
+    loop: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      curPaper: {},
+      curIndex: 0
+    };
+  },
+  computed: {
+    isFirst() {
+      return this.curIndex === 0;
+    },
+    isLast() {
+      return this.lastIndex === this.curIndex;
+    },
+    lastIndex() {
+      return this.papers.length ? this.papers.length - 1 : 0;
+    }
+  },
+  methods: {
+    initIndex() {
+      this.curIndex = 0;
+      if (this.papers.length) {
+        this.setCurPaper(0);
+      } else {
+        this.curPaper = {};
+      }
+    },
+    setCurPaper(index) {
+      this.curPaper = this.papers[index];
+      this.$emit("on-paper-change", this.curPaper);
+    },
+    handleLeft() {
+      if (this.isFirst) {
+        if (this.loop) {
+          this.curIndex = this.lastIndex;
+        } else {
+          this.$emit("on-prev-end");
+          return;
+        }
+      } else {
+        this.curIndex -= 1;
+      }
+      this.$emit("on-prev", this.curIndex);
+      this.setCurPaper(this.curIndex);
+    },
+    handleRight() {
+      if (this.isLast) {
+        if (this.loop) {
+          this.curIndex = 0;
+        } else {
+          this.$emit("on-next-end");
+          return;
+        }
+      } else {
+        this.curIndex += 1;
+      }
+      this.$emit("on-next", this.curIndex);
+      this.setCurPaper(this.curIndex);
+    },
+    clickHandle() {
+      this.$emit("on-paper-click", this.curIndex, this.papers);
+    }
+  }
+};
+</script>

+ 1 - 0
src/components/common/ImagePreview/ImagePreview.vue

@@ -165,6 +165,7 @@ export default {
       this.initData();
     },
     curFileChange(val) {
+      this.$emit("on-paper-change", val);
       const index = val || 0;
       this.nosition = true;
       this.curFile = this.imageList[index];

+ 1 - 1
src/constants/enumerate.js

@@ -31,7 +31,7 @@ export const LEVEL_TYPE = {
 // student score
 export const CODE_TYPE = {
   examNumber: "考号",
-  paper: "试卷号",
+  paper: "试卷号",
   task: "任务密号"
 };
 

+ 57 - 17
src/modules/grading/GradingDetail.vue

@@ -31,13 +31,15 @@
         <div class="detail-papers-carousel">
           <grade-standard-paper
             :levels="levels"
-            ref="GradeStandardPaper"
+            :question-id="filter.questionId"
+            @on-paper-click="toViewCarouselPaper"
+            v-if="levels && filter.questionId"
           ></grade-standard-paper>
-          <paper-carousel
-            :papers="historyList"
-            v-if="!IS_ADMIN"
-            ref="PaperCarousel"
-          ></paper-carousel>
+          <grade-history-paper
+            :question-id="filter.questionId"
+            @on-paper-click="toViewCarouselPaper"
+            v-if="filter.questionId && !IS_ADMIN"
+          ></grade-history-paper>
         </div>
         <div class="detail-papers-list">
           <div :class="imageViewClasses">
@@ -76,11 +78,11 @@
         <grade-action
           :cur-paper="curPaper"
           :levels="levels"
-          :step="curStep"
           :user-role="curUserRoleType"
           @on-leader-level="leaderSelectLevel"
+          @on-code-search="serachPaperByCode"
           ref="GradeAction"
-          v-if="curPaper.id && curStep.name"
+          v-if="curPaper.id"
         ></grade-action>
       </div>
     </div>
@@ -93,14 +95,24 @@
       class="grading-detail-image-preview"
       :image-list="papers"
       :init-index="curPaperIndex"
-      @on-prev="selectPaper"
-      @on-next="selectPaper"
+      @on-paper-change="selectPaper"
       @on-page-prev="prevPage"
       @on-page-next="nextPage"
       header-hide
       ref="ImagePreview"
       v-if="papers.length"
     ></image-preview>
+    <!-- carousel paper review -->
+    <image-preview
+      class="grading-detail-image-preview"
+      :image-list="carouselPapers"
+      :init-index="curCarouselPaperIndex"
+      @on-paper-change="selectCarouselPaper"
+      loop
+      header-hide
+      ref="CarouselPapersPreview"
+      v-if="carouselPapers.length"
+    ></image-preview>
     <!-- modify-leader-grading -->
     <modify-leader-grading
       :level-info="levelInfo"
@@ -117,12 +129,13 @@ import {
   levelStatData,
   areaList,
   workLevelList,
-  paperSelectLevel
+  paperSelectLevel,
+  taskSnSearch
 } from "@/api";
 import ImagePreview from "@/components/common/ImagePreview";
 import GradeStep from "./components/GradeStep";
 import GradeStandardPaper from "./components/GradeStandardPaper";
-import PaperCarousel from "./components/PaperCarousel";
+import GradeHistoryPaper from "./components/GradeHistoryPaper";
 import GradeAction from "./components/GradeAction";
 import GradeAnalysis from "./components/GradeAnalysis";
 import ModifyLeaderGrading from "./components/ModifyLeaderGrading";
@@ -138,8 +151,8 @@ export default {
   name: "grading-detail",
   components: {
     ImagePreview,
-    PaperCarousel,
     GradeStep,
+    GradeHistoryPaper,
     GradeStandardPaper,
     GradeAction,
     GradeAnalysis,
@@ -179,10 +192,12 @@ export default {
       papers: [],
       curPaper: {},
       curPaperIndex: 0,
-      historyList: [],
       // leader-grade
       levelInfo: {},
-      markers: []
+      markers: [],
+      // carousel paper review,
+      carouselPapers: [],
+      curCarouselPaperIndex: 0
     };
   },
   computed: {
@@ -291,6 +306,8 @@ export default {
       await this.getList();
       if (this.papers.length) {
         this.selectPaper(0);
+      } else {
+        this.curPaper = {};
       }
     },
     selectPaper(index) {
@@ -298,8 +315,7 @@ export default {
       this.curPaper = { ...this.papers[index] };
     },
     toReview(index) {
-      this.curPaper = { ...this.papers[index] };
-      this.curPaperIndex = index;
+      this.selectPaper(index);
       this.$refs.ImagePreview.open();
     },
     async prevPage() {
@@ -332,6 +348,20 @@ export default {
     toNext() {
       this.$refs.ImagePreview.showNext();
     },
+    async serachPaperByCode(params) {
+      const data = await taskSnSearch(
+        params.codeType,
+        params.code,
+        this.filter.questionId
+      );
+      if (!data) {
+        this.$Message.error("没有查找到结果!");
+        return;
+      }
+      data.title = data.examNumber;
+      this.papers = [data];
+      this.total = 1;
+    },
     leaderSelectLevel(levelInfo, markers) {
       this.levelInfo = levelInfo;
       this.markers = markers;
@@ -340,6 +370,16 @@ export default {
     leaderGradingSuccess() {
       this.getStepLevels();
       this.toNext();
+    },
+    // paper carousel
+    toViewCarouselPaper(paperIndex, papers) {
+      this.curCarouselPaperIndex = paperIndex;
+      this.carouselPapers = papers;
+      this.$refs.CarouselPapersPreview.open();
+    },
+    selectCarouselPaper(index) {
+      this.curCarouselPaperIndex = index;
+      this.curPaper = { ...this.carouselPapers[index] };
     }
   }
 };

+ 42 - 19
src/modules/grading/GradingOperation.vue

@@ -40,12 +40,15 @@
             <div class="detail-papers-carousel">
               <grade-standard-paper
                 :levels="levels"
-                ref="GradeStandardPaper"
+                :question-id="filter.questionId"
+                @on-paper-click="toViewCarouselPaper"
+                v-if="levels && filter.questionId"
               ></grade-standard-paper>
-              <paper-carousel
-                :papers="historyList"
-                ref="PaperCarousel"
-              ></paper-carousel>
+              <grade-history-paper
+                :question-id="filter.questionId"
+                @on-paper-click="toViewCarouselPaper"
+                v-if="filter.questionId"
+              ></grade-history-paper>
             </div>
             <div class="detail-papers-list">
               <div :class="imageViewClasses">
@@ -86,12 +89,11 @@
             <grade-action
               :cur-paper="curPaper"
               :levels="levels"
-              :step="curStep"
               :user-role="curUserRoleType"
               @on-select-level="gradeCurPaper"
               @on-pass="passCurPaper"
               ref="GradeAction"
-              v-if="curPaper.id && curStep.name"
+              v-if="curPaper.id"
             ></grade-action>
           </div>
         </div>
@@ -103,14 +105,25 @@
       class="grading-detail-image-preview"
       :image-list="papers"
       :init-index="curPaperIndex"
-      @on-prev="selectPaper"
-      @on-next="selectPaper"
+      @on-paper-change="selectPaper"
       @on-page-prev="prevPage"
       @on-page-next="nextPage"
       header-hide
       ref="ImagePreview"
       v-if="papers.length"
     ></image-preview>
+
+    <!-- carousel paper review -->
+    <image-preview
+      class="grading-detail-image-preview"
+      :image-list="carouselPapers"
+      :init-index="curCarouselPaperIndex"
+      @on-paper-change="selectCarouselPaper"
+      loop
+      header-hide
+      ref="CarouselPapersPreview"
+      v-if="carouselPapers.length"
+    ></image-preview>
   </div>
 </template>
 
@@ -127,13 +140,13 @@ import {
 import ImagePreview from "@/components/common/ImagePreview";
 import GradeStep from "./components/GradeStep";
 import GradeStandardPaper from "./components/GradeStandardPaper";
-import PaperCarousel from "./components/PaperCarousel";
+import GradeHistoryPaper from "./components/GradeHistoryPaper";
 import GradeAction from "./components/GradeAction";
 // 三种情况:
 // 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
 // 评卷员:标准卷,操作记录,试卷列表,操作盘(只分档)
 
-// TIP:不考虑管理员\科组长的情况
+// TIP:不考虑管理员科组长的情况
 // 管理员:标准卷,试卷列表,操作盘
 // 科组长:标准卷,操作记录,试卷列表,操作盘(定档,标准卷,打回)
 
@@ -141,8 +154,8 @@ export default {
   name: "grading-operation",
   components: {
     ImagePreview,
-    PaperCarousel,
     GradeStep,
+    GradeHistoryPaper,
     GradeStandardPaper,
     GradeAction
   },
@@ -181,7 +194,9 @@ export default {
       papers: [],
       curPaper: {},
       curPaperIndex: 0,
-      historyList: []
+      // carousel paper review,
+      carouselPapers: [],
+      curCarouselPaperIndex: 0
     };
   },
   computed: {
@@ -225,6 +240,7 @@ export default {
         return paper;
       });
       this.total = data.totalCount;
+      this.totalPage = data.totalPage;
     },
     toPage(page) {
       this.current = page;
@@ -296,11 +312,6 @@ export default {
       this.size = size;
       this.toPage(1);
       this.getStepLevels();
-      this.$nextTick(() => {
-        this.$refs.GradeStandardPaper.$refs.Carousel.handleResize();
-        this.$refs.PaperCarousel &&
-          this.$refs.PaperCarousel.$refs.Carousel.handleResize();
-      });
     },
     async stepChange(step) {
       this.curStep = step;
@@ -308,6 +319,8 @@ export default {
       await this.getList();
       if (this.papers.length) {
         this.selectPaper(0);
+      } else {
+        this.curPaper = {};
       }
     },
     selectPaper(index) {
@@ -333,7 +346,7 @@ export default {
         this.$Message.warning("当前已经是最后一条数据了");
         return;
       }
-      this.current++;
+      // 下一页时,继续获取当前页数据。
       await this.getList();
       this.selectPaper(0);
       this.$refs.ImagePreview.initData();
@@ -349,6 +362,16 @@ export default {
     },
     toNext() {
       this.$refs.ImagePreview.showNext();
+    },
+    // paper carousel
+    toViewCarouselPaper(paperIndex, papers) {
+      this.curCarouselPaperIndex = paperIndex;
+      this.carouselPapers = papers;
+      this.$refs.CarouselPapersPreview.open();
+    },
+    selectCarouselPaper(index) {
+      this.curCarouselPaperIndex = index;
+      this.curPaper = { ...this.carouselPapers[index] };
     }
   }
 };

+ 21 - 15
src/modules/grading/GradingProgress.vue

@@ -4,7 +4,7 @@
       <span>当前阶段:{{ stepName }}</span
       ><span>进度:{{ stepProgress }}</span>
     </div>
-    <div class="part-box-head">
+    <div class="part-box-head" v-if="IS_ADMIN">
       <div class="part-box-head-left">
         <Button type="primary" @click="toGrading" v-if="showGradingBtn"
           >正评任务创建</Button
@@ -60,7 +60,10 @@
 
     <!-- modify-unformal-grading-task -->
     <modify-unformal-grading-task
+      :cur-subject="curSubject"
+      @modified="getData"
       ref="ModifyUnformalGradingTask"
+      v-if="curSubject.id"
     ></modify-unformal-grading-task>
     <!-- modify-formal-grading-task -->
     <modify-formal-grading-task
@@ -88,15 +91,14 @@ export default {
   data() {
     return {
       subjectId: this.$route.params.subjectId,
-      workId: "",
-      subject: "",
       stepName: "",
       stepProgress: "",
       curSubject: {},
       SUBJECT_STAGE,
       totalProgress: {},
       areaProgress: [],
-      markerProgress: []
+      markerProgress: [],
+      curUserRoleType: ""
     };
   },
   computed: {
@@ -112,24 +114,28 @@ export default {
       );
     },
     showTryGradingBtn() {
-      return (
-        (this.curSubject.stage == "LEVEL" && this.stepProgress === 100) ||
-        (this.curSubject.stage == "SCORE" && !this.curSubject.allLevel)
-      );
-    },
-    showMarkBtn() {
       return (
         (this.curSubject.stage == "INIT" &&
           this.curSubject.test !== 2 &&
           !this.curSubject.formal) ||
         (this.curSubject.stage == "LEVEL" && this.curSubject.test === 2)
       );
+    },
+    showMarkBtn() {
+      return (
+        (this.curSubject.stage == "LEVEL" && this.stepProgress === 100) ||
+        (this.curSubject.stage == "SCORE" && !this.curSubject.allLevel)
+      );
+    },
+    IS_ADMIN() {
+      return this.curUserRoleType === "ADMIN";
+    },
+    IS_MARK_LEADER() {
+      return this.curUserRoleType === "MARK_LEADER";
     }
   },
   mounted() {
-    const ids = this.subjectId.split("-");
-    this.workId = ids[0];
-    this.subject = ids[1];
+    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
     this.getData();
   },
   methods: {
@@ -139,8 +145,8 @@ export default {
     },
     async getProgressDetail() {
       const data = await gradingProgressDetail({
-        workId: this.workId,
-        subject: this.subject
+        workId: this.curSubject.workId,
+        subject: this.curSubject.subject
       });
       this.totalProgress = data.totalProgress;
       this.stepProgress = data.totalProgress.progress.toFixed(2) + "%";

+ 36 - 38
src/modules/grading/components/GradeAction.vue

@@ -16,17 +16,17 @@
             :label="val"
           ></Option>
         </Select>
-        <Button icon="ios-search" slot="append" @click="search"></Button>
+        <Button icon="ios-search" slot="append" @click="searchCode"></Button>
       </Input>
     </div>
     <!-- 头部信息 ------ -->
     <!-- 试卷状态 -->
     <!-- 状态:已评,待评,打回,仲裁 -->
-    <div class="action-paper-state" v-if="rights.paperState">
+    <div class="action-paper-state">
       <p class="paper-state-cont">{{ stepLabel }}</p>
     </div>
     <!-- 试卷信息 -->
-    <div class="action-paper-info" v-if="rights.paperInfo">
+    <div class="action-paper-info">
       <p v-if="IS_ADMIN">{{ curPaper.examNumber }}</p>
       <p>NO.{{ curPaper.sn }}</p>
     </div>
@@ -82,7 +82,7 @@ import { CODE_TYPE } from "@/constants/enumerate";
 // 科组长:查询,头部信息,选择档位,评卷记录
 // 评卷员:头部信息,选择档位
 /*
-[curpaper sample]
+[curpaper template]
 {
   "id": 165,
   "sn": "029947536",
@@ -115,8 +115,6 @@ import { CODE_TYPE } from "@/constants/enumerate";
 
 const initRights = {
   search: false,
-  paperState: false,
-  paperInfo: false,
   gradeInfo: false,
   gradeList: false,
   gradeHis: false
@@ -140,12 +138,6 @@ export default {
     userRole: {
       type: String,
       default: "MARKER"
-    },
-    step: {
-      type: Object,
-      default() {
-        return {};
-      }
     }
   },
   data() {
@@ -155,31 +147,19 @@ export default {
       },
       roleRight: {
         ADMIN: {
-          done: ["search", "gradeHis", "paperState", "paperInfo", "gradeInfo"],
-          arbitrate: ["search", "gradeHis", "paperState", "paperInfo"]
+          done: ["search", "gradeHis", "gradeInfo"],
+          arbitrate: ["search", "gradeHis"]
         },
         MARK_LEADER: {
-          done: [
-            "search",
-            "gradeList",
-            "gradeHis",
-            "paperState",
-            "paperInfo",
-            "gradeInfo"
-          ],
-          arbitrate: [
-            "search",
-            "gradeList",
-            "gradeHis",
-            "paperState",
-            "paperInfo"
-          ]
+          done: ["search", "gradeList", "gradeHis", "gradeInfo"],
+          arbitrate: ["search", "gradeList", "gradeHis"]
         },
         MARKER: {
-          done: ["gradeList", "paperState", "paperInfo", "gradeInfo"],
-          undo: ["gradeList", "paperState", "paperInfo"],
-          reject: ["gradeList", "paperState", "paperInfo", "gradeInfo"]
-        }
+          done: ["gradeList", "gradeInfo"],
+          undo: ["gradeList"],
+          reject: ["gradeList", "gradeInfo"]
+        },
+        STANDARD: ["gradeInfo"]
       },
       filter: {
         codeType: "examNumber",
@@ -190,8 +170,10 @@ export default {
         undo: "待评",
         done: "已评",
         reject: "打回",
-        arbitrate: "仲裁"
+        arbitrate: "仲裁",
+        sample: "标准卷"
       },
+      stepType: "",
       stepLabel: "",
       gradingHistory: [],
       curLevel: {}
@@ -217,11 +199,26 @@ export default {
     this.rebuildRight();
   },
   methods: {
+    getStepType() {
+      const paper = this.curPaper;
+      if (paper.sample) return "sample";
+      if (paper.level) return "done";
+      if (paper.arbitrated) return "arbitrate";
+      if (paper.rejected) return "reject";
+      if (!paper.rejected && !paper.arbitrated && !paper.level) return "undo";
+      return;
+    },
     rebuildRight() {
-      this.stepLabel = this.stepDict[this.step.type];
+      let roleRights = [];
+      this.stepType = this.getStepType();
+      this.stepLabel = this.stepDict[this.stepType];
+      if (this.stepType === "sample") {
+        roleRights = this.roleRight.STANDARD;
+      } else {
+        roleRights = this.roleRight[this.userRole][this.stepType] || [];
+      }
       this.rights = { ...initRights };
-      const rights = this.roleRight[this.userRole][this.step.type] || [];
-      rights.map(key => {
+      roleRights.map(key => {
         this.rights[key] = true;
       });
       if (this.curPaper.level) {
@@ -248,6 +245,7 @@ export default {
         this.$emit(
           "on-leader-level",
           {
+            curPaperId: this.curPaper.id,
             curLevel: this.curPaper.level,
             selectLevel: level.name
           },
@@ -260,7 +258,7 @@ export default {
     toPass() {
       this.$emit("on-pass");
     },
-    search() {
+    searchCode() {
       this.$emit("on-code-search", this.filter);
     }
   }

+ 70 - 0
src/modules/grading/components/GradeHistoryPaper.vue

@@ -0,0 +1,70 @@
+<template>
+  <div class="grade-history-paper">
+    <div class="carousel-title">
+      <h3>{{ title }}</h3>
+    </div>
+    <paper-carousel
+      :papers="papers"
+      @on-paper-change="setCurPaper"
+      @on-paper-click="paperClick"
+      ref="PaperCarousel"
+    ></paper-carousel>
+  </div>
+</template>
+
+<script>
+import { actionHistory } from "@/api";
+import PaperCarousel from "@/components/PaperCarousel";
+
+export default {
+  name: "grade-history-paper",
+  components: { PaperCarousel },
+  props: {
+    questionId: {
+      type: Number
+    }
+  },
+  data() {
+    return {
+      userId: "",
+      stage: "LEVEL",
+      curPaper: {},
+      papers: []
+    };
+  },
+  computed: {
+    title() {
+      // TODO:根据不同试卷状态,展示不同信息
+      return this.curPaper.title;
+    }
+  },
+  watch: {
+    questionId(val) {
+      this.papers = [];
+      this.updatePapers();
+    }
+  },
+  mounted() {
+    this.userId = this.$ls.get("user", { id: "" }).id;
+    this.updatePapers();
+  },
+  methods: {
+    async updatePapers() {
+      const datas = {
+        markerId: this.userId,
+        stage: this.stage,
+        questionId: this.questionId
+      };
+
+      this.papers = await actionHistory(datas);
+      this.$refs.PaperCarousel.initIndex();
+    },
+    setCurPaper(paper) {
+      this.curPaper = paper;
+    },
+    paperClick(paperIndex, papers) {
+      this.$emit("on-paper-click", paperIndex, papers);
+    }
+  }
+};
+</script>

+ 81 - 23
src/modules/grading/components/GradeStandardPaper.vue

@@ -1,41 +1,40 @@
 <template>
-  <div class="grade-standard-paper paper-carousel">
+  <div class="grade-standard-paper">
     <div class="carousel-title">
       <h3>标准卷</h3>
-      <Select v-model="curLevel" @on-change="getPapers">
+      <Select v-model="curLevel" @on-change="curLevelChange">
         <Option
           v-for="(level, gindex) in levels"
           :key="gindex"
-          :value="level.id"
-          :label="level.code"
+          :value="level.name"
+          :label="level.name"
         ></Option>
       </Select>
     </div>
-    <div class="carousel-body">
-      <!-- 换一个轮播组件 -->
-      <Carousel
-        v-model="curPaperIndex"
-        arrow="always"
-        dots="none"
-        :loop="false"
-        ref="Carousel"
-      >
-        <CarouselItem v-for="(paper, pindex) in papers" :key="pindex">
-          <div class="image-view-contain">
-            <img :src="paper.thumbSrc" :alt="paper.title" />
-          </div>
-        </CarouselItem>
-      </Carousel>
+    <paper-carousel
+      :papers="papers"
+      @on-prev-end="prevLevel"
+      @on-next-end="nextLevel"
+      @on-paper-click="paperClick"
+      ref="PaperCarousel"
+    ></paper-carousel>
+    <div class="carousel-loading" v-if="isLoading">
+      <Icon class="ivu-load-loop" type="ios-loading" />
     </div>
   </div>
 </template>
 
 <script>
 import { paperList } from "@/api";
+import PaperCarousel from "@/components/PaperCarousel";
 
 export default {
   name: "grade-standard-paper",
+  components: { PaperCarousel },
   props: {
+    questionId: {
+      type: Number
+    },
     levels: {
       type: Array,
       default() {
@@ -46,23 +45,82 @@ export default {
   data() {
     return {
       curLevel: "",
+      curLevelIndex: 0,
       papers: [],
-      curPaperIndex: 0
+      paperMap: {},
+      isLoading: false
     };
   },
-  mounted() {},
+  computed: {
+    isFirstLevel() {
+      return this.curLevelIndex === 0;
+    },
+    isLastLevel() {
+      return this.lastLevelIndex === this.curLevelIndex;
+    },
+    lastLevelIndex() {
+      return this.levels.length ? this.levels.length - 1 : 0;
+    }
+  },
+  watch: {
+    questionId(val) {
+      this.paperMap = {};
+      this.papers = [];
+      this.updatePapers();
+    }
+  },
+  mounted() {
+    this.setCurLevel(this.curLevelIndex);
+    this.updatePapers();
+  },
   methods: {
+    setCurLevel(index) {
+      this.curLevel = this.levels[index].name;
+    },
+    curLevelChange() {
+      this.curLevelIndex = this.levels.findIndex(
+        item => item.name === this.curLevel
+      );
+      this.updatePapers();
+    },
+    async updatePapers() {
+      await this.getPapers();
+      this.$refs.PaperCarousel.initIndex();
+    },
     async getPapers() {
+      if (this.paperMap[this.curLevel] && this.paperMap[this.curLevel].length) {
+        this.papers = this.paperMap[this.curLevel];
+        return;
+      }
+      this.isLoading = true;
       const datas = {
+        questionId: this.questionId,
         level: this.curLevel,
         sort: "secretNumber",
         isSample: true,
         page: 0,
         size: 100
       };
-      const data = await paperList(datas);
+      const data = await paperList(datas).catch(() => {});
+      this.isLoading = false;
+      if (!data) return;
       this.papers = data.data;
-      this.curPaperIndex = 0;
+      this.paperMap[this.curLevel] = data.data;
+    },
+    prevLevel() {
+      if (this.isFirst) return;
+      this.curLevelIndex--;
+      this.setCurLevel(this.curLevelIndex);
+      this.updatePapers();
+    },
+    nextLevel() {
+      if (this.isLast) return;
+      this.curLevelIndex++;
+      this.setCurLevel(this.curLevelIndex);
+      this.updatePapers();
+    },
+    paperClick(paperIndex, papers) {
+      this.$emit("on-paper-click", paperIndex, papers);
     }
   }
 };

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

@@ -54,6 +54,7 @@ export default {
       type: Object,
       default() {
         return {
+          curPaperId: "",
           curLevel: "",
           selectLevel: ""
         };
@@ -108,7 +109,7 @@ export default {
         return;
       }
       const datas = {
-        aciton: this.actionType,
+        action: this.actionType,
         level: this.LevelInfo.selectLevel
       };
       if (this.actionType === "reject")
@@ -117,7 +118,7 @@ export default {
       if (this.isSubmit) return;
       this.isSubmit = true;
       let result = true;
-      await leaderGradingPaper(datas).catch(() => {
+      await leaderGradingPaper(this.LevelInfo.curPaperId, datas).catch(() => {
         result = false;
       });
       this.isSubmit = false;

+ 28 - 13
src/modules/grading/components/ModifyUnformalGradingTask.vue

@@ -11,7 +11,7 @@
         btn-icon="md-cloud-upload"
         :btn-content="uploadBtnName"
         :upload-url="uploadUrl"
-        :upload-data="data"
+        :upload-data="uploadData"
         :format="['xls', 'xlsx']"
         :auto-upload="false"
         @upload-success="uploadSuccess"
@@ -30,22 +30,25 @@
     </div>
     <div slot="footer">
       <Button type="text" @click="cancel">取消</Button>
-      <Button type="primary" :disabled="isSubmit" @click="submit"
+      <Button type="primary" :disabled="isSubmit" @click="toStartTask"
         >开始试评</Button
       >
+      <Button type="error" :disabled="isSubmit" @click="toOverTask"
+        >结束并清空数据</Button
+      >
     </div>
   </Modal>
 </template>
 
 <script>
-import { updateGradingUser } from "@/api";
+import { createTryGradingTask, finishTryGradingTask } from "@/api";
 import UploadButton from "@/components/UploadButton";
 
 export default {
   name: "modify-unformal-grading-task",
   components: { UploadButton },
   props: {
-    data: {
+    curSubject: {
       type: Object,
       default() {
         return {};
@@ -56,10 +59,17 @@ export default {
     return {
       modalIsShow: false,
       isSubmit: false,
+      uploadData: {},
       uploadBtnName: "导入考生数据",
       uploadUrl: this.GLOBAL.domain + "/import/students/batchAllForTrial"
     };
   },
+  created() {
+    this.uploadData = {
+      workId: this.curSubject.workId,
+      subject: this.curSubject.subject
+    };
+  },
   methods: {
     visibleChange(visible) {
       if (visible) {
@@ -82,22 +92,27 @@ export default {
       this.uploadBtnName = "导入考生数据";
       console.log(response);
     },
-    async submit() {
-      const valid = await this.$refs.modalFormComp.validate();
-      if (!valid) return;
-
+    async toStartTask() {
       if (this.isSubmit) return;
       this.isSubmit = true;
-      const data = await updateGradingUser(this.modalForm).catch(() => {
-        this.isSubmit = false;
-      });
-
+      const data = await createTryGradingTask(this.uploadData).catch(() => {});
+      this.isSubmit = false;
       if (!data) return;
 
-      this.isSubmit = false;
       this.$Message.success("发布任务成功!");
       this.$emit("modified");
       this.cancel();
+    },
+    async toOverTask() {
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const data = await finishTryGradingTask(this.data).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$Message.success("操作成功!");
+      this.$emit("modified");
+      this.cancel();
     }
   }
 };

+ 0 - 43
src/modules/grading/components/PaperCarousel.vue

@@ -1,43 +0,0 @@
-<template>
-  <div class="paper-carousel">
-    <div class="carousel-title">
-      <slot name="title">
-        <h3>No.123456789</h3>
-      </slot>
-    </div>
-    <div class="carousel-body">
-      <Carousel
-        v-model="curPaperIndex"
-        arrow="always"
-        dots="none"
-        ref="Carousel"
-      >
-        <CarouselItem v-for="(paper, pindex) in papers" :key="pindex">
-          <div class="image-view-contain">
-            <img :src="paper.thumbSrc" :alt="paper.title" />
-          </div>
-        </CarouselItem>
-      </Carousel>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  name: "paper-carousel",
-  props: {
-    papers: {
-      type: Array,
-      default() {
-        return [];
-      }
-    }
-  },
-  data() {
-    return {
-      curPaperIndex: 0
-    };
-  },
-  methods: {}
-};
-</script>

+ 46 - 12
src/modules/login/login.vue

@@ -45,7 +45,7 @@
 
 <script>
 import { username, password } from "@/plugins/formRules";
-import { login } from "@/api";
+import { login, subjectDetail } from "@/api";
 import ResetPwd from "./ResetPwd";
 
 export default {
@@ -61,6 +61,26 @@ export default {
         loginName: username,
         password
       },
+      rightRoutes: {
+        ADMIN: {
+          router: "WorkManage"
+        },
+        MARKER_LEVEL: {
+          router: "GradingOperation"
+        },
+        MARKER_SCORE: {
+          router: "MarkOperation"
+        },
+        MARK_LEADER_LEVEL: {
+          router: "Grading"
+        },
+        MARK_LEADER_SCORE: {
+          router: "Mark"
+        },
+        INSPECTOR: {
+          router: "Inspection"
+        }
+      },
       isSubmit: false
     };
   },
@@ -90,20 +110,34 @@ export default {
       //   return;
       // }
 
-      // TODO:根据角色跳转不同的路由
-      if (data.role === "MARKER") {
-        this.$router.push({
-          name: "GradingOperation",
-          params: {
-            workId: data.workId,
-            subjectId: `${data.workId}-${data.subject}`
-          }
-        });
-        return;
+      const params = {
+        workId: data.workId,
+        subjectId: `${data.workId}-${data.subject}`
+      };
+      const curSubject = await subjectDetail(params.subjectId);
+      const stage = curSubject.stage;
+
+      // 根据角色跳转不同的路由
+      const { role, markRight } = data;
+      if (role === "MARKER") {
+        if (stage === "INIT") {
+          this.$Message.error("当前工作未开启分档!");
+          return;
+        }
+        if (
+          (stage === "LEVEL" && markRight === "ALLOW_SCORING") ||
+          (stage === "SCORE" && markRight === "ALLOW_LEVELING")
+        ) {
+          this.$Message.error("您的权限不够!");
+          return;
+        }
       }
 
+      const type = role.includes("MARK") ? `${role}_${stage}` : role;
+      const routerName = this.rightRoutes[type].router;
       this.$router.push({
-        name: "WorkManage"
+        name: routerName,
+        params
       });
     },
     resetSuccess(newpassword) {

+ 5 - 3
src/modules/mark/MarkDetail.vue

@@ -22,7 +22,9 @@
           class="detail-papers-carousel"
           v-if="this.curUserRoleType !== 'ADMIN'"
         >
-          <paper-carousel :papers="papers" ref="PaperCarousel"></paper-carousel>
+          <grade-history-paper
+            :question-id="filter.questionId"
+          ></grade-history-paper>
         </div>
         <div class="detail-papers-list">
           <div :class="imageViewClasses">
@@ -89,7 +91,7 @@
 import { paperPageList } from "@/api";
 import ImagePreview from "@/components/common/ImagePreview";
 import GradeStep from "../grading/components/GradeStep";
-import PaperCarousel from "../grading/components/PaperCarousel";
+import GradeHistoryPaper from "../grading/components/GradeHistoryPaper";
 import MarkAction from "./components/MarkAction";
 // 三种情况:
 // 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
@@ -102,7 +104,7 @@ export default {
   components: {
     ImagePreview,
     GradeStep,
-    PaperCarousel,
+    GradeHistoryPaper,
     MarkAction
   },
   data() {

+ 34 - 0
src/plugins/emitter.js

@@ -0,0 +1,34 @@
+function broadcast(componentName, eventName, params) {
+  this.$children.forEach(child => {
+    const name = child.$options.name;
+
+    if (name === componentName) {
+      child.$emit.apply(child, [eventName].concat(params));
+    } else {
+      // todo 如果 params 是空数组,接收到的会是 undefined
+      broadcast.apply(child, [componentName, eventName].concat([params]));
+    }
+  });
+}
+export default {
+  methods: {
+    dispatch(componentName, eventName, params) {
+      let parent = this.$parent || this.$root;
+      let name = parent.$options.name;
+
+      while (parent && (!name || name !== componentName)) {
+        parent = parent.$parent;
+
+        if (parent) {
+          name = parent.$options.name;
+        }
+      }
+      if (parent) {
+        parent.$emit.apply(parent, [eventName].concat(params));
+      }
+    },
+    broadcast(componentName, eventName, params) {
+      broadcast.call(this, componentName, eventName, params);
+    }
+  }
+};