Selaa lähdekoodia

档位名称展示修改

zhangjie 2 vuotta sitten
vanhempi
commit
5f10a791db

+ 55 - 8
src/api.js

@@ -311,8 +311,36 @@ export const gradingStatData = datas => {
 };
 
 // level relate
-export const workLevelList = workId => {
-  return $get(`/api/admin/works/${workId}/levels`);
+export const workLevelList = async (workId, stage = "LEVEL") => {
+  const data = await $get(`/api/admin/works/${workId}/levels`);
+  if (stage === "ROUGH_LEVEL") {
+    const levelMap = [];
+    data.forEach(item => {
+      const ind = item.roughCode * 1 - 1;
+      if (!levelMap[ind]) levelMap[ind] = [];
+
+      levelMap[ind].push(item);
+    });
+    return levelMap.map((group, ind) => {
+      const levels = group.map(item => item.code);
+
+      return {
+        id: ind + 1,
+        name: ind + 1,
+        minScore: levels[0],
+        maxScore: levels.slice(-1)[0]
+      };
+    });
+  } else {
+    return data.map(item => {
+      return {
+        id: item.id,
+        name: item.code,
+        minScore: item.minScore,
+        maxScore: item.maxScore
+      };
+    });
+  }
 };
 export const levelStatData = (subjectId, questionId) => {
   return $get(`/api/marksubjects/${subjectId}/stat/levels`, { questionId });
@@ -320,10 +348,20 @@ export const levelStatData = (subjectId, questionId) => {
 export const scoreStatData = (subjectId, questionId) => {
   return $get(`/api/marksubjects/${subjectId}/stat/scores`, { questionId });
 };
-export const markLeaderLevelStatData = (subjectId, questionId) => {
-  return $get(`/api/marksubjects/${subjectId}/mark_leader/stat/levels`, {
-    questionId
-  });
+export const markLeaderLevelStatData = (
+  subjectId,
+  questionId,
+  stage = "LEVEL"
+) => {
+  if (stage === "LEVEL") {
+    return $get(`/api/marksubjects/${subjectId}/mark_leader/stat/levels`, {
+      questionId
+    });
+  } else {
+    return $get(`/api/marksubjects/${subjectId}/mark_leader/stat/roughLevels`, {
+      questionId
+    });
+  }
 };
 export const markLeaderScoreStatData = (subjectId, questionId) => {
   return $get(`/api/marksubjects/${subjectId}/mark_leader/stat/scores`, {
@@ -333,9 +371,18 @@ export const markLeaderScoreStatData = (subjectId, questionId) => {
 export const markerLevelStatData = (userId, questionId) => {
   return $get(`/api/markers/${userId}/stat/levels`, { questionId });
 };
-export const markerLevelTotalStatData = (userId, questionId) => {
-  return $get(`/api/markers/${userId}/stat/totalLevels`, { questionId });
+export const markerLevelTotalStatData = (
+  userId,
+  questionId,
+  stage = "LEVEL"
+) => {
+  if (stage === "LEVEL") {
+    return $get(`/api/markers/${userId}/stat/totalLevels`, { questionId });
+  } else {
+    return $get(`/api/markers/${userId}/stat/totalRoughLevels`, { questionId });
+  }
 };
+
 // area
 export const areaList = ({ workId, subject }) => {
   return $get("/api/questions", { workId, subject });

+ 3 - 10
src/modules/grading/GradingDetail.vue

@@ -127,7 +127,7 @@
                 ]"
                 @click="multipleSelectLevel(level)"
               >
-                <p>{{ level.name }}</p>
+                <p>{{ level.name | levelNameFilter }}</p>
                 <p>{{ level.minScore }}~{{ level.maxScore }}</p>
               </div>
             </div>
@@ -380,15 +380,8 @@ export default {
       }
     },
     async getWorkLevels() {
-      const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          id: item.id,
-          name: item.code,
-          minScore: item.minScore,
-          maxScore: item.maxScore
-        };
-      });
+      const data = await workLevelList(this.workId, this.curSubject.stage);
+      this.levels = data || [];
     },
     async stepChange(step) {
       this.curStep = step;

+ 2 - 9
src/modules/grading/GradingOperation.vue

@@ -382,15 +382,8 @@ export default {
       });
     },
     async getWorkLevels() {
-      const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          id: item.id,
-          name: item.code,
-          minScore: item.minScore,
-          maxScore: item.maxScore
-        };
-      });
+      const data = await workLevelList(this.workId, this.curSubject.stage);
+      this.levels = data || [];
     },
     pageSizeChange(size) {
       this.size = size;

+ 3 - 3
src/modules/grading/GradingStandardPaperManage.vue

@@ -179,13 +179,13 @@ export default {
       await this.getAreaList();
       this.questionId = this.areas[0] && this.areas[0].id;
       if (!this.questionId) return;
-      await this.getWorkLevels();
       await this.getSubjectDetail();
+      await this.getWorkLevels();
       this.search();
     },
     async getWorkLevels() {
-      const data = await workLevelList(this.workId);
-      this.levels = data.map(item => item.code);
+      const data = await workLevelList(this.workId, this.curSubject.stage);
+      this.levels = data.map(item => item.name);
     },
     async getAreaList() {
       const data = await sampleAreaList({

+ 3 - 3
src/modules/grading/components/GradeAction.vue

@@ -52,7 +52,7 @@
           ]"
           @click="selectLevel(level)"
         >
-          <p>{{ level.name }}</p>
+          <p>{{ level.name | levelNameFilter }}</p>
           <p>{{ level.minScore }}~{{ level.maxScore }}</p>
         </div>
       </div>
@@ -95,7 +95,7 @@
       建议档位:
     </h3>
     <div class="action-grade-info" v-if="rights.gradeInfo && curLevel.name">
-      <h3 class="grade-info-name">{{ curLevel.name }}</h3>
+      <h3 class="grade-info-name">{{ curLevel.name | levelNameFilter }}</h3>
       <div class="grade-info-range">
         <p>分数范围</p>
         <p>
@@ -125,7 +125,7 @@
           :key="his.id"
         >
           <p>{{ his.loginName }}</p>
-          <p>{{ his.value }}</p>
+          <p>{{ his.value | levelNameFilter }}</p>
         </div>
       </div>
     </div>

+ 84 - 84
src/modules/grading/components/GradeStep.vue

@@ -1,84 +1,84 @@
-<template>
-  <div class="grade-step">
-    <div
-      class="grade-step-other"
-      v-if="steps.otherStep && steps.otherStep.length"
-    >
-      <div
-        v-for="(step, sindex) in steps.otherStep"
-        :key="sindex"
-        :class="[
-          'step-item',
-          {
-            'step-act': curStep.name === step.name,
-            'step-other': step.type !== 'done'
-          }
-        ]"
-        @click="selectStep(step)"
-      >
-        <p>{{ step.count }}</p>
-        <p class="step-name">{{ step.name }}</p>
-        <p>{{ step.count }}</p>
-      </div>
-    </div>
-    <div class="grade-step-level">
-      <div
-        v-for="(step, sindex) in steps.levelStep"
-        :key="sindex"
-        :class="[
-          'step-item',
-          {
-            'step-act': curStep.name === step.name,
-            'step-other': step.type !== 'done'
-          }
-        ]"
-        @click="selectStep(step)"
-      >
-        <p>
-          <span>{{ step.gcount }}/</span><span>{{ step.gpercent }}%</span
-          ><span>({{ step.pt }}%)</span>
-        </p>
-        <p class="step-name">{{ step.name }}</p>
-        <p>
-          <span>{{ step.count }}/</span><span>{{ step.percent }}%</span
-          ><span v-if="step.kdpt !== null">({{ step.kdpt }}%)</span>
-        </p>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  name: "grade-step",
-  props: {
-    steps: {
-      type: Object,
-      default() {
-        return { levelStep: [], otherStep: [] };
-      }
-    },
-    initStep: {
-      type: Object,
-      default() {
-        return { type: "analysis", name: "analysis" };
-      }
-    }
-  },
-  data() {
-    return {
-      curStep: {}
-    };
-  },
-  mounted() {
-    // this.selectStep(this.initStep);
-    this.curStep = { ...this.initStep };
-  },
-  methods: {
-    selectStep(step) {
-      this.curStep = { ...step };
-      this.$emit("on-change", this.curStep);
-    }
-  }
-};
-</script>
+<template>
+  <div class="grade-step">
+    <div
+      class="grade-step-other"
+      v-if="steps.otherStep && steps.otherStep.length"
+    >
+      <div
+        v-for="(step, sindex) in steps.otherStep"
+        :key="sindex"
+        :class="[
+          'step-item',
+          {
+            'step-act': curStep.name === step.name,
+            'step-other': step.type !== 'done'
+          }
+        ]"
+        @click="selectStep(step)"
+      >
+        <p>{{ step.count }}</p>
+        <p class="step-name">{{ step.name }}</p>
+        <p>{{ step.count }}</p>
+      </div>
+    </div>
+    <div class="grade-step-level">
+      <div
+        v-for="(step, sindex) in steps.levelStep"
+        :key="sindex"
+        :class="[
+          'step-item',
+          {
+            'step-act': curStep.name === step.name,
+            'step-other': step.type !== 'done'
+          }
+        ]"
+        @click="selectStep(step)"
+      >
+        <p>
+          <span>{{ step.gcount }}/</span><span>{{ step.gpercent }}%</span
+          ><span>({{ step.pt }}%)</span>
+        </p>
+        <p class="step-name">{{ step.name | levelNameFilter }}</p>
+        <p>
+          <span>{{ step.count }}/</span><span>{{ step.percent }}%</span
+          ><span v-if="step.kdpt !== null">({{ step.kdpt }}%)</span>
+        </p>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "grade-step",
+  props: {
+    steps: {
+      type: Object,
+      default() {
+        return { levelStep: [], otherStep: [] };
+      }
+    },
+    initStep: {
+      type: Object,
+      default() {
+        return { type: "analysis", name: "analysis" };
+      }
+    }
+  },
+  data() {
+    return {
+      curStep: {}
+    };
+  },
+  mounted() {
+    // this.selectStep(this.initStep);
+    this.curStep = { ...this.initStep };
+  },
+  methods: {
+    selectStep(step) {
+      this.curStep = { ...step };
+      this.$emit("on-change", this.curStep);
+    }
+  }
+};
+</script>

+ 129 - 129
src/modules/grading/leader/LeaderAnalysisExport.vue

@@ -1,129 +1,129 @@
-<template>
-  <div class="leader-analysis-export analysis-export-modal">
-    <div class="print-box">
-      <h1>
-        分档详情数据
-      </h1>
-      <div class="quality-info">
-        <p>科目:{{ pageInfo.subjectName }}</p>
-        <p>考区:{{ pageInfo.areaName }}</p>
-        <p>截止时间:{{ currentTime }}</p>
-      </div>
-      <div class="print-chart">
-        <div class="print-chart-title">详细数值表:</div>
-        <table class="export-table">
-          <tr>
-            <th>档位</th>
-            <th>考区试卷数量</th>
-            <th>考区试卷占比</th>
-            <th>考区阈值</th>
-            <th>差值</th>
-            <th>累计数量</th>
-            <th>累计占比</th>
-            <th>调整</th>
-            <th>全部试卷数量</th>
-            <th>全部试卷占比</th>
-            <th>占比阈值</th>
-          </tr>
-          <tr v-for="(level, index) in chartData.levelData" :key="index">
-            <td>{{ level.code }}</td>
-            <td>{{ level.levelCount }}</td>
-            <td>{{ level.levelProp }}%</td>
-            <td>{{ level.examLevelProp }}%</td>
-            <td>{{ level.diffProp }}%</td>
-            <td>{{ level.cumulateCount }}</td>
-            <td>{{ level.cumulateProp }}%</td>
-            <td>{{ level.adjustmentCount }}</td>
-            <td class="td-bl">{{ level.gcount }}</td>
-            <td>{{ level.gpercent }}%</td>
-            <td>{{ level.pt }}%</td>
-          </tr>
-        </table>
-      </div>
-      <div class="print-chart" v-if="chartData.lineChartData">
-        <div class="print-chart-title">考区试卷数量分布图</div>
-        <div class="print-chart-body">
-          <echart-render
-            :chart-data="chartData.lineChartData"
-            :animation-is-open="false"
-            chart-type="darkLines"
-            ref="lineChart"
-            v-if="!showImg"
-          ></echart-render>
-          <img src="" ref="lineChartImg" v-show="showImg" />
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import EchartRender from "@/components/EchartRender";
-import { download, formatDate } from "@/plugins/utils";
-import html2canvas from "html2canvas";
-
-export default {
-  name: "leader-analysis-export",
-  components: { EchartRender },
-  props: {
-    chartData: {
-      type: Object,
-      default() {
-        return {};
-      }
-    },
-    pageInfo: {
-      type: Object,
-      default() {
-        return {};
-      }
-    }
-  },
-  data() {
-    return {
-      currentTime: formatDate(),
-      showImg: false
-    };
-  },
-  mounted() {
-    this.$nextTick(() => {
-      this.$refs.lineChartImg.src = this.$refs.lineChart.getDataURL({
-        backgroundColor: "#fff"
-      });
-
-      this.showImg = true;
-      this.$nextTick(() => {
-        this.toExport();
-      });
-    });
-  },
-  methods: {
-    async toExport() {
-      const canvas = await html2canvas(this.$el.childNodes[0], {
-        allowTaint: true
-      }).catch(() => {});
-
-      if (!canvas) {
-        this.$emit("on-exported", false);
-        return;
-      }
-
-      let result = true;
-      const user = this.$ls.get("user", { token: "", id: "" });
-      await download({
-        type: "post",
-        url: `${this.GLOBAL.domain}/api/exportPdf`,
-        header: { Authorization: user.token, userId: user.id },
-        data: {
-          content: [canvas.toDataURL().split(",")[1]]
-        },
-        fileName: `${this.pageInfo.subjectName}-${this.pageInfo.areaName}-分档详情分析.pdf`
-      }).catch(() => {
-        result = false;
-      });
-
-      this.$emit("on-exported", result);
-    }
-  }
-};
-</script>
+<template>
+  <div class="leader-analysis-export analysis-export-modal">
+    <div class="print-box">
+      <h1>
+        分档详情数据
+      </h1>
+      <div class="quality-info">
+        <p>科目:{{ pageInfo.subjectName }}</p>
+        <p>考区:{{ pageInfo.areaName }}</p>
+        <p>截止时间:{{ currentTime }}</p>
+      </div>
+      <div class="print-chart">
+        <div class="print-chart-title">详细数值表:</div>
+        <table class="export-table">
+          <tr>
+            <th>档位</th>
+            <th>考区试卷数量</th>
+            <th>考区试卷占比</th>
+            <th>考区阈值</th>
+            <th>差值</th>
+            <th>累计数量</th>
+            <th>累计占比</th>
+            <th>调整</th>
+            <th>全部试卷数量</th>
+            <th>全部试卷占比</th>
+            <th>占比阈值</th>
+          </tr>
+          <tr v-for="(level, index) in chartData.levelData" :key="index">
+            <td>{{ level.code | levelNameFilter }}</td>
+            <td>{{ level.levelCount }}</td>
+            <td>{{ level.levelProp }}%</td>
+            <td>{{ level.examLevelProp }}%</td>
+            <td>{{ level.diffProp }}%</td>
+            <td>{{ level.cumulateCount }}</td>
+            <td>{{ level.cumulateProp }}%</td>
+            <td>{{ level.adjustmentCount }}</td>
+            <td class="td-bl">{{ level.gcount }}</td>
+            <td>{{ level.gpercent }}%</td>
+            <td>{{ level.pt }}%</td>
+          </tr>
+        </table>
+      </div>
+      <div class="print-chart" v-if="chartData.lineChartData">
+        <div class="print-chart-title">考区试卷数量分布图</div>
+        <div class="print-chart-body">
+          <echart-render
+            :chart-data="chartData.lineChartData"
+            :animation-is-open="false"
+            chart-type="darkLines"
+            ref="lineChart"
+            v-if="!showImg"
+          ></echart-render>
+          <img src="" ref="lineChartImg" v-show="showImg" />
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import EchartRender from "@/components/EchartRender";
+import { download, formatDate } from "@/plugins/utils";
+import html2canvas from "html2canvas";
+
+export default {
+  name: "leader-analysis-export",
+  components: { EchartRender },
+  props: {
+    chartData: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    pageInfo: {
+      type: Object,
+      default() {
+        return {};
+      }
+    }
+  },
+  data() {
+    return {
+      currentTime: formatDate(),
+      showImg: false
+    };
+  },
+  mounted() {
+    this.$nextTick(() => {
+      this.$refs.lineChartImg.src = this.$refs.lineChart.getDataURL({
+        backgroundColor: "#fff"
+      });
+
+      this.showImg = true;
+      this.$nextTick(() => {
+        this.toExport();
+      });
+    });
+  },
+  methods: {
+    async toExport() {
+      const canvas = await html2canvas(this.$el.childNodes[0], {
+        allowTaint: true
+      }).catch(() => {});
+
+      if (!canvas) {
+        this.$emit("on-exported", false);
+        return;
+      }
+
+      let result = true;
+      const user = this.$ls.get("user", { token: "", id: "" });
+      await download({
+        type: "post",
+        url: `${this.GLOBAL.domain}/api/exportPdf`,
+        header: { Authorization: user.token, userId: user.id },
+        data: {
+          content: [canvas.toDataURL().split(",")[1]]
+        },
+        fileName: `${this.pageInfo.subjectName}-${this.pageInfo.areaName}-分档详情分析.pdf`
+      }).catch(() => {
+        result = false;
+      });
+
+      this.$emit("on-exported", result);
+    }
+  }
+};
+</script>

+ 8 - 14
src/modules/grading/leader/LeaderGrading.vue

@@ -253,10 +253,10 @@ export default {
       "setShortcut",
       "clearState"
     ]),
-    initData() {
-      this.getParamsSetInfo();
-      this.getSubjectDetail();
-      this.getWorkLevels();
+    async initData() {
+      await this.getSubjectDetail();
+      await this.getParamsSetInfo();
+      await this.getWorkLevels();
     },
     async getParamsSetInfo() {
       const data = await getParamsSet(this.workId);
@@ -330,7 +330,8 @@ export default {
     async getStepLevels() {
       const data = await markLeaderLevelStatData(
         this.subjectId,
-        this.filter.questionId
+        this.filter.questionId,
+        this.curSubject.stage
       );
       const undoIndex = data.findIndex(item => item.id === null);
       let otherStep = [];
@@ -383,15 +384,8 @@ export default {
       }
     },
     async getWorkLevels() {
-      const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          id: item.id,
-          name: item.code,
-          minScore: item.minScore,
-          maxScore: item.maxScore
-        };
-      });
+      const data = await workLevelList(this.workId, this.curSubject.stage);
+      this.levels = data || [];
     },
     async pageSetChange() {
       await this.getList();

+ 175 - 174
src/modules/grading/leader/LeaderStatistics.vue

@@ -1,174 +1,175 @@
-<template>
-  <Modal
-    v-model="modalIsShow"
-    class="leader-statistics marker-modal"
-    title="统计分析"
-    footer-hide
-    fullscreen
-    @on-visible-change="visibleChange"
-  >
-    <div class="box-justify mb-2">
-      <div>
-        <p>{{ curArea.areaName }}:{{ curSubject.name }}</p>
-      </div>
-      <div>
-        <Button
-          class="marker-btn-primary"
-          size="small"
-          type="primary"
-          @click="toExport"
-          :loading="isDownload"
-          >导出表格</Button
-        >
-      </div>
-    </div>
-    <div class="marker-statistics-table">
-      <table class="table table-dark">
-        <tr>
-          <th>档位</th>
-          <th>考区试卷数量</th>
-          <th>考区试卷占比</th>
-          <th>考区阈值</th>
-          <th>差值</th>
-          <th>累计数量</th>
-          <th>累计占比</th>
-          <th>调整</th>
-          <th class="td-bl">全部试卷数量</th>
-          <th>全部试卷占比</th>
-          <th>占比阈值</th>
-        </tr>
-        <tr v-for="(level, sindex) in levelData" :key="sindex">
-          <td>{{ level.code }}</td>
-          <td>{{ level.levelCount }}</td>
-          <td>{{ level.levelProp }}%</td>
-          <td>{{ level.examLevelProp }}%</td>
-          <td>{{ level.diffProp }}%</td>
-          <td>{{ level.cumulateCount }}</td>
-          <td>{{ level.cumulateProp }}%</td>
-          <td>{{ level.adjustmentCount }}</td>
-          <td class="td-bl">{{ level.gcount }}</td>
-          <td>{{ level.gpercent }}%</td>
-          <td>{{ level.pt }}%</td>
-        </tr>
-      </table>
-    </div>
-    <div class="marker-statistics-chart">
-      <h3>考区试卷数量分布图</h3>
-      <echart-render
-        :chart-data="lineChartData"
-        chart-type="darkLines"
-        v-if="lineChartData"
-      ></echart-render>
-    </div>
-
-    <!-- LeaderAnalysisExport -->
-    <leader-analysis-export
-      ref="LeaderAnalysisExport"
-      :chart-data="renderChartData"
-      :page-info="renderPageInfo"
-      @on-exported="exportOver"
-      v-if="renderExportPage"
-    ></leader-analysis-export>
-  </Modal>
-</template>
-
-<script>
-import { mapState } from "vuex";
-import { gradingStatData } from "@/api";
-import EchartRender from "@/components/EchartRender";
-import LeaderAnalysisExport from "./LeaderAnalysisExport";
-
-export default {
-  name: "leader-statistics",
-  components: { EchartRender, LeaderAnalysisExport },
-  props: {
-    questionId: {
-      type: [Number, String],
-      required: true
-    }
-  },
-  data() {
-    return {
-      modalIsShow: false,
-      levelData: [],
-      lineChartData: null,
-      // export
-      renderExportPage: false,
-      renderChartData: {},
-      renderPageInfo: {},
-      isDownload: false
-    };
-  },
-  computed: {
-    ...mapState("marker", ["paramsSet", "curSubject", "curArea", "areas"])
-  },
-  methods: {
-    visibleChange(visible) {
-      if (visible) {
-        this.initData();
-      } else {
-        this.lineChartData = null;
-      }
-    },
-    async initData() {
-      const subs = this.$route.params.subjectId.split("-");
-      this.levelData = await gradingStatData({
-        questionId: this.questionId,
-        workId: subs[0],
-        subject: subs[1]
-      });
-
-      const groups = [
-        {
-          key: "levelProp",
-          label: "考区"
-        },
-        {
-          key: "gpercent",
-          label: "全部"
-        }
-      ];
-      const groupList = this.areas.length === 1 ? groups.slice(0, 1) : groups;
-      this.lineChartData = groupList.map(group => {
-        const data = this.levelData.map(item => {
-          return {
-            name: item.code,
-            value: item[group.key]
-          };
-        });
-        return {
-          name: group.label,
-          data
-        };
-      });
-    },
-    // export
-    toExport() {
-      if (this.isDownload) return;
-      this.isDownload = true;
-      this.renderPageInfo = {
-        subjectName: this.curSubject.name,
-        areaName: this.curArea.areaName
-      };
-      this.renderChartData = {
-        levelData: this.levelData,
-        lineChartData: this.lineChartData
-      };
-      this.renderExportPage = true;
-    },
-    exportOver(result) {
-      if (!result) {
-        this.$Message.error("导出失败,请重新尝试!");
-      }
-      this.renderExportPage = false;
-      this.isDownload = false;
-    },
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    }
-  }
-};
-</script>
+<template>
+  <Modal
+    v-model="modalIsShow"
+    class="leader-statistics marker-modal"
+    title="统计分析"
+    footer-hide
+    fullscreen
+    @on-visible-change="visibleChange"
+  >
+    <div class="box-justify mb-2">
+      <div>
+        <p>{{ curArea.areaName }}:{{ curSubject.name }}</p>
+      </div>
+      <div>
+        <Button
+          class="marker-btn-primary"
+          size="small"
+          type="primary"
+          @click="toExport"
+          :loading="isDownload"
+          >导出表格</Button
+        >
+      </div>
+    </div>
+    <div class="marker-statistics-table">
+      <table class="table table-dark">
+        <tr>
+          <th>档位</th>
+          <th>考区试卷数量</th>
+          <th>考区试卷占比</th>
+          <th>考区阈值</th>
+          <th>差值</th>
+          <th>累计数量</th>
+          <th>累计占比</th>
+          <th>调整</th>
+          <th class="td-bl">全部试卷数量</th>
+          <th>全部试卷占比</th>
+          <th>占比阈值</th>
+        </tr>
+        <tr v-for="(level, sindex) in levelData" :key="sindex">
+          <td>{{ level.code | levelNameFilter }}</td>
+          <td>{{ level.levelCount }}</td>
+          <td>{{ level.levelProp }}%</td>
+          <td>{{ level.examLevelProp }}%</td>
+          <td>{{ level.diffProp }}%</td>
+          <td>{{ level.cumulateCount }}</td>
+          <td>{{ level.cumulateProp }}%</td>
+          <td>{{ level.adjustmentCount }}</td>
+          <td class="td-bl">{{ level.gcount }}</td>
+          <td>{{ level.gpercent }}%</td>
+          <td>{{ level.pt }}%</td>
+        </tr>
+      </table>
+    </div>
+    <div class="marker-statistics-chart">
+      <h3>考区试卷数量分布图</h3>
+      <echart-render
+        :chart-data="lineChartData"
+        chart-type="darkLines"
+        v-if="lineChartData"
+      ></echart-render>
+    </div>
+
+    <!-- LeaderAnalysisExport -->
+    <leader-analysis-export
+      ref="LeaderAnalysisExport"
+      :chart-data="renderChartData"
+      :page-info="renderPageInfo"
+      @on-exported="exportOver"
+      v-if="renderExportPage"
+    ></leader-analysis-export>
+  </Modal>
+</template>
+
+<script>
+import { mapState } from "vuex";
+import { gradingStatData } from "@/api";
+import EchartRender from "@/components/EchartRender";
+import LeaderAnalysisExport from "./LeaderAnalysisExport";
+import { levelNameTransform } from "@/plugins/utils";
+
+export default {
+  name: "leader-statistics",
+  components: { EchartRender, LeaderAnalysisExport },
+  props: {
+    questionId: {
+      type: [Number, String],
+      required: true
+    }
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      levelData: [],
+      lineChartData: null,
+      // export
+      renderExportPage: false,
+      renderChartData: {},
+      renderPageInfo: {},
+      isDownload: false
+    };
+  },
+  computed: {
+    ...mapState("marker", ["paramsSet", "curSubject", "curArea", "areas"])
+  },
+  methods: {
+    visibleChange(visible) {
+      if (visible) {
+        this.initData();
+      } else {
+        this.lineChartData = null;
+      }
+    },
+    async initData() {
+      const subs = this.$route.params.subjectId.split("-");
+      this.levelData = await gradingStatData({
+        questionId: this.questionId,
+        workId: subs[0],
+        subject: subs[1]
+      });
+
+      const groups = [
+        {
+          key: "levelProp",
+          label: "考区"
+        },
+        {
+          key: "gpercent",
+          label: "全部"
+        }
+      ];
+      const groupList = this.areas.length === 1 ? groups.slice(0, 1) : groups;
+      this.lineChartData = groupList.map(group => {
+        const data = this.levelData.map(item => {
+          return {
+            name: levelNameTransform(item.code),
+            value: item[group.key]
+          };
+        });
+        return {
+          name: group.label,
+          data
+        };
+      });
+    },
+    // export
+    toExport() {
+      if (this.isDownload) return;
+      this.isDownload = true;
+      this.renderPageInfo = {
+        subjectName: this.curSubject.name,
+        areaName: this.curArea.areaName
+      };
+      this.renderChartData = {
+        levelData: this.levelData,
+        lineChartData: this.lineChartData
+      };
+      this.renderExportPage = true;
+    },
+    exportOver(result) {
+      if (!result) {
+        this.$Message.error("导出失败,请重新尝试!");
+      }
+      this.renderExportPage = false;
+      this.isDownload = false;
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    }
+  }
+};
+</script>

+ 7 - 11
src/modules/grading/marker/MarkerGrading.vue

@@ -2,6 +2,7 @@
   <div class="marker-grading">
     <marker-header
       ref="MarkerHeader"
+      v-if="curSubject.id"
       @area-change="areaChange"
       @step-change="stepChange"
       @page-set-change="pageSetChange"
@@ -216,8 +217,9 @@ export default {
       "clearState"
     ]),
     async initData() {
-      await this.getParamsSetInfo();
       await this.getSubjectDetail();
+      await this.getParamsSetInfo();
+      // 必须在获取subject之后再获取levels
       await this.getWorkLevels();
     },
     async getParamsSetInfo() {
@@ -265,7 +267,8 @@ export default {
     async getStepLevels() {
       const data = await markerLevelTotalStatData(
         this.filter.markerId,
-        this.filter.questionId
+        this.filter.questionId,
+        this.curSubject.stage
       );
       const undoIndex = data.findIndex(item => item.id === null);
       let otherStep = [];
@@ -342,15 +345,8 @@ export default {
       this.setSteps(this.steps);
     },
     async getWorkLevels() {
-      const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          id: item.id,
-          name: item.code,
-          minScore: item.minScore,
-          maxScore: item.maxScore
-        };
-      });
+      const data = await workLevelList(this.workId, this.curSubject.stage);
+      this.levels = data || [];
     },
     async pageSetChange() {
       await this.getList();

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

@@ -195,7 +195,7 @@
           @on-click="stepClick"
         >
           <span class="el-dropdown-link">
-            <i>{{ curStep.name }}</i>
+            <i>{{ curStep.name | levelNameFilter }}</i>
             <i>:{{ curStep.count }} </i>
             <Icon type="ios-arrow-down"></Icon>
           </span>
@@ -215,7 +215,7 @@
               :key="step.name"
               :name="step.name"
             >
-              <i>{{ step.name }}</i>
+              <i>{{ step.name | levelNameFilter }}</i>
               <i v-if="IS_MARK_LEADER && !IS_MARK_LEADER__SCORE"
                 >({{ step.count }} / {{ step.gcount }})</i
               >

+ 8 - 2
src/modules/grading/marker/MarkerHistory.vue

@@ -16,9 +16,12 @@
         <div class="marker-image-content">
           <marker-image-view :data="paper" @to-review="toReview(index)">
             <div class="image-info">
-              <div class="image-level">
+              <div v-if="IS_SCORE" class="image-level">
                 {{ paper.actionResult }}
               </div>
+              <div v-else class="image-level">
+                {{ paper.actionResult | levelNameFilter }}
+              </div>
               <div class="image-action-name">{{ paper.actionName }}</div>
             </div>
             <div class="image-sn" :title="'NO.' + paper.sn">
@@ -62,7 +65,10 @@ export default {
     };
   },
   computed: {
-    ...mapState("marker", ["IS_MARK_LEADER"])
+    ...mapState("marker", ["IS_MARK_LEADER"]),
+    IS_SCORE() {
+      return this.stage === "SCORE";
+    }
   },
   mounted() {
     this.userId = this.$ls.get("user", { id: "" }).id;

+ 6 - 2
src/modules/grading/marker/MarkerImageView.vue

@@ -8,7 +8,9 @@
     <div class="image-view-footer">
       <slot>
         <div v-if="IS_LEVEL" class="image-info">
-          <div v-if="image.level" class="image-level">{{ image.level }}</div>
+          <div v-if="image.level" class="image-level">
+            {{ image.level | levelNameFilter }}
+          </div>
           <div v-if="image.sample" class="image-sample">标</div>
           <div
             v-else
@@ -24,7 +26,9 @@
           </div>
         </div>
         <div v-else class="image-info">
-          <div v-if="image.level" class="image-level">{{ image.level }}</div>
+          <div v-if="image.level" class="image-level">
+            {{ image.level }}
+          </div>
           <div v-if="image.score" class="image-level">{{ image.score }}</div>
         </div>
         <div class="image-title" :title="image.title" @click="toSelect">

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

@@ -84,7 +84,7 @@
           ]"
           @click="selectLevel(level.name)"
         >
-          {{ level.name }}
+          {{ level.name | levelNameFilter }}
         </p>
       </div>
 

+ 3 - 2
src/modules/grading/marker/MarkerStatistics.vue

@@ -19,7 +19,7 @@
           <!-- <th>当前批次阈值</th> -->
         </tr>
         <tr v-for="(step, sindex) in steps.levelStep" :key="sindex">
-          <td>{{ step.name }}</td>
+          <td>{{ step.name | levelNameFilter }}</td>
           <td>{{ step.gcount }}</td>
           <td>{{ step.gpercent }}%</td>
           <td>{{ step.pt }}%</td>
@@ -43,6 +43,7 @@
 <script>
 import { mapState } from "vuex";
 import EchartRender from "@/components/EchartRender";
+import { levelNameTransform } from "@/plugins/utils";
 
 export default {
   name: "marker-statistics",
@@ -79,7 +80,7 @@ export default {
       this.lineChartData = groups.map(group => {
         const data = this.steps.levelStep.map(item => {
           return {
-            name: item.name,
+            name: levelNameTransform(item.name),
             value: item[group.key]
           };
         });

+ 1 - 6
src/modules/mark/MarkDetail.vue

@@ -294,12 +294,7 @@ export default {
     },
     async getWorkLevels() {
       const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          ...item,
-          name: item.code
-        };
-      });
+      this.levels = data || [];
     },
     async stepChange(step) {
       this.applyChangeLevelStatus = 1;

+ 1 - 6
src/modules/mark/MarkOperation.vue

@@ -329,12 +329,7 @@ export default {
     },
     async getWorkLevels() {
       const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          ...item,
-          name: item.code
-        };
-      });
+      this.levels = data || [];
     },
     pageSizeChange(size) {
       this.size = size;

+ 82 - 82
src/modules/mark/components/MarkStep.vue

@@ -1,82 +1,82 @@
-<template>
-  <div class="mark-step grade-step">
-    <div
-      class="grade-step-other"
-      v-if="steps.otherStep && steps.otherStep.length"
-    >
-      <div
-        v-for="(step, sindex) in steps.otherStep"
-        :key="sindex"
-        :class="[
-          'step-item',
-          {
-            'step-act': curStep.name === step.name,
-            'step-other': step.type !== 'done'
-          }
-        ]"
-        @click="selectStep(step)"
-      >
-        <p v-if="showTopNumber"></p>
-        <p class="step-name">{{ step.name }}</p>
-        <p>{{ step.count }}</p>
-      </div>
-    </div>
-    <div class="grade-step-level">
-      <div
-        v-for="(step, sindex) in steps.levelStep"
-        :key="sindex"
-        :class="[
-          'step-item',
-          {
-            'step-act': curStep.name === step.name,
-            'step-other': step.type !== 'done'
-          }
-        ]"
-        @click="selectStep(step)"
-      >
-        <p v-if="showTopNumber">{{ step.gcount }}</p>
-        <p class="step-name">{{ step.name }}</p>
-        <p>{{ step.count }}</p>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  name: "mark-step",
-  props: {
-    showTopNumber: {
-      type: Boolean,
-      default: true
-    },
-    steps: {
-      type: Object,
-      default() {
-        return { levelStep: [], otherStep: [] };
-      }
-    },
-    initStep: {
-      type: Object,
-      default() {
-        return { type: "", name: "" };
-      }
-    }
-  },
-  data() {
-    return {
-      curStep: {}
-    };
-  },
-  mounted() {
-    // this.selectStep(this.initStep);
-    this.curStep = { ...this.initStep };
-  },
-  methods: {
-    selectStep(step) {
-      this.curStep = { ...step };
-      this.$emit("on-change", this.curStep);
-    }
-  }
-};
-</script>
+<template>
+  <div class="mark-step grade-step">
+    <div
+      class="grade-step-other"
+      v-if="steps.otherStep && steps.otherStep.length"
+    >
+      <div
+        v-for="(step, sindex) in steps.otherStep"
+        :key="sindex"
+        :class="[
+          'step-item',
+          {
+            'step-act': curStep.name === step.name,
+            'step-other': step.type !== 'done'
+          }
+        ]"
+        @click="selectStep(step)"
+      >
+        <p v-if="showTopNumber"></p>
+        <p class="step-name">{{ step.name }}</p>
+        <p>{{ step.count }}</p>
+      </div>
+    </div>
+    <div class="grade-step-level">
+      <div
+        v-for="(step, sindex) in steps.levelStep"
+        :key="sindex"
+        :class="[
+          'step-item',
+          {
+            'step-act': curStep.name === step.name,
+            'step-other': step.type !== 'done'
+          }
+        ]"
+        @click="selectStep(step)"
+      >
+        <p v-if="showTopNumber">{{ step.gcount }}</p>
+        <p class="step-name">{{ step.name | levelNameFilter }}</p>
+        <p>{{ step.count }}</p>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "mark-step",
+  props: {
+    showTopNumber: {
+      type: Boolean,
+      default: true
+    },
+    steps: {
+      type: Object,
+      default() {
+        return { levelStep: [], otherStep: [] };
+      }
+    },
+    initStep: {
+      type: Object,
+      default() {
+        return { type: "", name: "" };
+      }
+    }
+  },
+  data() {
+    return {
+      curStep: {}
+    };
+  },
+  mounted() {
+    // this.selectStep(this.initStep);
+    this.curStep = { ...this.initStep };
+  },
+  methods: {
+    selectStep(step) {
+      this.curStep = { ...step };
+      this.$emit("on-change", this.curStep);
+    }
+  }
+};
+</script>

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

@@ -329,12 +329,7 @@ export default {
     },
     async getWorkLevels() {
       const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          ...item,
-          name: item.code
-        };
-      });
+      this.levels = data || [];
     },
     async pageSetChange() {
       await this.getList();

+ 1 - 6
src/modules/mark/marker/MarkerMarking.vue

@@ -355,12 +355,7 @@ export default {
     },
     async getWorkLevels() {
       const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          ...item,
-          name: item.code
-        };
-      });
+      this.levels = data || [];
     },
     async pageSetChange() {
       await this.getList();

+ 4 - 1
src/plugins/filters.js

@@ -1,6 +1,9 @@
 import Vue from "vue";
-import { formatDate } from "./utils";
+import { formatDate, levelNameTransform } from "./utils";
 
 Vue.filter("timestampFilter", function(val) {
   return val ? formatDate("YYYY-MM-DD HH:mm:ss", new Date(val * 1)) : "";
 });
+Vue.filter("levelNameFilter", function(val) {
+  return levelNameTransform(val);
+});

+ 7 - 1
src/plugins/utils.js

@@ -1,3 +1,4 @@
+import { ROUGH_LEVEL_TYPE } from "../constants/enumerate";
 const deepmerge = require("deepmerge");
 
 /**
@@ -259,6 +260,10 @@ function filterObjNull(obj) {
   return newObj;
 }
 
+function levelNameTransform(val) {
+  return /^[0-9]$/.test(val) ? ROUGH_LEVEL_TYPE[val] : val;
+}
+
 export {
   objTypeOf,
   deepCopy,
@@ -272,5 +277,6 @@ export {
   removeHtmlTag,
   humpFormat,
   calcSum,
-  filterObjNull
+  filterObjNull,
+  levelNameTransform
 };