浏览代码

分档页面初步完成

zhangjie 3 年之前
父节点
当前提交
060b8a7052

+ 186 - 3
src/assets/styles/marker.less

@@ -199,6 +199,16 @@
     display: inline-block;
     vertical-align: top;
   }
+  .image-sample {
+    height: 26px;
+    width: 26px;
+    border-radius: 5px;
+    background-color: @color-act1;
+    color: @color-text;
+    font-size: 16px;
+    text-align: center;
+    line-height: 26px;
+  }
   .image-checkbox {
     height: 26px;
     width: 26px;
@@ -212,7 +222,7 @@
     cursor: pointer;
 
     &:hover,
-    &.image-checked {
+    &.image-selected {
       box-shadow: 0 0 3px inset @color-background-light;
     }
   }
@@ -242,6 +252,12 @@
     }
   }
 }
+.marker-image-none {
+  padding-top: 150px;
+  font-size: 16px;
+  text-align: center;
+  color: @color-text;
+}
 
 // marker-action
 .marker-action {
@@ -251,8 +267,61 @@
   top: 0;
   height: 100%;
   z-index: 8;
-  padding: 50px 10px 20px;
+  padding: 60px 10px 20px;
   background-color: @color-background-light;
+  color: @color-text;
+
+  &-fullscreen {
+    z-index: 10000;
+  }
+
+  .action-paper-state {
+    color: @color-text;
+    .paper-state-cont {
+      background: @color-background;
+    }
+  }
+
+  .action-paper-info {
+    color: @color-text;
+    span:last-child {
+      color: @color-text-act;
+    }
+  }
+  .action-grade-info {
+    background-color: @color-act1;
+    color: @color-text;
+    &-title {
+      color: @color-text;
+    }
+    .grade-info-name {
+      color: @color-text-act;
+    }
+  }
+  .action-grade-item {
+    color: @color-text;
+
+    &-content {
+      background: @color-background;
+
+      &:hover {
+        background-color: @color-act1;
+        color: @color-text-act;
+      }
+    }
+  }
+  .action-item-content-disabled {
+    background: shade(@color-background-light, 30%) !important;
+    color: @color-background-light!important;
+  }
+  .action-grade-pass {
+    background: @color-background;
+    color: @color-text;
+
+    &:hover {
+      background-color: shade(@color-background, 20%);
+    }
+  }
 }
 
 // marker-history
@@ -316,6 +385,90 @@
     color: @color-text;
   }
 }
+// marker-statistics
+.marker-statistics {
+  color: @color-text;
+  &-table {
+    tr {
+      background-color: @color-background-light;
+      td,
+      th {
+        color: @color-text;
+        padding: 8px 15px;
+      }
+    }
+  }
+  &-chart {
+    > h3 {
+      font-size: 16px;
+    }
+    .chart-box {
+      background-color: @color-background;
+    }
+  }
+}
+// marker-page
+.marker-page {
+  &-shortcut {
+    margin-bottom: 20px;
+    text-align: center;
+    font-size: 0;
+    .shortcut-item {
+      display: inline-block;
+      vertical-align: top;
+      height: 26px;
+      line-height: 26px;
+      width: 64px;
+      text-align: center;
+      margin: 0 3px;
+      background-color: @color-background-light;
+      border-radius: 5px;
+      font-size: 14px;
+      cursor: pointer;
+
+      &:hover {
+        background-color: @color-act1;
+        color: @color-text-act;
+      }
+    }
+  }
+
+  &-set {
+    margin-bottom: 10px;
+    > * {
+      display: inline-block;
+      vertical-align: middle;
+    }
+    .ivu-input-number {
+      width: 80px;
+      min-width: 0;
+      border-color: @color-text;
+      background-color: @color-text-act;
+      input {
+        box-shadow: none;
+        background-color: @color-text-act;
+      }
+    }
+    > span:first-child {
+      width: 80px;
+      text-align: right;
+    }
+  }
+  &-btn {
+    height: 24px;
+    line-height: 24px;
+    padding: 0 10px;
+    background-color: @color-background-light;
+    border-radius: 5px;
+    margin-left: 5px;
+    cursor: pointer;
+
+    &:hover {
+      background-color: @color-act1;
+      color: @color-text-act;
+    }
+  }
+}
 
 // marker-modal
 .marker-modal {
@@ -336,8 +489,38 @@
       text-align: left;
     }
   }
-
   .ivu-modal-body {
     padding: 15px;
   }
 }
+// marker-dropdown
+.marker-dropdown {
+  background-color: @color-background;
+  box-shadow: 0 1px 10px rgba(0, 0, 0, 0.5);
+
+  .ivu-dropdown-item {
+    margin-top: 0;
+    color: @color-text;
+    border-top: 1px solid @color-background-light;
+    &:hover {
+      background-color: @color-act1;
+    }
+  }
+}
+// marker-popper
+.marker-popper {
+  &.ivu-poptip-popper {
+    .ivu-poptip-arrow {
+      border-bottom-color: @color-act1;
+      &::after {
+        border-bottom-color: @color-act1;
+      }
+    }
+  }
+  .ivu-poptip-inner {
+    background-color: @color-background;
+    color: @color-text;
+
+    box-shadow: 0 1px 10px rgba(0, 0, 0, 0.5);
+  }
+}

+ 109 - 3
src/components/EchartRender.vue

@@ -23,9 +23,15 @@ export default {
       required: true,
       validator(value) {
         return (
-          ["bar", "barReverse", "pie", "line", "barGroup", "lineGroup"].indexOf(
-            value
-          ) !== -1
+          [
+            "bar",
+            "barReverse",
+            "pie",
+            "line",
+            "darkLine",
+            "barGroup",
+            "lineGroup"
+          ].indexOf(value) !== -1
         );
       }
     },
@@ -178,6 +184,106 @@ export default {
         ]
       };
     },
+    getDarkLineOption(datas) {
+      let labels = [],
+        vals = [];
+      datas.map(item => {
+        labels.push(item.name);
+        vals.push(item.value);
+      });
+      const linearColor = new echarts.graphic.LinearGradient(0, 1, 0, 0, [
+        {
+          offset: 1,
+          color: "rgba(21, 91, 146,1)"
+        },
+        {
+          offset: 0,
+          color: "rgba(21, 91, 146,0)"
+        }
+      ]);
+
+      return {
+        animation: this.animationIsOpen,
+        grid: {
+          top: "10%",
+          bottom: "12%",
+          left: "3.5%",
+          right: "3%"
+        },
+        tooltip: {
+          show: true,
+          formatter: function(params) {
+            return params.value + "%";
+          }
+        },
+        xAxis: {
+          type: "category",
+          data: labels,
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: "#3d3f55"
+            }
+          },
+          axisLine: {
+            lineStyle: {
+              color: "#3d3f55"
+            }
+          },
+          axisLabel: {
+            color: "#9d9c9c",
+            fontSize: 12,
+            fontWeight: "bold"
+          },
+          axisTick: {
+            show: false
+          }
+        },
+        yAxis: {
+          type: "value",
+          splitLine: {
+            show: true,
+            lineStyle: {
+              color: "#3d3f55"
+            }
+          },
+          axisLine: {
+            lineStyle: {
+              color: "#3d3f55"
+            }
+          },
+          axisLabel: {
+            fontSize: 12,
+            color: "#9d9c9c",
+            formatter: function(value, index) {
+              return value + "%";
+            }
+          },
+          axisTick: {
+            show: false
+          }
+        },
+        series: [
+          {
+            name: "数量",
+            type: "line",
+            smooth: true,
+            data: vals,
+            symbol: "circle",
+            symbolSize: 8,
+            itemStyle: {
+              color: "rgba(21, 91, 146, 1)"
+            },
+            lineStyle: {
+              color: "rgba(21, 91, 146, 0.6)"
+            },
+            areaStyle: {
+              color: linearColor
+            }
+          }
+        ]
+      };
+    },
     getPieOption(datas) {
       if (!datas.chartLabels.length) return;
       const seriesData = datas.chartLabels.map(function(item, index) {

+ 115 - 32
src/modules/grading/marker/MarkerGrading.vue

@@ -1,13 +1,60 @@
 <template>
   <div class="marker-grading">
     <marker-header
-      :data="workSubject"
+      :steps="steps"
       @area-change="areaChange"
+      @step-change="stepChange"
+      @page-set-change="pageSetChange"
       @to-history="toHistory"
       @to-standard="toStandard"
     ></marker-header>
 
-    <div class="marker-action"></div>
+    <div
+      :class="[
+        'marker-action',
+        { 'marker-action-fullscreen': isFullscreenMarking }
+      ]"
+      v-show="!multipleGradingList.length"
+    >
+      <grade-action
+        :cur-paper-or-task="curPaper"
+        :levels="levels"
+        :params-set="paramsSet"
+        @on-select-level="gradeCurPaper"
+        @on-pass="passCurPaper"
+        ref="GradeAction"
+        v-if="curPaper.id"
+      ></grade-action>
+    </div>
+    <!-- multiple grading action -->
+    <div class="marker-action" v-show="multipleGradingList.length">
+      <div class="grade-action">
+        <div class="action-paper-state">
+          <p class="paper-state-cont">批量分档</p>
+        </div>
+        <div class="action-paper-info">
+          <p><span>任务密号:</span><span>--</span></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 class="marker-body">
       <div :class="markerImageListClasses" v-if="papers.length">
@@ -25,25 +72,55 @@
             <marker-image-view
               :data="paper"
               @to-review="toReview(index)"
-              @to-check="toCheck"
+              @to-select="selectMultiplePaper"
             ></marker-image-view>
           </div>
         </div>
       </div>
+      <div v-else class="marker-image-none">暂无数据</div>
     </div>
 
     <!-- MarkerHistory -->
     <marker-history
       :question-id="filter.questionId"
+      @on-paper-click="
+        (index, papers) => {
+          toViewCarouselPaper(index, papers, 'history');
+        }
+      "
       ref="MarkerHistory"
     ></marker-history>
     <!-- MarkerStandard -->
     <marker-standard
       :question-id="filter.questionId"
       :levels="levels"
+      @on-paper-click="
+        (index, papers) => {
+          toViewCarouselPaper(index, papers, 'sample');
+        }
+      "
       ref="MarkerStandard"
       v-if="levels.length && filter.questionId && paramsSet.showSample"
     ></marker-standard>
+    <!-- image-preview -->
+    <simple-image-preview
+      class="grading-operation-image-preview"
+      :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="grading-operation-image-preview"
+      :cur-image="curPaper"
+      @on-prev="toCarousePaper('prev')"
+      @on-next="toCarousePaper('next')"
+      @on-close="carouseImagePreviewClose"
+      ref="CarouselPapersPreview"
+    ></simple-image-preview>
   </div>
 </template>
 
@@ -52,6 +129,9 @@ import MarkerHeader from "./MarkerHeader";
 import MarkerImageView from "./MarkerImageView";
 import MarkerHistory from "./MarkerHistory";
 import MarkerStandard from "./MarkerStandard";
+import GradeAction from "../components/GradeAction";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+
 import {
   markerTaskList,
   markerLevelTotalStatData,
@@ -64,7 +144,14 @@ import {
 
 export default {
   name: "marker-grading",
-  components: { MarkerHeader, MarkerImageView, MarkerHistory, MarkerStandard },
+  components: {
+    MarkerHeader,
+    MarkerImageView,
+    MarkerHistory,
+    MarkerStandard,
+    GradeAction,
+    SimpleImagePreview
+  },
   data() {
     return {
       filter: {
@@ -92,13 +179,21 @@ export default {
       totalPage: 1,
       curStep: null,
       curStandardGradeId: "",
-      steps: [],
+      steps: { levelStep: [], otherStep: [] },
       levels: [],
       curArea: {},
       papers: [],
       curPaper: {},
       curPaperIndex: 0,
-      paramsSet: {}
+      paramsSet: {},
+      // multiple grading
+      multiplebtnClicked: false,
+      multipleGradingList: [],
+      // carousel paper review,
+      carouselType: "",
+      carouselPapers: [],
+      curCarouselPaperIndex: 0,
+      isFullscreenMarking: false
     };
   },
   computed: {
@@ -233,10 +328,11 @@ export default {
         };
       });
     },
-    pageSizeChange(size) {
-      this.size = size;
-      this.toPage(1);
-      this.getStepLevels();
+    pageSetChange(page) {
+      this.size = page.pageSize;
+      this.current = page.current;
+      this.papers = [];
+      this.getList();
     },
     async stepChange(step) {
       this.curStep = step;
@@ -257,13 +353,14 @@ export default {
       this.filter.questionId = curArea.id;
       await this.getStepLevels();
       this.toPage(1);
-      // this.updateHistory();
     },
     // selectMultiplePaper
     selectMultiplePaper(paper) {
       if (paper.sample) return;
-      paper.selected = !paper.selected;
+      const curPaper = this.papers.find(p => p.id === paper.id);
+      curPaper.selected = paper.selected;
       this.multipleGradingList = this.papers.filter(paper => paper.selected);
+      console.log(this.multipleGradingList);
     },
     async multipleSelectLevel(level) {
       if (!this.multipleGradingList.length) return;
@@ -272,7 +369,7 @@ export default {
       const multipleGradingListCount = this.multipleGradingList.length;
 
       let result = true;
-      const papers = await paperSelectLevelBatch(
+      await paperSelectLevelBatch(
         this.multipleGradingList.map(item => item.id).join(), // is taskId
         level.name,
         "LEVEL"
@@ -286,7 +383,6 @@ export default {
       this.multipleGradingList = [];
       // this.getStepLevels();
       this.updateStepLevel(this.curStep, level.name, multipleGradingListCount);
-      this.updateHistory(papers);
 
       // update paper list
       if (
@@ -300,9 +396,6 @@ export default {
       await this.getList();
       this.selectPaper(this.curPaperIndex);
     },
-    toCheck(paper) {
-      console.log(paper);
-    },
     // paper view action
     toReview(index) {
       this.isFullscreenMarking = true;
@@ -370,20 +463,14 @@ export default {
         level.name,
         "LEVEL"
       );
+      if (!paper) return;
       this.updateStepLevel(this.curStep, level.name, 1);
-      this.updateCacheHistory([paper]);
       this.toActionNextPaper();
     },
     async passCurPaper() {
       await paperTaskPass(this.curPaper.id);
       this.toActionNextPaper();
     },
-    updateHistory() {
-      this.$refs.GradeHistoryPaper.updatePapers();
-    },
-    updateCacheHistory(papers) {
-      this.$refs.GradeHistoryPaper.updateCachePapers(papers);
-    },
     // paper carousel
     toViewCarouselPaper(paperIndex, papers, type) {
       this.carouselType = type;
@@ -399,10 +486,10 @@ export default {
       this.curPaper = { ...this.carouselPapers[index] };
     },
     toCarousePaper(type) {
-      if (this.carouselType === "sample") {
-        this.toSampleCarousePaper(type);
-        return;
-      }
+      // if (this.carouselType === "sample") {
+      //   this.toSampleCarousePaper(type);
+      //   return;
+      // }
       if (type === "prev" && this.curCarouselPaperIndex > 0) {
         this.curCarouselPaperIndex--;
       } else if (
@@ -425,10 +512,6 @@ export default {
       this.carouselType = "";
       this.selectPaper(this.curPaperIndex);
     },
-    standardPaperChange(curPaper) {
-      if (!this.isFullscreenMarking) return;
-      this.curPaper = { ...curPaper };
-    },
     // header
     toHistory() {
       this.$refs.MarkerHistory.open();

+ 140 - 20
src/modules/grading/marker/MarkerHeader.vue

@@ -3,9 +3,10 @@
     <div class="header-group">
       <div class="header-part">
         <Dropdown
-          placement="bottom-end"
+          placement="bottom"
           transfer
           trigger="click"
+          transfer-class-name="marker-dropdown"
           @on-click="areaClick"
         >
           <span class="el-dropdown-link">
@@ -21,15 +22,88 @@
           </DropdownMenu>
         </Dropdown>
       </div>
+      <div class="header-part" @click="toStatistics">
+        <p>统计分析 <Icon type="ios-arrow-down"></Icon></p>
+      </div>
       <div class="header-part">
-        <p>
-          {{ curStep.name }}:{{ curStep.count }}
-          <Icon type="ios-arrow-down"></Icon>
-        </p>
+        <Poptip
+          popper-class="marker-popper"
+          placement="bottom"
+          width="312"
+          transfer
+          v-model="pageVisible"
+        >
+          <p>
+            当前页:<span>{{ page.current }}</span
+            >/<span>{{ page.totalPage }} </span>
+            <Icon type="ios-arrow-down"></Icon>
+          </p>
+
+          <div class="marker-page" slot="content">
+            <div class="marker-page-shortcut">
+              <div class="shortcut-item" @click="toFirstPage">首页</div>
+              <div class="shortcut-item" @click="toPrevPage">上一页</div>
+              <div class="shortcut-item" @click="toNextPage">下一页</div>
+              <div class="shortcut-item" @click="toLastPage">尾页</div>
+            </div>
+            <div class="marker-page-set">
+              <span>当前页:</span>
+              <p>
+                <span>{{ page.current }}</span
+                >/<span>{{ page.totalPage }} </span>
+              </p>
+            </div>
+            <div class="marker-page-set">
+              <span>总张数:</span>
+              <p>
+                <span>{{ page.total }}</span>
+              </p>
+            </div>
+            <div class="marker-page-set">
+              <span>每页张数:</span>
+              <InputNumber size="small" v-model="page.pageSize"></InputNumber>
+              <div class="marker-page-btn" @click="pageSetChange">设置</div>
+            </div>
+            <div class="marker-page-set">
+              <span>页面跳转:</span>
+              <InputNumber size="small" v-model="page.pageNo"></InputNumber>
+              <div class="marker-page-btn" @click="pageNoSet">跳转</div>
+            </div>
+          </div>
+        </Poptip>
       </div>
-      <div class="header-part"></div>
     </div>
     <div class="header-group">
+      <div class="header-part">
+        <Dropdown
+          placement="bottom"
+          transfer
+          trigger="click"
+          transfer-class-name="marker-dropdown"
+          @on-click="stepClick"
+        >
+          <span class="el-dropdown-link">
+            {{ curStep.name }}:{{ curStep.count }}
+            <Icon type="ios-arrow-down"></Icon>
+          </span>
+          <DropdownMenu slot="list">
+            <DropdownItem
+              v-for="step in steps.levelStep"
+              :key="step.name"
+              :name="step.name"
+            >
+              {{ step.name }}
+            </DropdownItem>
+            <DropdownItem
+              v-for="step in steps.otherStep"
+              :key="step.type"
+              :name="step.name"
+            >
+              {{ step.name }}
+            </DropdownItem>
+          </DropdownMenu>
+        </Dropdown>
+      </div>
       <div class="header-part" @click="toStandard">
         <p>标准卷 <Icon type="ios-arrow-down"></Icon></p>
       </div>
@@ -38,9 +112,10 @@
       </div>
       <div class="header-user">
         <Dropdown
-          placement="bottom-end"
+          placement="bottom"
           transfer
           trigger="click"
+          transfer-class-name="marker-dropdown"
           @on-click="userClick"
         >
           <div class="user-name">
@@ -51,7 +126,7 @@
             <DropdownItem class="color-default-hover" name="toResetPwd"
               >修改密码</DropdownItem
             >
-            <DropdownItem class="color-error-hover" divided name="logout">
+            <DropdownItem class="color-error-hover" name="logout">
               退出登录
             </DropdownItem>
           </DropdownMenu>
@@ -61,48 +136,58 @@
 
     <!-- ResetPwd -->
     <reset-pwd ref="ResetPwd"></reset-pwd>
+    <!-- MarkerStatistics -->
+    <marker-statistics
+      :steps="steps"
+      ref="MarkerStatistics"
+    ></marker-statistics>
   </div>
 </template>
 
 <script>
 import { areaList, logout } from "@/api";
 import ResetPwd from "@/modules/login/ResetPwd";
+import MarkerStatistics from "./MarkerStatistics";
 
 export default {
   name: "marker-header",
-  components: { ResetPwd },
+  components: { ResetPwd, MarkerStatistics },
   props: {
-    data: {
+    steps: {
       type: Object,
       default() {
-        return {
-          workId: "",
-          subject: ""
-        };
+        return { levelStep: [], otherStep: [] };
       }
     }
   },
   data() {
     return {
+      filter: {
+        workId: "",
+        subject: ""
+      },
       username: this.$ls.get("user", { loginName: "" }).loginName,
       areas: [],
       curArea: { areaName: "校区" },
       curStep: { name: "待评", count: 0 },
+      pageVisible: false,
       page: {
-        total: 10,
-        current: 0
+        totalPage: 10,
+        current: 1,
+        pageSize: 12,
+        pageNo: 1
       }
     };
   },
   mounted() {
+    const subjectId = this.$route.params.subjectId.split("-");
+    this.filter.workId = subjectId[0];
+    this.filter.subject = subjectId[1];
     this.getAreaList();
   },
   methods: {
     async getAreaList() {
-      const data = await areaList({
-        workId: this.data.workId,
-        subject: this.data.subject
-      });
+      const data = await areaList(this.filter);
       this.areas = data.map(item => {
         return {
           id: item.id,
@@ -120,12 +205,47 @@ export default {
       this.curArea = this.areas.find(item => item.id === val);
       this.$emit("area-change", this.curArea);
     },
+    stepClick(val) {
+      this.curStep = [...this.steps.levelStep, ...this.steps.otherStep].find(
+        item => item.name === val
+      );
+      this.$emit("step-change", this.curStep);
+    },
     toHistory() {
       this.$emit("to-history");
     },
     toStandard() {
       this.$emit("to-standard");
     },
+    pageNoSet() {
+      this.page.current = this.page.pageNo;
+      this.pageSetChange();
+    },
+    toFirstPage() {
+      this.page.current = 0;
+      this.pageSetChange();
+    },
+    toLastPage() {
+      this.page.current = this.page.totalPage;
+      this.pageSetChange();
+    },
+    toPrevPage() {
+      if (this.page.current === 1) return;
+      this.page.current--;
+      this.pageSetChange();
+    },
+    toNextPage() {
+      if (this.page.current === this.page.totalPage) return;
+      this.page.current++;
+      this.pageSetChange();
+    },
+    pageSetChange() {
+      this.pageVisible = false;
+      this.$emit("page-set-change", this.page);
+    },
+    toStatistics() {
+      this.$refs.MarkerStatistics.open();
+    },
     userClick(name) {
       if (!name) return;
       this[name]();

+ 11 - 0
src/modules/grading/marker/MarkerHistory.vue

@@ -98,6 +98,17 @@ export default {
 
       this.papers = data.reverse();
     },
+    updateCachePapers(papers) {
+      papers.forEach(paper => {
+        const paperIndex = this.papers.findIndex(
+          item => item.paperId === paper.paperId
+        );
+        if (paperIndex !== -1) {
+          this.papers.splice(paperIndex, 1);
+        }
+      });
+      this.papers = [...this.papers, ...papers].slice(-5);
+    },
     cancel() {
       this.modalIsShow = false;
     },

+ 19 - 8
src/modules/grading/marker/MarkerImageView.vue

@@ -9,13 +9,22 @@
       <slot>
         <div class="image-info">
           <div v-if="image.level" class="image-level">{{ image.level }}</div>
+          <div v-if="image.sample" class="image-sample">标</div>
           <div
-            :class="['image-checkbox', { 'image-checked': image.checked }]"
-            @click="toCheck"
+            v-else
+            :class="[
+              'image-checkbox',
+              {
+                'image-selected': image.selected
+              }
+            ]"
+            @click="toSelect"
           >
-            <Icon v-if="image.checked" type="md-checkmark" />
+            <Icon v-if="image.selected" type="md-checkmark" />
+          </div>
+          <div class="image-title" @click="toSelect">
+            {{ image.title }}
           </div>
-          <div class="image-title" @click="toCheck">{{ image.title }}</div>
         </div>
         <div class="image-rotate" @click="toRotate">
           <Icon type="md-refresh-circle" />
@@ -50,7 +59,8 @@ export default {
         title: "",
         level: "",
         deg: 0,
-        checked: false
+        sample: false,
+        selected: false
       },
       image: {}
     };
@@ -66,9 +76,10 @@ export default {
 
       this.$refs.ImageViewContain.resizeImage(image.deg);
     },
-    toCheck() {
-      this.image.checked = !this.image.checked;
-      this.$emit("to-check", this.image);
+    toSelect() {
+      if (this.image.sample) return;
+      this.image.selected = !this.image.selected;
+      this.$emit("to-select", this.image);
     }
   }
 };

+ 97 - 0
src/modules/grading/marker/MarkerStatistics.vue

@@ -0,0 +1,97 @@
+<template>
+  <Modal
+    v-model="modalIsShow"
+    class="marker-statistics marker-modal"
+    title="统计分析"
+    footer-hide
+    fullscreen
+    @on-visible-change="visibleChange"
+  >
+    <div class="marker-statistics-table">
+      <table class="table">
+        <tr>
+          <th>档位</th>
+          <th v-if="showCount">考区定档数量</th>
+          <th>考区内试卷总数</th>
+          <th>考区阈值</th>
+          <th v-if="showCount">当前批次评卷员分档数量</th>
+          <th>当前批次试卷总数</th>
+          <!-- <th>当前批次阈值</th> -->
+          <!-- <th>操作</th> -->
+        </tr>
+        <tr v-for="(step, sindex) in steps.levelStep" :key="sindex">
+          <td>{{ step.name }}</td>
+          <td v-if="showCount">{{ step.gcount }}</td>
+          <td>{{ step.gpercent }}%</td>
+          <td>{{ step.pt }}%</td>
+          <td v-if="showCount">{{ step.count }}</td>
+          <td>{{ step.percent }}%</td>
+          <!-- <td>{{ step.kdpt !== null ? step.kdpt + "%" : "" }}</td> -->
+          <!-- <td><p @click="stepClick(step)">进入评卷</p></td> -->
+        </tr>
+      </table>
+    </div>
+    <div class="marker-statistics-chart">
+      <h3>数量统计</h3>
+      <echart-render
+        :chart-data="lineChartData"
+        chart-type="darkLine"
+        v-if="lineChartData"
+      ></echart-render>
+    </div>
+  </Modal>
+</template>
+
+<script>
+import EchartRender from "@/components/EchartRender";
+
+export default {
+  name: "marker-statistics",
+  props: {
+    steps: {
+      type: Object,
+      default() {
+        return { levelStep: [], otherStep: [] };
+      }
+    },
+    showCount: {
+      type: Boolean,
+      default: true
+    }
+  },
+  components: { EchartRender },
+  data() {
+    return {
+      modalIsShow: false,
+      lineChartData: null
+    };
+  },
+  methods: {
+    visibleChange(visible) {
+      if (visible) {
+        this.initData();
+      } else {
+        this.lineChartData = null;
+      }
+    },
+    initData() {
+      this.lineChartData = this.steps.levelStep.map(item => {
+        return {
+          name: item.name,
+          value: item.count
+        };
+      });
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    stepClick(step) {
+      this.cancel();
+      this.$emit("step-change", step.name);
+    }
+  }
+};
+</script>