zhangjie 2 年 前
コミット
fef4befb50

+ 16 - 2
src/assets/styles/marker.less

@@ -378,8 +378,8 @@
     justify-content: space-between;
   }
   .image-info {
-    white-space: nowrap;
-    overflow: hidden;
+    flex-grow: 0;
+    flex-shrink: 0;
     > div {
       display: inline-block;
       vertical-align: top;
@@ -424,12 +424,18 @@
   .image-title {
     height: 26px;
     padding-left: 5px;
+    flex-grow: 2;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
     cursor: pointer;
     &:hover {
       color: @color-text-act;
     }
   }
   .image-action {
+    flex-grow: 0;
+    flex-shrink: 0;
     .ivu-btn {
       width: 26px;
       height: 26px;
@@ -458,6 +464,14 @@
       color: @warning-color;
     }
   }
+  .image-sn {
+    padding-left: 10px;
+    flex-grow: 2;
+    text-align: right;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
 }
 .marker-image-none {
   padding-top: 150px;

+ 427 - 427
src/modules/grading-set/GradingLevelSet.vue

@@ -1,427 +1,427 @@
-<template>
-  <div class="grading-level-set">
-    <Button
-      class="level-add-btn"
-      type="success"
-      icon="recode-white icon"
-      shape="circle"
-      @click="toAdd"
-      >新增档位</Button
-    >
-    <table class="table table-noborder grading-table">
-      <tr>
-        <th>档位</th>
-        <th>最低分</th>
-        <th>最高分</th>
-        <th>给分间隔</th>
-        <th>典型值</th>
-        <th>类型</th>
-        <th>给分项</th>
-        <th>考区阈值%</th>
-        <th>占比阈值%</th>
-        <th>操作</th>
-      </tr>
-      <template v-for="(level, index) in levels">
-        <tr :key="index">
-          <td>
-            <Input
-              v-model="level.code"
-              style="width: 60px"
-              @on-blur="codeChange(level)"
-              v-if="level.canEdit && workDetail.modifyOtherVal"
-            ></Input>
-            <p v-else>{{ level.code }}</p>
-          </td>
-          <td>
-            <InputNumber
-              v-model="level.minScore"
-              :min="0"
-              :max="1000"
-              @on-blur="checkLevelValidate(level)"
-              v-if="level.canEdit && workDetail.modifyOtherVal"
-            ></InputNumber>
-            <p v-else>{{ level.minScore }}</p>
-          </td>
-          <td>
-            <InputNumber
-              v-model="level.maxScore"
-              :min="1"
-              :max="1000"
-              @on-blur="checkLevelValidate(level)"
-              v-if="level.canEdit && workDetail.modifyOtherVal"
-            ></InputNumber>
-            <p v-else>{{ level.maxScore }}</p>
-          </td>
-          <td style="min-width: 100px">
-            <InputNumber
-              v-model="level.intervalScore"
-              :min="1"
-              :max="100"
-              :precision="0"
-              :disabled="!level.canEdit"
-              @on-blur="checkLevelValidate(level)"
-              v-if="
-                level.levelType === 'ADMITED' &&
-                  level.canEdit &&
-                  workDetail.modifyOtherVal
-              "
-            ></InputNumber>
-            <p v-else>{{ level.intervalScore }}</p>
-          </td>
-          <td>
-            <InputNumber
-              v-model="level.weight"
-              :min="1"
-              :max="100"
-              @on-blur="checkLevelValidate(level)"
-              v-if="level.canEdit && workDetail.modifyOtherVal"
-            ></InputNumber>
-            <p v-else>{{ level.weight }}</p>
-          </td>
-          <td>
-            <Select
-              v-model="level.levelType"
-              @on-change="levelTypeChange(level)"
-              style="width: 120px"
-              v-if="level.canEdit && workDetail.modifyOtherVal"
-            >
-              <Option
-                v-for="(val, key) in LEVEL_TYPE"
-                :key="key"
-                :value="key"
-                >{{ val }}</Option
-              >
-            </Select>
-            <p v-else>{{ LEVEL_TYPE[level.levelType] }}</p>
-          </td>
-          <td style="min-width: 140px">
-            <Input
-              v-model="level.scoreList"
-              @on-blur="checkLevelValidate(level)"
-              v-if="
-                level.levelType === 'UNADMIT' &&
-                  level.canEdit &&
-                  workDetail.modifyOtherVal
-              "
-            ></Input>
-            <p v-else>{{ level.scoreList }}</p>
-          </td>
-          <td>
-            <InputNumber
-              v-model="level.kdpt"
-              :min="1"
-              :max="100"
-              @on-blur="checkLevelValidate(level)"
-              v-if="level.canEdit"
-            ></InputNumber>
-            <p v-else>{{ level.kdpt }}</p>
-          </td>
-          <td>
-            <InputNumber
-              v-model="level.pt"
-              :min="1"
-              :max="100"
-              @on-blur="checkLevelValidate(level)"
-              v-if="level.canEdit"
-            ></InputNumber>
-            <p v-else>{{ level.pt }}</p>
-          </td>
-          <td class="table-action">
-            <div style="width: 60px">
-              <Icon type="md-create" title="编辑" @click="toEdit(index)" />
-              <Icon
-                class="icon-danger"
-                type="md-trash"
-                title="删除"
-                @click="toDelete(index)"
-                v-if="workDetail.modifyOtherVal"
-              />
-            </div>
-          </td>
-        </tr>
-        <tr class="tr-tips-error" v-if="level.errors" :key="index + '1'">
-          <td>
-            {{ level.errors.code }}
-          </td>
-          <td>
-            {{ level.errors.minScore }}
-          </td>
-          <td>
-            {{ level.errors.maxScore }}
-          </td>
-          <td>
-            {{ level.errors.intervalScore }}
-          </td>
-          <td>
-            {{ level.errors.weight }}
-          </td>
-          <td></td>
-          <td>
-            {{ level.errors.scoreList }}
-          </td>
-          <td>
-            {{ level.errors.kdpt }}
-          </td>
-          <td>
-            {{ level.errors.pt }}
-          </td>
-          <td></td>
-        </tr>
-      </template>
-    </table>
-
-    <div class="text-center">
-      <Button
-        type="primary"
-        shape="circle"
-        @click="toSubmit"
-        style="width: 80px;"
-        :disabled="isSubmit"
-        >确定</Button
-      >
-    </div>
-  </div>
-</template>
-
-<script>
-import { workDetail, updateWork } from "@/api";
-import { LEVEL_TYPE } from "@/constants/enumerate";
-import schema from "async-validator";
-schema.warning = function() {};
-
-const initLevel = {
-  id: null,
-  workId: null,
-  code: null,
-  levelValue: 0,
-  maxScore: null,
-  minScore: null,
-  intervalScore: null,
-  weight: null,
-  levelType: "ADMITED",
-  scoreList: null,
-  pt: null,
-  kdpt: null
-};
-
-export default {
-  name: "grading-level-set",
-  data() {
-    return {
-      LEVEL_TYPE,
-      workId: this.$route.params.workId,
-      letterRelateNumber: {},
-      levels: [],
-      workDetail: {},
-      isSubmit: false
-    };
-  },
-  mounted() {
-    this.initData();
-  },
-  methods: {
-    initData() {
-      const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-      letters.split("").map((item, index) => {
-        this.letterRelateNumber[item] = index + 1;
-      });
-
-      this.getData();
-    },
-    async getData() {
-      const data = await workDetail(this.workId);
-      this.workDetail = data;
-      this.levels = data.levels.map(item => {
-        item.canEdit = false;
-        return item;
-      });
-    },
-    checkLevelCodeIsContinuous() {
-      let levelIsContinuous = true;
-      for (var i = 0, num = this.levels.length; i < num; i++) {
-        if (i > 0) {
-          const beforeCodeNum = this.letterRelateNumber[
-            this.levels[i - 1].code
-          ];
-          const curCodeNum = this.letterRelateNumber[this.levels[i].code];
-          levelIsContinuous =
-            levelIsContinuous && curCodeNum - beforeCodeNum === 1;
-
-          if (!levelIsContinuous) {
-            return false;
-          }
-        }
-      }
-
-      return true;
-    },
-    levelTypeChange(level) {
-      if (level.levelType === "ADMITED") {
-        level.scoreList = null;
-      } else {
-        level.intervalScore = null;
-      }
-    },
-    codeChange(level) {
-      level.code = level.code.toUpperCase();
-      this.levels.sort((a, b) => {
-        if (
-          !a.code ||
-          !b.code ||
-          !this.letterRelateNumber[a.code] ||
-          !this.letterRelateNumber[b.code]
-        )
-          return 0;
-
-        return (
-          this.letterRelateNumber[a.code] - this.letterRelateNumber[b.code]
-        );
-      });
-      this.checkLevelValidate(level);
-    },
-    getNextLevelCode() {
-      const codeNumbers = this.levels.map(
-        level => this.letterRelateNumber[level.code] || 0
-      );
-      const maxCodeNumber = Math.max.apply(null, codeNumbers);
-      const nextLevel = Object.entries(this.letterRelateNumber).find(
-        ([key, val]) => {
-          return maxCodeNumber < val;
-        }
-      );
-      return nextLevel ? nextLevel[0] : "";
-    },
-    toAdd() {
-      let level = { ...initLevel };
-      level.workId = this.workId;
-      level.code = this.getNextLevelCode();
-      this.levels.push(level);
-    },
-    toEdit(index) {
-      this.levels[index].canEdit = true;
-      this.$forceUpdate();
-    },
-    toDelete(index) {
-      this.levels.splice(index, 1);
-    },
-    checkLevelValidate(level) {
-      const descriptor = {
-        code: {
-          type: "string",
-          required: true,
-          pattern: /^[A-Z]{1}$/,
-          message: "请输入单个大写字母"
-        },
-        minScore: {
-          type: "number",
-          required: true,
-          message: "请输入最低分"
-        },
-        maxScore: {
-          type: "number",
-          required: true,
-          validator: (rule, value, callback) => {
-            if (!value || value < level.minScore) {
-              callback(new Error("最高分不得小于最低分"));
-            } else {
-              callback();
-            }
-          }
-        },
-        intervalScore: {
-          type: "number",
-          validator: (rule, value, callback) => {
-            if (level.levelType === "ADMITED" && !value) {
-              callback(new Error("请输入给分间隔"));
-            } else {
-              callback();
-            }
-          }
-        },
-        weight: {
-          type: "number",
-          required: true,
-          message: "请输入典型值"
-        },
-        scoreList: {
-          type: "string",
-          validator: (rule, value, callback) => {
-            if (level.levelType !== "UNADMIT") return callback();
-
-            if (level.levelType === "UNADMIT" && !value) {
-              return callback(new Error("请输入给分项"));
-            }
-            if (!value.match(/^[0-9,]+$/)) {
-              return callback(new Error("给分项只能包含数字和英文逗号"));
-            }
-            const unvalid = value
-              .split(",")
-              .filter(item => item)
-              .some(item => {
-                const num = item * 1;
-                return num < level.minScore || num > level.maxScore;
-              });
-            if (unvalid) {
-              return callback(
-                new Error("给分项包含的分值只能介于最低分和最高分之间")
-              );
-            }
-
-            callback();
-          }
-        },
-        pt: {
-          type: "number",
-          required: true,
-          message: "请输入占比阀值"
-        },
-        kdpt: {
-          type: "number",
-          required: true,
-          message: "请输入考区阀值"
-        }
-      };
-      return new schema(descriptor)
-        .validate(level)
-        .then(() => {
-          if (level.errors) level.errors = null;
-        })
-        .catch(({ errors, fields }) => {
-          let errorMsgs = {};
-          errors.map(error => {
-            errorMsgs[error.field] = error.message;
-          });
-          this.$set(level, "errors", errorMsgs);
-          return { errors };
-        });
-    },
-    async toSubmit() {
-      const validatorAll = this.levels.map(level =>
-        this.checkLevelValidate(level)
-      );
-      const result = await Promise.all(validatorAll);
-      const hasUnvalidate = result.some(item => !!item);
-
-      if (hasUnvalidate) return;
-
-      if (!this.checkLevelCodeIsContinuous()) {
-        this.$Message.error("请保持档位连续!");
-        return;
-      }
-
-      if (this.isSubmit) return;
-      this.isSubmit = true;
-      this.workDetail.levels = this.levels;
-      const data = await updateWork(this.workDetail).catch(() => {
-        this.isSubmit = false;
-      });
-
-      if (!data) return;
-
-      this.isSubmit = false;
-      this.getData();
-      this.$Message.success("保存成功!");
-    }
-  }
-};
-</script>
+<template>
+  <div class="grading-level-set">
+    <Button
+      class="level-add-btn"
+      type="success"
+      icon="recode-white icon"
+      shape="circle"
+      @click="toAdd"
+      >新增档位</Button
+    >
+    <table class="table table-noborder grading-table">
+      <tr>
+        <th>档位</th>
+        <th>最低分</th>
+        <th>最高分</th>
+        <th>给分间隔</th>
+        <th>典型值</th>
+        <th>类型</th>
+        <th>给分项</th>
+        <th>考区阈值%</th>
+        <th>占比阈值%</th>
+        <th>操作</th>
+      </tr>
+      <template v-for="(level, index) in levels">
+        <tr :key="index">
+          <td>
+            <Input
+              v-model="level.code"
+              style="width: 60px"
+              @on-blur="codeChange(level)"
+              v-if="level.canEdit && workDetail.modifyOtherVal"
+            ></Input>
+            <p v-else>{{ level.code }}</p>
+          </td>
+          <td>
+            <InputNumber
+              v-model="level.minScore"
+              :min="0"
+              :max="1000"
+              @on-blur="checkLevelValidate(level)"
+              v-if="level.canEdit && workDetail.modifyOtherVal"
+            ></InputNumber>
+            <p v-else>{{ level.minScore }}</p>
+          </td>
+          <td>
+            <InputNumber
+              v-model="level.maxScore"
+              :min="1"
+              :max="1000"
+              @on-blur="checkLevelValidate(level)"
+              v-if="level.canEdit && workDetail.modifyOtherVal"
+            ></InputNumber>
+            <p v-else>{{ level.maxScore }}</p>
+          </td>
+          <td style="min-width: 100px">
+            <InputNumber
+              v-model="level.intervalScore"
+              :min="1"
+              :max="100"
+              :precision="0"
+              :disabled="!level.canEdit"
+              @on-blur="checkLevelValidate(level)"
+              v-if="
+                level.levelType === 'ADMITED' &&
+                  level.canEdit &&
+                  workDetail.modifyOtherVal
+              "
+            ></InputNumber>
+            <p v-else>{{ level.intervalScore }}</p>
+          </td>
+          <td>
+            <InputNumber
+              v-model="level.weight"
+              :min="1"
+              :max="1000"
+              @on-blur="checkLevelValidate(level)"
+              v-if="level.canEdit && workDetail.modifyOtherVal"
+            ></InputNumber>
+            <p v-else>{{ level.weight }}</p>
+          </td>
+          <td>
+            <Select
+              v-model="level.levelType"
+              @on-change="levelTypeChange(level)"
+              style="width: 120px"
+              v-if="level.canEdit && workDetail.modifyOtherVal"
+            >
+              <Option
+                v-for="(val, key) in LEVEL_TYPE"
+                :key="key"
+                :value="key"
+                >{{ val }}</Option
+              >
+            </Select>
+            <p v-else>{{ LEVEL_TYPE[level.levelType] }}</p>
+          </td>
+          <td style="min-width: 140px">
+            <Input
+              v-model="level.scoreList"
+              @on-blur="checkLevelValidate(level)"
+              v-if="
+                level.levelType === 'UNADMIT' &&
+                  level.canEdit &&
+                  workDetail.modifyOtherVal
+              "
+            ></Input>
+            <p v-else>{{ level.scoreList }}</p>
+          </td>
+          <td>
+            <InputNumber
+              v-model="level.kdpt"
+              :min="1"
+              :max="100"
+              @on-blur="checkLevelValidate(level)"
+              v-if="level.canEdit"
+            ></InputNumber>
+            <p v-else>{{ level.kdpt }}</p>
+          </td>
+          <td>
+            <InputNumber
+              v-model="level.pt"
+              :min="1"
+              :max="100"
+              @on-blur="checkLevelValidate(level)"
+              v-if="level.canEdit"
+            ></InputNumber>
+            <p v-else>{{ level.pt }}</p>
+          </td>
+          <td class="table-action">
+            <div style="width: 60px">
+              <Icon type="md-create" title="编辑" @click="toEdit(index)" />
+              <Icon
+                class="icon-danger"
+                type="md-trash"
+                title="删除"
+                @click="toDelete(index)"
+                v-if="workDetail.modifyOtherVal"
+              />
+            </div>
+          </td>
+        </tr>
+        <tr class="tr-tips-error" v-if="level.errors" :key="index + '1'">
+          <td>
+            {{ level.errors.code }}
+          </td>
+          <td>
+            {{ level.errors.minScore }}
+          </td>
+          <td>
+            {{ level.errors.maxScore }}
+          </td>
+          <td>
+            {{ level.errors.intervalScore }}
+          </td>
+          <td>
+            {{ level.errors.weight }}
+          </td>
+          <td></td>
+          <td>
+            {{ level.errors.scoreList }}
+          </td>
+          <td>
+            {{ level.errors.kdpt }}
+          </td>
+          <td>
+            {{ level.errors.pt }}
+          </td>
+          <td></td>
+        </tr>
+      </template>
+    </table>
+
+    <div class="text-center">
+      <Button
+        type="primary"
+        shape="circle"
+        @click="toSubmit"
+        style="width: 80px;"
+        :disabled="isSubmit"
+        >确定</Button
+      >
+    </div>
+  </div>
+</template>
+
+<script>
+import { workDetail, updateWork } from "@/api";
+import { LEVEL_TYPE } from "@/constants/enumerate";
+import schema from "async-validator";
+schema.warning = function() {};
+
+const initLevel = {
+  id: null,
+  workId: null,
+  code: null,
+  levelValue: 0,
+  maxScore: null,
+  minScore: null,
+  intervalScore: null,
+  weight: null,
+  levelType: "ADMITED",
+  scoreList: null,
+  pt: null,
+  kdpt: null
+};
+
+export default {
+  name: "grading-level-set",
+  data() {
+    return {
+      LEVEL_TYPE,
+      workId: this.$route.params.workId,
+      letterRelateNumber: {},
+      levels: [],
+      workDetail: {},
+      isSubmit: false
+    };
+  },
+  mounted() {
+    this.initData();
+  },
+  methods: {
+    initData() {
+      const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+      letters.split("").map((item, index) => {
+        this.letterRelateNumber[item] = index + 1;
+      });
+
+      this.getData();
+    },
+    async getData() {
+      const data = await workDetail(this.workId);
+      this.workDetail = data;
+      this.levels = data.levels.map(item => {
+        item.canEdit = false;
+        return item;
+      });
+    },
+    checkLevelCodeIsContinuous() {
+      let levelIsContinuous = true;
+      for (var i = 0, num = this.levels.length; i < num; i++) {
+        if (i > 0) {
+          const beforeCodeNum = this.letterRelateNumber[
+            this.levels[i - 1].code
+          ];
+          const curCodeNum = this.letterRelateNumber[this.levels[i].code];
+          levelIsContinuous =
+            levelIsContinuous && curCodeNum - beforeCodeNum === 1;
+
+          if (!levelIsContinuous) {
+            return false;
+          }
+        }
+      }
+
+      return true;
+    },
+    levelTypeChange(level) {
+      if (level.levelType === "ADMITED") {
+        level.scoreList = null;
+      } else {
+        level.intervalScore = null;
+      }
+    },
+    codeChange(level) {
+      level.code = level.code.toUpperCase();
+      this.levels.sort((a, b) => {
+        if (
+          !a.code ||
+          !b.code ||
+          !this.letterRelateNumber[a.code] ||
+          !this.letterRelateNumber[b.code]
+        )
+          return 0;
+
+        return (
+          this.letterRelateNumber[a.code] - this.letterRelateNumber[b.code]
+        );
+      });
+      this.checkLevelValidate(level);
+    },
+    getNextLevelCode() {
+      const codeNumbers = this.levels.map(
+        level => this.letterRelateNumber[level.code] || 0
+      );
+      const maxCodeNumber = Math.max.apply(null, codeNumbers);
+      const nextLevel = Object.entries(this.letterRelateNumber).find(
+        ([key, val]) => {
+          return maxCodeNumber < val;
+        }
+      );
+      return nextLevel ? nextLevel[0] : "";
+    },
+    toAdd() {
+      let level = { ...initLevel };
+      level.workId = this.workId;
+      level.code = this.getNextLevelCode();
+      this.levels.push(level);
+    },
+    toEdit(index) {
+      this.levels[index].canEdit = true;
+      this.$forceUpdate();
+    },
+    toDelete(index) {
+      this.levels.splice(index, 1);
+    },
+    checkLevelValidate(level) {
+      const descriptor = {
+        code: {
+          type: "string",
+          required: true,
+          pattern: /^[A-Z]{1}$/,
+          message: "请输入单个大写字母"
+        },
+        minScore: {
+          type: "number",
+          required: true,
+          message: "请输入最低分"
+        },
+        maxScore: {
+          type: "number",
+          required: true,
+          validator: (rule, value, callback) => {
+            if (!value || value < level.minScore) {
+              callback(new Error("最高分不得小于最低分"));
+            } else {
+              callback();
+            }
+          }
+        },
+        intervalScore: {
+          type: "number",
+          validator: (rule, value, callback) => {
+            if (level.levelType === "ADMITED" && !value) {
+              callback(new Error("请输入给分间隔"));
+            } else {
+              callback();
+            }
+          }
+        },
+        weight: {
+          type: "number",
+          required: true,
+          message: "请输入典型值"
+        },
+        scoreList: {
+          type: "string",
+          validator: (rule, value, callback) => {
+            if (level.levelType !== "UNADMIT") return callback();
+
+            if (level.levelType === "UNADMIT" && !value) {
+              return callback(new Error("请输入给分项"));
+            }
+            if (!value.match(/^[0-9,]+$/)) {
+              return callback(new Error("给分项只能包含数字和英文逗号"));
+            }
+            const unvalid = value
+              .split(",")
+              .filter(item => item)
+              .some(item => {
+                const num = item * 1;
+                return num < level.minScore || num > level.maxScore;
+              });
+            if (unvalid) {
+              return callback(
+                new Error("给分项包含的分值只能介于最低分和最高分之间")
+              );
+            }
+
+            callback();
+          }
+        },
+        pt: {
+          type: "number",
+          required: true,
+          message: "请输入占比阀值"
+        },
+        kdpt: {
+          type: "number",
+          required: true,
+          message: "请输入考区阀值"
+        }
+      };
+      return new schema(descriptor)
+        .validate(level)
+        .then(() => {
+          if (level.errors) level.errors = null;
+        })
+        .catch(({ errors, fields }) => {
+          let errorMsgs = {};
+          errors.map(error => {
+            errorMsgs[error.field] = error.message;
+          });
+          this.$set(level, "errors", errorMsgs);
+          return { errors };
+        });
+    },
+    async toSubmit() {
+      const validatorAll = this.levels.map(level =>
+        this.checkLevelValidate(level)
+      );
+      const result = await Promise.all(validatorAll);
+      const hasUnvalidate = result.some(item => !!item);
+
+      if (hasUnvalidate) return;
+
+      if (!this.checkLevelCodeIsContinuous()) {
+        this.$Message.error("请保持档位连续!");
+        return;
+      }
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      this.workDetail.levels = this.levels;
+      const data = await updateWork(this.workDetail).catch(() => {
+        this.isSubmit = false;
+      });
+
+      if (!data) return;
+
+      this.isSubmit = false;
+      this.getData();
+      this.$Message.success("保存成功!");
+    }
+  }
+};
+</script>

+ 7 - 6
src/modules/grading/components/GradeAction.vue

@@ -98,7 +98,7 @@
     <!-- 跳过 -->
     <div
       class="action-grade-pass"
-      v-if="rights.gradeList && IS_MARKER"
+      v-if="rights.gradePass && IS_MARKER"
       @click="toPass"
     >
       跳过
@@ -217,6 +217,7 @@ const initRights = {
   search: false,
   gradeInfo: false,
   gradeList: false,
+  gradePass: false,
   gradeHis: false
 };
 
@@ -260,15 +261,15 @@ export default {
           arbitrate: ["search", "gradeHis"]
         },
         MARK_LEADER: {
-          undo: ["gradeList", "gradeInfo"],
+          undo: ["gradeList", "gradePass", "gradeInfo"],
           done: ["gradeList", "gradeHis", "gradeInfo"],
-          reject: ["gradeList", "gradeInfo", "gradeHis"],
-          arbitrate: ["gradeList", "gradeHis"]
+          reject: ["gradeList", "gradePass", "gradeInfo", "gradeHis"],
+          arbitrate: ["gradeList", "gradePass", "gradeHis"]
         },
         MARKER: {
           done: ["gradeList", "gradeInfo"],
-          undo: ["gradeList"],
-          reject: ["gradeList", "gradeInfo"]
+          undo: ["gradeList", "gradePass"],
+          reject: ["gradeList", "gradePass", "gradeInfo"]
         },
         STANDARD: ["gradeInfo"]
       },

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

@@ -281,7 +281,7 @@ export default {
       this.setCurSubject(curSubject || {});
     },
     async getList() {
-      this.multipleGradingList = [];
+      this.clearMultiplePaper();
 
       let data = {
         data: [],
@@ -435,6 +435,12 @@ export default {
       curPaper.selected = paper.selected;
       this.multipleGradingList = this.papers.filter(paper => paper.selected);
     },
+    clearMultiplePaper() {
+      this.multipleGradingList = [];
+      this.papers.forEach(paper => {
+        paper.selected = false;
+      });
+    },
     async multipleSelectLevel(level) {
       if (!this.multipleGradingList.length) return;
       if (this.multiplebtnClicked) return;
@@ -469,7 +475,7 @@ export default {
     // paper view action
     toReview(index) {
       this.isFullscreenMarking = true;
-      this.multipleGradingList = [];
+      this.clearMultiplePaper();
       this.selectPaper(index);
       this.$refs.SimpleImagePreview.open();
     },

+ 554 - 549
src/modules/grading/marker/MarkerGrading.vue

@@ -1,549 +1,554 @@
-<template>
-  <div class="marker-grading">
-    <marker-header
-      @area-change="areaChange"
-      @step-change="stepChange"
-      @page-set-change="pageSetChange"
-      @to-history="toHistory"
-      @to-standard="toStandard"
-      @to-statistics="toStatistics"
-    ></marker-header>
-
-    <div
-      :class="[
-        'marker-action',
-        { 'marker-action-fullscreen': isFullscreenMarking }
-      ]"
-      v-show="!multipleGradingList.length"
-    >
-      <grade-action
-        :cur-paper-or-task="curPaper"
-        :levels="levels"
-        :params-set="paramsSet"
-        :key="curPaper.key"
-        @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">
-        <div
-          v-for="(paper, index) in papers"
-          :key="paper.key"
-          :class="[
-            'marker-image-item',
-            {
-              'marker-image-item-act': curPaperIndex === index
-            }
-          ]"
-        >
-          <div class="marker-image-content">
-            <marker-image-view
-              :data="paper"
-              @to-review="toReview(index)"
-              @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>
-    <!-- MarkerStatistics -->
-    <marker-statistics ref="MarkerStatistics"></marker-statistics>
-    <!-- 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>
-
-<script>
-import { mapState, mapMutations } from "vuex";
-import MarkerHeader from "./MarkerHeader";
-import MarkerImageView from "./MarkerImageView";
-import MarkerHistory from "./MarkerHistory";
-import MarkerStandard from "./MarkerStandard";
-import MarkerStatistics from "./MarkerStatistics";
-import GradeAction from "../components/GradeAction";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-
-import {
-  markerTaskList,
-  markerLevelTotalStatData,
-  workLevelList,
-  paperSelectLevelOrScore,
-  paperSelectLevelBatch,
-  paperTaskPass,
-  getParamsSet
-} from "@/api";
-
-export default {
-  name: "marker-grading",
-  components: {
-    MarkerHeader,
-    MarkerImageView,
-    MarkerHistory,
-    MarkerStandard,
-    MarkerStatistics,
-    GradeAction,
-    SimpleImagePreview
-  },
-  data() {
-    return {
-      filter: {
-        markerId: this.$ls.get("user").id,
-        questionId: "",
-        sort: "randomSeq,asc",
-        stage: "LEVEL"
-      },
-      typeFilter: {
-        done: {
-          level: ""
-        },
-        undo: {},
-        reject: {
-          reject: true
-        }
-      },
-      workId: this.$route.params.workId,
-      subjectId: this.$route.params.subjectId,
-      subject: "",
-      workSubject: {},
-      curStandardGradeId: "",
-      levels: [],
-      papers: [],
-      curPaper: {},
-      curPaperIndex: 0,
-      // multiple grading
-      multiplebtnClicked: false,
-      multipleGradingList: [],
-      // carousel paper review,
-      carouselType: "",
-      carouselPapers: [],
-      curCarouselPaperIndex: 0,
-      isFullscreenMarking: false
-    };
-  },
-  computed: {
-    ...mapState("marker", ["paramsSet", "page", "steps", "curStep", "curArea"]),
-    markerImageListClasses() {
-      return ["marker-image-list", `marker-image-list-${this.page.size}`];
-    }
-  },
-  created() {
-    this.subject = this.subjectId.split("-")[1];
-    this.workSubject = {
-      workId: this.workId,
-      subject: this.subject
-    };
-    const curUserRoleType = this.$ls.get("user", { role: "" }).role;
-    this.setCurUserRoleType(curUserRoleType);
-    this.initData();
-  },
-  methods: {
-    ...mapMutations("marker", [
-      "setParamSet",
-      "setPage",
-      "setSteps",
-      "setCurArea",
-      "setCurStep",
-      "setCurUserRoleType",
-      "clearState"
-    ]),
-    async initData() {
-      await this.getParamsSetInfo();
-      await this.getWorkLevels();
-    },
-    async getParamsSetInfo() {
-      const data = await getParamsSet(this.workId);
-      this.setParamSet(data || {});
-    },
-    async getList() {
-      this.multipleGradingList = [];
-      const datas = {
-        ...this.filter,
-        ...this.typeFilter[this.curStep.type],
-        workId: this.workId,
-        page: this.page.current - 1,
-        size: this.page.size
-      };
-      if (this.curStep.type === "done") {
-        datas.level = this.curStep.name;
-        datas.sort = "updatedOn,desc";
-      }
-
-      const data = await markerTaskList(datas);
-      this.papers = data.data.map(paper => {
-        paper.key = this.$randomCode();
-        paper.title = `NO.${paper.sn}`;
-        paper.selected = false;
-        return paper;
-      });
-      this.setPage({
-        total: data.totalCount,
-        totalPage: data.pageCount
-      });
-    },
-    async toPage(page) {
-      this.setPage({
-        current: page
-      });
-      await this.getList();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async getStepLevels() {
-      const data = await markerLevelTotalStatData(
-        this.filter.markerId,
-        this.filter.questionId
-      );
-      const undoIndex = data.findIndex(item => item.id === null);
-      let otherStep = [];
-      let undo = {
-        count: 0,
-        rejected: 0
-      };
-      if (undoIndex !== -1) {
-        undo = { ...data[undoIndex] };
-        data.splice(undoIndex, 1);
-      }
-
-      otherStep.push({
-        name: "待评",
-        count: undo.count,
-        type: "undo"
-      });
-      otherStep.push({
-        name: "打回",
-        count: undo.rejected,
-        type: "reject"
-      });
-      let levelStep = data.map(item => {
-        // 评卷员不展示kdpt
-        item.kdpt = null;
-        return {
-          ...item,
-          name: item.id,
-          type: "done"
-        };
-      });
-      this.setSteps({ levelStep, otherStep });
-
-      if (!this.curStep.name) {
-        let curStep = {};
-        if (undoIndex === -1) {
-          curStep = levelStep[0];
-        } else {
-          const firstStep = otherStep.find(item => item.count);
-          curStep = firstStep || levelStep[0];
-        }
-        this.setCurStep(curStep);
-      } else {
-        const curStep = [...levelStep, ...otherStep].find(
-          item => item.name === this.curStep.name
-        );
-        this.setCurStep(curStep);
-      }
-    },
-    updateStepLevel(curStep, curLevel, count) {
-      if (curStep.type === "done") {
-        const lpos = this.steps.levelStep.findIndex(
-          item => item.name === curStep.name
-        );
-        this.steps.levelStep[lpos].count -= count;
-      } else {
-        const opos = this.steps.otherStep.findIndex(
-          item => item.type === curStep.type
-        );
-        this.steps.otherStep[opos].count -= count;
-      }
-
-      const pos = this.steps.levelStep.findIndex(
-        item => item.name === curLevel
-      );
-      this.steps.levelStep[pos].count += count;
-
-      this.steps.levelStep.forEach(item => {
-        item.percent =
-          item.finalKdTotal && item.count
-            ? ((100 * item.count) / item.finalKdTotal).toFixed(3)
-            : 0;
-      });
-      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
-        };
-      });
-    },
-    async pageSetChange() {
-      await this.getList();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async stepChange(step) {
-      this.setCurStep(step);
-      this.setPage({ current: 1 });
-      this.isFullscreenMarking = false;
-      await this.getList();
-      this.getStepLevels();
-      if (this.papers.length) {
-        this.selectPaper(0);
-      } else {
-        this.curPaper = {};
-      }
-    },
-    async areaChange(curArea) {
-      this.setCurArea(curArea);
-      this.filter.questionId = curArea.id;
-      await this.getStepLevels();
-      this.toPage(1);
-    },
-    // selectMultiplePaper
-    selectMultiplePaper(paper) {
-      if (paper.sample) return;
-      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;
-      if (this.multiplebtnClicked) return;
-      this.multiplebtnClicked = true;
-      const multipleGradingListCount = this.multipleGradingList.length;
-
-      let result = true;
-      await paperSelectLevelBatch(
-        this.multipleGradingList.map(item => item.id).join(), // is taskId
-        level.name,
-        "LEVEL"
-      ).catch(() => {
-        result = false;
-      });
-
-      this.multiplebtnClicked = false;
-      if (!result) return;
-
-      this.multipleGradingList = [];
-      // this.getStepLevels();
-      this.updateStepLevel(this.curStep, level.name, multipleGradingListCount);
-
-      // update paper list
-      if (
-        this.page.current > 1 &&
-        this.page.current === this.page.totalPage &&
-        this.papers.length === multipleGradingListCount
-      ) {
-        this.setPage({ current: this.page.current - 1 });
-      }
-
-      await this.getList();
-      this.selectPaper(this.curPaperIndex);
-    },
-    // paper view action
-    toReview(index) {
-      this.isFullscreenMarking = true;
-      this.multipleGradingList = [];
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        if (this.page.current > 1) {
-          this.setPage({ current: this.page.current - 1 });
-          this.curPaperIndex = this.page.size - 1;
-          await this.getList();
-        } else {
-          this.$Message.warning("当前已经是第一条数据了");
-          return;
-        }
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        if (this.page.current === this.page.totalPage) {
-          this.$Message.warning("当前已经是最后一条数据了");
-          return;
-        } else {
-          this.setPage({ current: this.page.current + 1 });
-          this.curPaperIndex = 0;
-          await this.getList();
-        }
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toActionNextPaper() {
-      if (this.page.current > 1 && this.papers.length === 1) {
-        this.setPage({ current: this.page.current - 1 });
-        this.curPaperIndex = this.page.size;
-      }
-
-      await this.getList();
-      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async gradeCurPaper(level) {
-      const paper = await paperSelectLevelOrScore(
-        this.curPaper.id, // is taskId
-        level.name,
-        "LEVEL"
-      );
-      if (!paper) return;
-      this.updateStepLevel(this.curStep, level.name, 1);
-      this.toActionNextPaper();
-    },
-    async passCurPaper() {
-      await paperTaskPass(this.curPaper.id);
-      this.toActionNextPaper();
-    },
-    // paper carousel
-    toViewCarouselPaper(paperIndex, papers, type) {
-      this.carouselType = type;
-      this.isFullscreenMarking = true;
-      this.carouselPapers = papers;
-      this.selectCarouselPaper(paperIndex);
-      this.$nextTick(() => {
-        this.$refs.CarouselPapersPreview.open();
-      });
-    },
-    selectCarouselPaper(index) {
-      this.curCarouselPaperIndex = index;
-      this.curPaper = { ...this.carouselPapers[index] };
-    },
-    toCarousePaper(type) {
-      // if (this.carouselType === "sample") {
-      //   this.toSampleCarousePaper(type);
-      //   return;
-      // }
-      if (type === "prev" && this.curCarouselPaperIndex > 0) {
-        this.curCarouselPaperIndex--;
-      } else if (
-        type === "next" &&
-        this.curCarouselPaperIndex < this.carouselPapers.length - 1
-      ) {
-        this.curCarouselPaperIndex++;
-      }
-      this.selectCarouselPaper(this.curCarouselPaperIndex);
-    },
-    toSampleCarousePaper(type) {
-      if (type === "prev") {
-        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleLeft();
-      } else if (type === "next") {
-        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleRight();
-      }
-    },
-    carouseImagePreviewClose() {
-      this.isFullscreenMarking = false;
-      this.carouselType = "";
-      this.selectPaper(this.curPaperIndex);
-    },
-    // header
-    toHistory() {
-      this.$refs.MarkerHistory.open();
-    },
-    toStandard() {
-      this.$refs.MarkerStandard.open();
-    },
-    toStatistics() {
-      this.$refs.MarkerStatistics.open();
-    }
-  },
-  beforeDestroy() {
-    this.clearState();
-  }
-};
-</script>
+<template>
+  <div class="marker-grading">
+    <marker-header
+      @area-change="areaChange"
+      @step-change="stepChange"
+      @page-set-change="pageSetChange"
+      @to-history="toHistory"
+      @to-standard="toStandard"
+      @to-statistics="toStatistics"
+    ></marker-header>
+
+    <div
+      :class="[
+        'marker-action',
+        { 'marker-action-fullscreen': isFullscreenMarking }
+      ]"
+      v-show="!multipleGradingList.length"
+    >
+      <grade-action
+        :cur-paper-or-task="curPaper"
+        :levels="levels"
+        :params-set="paramsSet"
+        :key="curPaper.key"
+        @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">
+        <div
+          v-for="(paper, index) in papers"
+          :key="paper.key"
+          :class="[
+            'marker-image-item',
+            {
+              'marker-image-item-act': curPaperIndex === index
+            }
+          ]"
+        >
+          <div class="marker-image-content">
+            <marker-image-view
+              :data="paper"
+              @to-review="toReview(index)"
+              @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>
+    <!-- MarkerStatistics -->
+    <marker-statistics ref="MarkerStatistics"></marker-statistics>
+    <!-- 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>
+
+<script>
+import { mapState, mapMutations } from "vuex";
+import MarkerHeader from "./MarkerHeader";
+import MarkerImageView from "./MarkerImageView";
+import MarkerHistory from "./MarkerHistory";
+import MarkerStandard from "./MarkerStandard";
+import MarkerStatistics from "./MarkerStatistics";
+import GradeAction from "../components/GradeAction";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+
+import {
+  markerTaskList,
+  markerLevelTotalStatData,
+  workLevelList,
+  paperSelectLevelOrScore,
+  paperSelectLevelBatch,
+  paperTaskPass,
+  getParamsSet
+} from "@/api";
+
+export default {
+  name: "marker-grading",
+  components: {
+    MarkerHeader,
+    MarkerImageView,
+    MarkerHistory,
+    MarkerStandard,
+    MarkerStatistics,
+    GradeAction,
+    SimpleImagePreview
+  },
+  data() {
+    return {
+      filter: {
+        markerId: this.$ls.get("user").id,
+        questionId: "",
+        sort: "randomSeq,asc",
+        stage: "LEVEL"
+      },
+      typeFilter: {
+        done: {
+          level: ""
+        },
+        undo: {},
+        reject: {
+          reject: true
+        }
+      },
+      workId: this.$route.params.workId,
+      subjectId: this.$route.params.subjectId,
+      subject: "",
+      workSubject: {},
+      curStandardGradeId: "",
+      levels: [],
+      papers: [],
+      curPaper: {},
+      curPaperIndex: 0,
+      // multiple grading
+      multiplebtnClicked: false,
+      multipleGradingList: [],
+      // carousel paper review,
+      carouselType: "",
+      carouselPapers: [],
+      curCarouselPaperIndex: 0,
+      isFullscreenMarking: false
+    };
+  },
+  computed: {
+    ...mapState("marker", ["paramsSet", "page", "steps", "curStep", "curArea"]),
+    markerImageListClasses() {
+      return ["marker-image-list", `marker-image-list-${this.page.size}`];
+    }
+  },
+  created() {
+    this.subject = this.subjectId.split("-")[1];
+    this.workSubject = {
+      workId: this.workId,
+      subject: this.subject
+    };
+    const curUserRoleType = this.$ls.get("user", { role: "" }).role;
+    this.setCurUserRoleType(curUserRoleType);
+    this.initData();
+  },
+  methods: {
+    ...mapMutations("marker", [
+      "setParamSet",
+      "setPage",
+      "setSteps",
+      "setCurArea",
+      "setCurStep",
+      "setCurUserRoleType",
+      "clearState"
+    ]),
+    async initData() {
+      await this.getParamsSetInfo();
+      await this.getWorkLevels();
+    },
+    async getParamsSetInfo() {
+      const data = await getParamsSet(this.workId);
+      this.setParamSet(data || {});
+    },
+    async getList() {
+      this.clearMultiplePaper();
+      const datas = {
+        ...this.filter,
+        ...this.typeFilter[this.curStep.type],
+        workId: this.workId,
+        page: this.page.current - 1,
+        size: this.page.size
+      };
+      if (this.curStep.type === "done") {
+        datas.level = this.curStep.name;
+        datas.sort = "updatedOn,desc";
+      }
+
+      const data = await markerTaskList(datas);
+      this.papers = data.data.map(paper => {
+        paper.key = this.$randomCode();
+        paper.title = `NO.${paper.sn}`;
+        paper.selected = false;
+        return paper;
+      });
+      this.setPage({
+        total: data.totalCount,
+        totalPage: data.pageCount
+      });
+    },
+    async toPage(page) {
+      this.setPage({
+        current: page
+      });
+      await this.getList();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async getStepLevels() {
+      const data = await markerLevelTotalStatData(
+        this.filter.markerId,
+        this.filter.questionId
+      );
+      const undoIndex = data.findIndex(item => item.id === null);
+      let otherStep = [];
+      let undo = {
+        count: 0,
+        rejected: 0
+      };
+      if (undoIndex !== -1) {
+        undo = { ...data[undoIndex] };
+        data.splice(undoIndex, 1);
+      }
+
+      otherStep.push({
+        name: "待评",
+        count: undo.count,
+        type: "undo"
+      });
+      otherStep.push({
+        name: "打回",
+        count: undo.rejected,
+        type: "reject"
+      });
+      let levelStep = data.map(item => {
+        // 评卷员不展示kdpt
+        item.kdpt = null;
+        return {
+          ...item,
+          name: item.id,
+          type: "done"
+        };
+      });
+      this.setSteps({ levelStep, otherStep });
+
+      if (!this.curStep.name) {
+        let curStep = {};
+        if (undoIndex === -1) {
+          curStep = levelStep[0];
+        } else {
+          const firstStep = otherStep.find(item => item.count);
+          curStep = firstStep || levelStep[0];
+        }
+        this.setCurStep(curStep);
+      } else {
+        const curStep = [...levelStep, ...otherStep].find(
+          item => item.name === this.curStep.name
+        );
+        this.setCurStep(curStep);
+      }
+    },
+    updateStepLevel(curStep, curLevel, count) {
+      if (curStep.type === "done") {
+        const lpos = this.steps.levelStep.findIndex(
+          item => item.name === curStep.name
+        );
+        this.steps.levelStep[lpos].count -= count;
+      } else {
+        const opos = this.steps.otherStep.findIndex(
+          item => item.type === curStep.type
+        );
+        this.steps.otherStep[opos].count -= count;
+      }
+
+      const pos = this.steps.levelStep.findIndex(
+        item => item.name === curLevel
+      );
+      this.steps.levelStep[pos].count += count;
+
+      this.steps.levelStep.forEach(item => {
+        item.percent =
+          item.finalKdTotal && item.count
+            ? ((100 * item.count) / item.finalKdTotal).toFixed(3)
+            : 0;
+      });
+      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
+        };
+      });
+    },
+    async pageSetChange() {
+      await this.getList();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async stepChange(step) {
+      this.setCurStep(step);
+      this.setPage({ current: 1 });
+      this.isFullscreenMarking = false;
+      await this.getList();
+      this.getStepLevels();
+      if (this.papers.length) {
+        this.selectPaper(0);
+      } else {
+        this.curPaper = {};
+      }
+    },
+    async areaChange(curArea) {
+      this.setCurArea(curArea);
+      this.filter.questionId = curArea.id;
+      await this.getStepLevels();
+      this.toPage(1);
+    },
+    // selectMultiplePaper
+    selectMultiplePaper(paper) {
+      if (paper.sample) return;
+      const curPaper = this.papers.find(p => p.id === paper.id);
+      curPaper.selected = paper.selected;
+      this.multipleGradingList = this.papers.filter(paper => paper.selected);
+    },
+    clearMultiplePaper() {
+      this.multipleGradingList = [];
+      this.papers.forEach(paper => {
+        paper.selected = false;
+      });
+    },
+    async multipleSelectLevel(level) {
+      if (!this.multipleGradingList.length) return;
+      if (this.multiplebtnClicked) return;
+      this.multiplebtnClicked = true;
+      const multipleGradingListCount = this.multipleGradingList.length;
+
+      let result = true;
+      await paperSelectLevelBatch(
+        this.multipleGradingList.map(item => item.id).join(), // is taskId
+        level.name,
+        "LEVEL"
+      ).catch(() => {
+        result = false;
+      });
+
+      this.multiplebtnClicked = false;
+      if (!result) return;
+
+      this.multipleGradingList = [];
+      // this.getStepLevels();
+      this.updateStepLevel(this.curStep, level.name, multipleGradingListCount);
+
+      // update paper list
+      if (
+        this.page.current > 1 &&
+        this.page.current === this.page.totalPage &&
+        this.papers.length === multipleGradingListCount
+      ) {
+        this.setPage({ current: this.page.current - 1 });
+      }
+
+      await this.getList();
+      this.selectPaper(this.curPaperIndex);
+    },
+    // paper view action
+    toReview(index) {
+      this.isFullscreenMarking = true;
+      this.clearMultiplePaper();
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        if (this.page.current > 1) {
+          this.setPage({ current: this.page.current - 1 });
+          this.curPaperIndex = this.page.size - 1;
+          await this.getList();
+        } else {
+          this.$Message.warning("当前已经是第一条数据了");
+          return;
+        }
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        if (this.page.current === this.page.totalPage) {
+          this.$Message.warning("当前已经是最后一条数据了");
+          return;
+        } else {
+          this.setPage({ current: this.page.current + 1 });
+          this.curPaperIndex = 0;
+          await this.getList();
+        }
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toActionNextPaper() {
+      if (this.page.current > 1 && this.papers.length === 1) {
+        this.setPage({ current: this.page.current - 1 });
+        this.curPaperIndex = this.page.size;
+      }
+
+      await this.getList();
+      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async gradeCurPaper(level) {
+      const paper = await paperSelectLevelOrScore(
+        this.curPaper.id, // is taskId
+        level.name,
+        "LEVEL"
+      );
+      if (!paper) return;
+      this.updateStepLevel(this.curStep, level.name, 1);
+      this.toActionNextPaper();
+    },
+    async passCurPaper() {
+      await paperTaskPass(this.curPaper.id);
+      this.toActionNextPaper();
+    },
+    // paper carousel
+    toViewCarouselPaper(paperIndex, papers, type) {
+      this.carouselType = type;
+      this.isFullscreenMarking = true;
+      this.carouselPapers = papers;
+      this.selectCarouselPaper(paperIndex);
+      this.$nextTick(() => {
+        this.$refs.CarouselPapersPreview.open();
+      });
+    },
+    selectCarouselPaper(index) {
+      this.curCarouselPaperIndex = index;
+      this.curPaper = { ...this.carouselPapers[index] };
+    },
+    toCarousePaper(type) {
+      // if (this.carouselType === "sample") {
+      //   this.toSampleCarousePaper(type);
+      //   return;
+      // }
+      if (type === "prev" && this.curCarouselPaperIndex > 0) {
+        this.curCarouselPaperIndex--;
+      } else if (
+        type === "next" &&
+        this.curCarouselPaperIndex < this.carouselPapers.length - 1
+      ) {
+        this.curCarouselPaperIndex++;
+      }
+      this.selectCarouselPaper(this.curCarouselPaperIndex);
+    },
+    toSampleCarousePaper(type) {
+      if (type === "prev") {
+        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleLeft();
+      } else if (type === "next") {
+        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleRight();
+      }
+    },
+    carouseImagePreviewClose() {
+      this.isFullscreenMarking = false;
+      this.carouselType = "";
+      this.selectPaper(this.curPaperIndex);
+    },
+    // header
+    toHistory() {
+      this.$refs.MarkerHistory.open();
+    },
+    toStandard() {
+      this.$refs.MarkerStandard.open();
+    },
+    toStatistics() {
+      this.$refs.MarkerStatistics.open();
+    }
+  },
+  beforeDestroy() {
+    this.clearState();
+  }
+};
+</script>

+ 3 - 1
src/modules/grading/marker/MarkerHistory.vue

@@ -21,7 +21,9 @@
               </div>
               <div class="image-action-name">{{ paper.actionName }}</div>
             </div>
-            <div class="image-sn">NO.{{ paper.sn }}</div>
+            <div class="image-sn" :title="'NO.' + paper.sn">
+              NO.{{ paper.sn }}
+            </div>
           </marker-image-view>
         </div>
       </div>

+ 20 - 5
src/modules/grading/marker/MarkerImageView.vue

@@ -22,14 +22,19 @@
           >
             <Icon v-if="image.selected" type="md-checkmark" />
           </div>
-          <div class="image-title" @click="toSelect">
-            {{ image.title }}
-          </div>
         </div>
         <div v-else class="image-info">
           <div v-if="image.level" class="image-level">{{ image.level }}</div>
           <div v-if="image.score" class="image-level">{{ image.score }}</div>
         </div>
+        <div
+          v-if="IS_LEVEL"
+          class="image-title"
+          :title="image.title"
+          @click="toSelect"
+        >
+          {{ image.title }}
+        </div>
         <div class="image-action">
           <div class="image-action-li" @click="toMark">
             <Icon :class="{ 'mark-act': image.mark }" type="md-bookmark" />
@@ -72,7 +77,14 @@ export default {
     }
   },
   created() {
-    this.image = this.$objAssign(this.initImage, this.data);
+    this.initData();
+  },
+  watch: {
+    "data.selected": {
+      handler() {
+        this.initData();
+      }
+    }
   },
   data() {
     return {
@@ -92,6 +104,9 @@ export default {
     };
   },
   methods: {
+    initData() {
+      this.image = this.$objAssign(this.initImage, this.data);
+    },
     toReview() {
       this.$emit("to-review", this.data);
     },
@@ -114,7 +129,7 @@ export default {
       this.image.mark = !this.image.mark;
     },
     toSelect() {
-      if (this.image.sample) return;
+      if (this.image.sample || !this.IS_LEVEL) return;
       this.image.selected = !this.image.selected;
       this.$emit("to-select", this.image);
     },

+ 244 - 242
src/modules/grading/marker/MarkerStandard.vue

@@ -1,242 +1,244 @@
-<template>
-  <Modal
-    v-model="modalIsShow"
-    class="marker-standard marker-modal"
-    title="标准卷"
-    footer-hide
-    fullscreen
-    @on-visible-change="visibleChange"
-  >
-    <div class="level-list">
-      <div
-        v-for="(level, index) in levels"
-        :key="index"
-        :class="['level-item', { 'level-item-act': curLevel === level.name }]"
-        @click="setCurLevel(level.name)"
-      >
-        {{ level.name }}
-      </div>
-      <div
-        :class="['level-item', { 'level-item-act': !curLevel }]"
-        @click="setCurLevel('')"
-      >
-        全部
-      </div>
-    </div>
-
-    <div class="standard-image-list marker-image-list" v-if="papers.length">
-      <div
-        v-for="(paper, index) in papers"
-        :key="paper.id"
-        class="marker-image-item"
-      >
-        <div class="marker-image-content">
-          <marker-image-view :data="paper" @to-review="toReview(index)">
-            <div class="image-info">
-              <div class="image-level">
-                {{ paper.level }}
-              </div>
-              <div class="image-title">{{ paper.title }}</div>
-            </div>
-            <div v-if="IS_MARK_LEADER" class="image-action">
-              <Button
-                type="error"
-                size="small"
-                icon="md-trash"
-                :disabled="paper.loading"
-                @click="cancelPaper(paper)"
-              ></Button>
-              <Button
-                type="primary"
-                size="small"
-                icon="md-create"
-                @click="toChangePaper(paper)"
-              ></Button>
-            </div>
-          </marker-image-view>
-        </div>
-      </div>
-    </div>
-    <div v-else class="standard-image-none">
-      <p>暂无数据</p>
-    </div>
-
-    <!-- change-standard -->
-    <Modal
-      class="change-standard marker-modal"
-      v-model="levelModalIsShow"
-      title="修改标准卷"
-      width="400px"
-      :mask-closable="false"
-    >
-      <div class="level-list">
-        <p
-          v-for="level in levels"
-          :key="level.name"
-          :class="[
-            'level-item',
-            {
-              'level-item-act': level.name === curSelectLevel,
-              'level-item-disabled': level.name === curChangePaper.level
-            }
-          ]"
-          @click="selectLevel(level.name)"
-        >
-          {{ level.name }}
-        </p>
-      </div>
-
-      <div slot="footer">
-        <Button
-          type="primary"
-          size="small"
-          :disabled="isSubmit || !curSelectLevel"
-          @click="confirmChange"
-          >确认</Button
-        >
-        <Button size="small" @click="cancelChange">取消</Button>
-      </div>
-    </Modal>
-  </Modal>
-</template>
-
-<script>
-import { mapState } from "vuex";
-import { paperList, cancelStandardPaper, leaderGradingPaper } from "@/api";
-import MarkerImageView from "./MarkerImageView";
-
-export default {
-  name: "marker-standard",
-  props: {
-    questionId: {
-      type: [Number, String]
-    },
-    levels: {
-      type: Array,
-      default() {
-        return [];
-      }
-    }
-  },
-  components: { MarkerImageView },
-  data() {
-    return {
-      modalIsShow: false,
-      curLevel: "",
-      paperList: [],
-      papers: [],
-      // change standard
-      levelModalIsShow: false,
-      curChangePaper: {},
-      curSelectLevel: null,
-      isSubmit: false
-    };
-  },
-  watch: {
-    questionId(val, oldval) {
-      if (val !== oldval) this.getPaperList();
-    }
-  },
-  computed: {
-    ...mapState("marker", ["IS_MARK_LEADER"])
-  },
-  methods: {
-    visibleChange(visible) {
-      if (!visible) return;
-
-      this.getPaperList();
-    },
-    async getPaperList() {
-      const datas = {
-        questionId: this.questionId,
-        level: "",
-        sort: "secretNumber",
-        isSample: true,
-        page: 0,
-        size: 1000
-      };
-      const data = await paperList(datas).catch(() => {});
-      if (!data) return;
-      this.paperList = data.data.map(item => {
-        item.title = `NO.${item.sn}`;
-        item.loading = false;
-        return item;
-      });
-      this.paperList.sort((a, b) => (a.level < b.level ? -1 : 1));
-
-      this.updatePapers();
-    },
-    updatePapers() {
-      if (this.curLevel) {
-        this.papers = this.paperList.filter(
-          paper => paper.level === this.curLevel
-        );
-      } else {
-        this.papers = this.paperList;
-      }
-    },
-    setCurLevel(levelName) {
-      this.curLevel = levelName;
-      this.updatePapers();
-    },
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    },
-    toReview(index) {
-      this.$emit("on-paper-click", index, this.papers);
-    },
-    cancelPaper(paper) {
-      if (paper.loading) return;
-      this.$Modal.confirm({
-        content: "确定要取消当前标准卷吗?",
-        onOk: async () => {
-          paper.loading = true;
-          const res = await cancelStandardPaper(paper.id).catch(() => {});
-          paper.loading = false;
-          if (!res) return;
-          this.getPaperList();
-        }
-      });
-    },
-    // change standard paper
-    toChangePaper(paper) {
-      this.curChangePaper = paper;
-      this.levelModalIsShow = true;
-    },
-    selectLevel(levelName) {
-      if (levelName === this.curChangePaper.level) return;
-      this.curSelectLevel = levelName;
-    },
-    async confirmChange() {
-      if (!this.curSelectLevel) return;
-      if (this.isSubmit) return;
-
-      this.isSubmit = true;
-      const datas = {
-        action: "sampling",
-        level: this.curSelectLevel,
-        originLevel: this.curChangePaper.level,
-        paperIds: this.curChangePaper.id
-      };
-      let result = true;
-      await leaderGradingPaper(datas).catch(() => {
-        result = false;
-      });
-      this.isSubmit = false;
-
-      if (!result) return;
-
-      this.$Message.success("操作成功!");
-      this.getPaperList();
-      this.cancelChange();
-    },
-    cancelChange() {
-      this.curSelectLevel = null;
-      this.levelModalIsShow = false;
-    }
-  }
-};
-</script>
+<template>
+  <Modal
+    v-model="modalIsShow"
+    class="marker-standard marker-modal"
+    title="标准卷"
+    footer-hide
+    fullscreen
+    @on-visible-change="visibleChange"
+  >
+    <div class="level-list">
+      <div
+        v-for="(level, index) in levels"
+        :key="index"
+        :class="['level-item', { 'level-item-act': curLevel === level.name }]"
+        @click="setCurLevel(level.name)"
+      >
+        {{ level.name }}
+      </div>
+      <div
+        :class="['level-item', { 'level-item-act': !curLevel }]"
+        @click="setCurLevel('')"
+      >
+        全部
+      </div>
+    </div>
+
+    <div class="standard-image-list marker-image-list" v-if="papers.length">
+      <div
+        v-for="(paper, index) in papers"
+        :key="paper.id"
+        class="marker-image-item"
+      >
+        <div class="marker-image-content">
+          <marker-image-view :data="paper" @to-review="toReview(index)">
+            <div class="image-info">
+              <div class="image-level">
+                {{ paper.level }}
+              </div>
+            </div>
+            <div class="image-title" :title="paper.title">
+              {{ paper.title }}
+            </div>
+            <div v-if="IS_MARK_LEADER" class="image-action">
+              <Button
+                type="error"
+                size="small"
+                icon="md-trash"
+                :disabled="paper.loading"
+                @click="cancelPaper(paper)"
+              ></Button>
+              <Button
+                type="primary"
+                size="small"
+                icon="md-create"
+                @click="toChangePaper(paper)"
+              ></Button>
+            </div>
+          </marker-image-view>
+        </div>
+      </div>
+    </div>
+    <div v-else class="standard-image-none">
+      <p>暂无数据</p>
+    </div>
+
+    <!-- change-standard -->
+    <Modal
+      class="change-standard marker-modal"
+      v-model="levelModalIsShow"
+      title="修改标准卷"
+      width="400px"
+      :mask-closable="false"
+    >
+      <div class="level-list">
+        <p
+          v-for="level in levels"
+          :key="level.name"
+          :class="[
+            'level-item',
+            {
+              'level-item-act': level.name === curSelectLevel,
+              'level-item-disabled': level.name === curChangePaper.level
+            }
+          ]"
+          @click="selectLevel(level.name)"
+        >
+          {{ level.name }}
+        </p>
+      </div>
+
+      <div slot="footer">
+        <Button
+          type="primary"
+          size="small"
+          :disabled="isSubmit || !curSelectLevel"
+          @click="confirmChange"
+          >确认</Button
+        >
+        <Button size="small" @click="cancelChange">取消</Button>
+      </div>
+    </Modal>
+  </Modal>
+</template>
+
+<script>
+import { mapState } from "vuex";
+import { paperList, cancelStandardPaper, leaderGradingPaper } from "@/api";
+import MarkerImageView from "./MarkerImageView";
+
+export default {
+  name: "marker-standard",
+  props: {
+    questionId: {
+      type: [Number, String]
+    },
+    levels: {
+      type: Array,
+      default() {
+        return [];
+      }
+    }
+  },
+  components: { MarkerImageView },
+  data() {
+    return {
+      modalIsShow: false,
+      curLevel: "",
+      paperList: [],
+      papers: [],
+      // change standard
+      levelModalIsShow: false,
+      curChangePaper: {},
+      curSelectLevel: null,
+      isSubmit: false
+    };
+  },
+  watch: {
+    questionId(val, oldval) {
+      if (val !== oldval) this.getPaperList();
+    }
+  },
+  computed: {
+    ...mapState("marker", ["IS_MARK_LEADER"])
+  },
+  methods: {
+    visibleChange(visible) {
+      if (!visible) return;
+
+      this.getPaperList();
+    },
+    async getPaperList() {
+      const datas = {
+        questionId: this.questionId,
+        level: "",
+        sort: "secretNumber",
+        isSample: true,
+        page: 0,
+        size: 1000
+      };
+      const data = await paperList(datas).catch(() => {});
+      if (!data) return;
+      this.paperList = data.data.map(item => {
+        item.title = `NO.${item.sn}`;
+        item.loading = false;
+        return item;
+      });
+      this.paperList.sort((a, b) => (a.level < b.level ? -1 : 1));
+
+      this.updatePapers();
+    },
+    updatePapers() {
+      if (this.curLevel) {
+        this.papers = this.paperList.filter(
+          paper => paper.level === this.curLevel
+        );
+      } else {
+        this.papers = this.paperList;
+      }
+    },
+    setCurLevel(levelName) {
+      this.curLevel = levelName;
+      this.updatePapers();
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    toReview(index) {
+      this.$emit("on-paper-click", index, this.papers);
+    },
+    cancelPaper(paper) {
+      if (paper.loading) return;
+      this.$Modal.confirm({
+        content: "确定要取消当前标准卷吗?",
+        onOk: async () => {
+          paper.loading = true;
+          const res = await cancelStandardPaper(paper.id).catch(() => {});
+          paper.loading = false;
+          if (!res) return;
+          this.getPaperList();
+        }
+      });
+    },
+    // change standard paper
+    toChangePaper(paper) {
+      this.curChangePaper = paper;
+      this.levelModalIsShow = true;
+    },
+    selectLevel(levelName) {
+      if (levelName === this.curChangePaper.level) return;
+      this.curSelectLevel = levelName;
+    },
+    async confirmChange() {
+      if (!this.curSelectLevel) return;
+      if (this.isSubmit) return;
+
+      this.isSubmit = true;
+      const datas = {
+        action: "sampling",
+        level: this.curSelectLevel,
+        originLevel: this.curChangePaper.level,
+        paperIds: this.curChangePaper.id
+      };
+      let result = true;
+      await leaderGradingPaper(datas).catch(() => {
+        result = false;
+      });
+      this.isSubmit = false;
+
+      if (!result) return;
+
+      this.$Message.success("操作成功!");
+      this.getPaperList();
+      this.cancelChange();
+    },
+    cancelChange() {
+      this.curSelectLevel = null;
+      this.levelModalIsShow = false;
+    }
+  }
+};
+</script>

+ 346 - 346
src/modules/inspection/InspectionGrading.vue

@@ -1,346 +1,346 @@
-<template>
-  <div class="inspection-grading page-container-flex">
-    <div class="part-box part-box-filter">
-      <Form ref="FilterForm" label-position="left" inline>
-        <FormItem>
-          <Select
-            v-model="filter.workId"
-            @on-change="workChange"
-            placeholder="工作文件夹"
-            style="width: 150px"
-          >
-            <Option
-              v-for="(work, windex) in works"
-              :key="windex"
-              :value="work.id"
-              :label="work.name"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select
-            v-model="filter.subject"
-            @on-change="subjectChange"
-            placeholder="科目"
-          >
-            <Option
-              v-for="subject in subjects"
-              :key="subject.id"
-              :value="subject.subject"
-              :label="subject.name"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.questionId" placeholder="考区">
-            <Option
-              v-for="area in areas"
-              :key="area.id"
-              :value="area.id"
-              :label="area.areaName"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select
-            v-model="filter.status"
-            placeholder="类型"
-            clearable
-            style="width: 120px"
-          >
-            <Option
-              v-for="(val, key) in CHANGE_LEVEL_STATUS"
-              :key="key"
-              :value="key * 1"
-              :label="val"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Button
-            type="primary"
-            class="btn-form-search"
-            size="small"
-            @click="toPage(1)"
-            >查询</Button
-          >
-        </FormItem>
-      </Form>
-    </div>
-
-    <div class="check-grade" v-if="papers.length">
-      <!-- paper-list -->
-      <div class="check-grade-body part-box">
-        <div class="check-grade-list image-view-list image-view-list-4">
-          <div
-            :class="[
-              'image-view',
-              { 'image-view-act': curPaperIndex === index }
-            ]"
-            v-for="(image, index) in papers"
-            :key="index"
-          >
-            <div class="image-view-container">
-              <h5 class="image-view-title">{{ image.title }}</h5>
-              <div class="image-view-contain">
-                <img
-                  :src="image.thumbSrc"
-                  :alt="image.title"
-                  @click="toReview(index)"
-                />
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="part-page" v-if="total > size">
-          <Page
-            :current="current"
-            :total="total"
-            :page-size="size"
-            show-total
-            show-elevator
-            @on-change="toPage"
-          ></Page>
-        </div>
-      </div>
-      <!-- action -->
-      <div
-        :class="[
-          'check-grade-action',
-          { 'check-grade-action-fullscreen': isFullscreenMarking }
-        ]"
-        v-if="curPaper.id"
-      >
-        <div class="action-paper-info">
-          <p>
-            <span>试卷考号:</span><span>{{ curPaper.examNumber }}</span>
-          </p>
-          <p>
-            <span>试卷密号:</span><span>NO.{{ curPaper.sn }}</span>
-          </p>
-        </div>
-        <div class="action-grade-info">
-          <p>
-            <span>原始档位:</span><span>{{ curPaper.originLevel }}</span>
-          </p>
-          <p>
-            <span>申请档位:</span><span>{{ curPaper.redoLevel }}</span>
-          </p>
-        </div>
-        <div
-          :class="[
-            'action-grade-result',
-            { 'action-grade-result-error': curPaper.auditStatus === 2 }
-          ]"
-          v-if="curPaper.auditStatus !== 0"
-        >
-          <p>{{ curPaper.auditStatus === 1 ? "同意改档" : "不同意改档" }}</p>
-        </div>
-        <div class="action-grade-btn" v-else>
-          <Button shape="circle" type="primary" @click="confirm(1)"
-            >同意改档</Button
-          >
-          <Button shape="circle" type="error" @click="confirm(2)"
-            >不同意改档</Button
-          >
-        </div>
-      </div>
-      <!-- 占位 -->
-      <div class="check-grade-action" v-if="isFullscreenMarking"></div>
-    </div>
-    <div class="check-grade" v-else>
-      <p class="check-grade-none">暂无数据</p>
-    </div>
-
-    <!-- image-preview -->
-    <simple-image-preview
-      class="check-grade-image-preview"
-      :cur-image="curPaper"
-      @on-prev="toPrevPaper"
-      @on-next="toNextPaper"
-      @on-close="isFullscreenMarking = false"
-      ref="SimpleImagePreview"
-    ></simple-image-preview>
-  </div>
-</template>
-
-<script>
-import {
-  changeLevelPaperList,
-  inspectionConfirmCheckGrade,
-  workList,
-  areaList
-} from "@/api";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-import { CHANGE_LEVEL_STATUS } from "@/constants/enumerate";
-
-export default {
-  name: "inspection-grading",
-  components: { SimpleImagePreview },
-  data() {
-    return {
-      filter: {
-        workId: "",
-        subject: "",
-        questionId: "",
-        status: 0,
-        type: 1
-      },
-      CHANGE_LEVEL_STATUS,
-      works: [],
-      subjects: [],
-      areas: [],
-      current: 1,
-      size: 8,
-      total: 0,
-      totalPage: 1,
-      papers: [],
-      curPaper: {},
-      curPaperIndex: 0,
-      isFullscreenMarking: false
-    };
-  },
-  mounted() {
-    this.initData();
-  },
-  methods: {
-    async initData() {
-      await this.getWorkList();
-      this.filter.workId = this.works[0].id;
-      this.workChange();
-      await this.getAreaList();
-      this.filter.questionId = this.areas[0].id;
-      this.getList();
-    },
-    async getWorkList() {
-      this.works = await workList();
-    },
-    async getAreaList() {
-      const data = await areaList({
-        workId: this.filter.workId,
-        subject: this.filter.subject
-      });
-      this.areas = data.map(item => {
-        return {
-          id: item.id,
-          areaName: item.areaName,
-          areaCode: item.areaCode
-        };
-      });
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        current: this.current,
-        size: this.size
-      };
-      const data = await changeLevelPaperList(datas);
-      this.papers = data.data.map(item => {
-        item.title = `NO.${item.sn}`;
-        return item;
-      });
-      this.total = data.totalCount;
-      this.totalPage = data.pageCount;
-      this.selectPaper(0);
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    workChange() {
-      this.filter.subject = null;
-      this.filter.questionId = null;
-      const curWork = this.works.find(item => item.id === this.filter.workId);
-      this.subjects = curWork.subjects;
-      this.filter.subject = this.subjects[0].subject;
-      this.subjectChange();
-    },
-    subjectChange() {
-      this.areas = [];
-      this.filter.questionId = null;
-      this.getAreaList();
-    },
-    async confirm(isAgree) {
-      if (isAgree === 1) {
-        this.updateCheckGradeState(isAgree);
-        return;
-      }
-
-      this.$Modal.confirm({
-        content: "确定不同意当前改档吗?",
-        onOk: () => {
-          this.updateCheckGradeState(isAgree);
-        }
-      });
-    },
-    async updateCheckGradeState(auditStatus) {
-      await inspectionConfirmCheckGrade({
-        id: this.curPaper.id,
-        auditStatus,
-        userId: this.$ls.get("user", { id: "" }).id
-      });
-      this.toActionNextPaper();
-    },
-    // paper view action
-    toReview(index) {
-      this.isFullscreenMarking = true;
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        if (this.current > 1) {
-          this.current--;
-          this.curPaperIndex = this.size - 1;
-          await this.getList();
-        } else {
-          this.$Message.warning("当前已经是第一条数据了");
-          return;
-        }
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        if (this.current === this.totalPage) {
-          this.$Message.warning("当前已经是最后一条数据了");
-          return;
-        } else {
-          this.current++;
-          this.curPaperIndex = 0;
-          await this.getList();
-        }
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toActionNextPaper() {
-      if (this.current > 1 && this.papers.length === 1) {
-        this.current--;
-        this.curPaperIndex = this.size;
-      }
-
-      await this.getList();
-      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
-      this.selectPaper(this.curPaperIndex);
-    }
-  }
-};
-</script>
+<template>
+  <div class="inspection-grading page-container-flex">
+    <div class="part-box part-box-filter">
+      <Form ref="FilterForm" label-position="left" inline>
+        <FormItem>
+          <Select
+            v-model="filter.workId"
+            @on-change="workChange"
+            placeholder="工作文件夹"
+            style="width: 150px"
+          >
+            <Option
+              v-for="(work, windex) in works"
+              :key="windex"
+              :value="work.id"
+              :label="work.name"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select
+            v-model="filter.subject"
+            @on-change="subjectChange"
+            placeholder="科目"
+          >
+            <Option
+              v-for="subject in subjects"
+              :key="subject.id"
+              :value="subject.subject"
+              :label="subject.name"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select v-model="filter.questionId" placeholder="考区">
+            <Option
+              v-for="area in areas"
+              :key="area.id"
+              :value="area.id"
+              :label="area.areaName"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select
+            v-model="filter.status"
+            placeholder="类型"
+            clearable
+            style="width: 120px"
+          >
+            <Option
+              v-for="(val, key) in CHANGE_LEVEL_STATUS"
+              :key="key"
+              :value="key * 1"
+              :label="val"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Button
+            type="primary"
+            class="btn-form-search"
+            size="small"
+            @click="toPage(1)"
+            >查询</Button
+          >
+        </FormItem>
+      </Form>
+    </div>
+
+    <div class="check-grade" v-if="papers.length">
+      <!-- paper-list -->
+      <div class="check-grade-body part-box">
+        <div class="check-grade-list image-view-list image-view-list-4">
+          <div
+            :class="[
+              'image-view',
+              { 'image-view-act': curPaperIndex === index }
+            ]"
+            v-for="(image, index) in papers"
+            :key="index"
+          >
+            <div class="image-view-container">
+              <h5 class="image-view-title">{{ image.title }}</h5>
+              <div class="image-view-contain">
+                <img
+                  :src="image.thumbSrc"
+                  :alt="image.title"
+                  @click="toReview(index)"
+                />
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="part-page">
+          <Page
+            :current="current"
+            :total="total"
+            :page-size="size"
+            show-total
+            show-elevator
+            @on-change="toPage"
+          ></Page>
+        </div>
+      </div>
+      <!-- action -->
+      <div
+        :class="[
+          'check-grade-action',
+          { 'check-grade-action-fullscreen': isFullscreenMarking }
+        ]"
+        v-if="curPaper.id"
+      >
+        <div class="action-paper-info">
+          <p>
+            <span>试卷考号:</span><span>{{ curPaper.examNumber }}</span>
+          </p>
+          <p>
+            <span>试卷密号:</span><span>NO.{{ curPaper.sn }}</span>
+          </p>
+        </div>
+        <div class="action-grade-info">
+          <p>
+            <span>原始档位:</span><span>{{ curPaper.originLevel }}</span>
+          </p>
+          <p>
+            <span>申请档位:</span><span>{{ curPaper.redoLevel }}</span>
+          </p>
+        </div>
+        <div
+          :class="[
+            'action-grade-result',
+            { 'action-grade-result-error': curPaper.auditStatus === 2 }
+          ]"
+          v-if="curPaper.auditStatus !== 0"
+        >
+          <p>{{ curPaper.auditStatus === 1 ? "同意改档" : "不同意改档" }}</p>
+        </div>
+        <div class="action-grade-btn" v-else>
+          <Button shape="circle" type="primary" @click="confirm(1)"
+            >同意改档</Button
+          >
+          <Button shape="circle" type="error" @click="confirm(2)"
+            >不同意改档</Button
+          >
+        </div>
+      </div>
+      <!-- 占位 -->
+      <div class="check-grade-action" v-if="isFullscreenMarking"></div>
+    </div>
+    <div class="check-grade" v-else>
+      <p class="check-grade-none">暂无数据</p>
+    </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      class="check-grade-image-preview"
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      @on-close="isFullscreenMarking = false"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
+  </div>
+</template>
+
+<script>
+import {
+  changeLevelPaperList,
+  inspectionConfirmCheckGrade,
+  workList,
+  areaList
+} from "@/api";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+import { CHANGE_LEVEL_STATUS } from "@/constants/enumerate";
+
+export default {
+  name: "inspection-grading",
+  components: { SimpleImagePreview },
+  data() {
+    return {
+      filter: {
+        workId: "",
+        subject: "",
+        questionId: "",
+        status: 0,
+        type: 1
+      },
+      CHANGE_LEVEL_STATUS,
+      works: [],
+      subjects: [],
+      areas: [],
+      current: 1,
+      size: 8,
+      total: 0,
+      totalPage: 1,
+      papers: [],
+      curPaper: {},
+      curPaperIndex: 0,
+      isFullscreenMarking: false
+    };
+  },
+  mounted() {
+    this.initData();
+  },
+  methods: {
+    async initData() {
+      await this.getWorkList();
+      this.filter.workId = this.works[0].id;
+      this.workChange();
+      await this.getAreaList();
+      this.filter.questionId = this.areas[0].id;
+      this.getList();
+    },
+    async getWorkList() {
+      this.works = await workList();
+    },
+    async getAreaList() {
+      const data = await areaList({
+        workId: this.filter.workId,
+        subject: this.filter.subject
+      });
+      this.areas = data.map(item => {
+        return {
+          id: item.id,
+          areaName: item.areaName,
+          areaCode: item.areaCode
+        };
+      });
+    },
+    async getList() {
+      const datas = {
+        ...this.filter,
+        current: this.current,
+        size: this.size
+      };
+      const data = await changeLevelPaperList(datas);
+      this.papers = data.data.map(item => {
+        item.title = `NO.${item.sn}`;
+        return item;
+      });
+      this.total = data.totalCount;
+      this.totalPage = data.pageCount;
+      this.selectPaper(0);
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    workChange() {
+      this.filter.subject = null;
+      this.filter.questionId = null;
+      const curWork = this.works.find(item => item.id === this.filter.workId);
+      this.subjects = curWork.subjects;
+      this.filter.subject = this.subjects[0].subject;
+      this.subjectChange();
+    },
+    subjectChange() {
+      this.areas = [];
+      this.filter.questionId = null;
+      this.getAreaList();
+    },
+    async confirm(isAgree) {
+      if (isAgree === 1) {
+        this.updateCheckGradeState(isAgree);
+        return;
+      }
+
+      this.$Modal.confirm({
+        content: "确定不同意当前改档吗?",
+        onOk: () => {
+          this.updateCheckGradeState(isAgree);
+        }
+      });
+    },
+    async updateCheckGradeState(auditStatus) {
+      await inspectionConfirmCheckGrade({
+        id: this.curPaper.id,
+        auditStatus,
+        userId: this.$ls.get("user", { id: "" }).id
+      });
+      this.toActionNextPaper();
+    },
+    // paper view action
+    toReview(index) {
+      this.isFullscreenMarking = true;
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        if (this.current > 1) {
+          this.current--;
+          this.curPaperIndex = this.size - 1;
+          await this.getList();
+        } else {
+          this.$Message.warning("当前已经是第一条数据了");
+          return;
+        }
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        if (this.current === this.totalPage) {
+          this.$Message.warning("当前已经是最后一条数据了");
+          return;
+        } else {
+          this.current++;
+          this.curPaperIndex = 0;
+          await this.getList();
+        }
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toActionNextPaper() {
+      if (this.current > 1 && this.papers.length === 1) {
+        this.current--;
+        this.curPaperIndex = this.size;
+      }
+
+      await this.getList();
+      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
+      this.selectPaper(this.curPaperIndex);
+    }
+  }
+};
+</script>

+ 1 - 1
src/modules/main/PaperManage.vue

@@ -107,7 +107,7 @@
       ref="ImageActionList"
     ></image-action-list>
 
-    <div class="part-page" v-if="total > size">
+    <div class="part-page">
       <Page
         :current="current"
         :total="total"

+ 515 - 515
src/modules/main/StudentManage.vue

@@ -1,515 +1,515 @@
-<template>
-  <div class="students ">
-    <div class="part-box-head">
-      <div class="part-box-head-left">
-        <Button
-          icon="upload icon"
-          shape="circle"
-          @click="$refs.ExportStudent.open()"
-          >导入考生信息</Button
-        >
-        <!-- <Button
-          icon="upload icon"
-          shape="circle"
-          @click="$refs.ExportRelate.open()"
-          >导入关联信息</Button
-        > -->
-      </div>
-      <div class="part-box-head-right">
-        <Button
-          type="success"
-          icon="recode-white icon"
-          shape="circle"
-          @click="toAdd"
-          >添加考生</Button
-        >
-        <Button
-          type="success"
-          icon="upload-white icon"
-          shape="circle"
-          @click="toExport"
-          >导出表格</Button
-        >
-      </div>
-    </div>
-    <div class="part-box part-box-filter">
-      <Form ref="FilterForm" label-position="left" inline>
-        <FormItem>
-          <Select
-            v-model="filter.areaCode"
-            @on-change="areaChange"
-            placeholder="考区"
-            clearable
-          >
-            <Option
-              v-for="area in cascadeList"
-              :key="area.areaCode"
-              :value="area.areaCode"
-              :label="area.areaName"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select
-            v-model="filter.school"
-            @on-change="schoolChange"
-            placeholder="学校"
-            filterable
-            clearable
-          >
-            <Option
-              v-for="(item, index) in schools"
-              :key="index"
-              :value="item.school"
-              :label="item.school"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.examRoom" placeholder="考场" clearable>
-            <Option
-              v-for="(room, index) in rooms"
-              :key="index"
-              :value="room"
-              :label="room"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Input
-            v-model="filter.startNumber"
-            type="text"
-            placeholder="输入开始编号"
-            clearable
-          />
-        </FormItem>
-        <FormItem>
-          <Input
-            v-model="filter.endNumber"
-            type="text"
-            placeholder="输入结束编号"
-            clearable
-          />
-        </FormItem>
-        <FormItem>
-          <Input
-            v-model.trim="filter.studentName"
-            placeholder="输入姓名"
-            clearable
-          ></Input>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.isAbsent" placeholder="是否缺考" clearable>
-            <Option
-              v-for="(val, key) in BOOLEAN_TYPE"
-              :key="key"
-              :value="key * 1"
-              >{{ val }}</Option
-            >
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.upload" placeholder="是否上传" clearable>
-            <Option
-              v-for="(val, key) in PAPER_UPLOAD_TYPE"
-              :key="key"
-              :value="key * 1"
-              >{{ val }}</Option
-            >
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.subject" placeholder="科目" clearable>
-            <Option
-              v-for="item in subjects"
-              :key="item.subject"
-              :value="item.subject"
-              :label="item.name"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Button
-            size="small"
-            class="btn-form-search"
-            type="primary"
-            @click="toPage(1)"
-            >查询</Button
-          >
-        </FormItem>
-      </Form>
-    </div>
-    <Table
-      ref="TableList"
-      :columns="columns"
-      :data="students"
-      disabled-hover
-      border
-    ></Table>
-
-    <div class="part-page" v-if="total > size">
-      <Page
-        :current="current"
-        :total="total"
-        :page-size="size"
-        show-total
-        show-elevator
-        @on-change="toPage"
-      ></Page>
-    </div>
-
-    <!-- import student  -->
-    <import-file
-      title="导入考生信息"
-      :upload-url="uploadStudentUrl"
-      :upload-data="uploadData"
-      :download-url="downloadStudentTemplateUrl"
-      :download-filename="downloadStudentTemplateFilename"
-      :headers="headers"
-      :format="['xls', 'xlsx']"
-      @upload-success="uploadSuccess"
-      ref="ExportStudent"
-    >
-    </import-file>
-    <!-- import-relate -->
-    <import-file
-      title="导入关联信息"
-      :upload-url="uploadRelateUrl"
-      :upload-data="uploadData"
-      :download-url="downloadRelateTemplateUrl"
-      :download-filename="downloadRelateTemplateFilename"
-      :headers="headers"
-      :format="['xls', 'xlsx']"
-      ref="ExportRelate"
-    >
-    </import-file>
-    <!-- modify-student -->
-    <modify-student
-      :cascade-list="cascadeList"
-      :instance="curStudent"
-      @modified="getList"
-      @on-close="getAreaList"
-      ref="ModifyStudent"
-    ></modify-student>
-  </div>
-</template>
-
-<script>
-import {
-  subjectList,
-  studentPageList,
-  deleteStudent,
-  areaSchoolRoomCascadeList,
-  absentStudentSubject
-} from "@/api";
-import ImportFile from "@/components/common/ImportFile";
-import ModifyStudent from "./components/ModifyStudent";
-import { BOOLEAN_TYPE, PAPER_UPLOAD_TYPE } from "@/constants/enumerate";
-import qs from "qs";
-
-export default {
-  name: "students",
-  components: { ImportFile, ModifyStudent },
-  data() {
-    return {
-      filter: {
-        workId: this.$route.params.workId,
-        subject: null,
-        areaCode: null,
-        school: "",
-        examRoom: "",
-        startNumber: null,
-        endNumber: null,
-        studentName: "",
-        upload: null,
-        isAbsent: null
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      students: [],
-      curStudent: {},
-      subjects: [],
-      cascadeList: [],
-      schools: [],
-      rooms: [],
-      BOOLEAN_TYPE,
-      PAPER_UPLOAD_TYPE,
-      columns: [
-        {
-          type: "index",
-          title: "序号",
-          width: 80,
-          align: "center",
-          indexMethod: row => {
-            return (this.current - 1) * this.size + row._index + 1;
-          }
-        },
-        {
-          title: "姓名",
-          key: "name",
-          width: 100
-        },
-        {
-          title: "考号",
-          key: "examNumber",
-          minWidth: 120
-        },
-        // {
-        //   title: "关联考号",
-        //   key: "relateExamNumber",
-        //   minWidth: 120
-        // },
-        {
-          title: "考区",
-          key: "areaName",
-          minWidth: 120
-        },
-        {
-          title: "学校",
-          key: "school",
-          minWidth: 150
-        },
-        {
-          title: "考场",
-          key: "examRoom",
-          minWidth: 100
-        },
-        {
-          title: "操作",
-          key: "action",
-          width: 100,
-          align: "center",
-          className: "table-action",
-          render: (h, param) => {
-            let actions = [];
-
-            if (param.row.canEdit) {
-              actions.push({
-                icon: "md-create",
-                attrs: {
-                  title: "编辑"
-                },
-                action: () => {
-                  this.toEdit(param.row);
-                }
-              });
-            }
-            if (param.row.canDelete) {
-              actions.push({
-                icon: "md-trash",
-                classes: ["icon-danger"],
-                attrs: {
-                  title: "删除"
-                },
-                action: () => {
-                  this.toDelete(param.row);
-                }
-              });
-            }
-
-            return h("div", this.$tableIconAction(h, actions));
-          }
-        }
-      ],
-      // upload
-      headers: {
-        Authorization: this.$ls.get("user", { token: "" }).token,
-        workId: this.$route.params.workId,
-        userId: this.$ls.get("user", { id: "" }).id
-      },
-      uploadData: {
-        workId: this.$route.params.workId
-      },
-      uploadStudentUrl: this.GLOBAL.domain + "/api/import/students",
-      downloadStudentTemplateUrl: "/templates/考生信息表-模板.xlsx",
-      downloadStudentTemplateFilename: "考生信息表-模板.xlsx",
-      uploadRelateUrl: "/api/import/students/relateStudent",
-      downloadRelateTemplateUrl: "/templates/关联考生信息表-模板.xlsx",
-      downloadRelateTemplateFilename: "关联考生信息表-模板.xlsx"
-    };
-  },
-  mounted() {
-    this.iniData();
-  },
-  methods: {
-    async iniData() {
-      await this.getSubjects();
-      this.getAreaList();
-      this.getList();
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        page: this.current - 1,
-        size: this.size
-      };
-      // if (
-      //   ((datas.upload || datas.upload === 0) && !datas.subject) ||
-      //   (!datas.upload && datas.upload !== 0 && datas.subject)
-      // ) {
-      //   this.$Message.error("上传状态和科目必须同时选择!");
-      //   return;
-      // }
-      // if (datas.subject === "ONE") datas.subject = null;
-      const data = await studentPageList(datas);
-      this.students = data.data.map(student => {
-        student.uploadStatus.split(",").map(status => {
-          const [subjectCode, subjectUploadStatus] = status.split(":");
-          student[subjectCode] = subjectUploadStatus * 1;
-        });
-        student.canEdit = student.uploadStatus.includes("0");
-        student.canDelete = !student.uploadStatus.includes("1");
-        student.uploadStatus.split(",").map(status => {
-          const [subject, hasScan] = status.split(":");
-          student[subject] = {
-            hasScan: hasScan * 1,
-            manual: student[`${subject.toLowerCase()}Missing`]
-          };
-        });
-        // student.manualStatus = "SC:1,SM:0,SX:1";
-        // student.manualStatus.split(",").map(status => {
-        //   const [subject, manual] = status.split(":");
-        //   student[subject].manual = manual * 1;
-        // });
-        student.workId = this.filter.workId;
-        student.relateExamNumber =
-          student.relateExamNumber === student.examNumber
-            ? "--"
-            : student.relateExamNumber;
-        return student;
-      });
-      this.total = data.totalCount;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    async getAreaList() {
-      this.cascadeList = await areaSchoolRoomCascadeList(this.filter.workId);
-    },
-    async getSubjects() {
-      const data = await subjectList(this.filter.workId);
-      this.subjects = data.filter(item => item.enable);
-      this.subjects.map(item => {
-        const column = {
-          title: item.name,
-          key: item.subject,
-          minWidth: 140,
-          render: (h, param) => {
-            const hasScan = param.row[item.subject].hasScan;
-            const isManual = param.row[item.subject].manual;
-            const btnCls = `ivu-btn ivu-btn-text ivu-btn-small ${
-              isManual ? "color-error-hover" : "color-text-hover"
-            }`;
-
-            return h("div", [
-              h(
-                "span",
-                {
-                  attrs: {
-                    class: hasScan ? "" : "color-error",
-                    style: "display:inline-block;vertical-align: middle;"
-                  }
-                },
-                hasScan ? "已上传" : "未上传"
-              ),
-              h(
-                "Button",
-                {
-                  props: {
-                    type: "text",
-                    size: "small"
-                  },
-                  attrs: {
-                    class: btnCls
-                  },
-                  on: {
-                    click: () => {
-                      this.toManual(param.row, item.subject);
-                    }
-                  }
-                },
-                "缺考"
-              )
-            ]);
-          }
-        };
-        this.columns.splice(this.columns.length - 1, 0, column);
-      });
-      this.subjects.unshift({
-        subject: "ONE",
-        name: "查漏"
-      });
-    },
-    async toManual(row, subject) {
-      console.log(row);
-      await absentStudentSubject({
-        studentId: row.id,
-        subject,
-        isManual: !row[subject].manual
-      });
-      row[subject].manual = !row[subject].manual;
-    },
-    areaChange() {
-      const curArea = this.cascadeList.find(
-        item => item.areaCode === this.filter.areaCode
-      );
-      this.schools = curArea ? curArea.schools : [];
-      this.rooms = [];
-      this.filter.school = null;
-      this.filter.examRoom = null;
-      if (curArea.schools.length === 1) {
-        this.filter.school = curArea.schools[0].school;
-        this.schoolChange();
-      }
-    },
-    schoolChange() {
-      const curSchool = this.schools.find(
-        item => item.school === this.filter.school
-      );
-      this.rooms = curSchool ? curSchool.rooms : [];
-      this.filter.examRoom = null;
-    },
-    uploadSuccess() {
-      this.getList();
-      this.getAreaList();
-      this.$Notice.success({
-        title: "导入提示",
-        desc: "考生信息导入成功!",
-        duration: 0
-      });
-    },
-    toAdd() {
-      this.curStudent = { workId: this.filter.workId };
-      this.$refs.ModifyStudent.open();
-    },
-    toEdit(row) {
-      this.curStudent = row;
-      this.$refs.ModifyStudent.open();
-    },
-    toDelete(row) {
-      this.$Modal.confirm({
-        width: 340,
-        content: "确定要删除该考生吗?",
-        onOk: () => {
-          this.toDel(row.id);
-        }
-      });
-    },
-    async toDel(id) {
-      await deleteStudent(id);
-      this.$Message.success("删除成功!");
-      this.deletePageLastItem();
-    },
-    toExport() {
-      const sqDatas = qs.stringify(this.filter, {
-        arrayFormat: "brackets"
-      });
-      window.open(
-        this.urlAddAuthor(`${this.GLOBAL.domain}/api/export/student?${sqDatas}`)
-      );
-    }
-  }
-};
-</script>
+<template>
+  <div class="students ">
+    <div class="part-box-head">
+      <div class="part-box-head-left">
+        <Button
+          icon="upload icon"
+          shape="circle"
+          @click="$refs.ExportStudent.open()"
+          >导入考生信息</Button
+        >
+        <!-- <Button
+          icon="upload icon"
+          shape="circle"
+          @click="$refs.ExportRelate.open()"
+          >导入关联信息</Button
+        > -->
+      </div>
+      <div class="part-box-head-right">
+        <Button
+          type="success"
+          icon="recode-white icon"
+          shape="circle"
+          @click="toAdd"
+          >添加考生</Button
+        >
+        <Button
+          type="success"
+          icon="upload-white icon"
+          shape="circle"
+          @click="toExport"
+          >导出表格</Button
+        >
+      </div>
+    </div>
+    <div class="part-box part-box-filter">
+      <Form ref="FilterForm" label-position="left" inline>
+        <FormItem>
+          <Select
+            v-model="filter.areaCode"
+            @on-change="areaChange"
+            placeholder="考区"
+            clearable
+          >
+            <Option
+              v-for="area in cascadeList"
+              :key="area.areaCode"
+              :value="area.areaCode"
+              :label="area.areaName"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select
+            v-model="filter.school"
+            @on-change="schoolChange"
+            placeholder="学校"
+            filterable
+            clearable
+          >
+            <Option
+              v-for="(item, index) in schools"
+              :key="index"
+              :value="item.school"
+              :label="item.school"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select v-model="filter.examRoom" placeholder="考场" clearable>
+            <Option
+              v-for="(room, index) in rooms"
+              :key="index"
+              :value="room"
+              :label="room"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Input
+            v-model="filter.startNumber"
+            type="text"
+            placeholder="输入开始编号"
+            clearable
+          />
+        </FormItem>
+        <FormItem>
+          <Input
+            v-model="filter.endNumber"
+            type="text"
+            placeholder="输入结束编号"
+            clearable
+          />
+        </FormItem>
+        <FormItem>
+          <Input
+            v-model.trim="filter.studentName"
+            placeholder="输入姓名"
+            clearable
+          ></Input>
+        </FormItem>
+        <FormItem>
+          <Select v-model="filter.isAbsent" placeholder="是否缺考" clearable>
+            <Option
+              v-for="(val, key) in BOOLEAN_TYPE"
+              :key="key"
+              :value="key * 1"
+              >{{ val }}</Option
+            >
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select v-model="filter.upload" placeholder="是否上传" clearable>
+            <Option
+              v-for="(val, key) in PAPER_UPLOAD_TYPE"
+              :key="key"
+              :value="key * 1"
+              >{{ val }}</Option
+            >
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select v-model="filter.subject" placeholder="科目" clearable>
+            <Option
+              v-for="item in subjects"
+              :key="item.subject"
+              :value="item.subject"
+              :label="item.name"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Button
+            size="small"
+            class="btn-form-search"
+            type="primary"
+            @click="toPage(1)"
+            >查询</Button
+          >
+        </FormItem>
+      </Form>
+    </div>
+    <Table
+      ref="TableList"
+      :columns="columns"
+      :data="students"
+      disabled-hover
+      border
+    ></Table>
+
+    <div class="part-page">
+      <Page
+        :current="current"
+        :total="total"
+        :page-size="size"
+        show-total
+        show-elevator
+        @on-change="toPage"
+      ></Page>
+    </div>
+
+    <!-- import student  -->
+    <import-file
+      title="导入考生信息"
+      :upload-url="uploadStudentUrl"
+      :upload-data="uploadData"
+      :download-url="downloadStudentTemplateUrl"
+      :download-filename="downloadStudentTemplateFilename"
+      :headers="headers"
+      :format="['xls', 'xlsx']"
+      @upload-success="uploadSuccess"
+      ref="ExportStudent"
+    >
+    </import-file>
+    <!-- import-relate -->
+    <import-file
+      title="导入关联信息"
+      :upload-url="uploadRelateUrl"
+      :upload-data="uploadData"
+      :download-url="downloadRelateTemplateUrl"
+      :download-filename="downloadRelateTemplateFilename"
+      :headers="headers"
+      :format="['xls', 'xlsx']"
+      ref="ExportRelate"
+    >
+    </import-file>
+    <!-- modify-student -->
+    <modify-student
+      :cascade-list="cascadeList"
+      :instance="curStudent"
+      @modified="getList"
+      @on-close="getAreaList"
+      ref="ModifyStudent"
+    ></modify-student>
+  </div>
+</template>
+
+<script>
+import {
+  subjectList,
+  studentPageList,
+  deleteStudent,
+  areaSchoolRoomCascadeList,
+  absentStudentSubject
+} from "@/api";
+import ImportFile from "@/components/common/ImportFile";
+import ModifyStudent from "./components/ModifyStudent";
+import { BOOLEAN_TYPE, PAPER_UPLOAD_TYPE } from "@/constants/enumerate";
+import qs from "qs";
+
+export default {
+  name: "students",
+  components: { ImportFile, ModifyStudent },
+  data() {
+    return {
+      filter: {
+        workId: this.$route.params.workId,
+        subject: null,
+        areaCode: null,
+        school: "",
+        examRoom: "",
+        startNumber: null,
+        endNumber: null,
+        studentName: "",
+        upload: null,
+        isAbsent: null
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      students: [],
+      curStudent: {},
+      subjects: [],
+      cascadeList: [],
+      schools: [],
+      rooms: [],
+      BOOLEAN_TYPE,
+      PAPER_UPLOAD_TYPE,
+      columns: [
+        {
+          type: "index",
+          title: "序号",
+          width: 80,
+          align: "center",
+          indexMethod: row => {
+            return (this.current - 1) * this.size + row._index + 1;
+          }
+        },
+        {
+          title: "姓名",
+          key: "name",
+          width: 100
+        },
+        {
+          title: "考号",
+          key: "examNumber",
+          minWidth: 120
+        },
+        // {
+        //   title: "关联考号",
+        //   key: "relateExamNumber",
+        //   minWidth: 120
+        // },
+        {
+          title: "考区",
+          key: "areaName",
+          minWidth: 120
+        },
+        {
+          title: "学校",
+          key: "school",
+          minWidth: 150
+        },
+        {
+          title: "考场",
+          key: "examRoom",
+          minWidth: 100
+        },
+        {
+          title: "操作",
+          key: "action",
+          width: 100,
+          align: "center",
+          className: "table-action",
+          render: (h, param) => {
+            let actions = [];
+
+            if (param.row.canEdit) {
+              actions.push({
+                icon: "md-create",
+                attrs: {
+                  title: "编辑"
+                },
+                action: () => {
+                  this.toEdit(param.row);
+                }
+              });
+            }
+            if (param.row.canDelete) {
+              actions.push({
+                icon: "md-trash",
+                classes: ["icon-danger"],
+                attrs: {
+                  title: "删除"
+                },
+                action: () => {
+                  this.toDelete(param.row);
+                }
+              });
+            }
+
+            return h("div", this.$tableIconAction(h, actions));
+          }
+        }
+      ],
+      // upload
+      headers: {
+        Authorization: this.$ls.get("user", { token: "" }).token,
+        workId: this.$route.params.workId,
+        userId: this.$ls.get("user", { id: "" }).id
+      },
+      uploadData: {
+        workId: this.$route.params.workId
+      },
+      uploadStudentUrl: this.GLOBAL.domain + "/api/import/students",
+      downloadStudentTemplateUrl: "/templates/考生信息表-模板.xlsx",
+      downloadStudentTemplateFilename: "考生信息表-模板.xlsx",
+      uploadRelateUrl: "/api/import/students/relateStudent",
+      downloadRelateTemplateUrl: "/templates/关联考生信息表-模板.xlsx",
+      downloadRelateTemplateFilename: "关联考生信息表-模板.xlsx"
+    };
+  },
+  mounted() {
+    this.iniData();
+  },
+  methods: {
+    async iniData() {
+      await this.getSubjects();
+      this.getAreaList();
+      this.getList();
+    },
+    async getList() {
+      const datas = {
+        ...this.filter,
+        page: this.current - 1,
+        size: this.size
+      };
+      // if (
+      //   ((datas.upload || datas.upload === 0) && !datas.subject) ||
+      //   (!datas.upload && datas.upload !== 0 && datas.subject)
+      // ) {
+      //   this.$Message.error("上传状态和科目必须同时选择!");
+      //   return;
+      // }
+      // if (datas.subject === "ONE") datas.subject = null;
+      const data = await studentPageList(datas);
+      this.students = data.data.map(student => {
+        student.uploadStatus.split(",").map(status => {
+          const [subjectCode, subjectUploadStatus] = status.split(":");
+          student[subjectCode] = subjectUploadStatus * 1;
+        });
+        student.canEdit = student.uploadStatus.includes("0");
+        student.canDelete = !student.uploadStatus.includes("1");
+        student.uploadStatus.split(",").map(status => {
+          const [subject, hasScan] = status.split(":");
+          student[subject] = {
+            hasScan: hasScan * 1,
+            manual: student[`${subject.toLowerCase()}Missing`]
+          };
+        });
+        // student.manualStatus = "SC:1,SM:0,SX:1";
+        // student.manualStatus.split(",").map(status => {
+        //   const [subject, manual] = status.split(":");
+        //   student[subject].manual = manual * 1;
+        // });
+        student.workId = this.filter.workId;
+        student.relateExamNumber =
+          student.relateExamNumber === student.examNumber
+            ? "--"
+            : student.relateExamNumber;
+        return student;
+      });
+      this.total = data.totalCount;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    async getAreaList() {
+      this.cascadeList = await areaSchoolRoomCascadeList(this.filter.workId);
+    },
+    async getSubjects() {
+      const data = await subjectList(this.filter.workId);
+      this.subjects = data.filter(item => item.enable);
+      this.subjects.map(item => {
+        const column = {
+          title: item.name,
+          key: item.subject,
+          minWidth: 140,
+          render: (h, param) => {
+            const hasScan = param.row[item.subject].hasScan;
+            const isManual = param.row[item.subject].manual;
+            const btnCls = `ivu-btn ivu-btn-text ivu-btn-small ${
+              isManual ? "color-error-hover" : "color-text-hover"
+            }`;
+
+            return h("div", [
+              h(
+                "span",
+                {
+                  attrs: {
+                    class: hasScan ? "" : "color-error",
+                    style: "display:inline-block;vertical-align: middle;"
+                  }
+                },
+                hasScan ? "已上传" : "未上传"
+              ),
+              h(
+                "Button",
+                {
+                  props: {
+                    type: "text",
+                    size: "small"
+                  },
+                  attrs: {
+                    class: btnCls
+                  },
+                  on: {
+                    click: () => {
+                      this.toManual(param.row, item.subject);
+                    }
+                  }
+                },
+                "缺考"
+              )
+            ]);
+          }
+        };
+        this.columns.splice(this.columns.length - 1, 0, column);
+      });
+      this.subjects.unshift({
+        subject: "ONE",
+        name: "查漏"
+      });
+    },
+    async toManual(row, subject) {
+      console.log(row);
+      await absentStudentSubject({
+        studentId: row.id,
+        subject,
+        isManual: !row[subject].manual
+      });
+      row[subject].manual = !row[subject].manual;
+    },
+    areaChange() {
+      const curArea = this.cascadeList.find(
+        item => item.areaCode === this.filter.areaCode
+      );
+      this.schools = curArea ? curArea.schools : [];
+      this.rooms = [];
+      this.filter.school = null;
+      this.filter.examRoom = null;
+      if (curArea.schools.length === 1) {
+        this.filter.school = curArea.schools[0].school;
+        this.schoolChange();
+      }
+    },
+    schoolChange() {
+      const curSchool = this.schools.find(
+        item => item.school === this.filter.school
+      );
+      this.rooms = curSchool ? curSchool.rooms : [];
+      this.filter.examRoom = null;
+    },
+    uploadSuccess() {
+      this.getList();
+      this.getAreaList();
+      this.$Notice.success({
+        title: "导入提示",
+        desc: "考生信息导入成功!",
+        duration: 0
+      });
+    },
+    toAdd() {
+      this.curStudent = { workId: this.filter.workId };
+      this.$refs.ModifyStudent.open();
+    },
+    toEdit(row) {
+      this.curStudent = row;
+      this.$refs.ModifyStudent.open();
+    },
+    toDelete(row) {
+      this.$Modal.confirm({
+        width: 340,
+        content: "确定要删除该考生吗?",
+        onOk: () => {
+          this.toDel(row.id);
+        }
+      });
+    },
+    async toDel(id) {
+      await deleteStudent(id);
+      this.$Message.success("删除成功!");
+      this.deletePageLastItem();
+    },
+    toExport() {
+      const sqDatas = qs.stringify(this.filter, {
+        arrayFormat: "brackets"
+      });
+      window.open(
+        this.urlAddAuthor(`${this.GLOBAL.domain}/api/export/student?${sqDatas}`)
+      );
+    }
+  }
+};
+</script>

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

@@ -60,7 +60,6 @@
               'part-page',
               { 'part-page-simple': !showPaperRelateCount }
             ]"
-            v-if="total > size"
           >
             <Page
               :current="current"

+ 538 - 539
src/modules/mark/MarkOperation.vue

@@ -1,539 +1,538 @@
-<template>
-  <div class="mark-operation grading-operation home">
-    <view-header> </view-header>
-    <div class="home-body">
-      <div class="home-main">
-        <div class="grading-detail page-container-flex">
-          <grade-filter
-            ref="GradeFilter"
-            :data="workSubject"
-            @change="areaChange"
-          ></grade-filter>
-          <mark-step
-            :steps="steps"
-            :init-step="curStep"
-            :show-count="showPaperRelateCount"
-            :show-top-number="false"
-            @on-change="stepChange"
-            ref="MarkStep"
-            v-if="steps.levelStep"
-          ></mark-step>
-          <div class="detail-body">
-            <!-- detail-papers -->
-            <div :class="detailPapersClasses">
-              <div class="detail-papers-carousel">
-                <grade-history-paper
-                  :question-id="filter.questionId"
-                  stage="SCORE"
-                  @on-paper-click="toViewCarouselPaper"
-                  v-if="filter.questionId"
-                  ref="GradeHistoryPaper"
-                ></grade-history-paper>
-              </div>
-              <div class="detail-papers-list" v-if="papers.length">
-                <div :class="imageViewClasses">
-                  <div
-                    :class="[
-                      'image-view',
-                      { 'image-view-act': curPaperIndex === index }
-                    ]"
-                    v-for="(image, index) in papers"
-                    :key="index"
-                  >
-                    <div class="image-view-container">
-                      <h5 class="image-view-title">{{ image.title }}</h5>
-                      <div class="image-view-contain">
-                        <img
-                          :src="image.thumbSrc"
-                          :alt="image.title"
-                          @click="toReview(index)"
-                        />
-                      </div>
-                      <div class="image-view-actions">
-                        <span
-                          v-if="image.score || image.score === 0"
-                          class="color-error"
-                          >{{ image.score }}分</span
-                        >
-                      </div>
-                    </div>
-                  </div>
-                </div>
-                <div
-                  :class="[
-                    'part-page',
-                    { 'part-page-simple': !showPaperRelateCount }
-                  ]"
-                  v-if="total > size"
-                >
-                  <Page
-                    :current="current"
-                    :total="total"
-                    :page-size="size"
-                    :show-total="showPaperRelateCount"
-                    show-elevator
-                    :page-size-opts="[4, 6, 8]"
-                    @on-page-size-change="pageSizeChange"
-                    @on-change="toPage"
-                  ></Page>
-                </div>
-              </div>
-              <div class="detail-papers-list" v-else>
-                <p class="detail-papers-none">暂无数据</p>
-              </div>
-            </div>
-            <!-- detail-aciton -->
-            <div
-              :class="[
-                'detail-action',
-                { 'detail-action-fullscreen': isFullscreenMarking }
-              ]"
-            >
-              <mark-action
-                :cur-paper-or-task="curPaper"
-                :levels="levels"
-                :show-count="showPaperRelateCount"
-                :params-set="paramsSet"
-                @on-leader-level="gradingCurPaper"
-                @on-select-score="scoreCurPaper"
-                @on-pass="passCurPaper"
-                ref="GradeAction"
-                v-if="curPaper.id"
-              ></mark-action>
-            </div>
-            <!-- 占位 -->
-            <div class="detail-action" v-if="isFullscreenMarking"></div>
-          </div>
-        </div>
-
-        <!-- <view-footer></view-footer> -->
-      </div>
-    </div>
-
-    <!-- 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>
-
-<script>
-import {
-  getParamsSet,
-  markerTaskList,
-  markerChangeLevelPaperList,
-  markerScoreTotalStatData,
-  workLevelList,
-  subjectDetail,
-  paperSelectLevelOrScore,
-  markerManualScorePaperList,
-  paperTaskPass
-} from "@/api";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-import MarkStep from "./components/MarkStep";
-import GradeFilter from "../grading/components/GradeFilter";
-import GradeHistoryPaper from "../grading/components/GradeHistoryPaper";
-import MarkAction from "./components/MarkAction";
-// 三种情况:
-// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
-// 评卷员:操作记录,试卷列表,操作盘(打分)
-
-// TIP:不考虑管理员、科组长的情况
-// 管理员:试卷列表,操作盘
-// 科组长:操作记录,试卷列表,操作盘(改档)
-
-export default {
-  name: "mark-operation",
-  components: {
-    SimpleImagePreview,
-    MarkStep,
-    GradeFilter,
-    GradeHistoryPaper,
-    MarkAction
-  },
-  data() {
-    return {
-      filter: {
-        markerId: this.$ls.get("user").id,
-        questionId: ""
-      },
-      typeFilter: {
-        undo: {
-          sort: "paper.level",
-          stage: "SCORE"
-        },
-        done: {
-          level: "",
-          sort: "updatedOn,desc",
-          stage: "SCORE"
-        },
-        shift: {
-          isShift: true,
-          isShiftScore: false
-        },
-        shiftScore: {
-          isShift: false,
-          isShiftScore: true
-        },
-        manualScore: {}
-      },
-      workId: this.$route.params.workId,
-      subjectId: this.$route.params.subjectId,
-      subject: "",
-      workSubject: {},
-      curSubject: {},
-      curUserRoleType: "MARKER",
-      changeStage: 0, // 是否显示改档及改档打分
-      current: 1,
-      size: 6,
-      total: 0,
-      totalPage: 1,
-      curStep: null,
-      curStandardGradeId: "",
-      steps: [],
-      levels: [],
-      curArea: {},
-      papers: [],
-      curPaper: {},
-      curPaperIndex: 0,
-      paramsSet: {},
-      // carousel paper review,
-      carouselPapers: [],
-      curCarouselPaperIndex: 0,
-      isFullscreenMarking: false
-    };
-  },
-  computed: {
-    detailPapersClasses() {
-      return ["detail-papers", `detail-papers-col-${1 + this.size / 2}`];
-    },
-    imageViewClasses() {
-      return ["image-view-list", `image-view-list-${this.size / 2}`];
-    },
-    showPaperRelateCount() {
-      return !!this.paramsSet["showPaperCount"];
-    }
-  },
-  created() {
-    this.subject = this.subjectId.split("-")[1];
-    this.workSubject = {
-      workId: this.workId,
-      subject: this.subject
-    };
-    this.initData();
-  },
-  methods: {
-    async initData() {
-      await this.getParamsSetInfo();
-      await this.getWorkLevels();
-      // this.getSubjectDetail();
-    },
-    async getSubjectDetail() {
-      this.curSubject = await subjectDetail(this.subjectId);
-    },
-    async getParamsSetInfo() {
-      this.paramsSet = await getParamsSet(this.workId);
-      this.changeStage = this.paramsSet.changeStage;
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        ...this.typeFilter[this.curStep.type],
-        subject: this.subject,
-        workId: this.workId,
-        page: this.current - 1,
-        size: this.size
-      };
-      if (this.curStep.type === "done") {
-        datas.level = this.curStep.name;
-      }
-
-      let requestAction = null;
-      if (this.curStep.type.includes("shift")) {
-        requestAction = markerChangeLevelPaperList;
-      } else if (this.curStep.type === "manualScore") {
-        requestAction = markerManualScorePaperList;
-      } else {
-        requestAction = markerTaskList;
-      }
-
-      const data = await requestAction(datas);
-      this.papers = data.data.map(paper => {
-        paper.title = `NO.${paper.sn}`;
-        return paper;
-      });
-      this.total = data.totalCount;
-      this.totalPage = data.pageCount;
-    },
-    async toPage(page) {
-      this.current = page;
-      await this.getList();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async getStepLevels() {
-      const data = await markerScoreTotalStatData(
-        this.filter.markerId,
-        this.filter.questionId
-      );
-      const undoIndex = data.findIndex(item => item.id === null);
-      let otherStep = [];
-      let undo = {
-        count: 0,
-        shift: 0,
-        shiftScore: 0
-      };
-      if (undoIndex !== -1) {
-        undo = { ...data[undoIndex] };
-        data.splice(undoIndex, 1);
-      }
-      otherStep.push({
-        name: "待评",
-        count: undo.count,
-        type: "undo"
-      });
-
-      if (this.changeStage) {
-        otherStep.push({
-          name: "改档",
-          count: undo.shift,
-          type: "shift"
-        });
-        otherStep.push({
-          name: "改档打分",
-          count: undo.shiftScore,
-          type: "shiftScore"
-        });
-      }
-
-      let levelStep = data
-        .filter(item => item.id !== "manualScore")
-        .map(item => {
-          return {
-            ...item,
-            name: item.id,
-            type: "done"
-          };
-        });
-      const msInfo = data.find(item => item.id === "manualScore");
-      if (msInfo) {
-        levelStep.push({
-          count: msInfo.count,
-          name: "输分试卷",
-          type: "manualScore"
-        });
-      }
-
-      this.steps = { levelStep, otherStep };
-
-      if (!this.curStep) {
-        let curStep = {};
-        if (undoIndex === -1) {
-          curStep = levelStep[0];
-        } else {
-          curStep = otherStep[0];
-        }
-        this.curStep = curStep;
-      }
-    },
-    updateStepLevel(curStep, curLevel, count = 1) {
-      if (curStep.type === "done") return;
-
-      const opos = this.steps.otherStep.findIndex(
-        item => item.type === curStep.type
-      );
-      this.steps.otherStep[opos].count -= count;
-
-      if (curStep.type === "shift") {
-        const spos = this.steps.otherStep.findIndex(
-          item => item.type === "shiftScore"
-        );
-        this.steps.otherStep[spos].count += count;
-      } else {
-        const pos = this.steps.levelStep.findIndex(
-          item => item.name === curLevel
-        );
-        this.steps.levelStep[pos].count += count;
-      }
-    },
-    async getWorkLevels() {
-      const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          ...item,
-          name: item.code
-        };
-      });
-    },
-    pageSizeChange(size) {
-      this.size = size;
-      this.toPage(1);
-      this.getStepLevels();
-    },
-    async stepChange(step) {
-      this.curStep = step;
-      // this.getStepLevels();
-      // this.toPage(1);
-      this.current = 1;
-      await this.getList();
-      this.getStepLevels();
-      if (this.papers.length) {
-        this.selectPaper(0);
-      } else {
-        this.curPaper = {};
-      }
-    },
-    async areaChange(curArea) {
-      this.curArea = curArea;
-      this.filter.questionId = curArea.id;
-      await this.getStepLevels();
-      this.toPage(1);
-      this.updateHistory();
-    },
-    toReview(index) {
-      this.isFullscreenMarking = true;
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      const lastPaper = { ...this.curPaper };
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-
-      // 待评时,检查当前试卷是否已经切换档位
-      if (
-        this.curStep.type === "undo" &&
-        this.curPaper["level"] &&
-        this.curPaper["level"] !== lastPaper["level"]
-      ) {
-        this.$Modal.info({
-          content: `即将打分档位:${this.curPaper.level}`
-        });
-      }
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        if (this.current > 1) {
-          this.current--;
-          this.curPaperIndex = this.size - 1;
-          await this.getList();
-        } else {
-          this.$Message.warning("当前已经是第一条数据了");
-          return;
-        }
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        if (this.current === this.totalPage) {
-          this.$Message.warning("当前已经是最后一条数据了");
-          return;
-        } else {
-          this.current++;
-          this.curPaperIndex = 0;
-          await this.getList();
-        }
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toActionNextPaper() {
-      if (this.current > 1 && this.papers.length === 1) {
-        this.current--;
-        this.curPaperIndex = this.size;
-      }
-
-      await this.getList();
-      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async gradingCurPaper({ selectedLevel }) {
-      await paperSelectLevelOrScore(
-        this.curPaper.id, // is taskId
-        selectedLevel,
-        "LEVEL"
-      );
-      this.updateStepLevel(this.curStep, "shiftScore");
-      this.toActionNextPaper();
-    },
-    async scoreCurPaper(info) {
-      const paper = await paperSelectLevelOrScore(
-        this.curPaper.id, // is taskId
-        info.score,
-        "SCORE",
-        info.manualScore
-      );
-      // this.getStepLevels();
-      this.updateStepLevel(this.curStep, this.curPaper.level);
-      this.updateCacheHistory([paper]);
-      this.toActionNextPaper();
-    },
-    async passCurPaper(level) {
-      await paperTaskPass(this.curPaper.id);
-      this.toActionNextPaper();
-    },
-    updateHistory() {
-      this.$refs.GradeHistoryPaper.updatePapers();
-    },
-    updateCacheHistory(papers) {
-      this.$refs.GradeHistoryPaper.updateCachePapers(papers);
-    },
-    // paper carousel
-    toViewCarouselPaper(paperIndex, papers) {
-      this.isFullscreenMarking = true;
-      this.carouselPapers = papers;
-      this.selectCarouselPaper(paperIndex);
-      this.$nextTick(() => {
-        this.$refs.CarouselPapersPreview.open();
-      });
-    },
-    selectCarouselPaper(index) {
-      this.curCarouselPaperIndex = index;
-      this.curPaper = { ...this.carouselPapers[index] };
-    },
-    toCarousePaper(type) {
-      if (type === "prev" && this.curCarouselPaperIndex > 0) {
-        this.curCarouselPaperIndex--;
-      } else if (
-        type === "next" &&
-        this.curCarouselPaperIndex < this.carouselPapers.length - 1
-      ) {
-        this.curCarouselPaperIndex++;
-      }
-      this.selectCarouselPaper(this.curCarouselPaperIndex);
-    },
-    carouseImagePreviewClose() {
-      this.isFullscreenMarking = false;
-      this.selectPaper(this.curPaperIndex);
-    }
-  }
-};
-</script>
+<template>
+  <div class="mark-operation grading-operation home">
+    <view-header> </view-header>
+    <div class="home-body">
+      <div class="home-main">
+        <div class="grading-detail page-container-flex">
+          <grade-filter
+            ref="GradeFilter"
+            :data="workSubject"
+            @change="areaChange"
+          ></grade-filter>
+          <mark-step
+            :steps="steps"
+            :init-step="curStep"
+            :show-count="showPaperRelateCount"
+            :show-top-number="false"
+            @on-change="stepChange"
+            ref="MarkStep"
+            v-if="steps.levelStep"
+          ></mark-step>
+          <div class="detail-body">
+            <!-- detail-papers -->
+            <div :class="detailPapersClasses">
+              <div class="detail-papers-carousel">
+                <grade-history-paper
+                  :question-id="filter.questionId"
+                  stage="SCORE"
+                  @on-paper-click="toViewCarouselPaper"
+                  v-if="filter.questionId"
+                  ref="GradeHistoryPaper"
+                ></grade-history-paper>
+              </div>
+              <div class="detail-papers-list" v-if="papers.length">
+                <div :class="imageViewClasses">
+                  <div
+                    :class="[
+                      'image-view',
+                      { 'image-view-act': curPaperIndex === index }
+                    ]"
+                    v-for="(image, index) in papers"
+                    :key="index"
+                  >
+                    <div class="image-view-container">
+                      <h5 class="image-view-title">{{ image.title }}</h5>
+                      <div class="image-view-contain">
+                        <img
+                          :src="image.thumbSrc"
+                          :alt="image.title"
+                          @click="toReview(index)"
+                        />
+                      </div>
+                      <div class="image-view-actions">
+                        <span
+                          v-if="image.score || image.score === 0"
+                          class="color-error"
+                          >{{ image.score }}分</span
+                        >
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div
+                  :class="[
+                    'part-page',
+                    { 'part-page-simple': !showPaperRelateCount }
+                  ]"
+                >
+                  <Page
+                    :current="current"
+                    :total="total"
+                    :page-size="size"
+                    :show-total="showPaperRelateCount"
+                    show-elevator
+                    :page-size-opts="[4, 6, 8]"
+                    @on-page-size-change="pageSizeChange"
+                    @on-change="toPage"
+                  ></Page>
+                </div>
+              </div>
+              <div class="detail-papers-list" v-else>
+                <p class="detail-papers-none">暂无数据</p>
+              </div>
+            </div>
+            <!-- detail-aciton -->
+            <div
+              :class="[
+                'detail-action',
+                { 'detail-action-fullscreen': isFullscreenMarking }
+              ]"
+            >
+              <mark-action
+                :cur-paper-or-task="curPaper"
+                :levels="levels"
+                :show-count="showPaperRelateCount"
+                :params-set="paramsSet"
+                @on-leader-level="gradingCurPaper"
+                @on-select-score="scoreCurPaper"
+                @on-pass="passCurPaper"
+                ref="GradeAction"
+                v-if="curPaper.id"
+              ></mark-action>
+            </div>
+            <!-- 占位 -->
+            <div class="detail-action" v-if="isFullscreenMarking"></div>
+          </div>
+        </div>
+
+        <!-- <view-footer></view-footer> -->
+      </div>
+    </div>
+
+    <!-- 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>
+
+<script>
+import {
+  getParamsSet,
+  markerTaskList,
+  markerChangeLevelPaperList,
+  markerScoreTotalStatData,
+  workLevelList,
+  subjectDetail,
+  paperSelectLevelOrScore,
+  markerManualScorePaperList,
+  paperTaskPass
+} from "@/api";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+import MarkStep from "./components/MarkStep";
+import GradeFilter from "../grading/components/GradeFilter";
+import GradeHistoryPaper from "../grading/components/GradeHistoryPaper";
+import MarkAction from "./components/MarkAction";
+// 三种情况:
+// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
+// 评卷员:操作记录,试卷列表,操作盘(打分)
+
+// TIP:不考虑管理员、科组长的情况
+// 管理员:试卷列表,操作盘
+// 科组长:操作记录,试卷列表,操作盘(改档)
+
+export default {
+  name: "mark-operation",
+  components: {
+    SimpleImagePreview,
+    MarkStep,
+    GradeFilter,
+    GradeHistoryPaper,
+    MarkAction
+  },
+  data() {
+    return {
+      filter: {
+        markerId: this.$ls.get("user").id,
+        questionId: ""
+      },
+      typeFilter: {
+        undo: {
+          sort: "paper.level",
+          stage: "SCORE"
+        },
+        done: {
+          level: "",
+          sort: "updatedOn,desc",
+          stage: "SCORE"
+        },
+        shift: {
+          isShift: true,
+          isShiftScore: false
+        },
+        shiftScore: {
+          isShift: false,
+          isShiftScore: true
+        },
+        manualScore: {}
+      },
+      workId: this.$route.params.workId,
+      subjectId: this.$route.params.subjectId,
+      subject: "",
+      workSubject: {},
+      curSubject: {},
+      curUserRoleType: "MARKER",
+      changeStage: 0, // 是否显示改档及改档打分
+      current: 1,
+      size: 6,
+      total: 0,
+      totalPage: 1,
+      curStep: null,
+      curStandardGradeId: "",
+      steps: [],
+      levels: [],
+      curArea: {},
+      papers: [],
+      curPaper: {},
+      curPaperIndex: 0,
+      paramsSet: {},
+      // carousel paper review,
+      carouselPapers: [],
+      curCarouselPaperIndex: 0,
+      isFullscreenMarking: false
+    };
+  },
+  computed: {
+    detailPapersClasses() {
+      return ["detail-papers", `detail-papers-col-${1 + this.size / 2}`];
+    },
+    imageViewClasses() {
+      return ["image-view-list", `image-view-list-${this.size / 2}`];
+    },
+    showPaperRelateCount() {
+      return !!this.paramsSet["showPaperCount"];
+    }
+  },
+  created() {
+    this.subject = this.subjectId.split("-")[1];
+    this.workSubject = {
+      workId: this.workId,
+      subject: this.subject
+    };
+    this.initData();
+  },
+  methods: {
+    async initData() {
+      await this.getParamsSetInfo();
+      await this.getWorkLevels();
+      // this.getSubjectDetail();
+    },
+    async getSubjectDetail() {
+      this.curSubject = await subjectDetail(this.subjectId);
+    },
+    async getParamsSetInfo() {
+      this.paramsSet = await getParamsSet(this.workId);
+      this.changeStage = this.paramsSet.changeStage;
+    },
+    async getList() {
+      const datas = {
+        ...this.filter,
+        ...this.typeFilter[this.curStep.type],
+        subject: this.subject,
+        workId: this.workId,
+        page: this.current - 1,
+        size: this.size
+      };
+      if (this.curStep.type === "done") {
+        datas.level = this.curStep.name;
+      }
+
+      let requestAction = null;
+      if (this.curStep.type.includes("shift")) {
+        requestAction = markerChangeLevelPaperList;
+      } else if (this.curStep.type === "manualScore") {
+        requestAction = markerManualScorePaperList;
+      } else {
+        requestAction = markerTaskList;
+      }
+
+      const data = await requestAction(datas);
+      this.papers = data.data.map(paper => {
+        paper.title = `NO.${paper.sn}`;
+        return paper;
+      });
+      this.total = data.totalCount;
+      this.totalPage = data.pageCount;
+    },
+    async toPage(page) {
+      this.current = page;
+      await this.getList();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async getStepLevels() {
+      const data = await markerScoreTotalStatData(
+        this.filter.markerId,
+        this.filter.questionId
+      );
+      const undoIndex = data.findIndex(item => item.id === null);
+      let otherStep = [];
+      let undo = {
+        count: 0,
+        shift: 0,
+        shiftScore: 0
+      };
+      if (undoIndex !== -1) {
+        undo = { ...data[undoIndex] };
+        data.splice(undoIndex, 1);
+      }
+      otherStep.push({
+        name: "待评",
+        count: undo.count,
+        type: "undo"
+      });
+
+      if (this.changeStage) {
+        otherStep.push({
+          name: "改档",
+          count: undo.shift,
+          type: "shift"
+        });
+        otherStep.push({
+          name: "改档打分",
+          count: undo.shiftScore,
+          type: "shiftScore"
+        });
+      }
+
+      let levelStep = data
+        .filter(item => item.id !== "manualScore")
+        .map(item => {
+          return {
+            ...item,
+            name: item.id,
+            type: "done"
+          };
+        });
+      const msInfo = data.find(item => item.id === "manualScore");
+      if (msInfo) {
+        levelStep.push({
+          count: msInfo.count,
+          name: "输分试卷",
+          type: "manualScore"
+        });
+      }
+
+      this.steps = { levelStep, otherStep };
+
+      if (!this.curStep) {
+        let curStep = {};
+        if (undoIndex === -1) {
+          curStep = levelStep[0];
+        } else {
+          curStep = otherStep[0];
+        }
+        this.curStep = curStep;
+      }
+    },
+    updateStepLevel(curStep, curLevel, count = 1) {
+      if (curStep.type === "done") return;
+
+      const opos = this.steps.otherStep.findIndex(
+        item => item.type === curStep.type
+      );
+      this.steps.otherStep[opos].count -= count;
+
+      if (curStep.type === "shift") {
+        const spos = this.steps.otherStep.findIndex(
+          item => item.type === "shiftScore"
+        );
+        this.steps.otherStep[spos].count += count;
+      } else {
+        const pos = this.steps.levelStep.findIndex(
+          item => item.name === curLevel
+        );
+        this.steps.levelStep[pos].count += count;
+      }
+    },
+    async getWorkLevels() {
+      const data = await workLevelList(this.workId);
+      this.levels = data.map(item => {
+        return {
+          ...item,
+          name: item.code
+        };
+      });
+    },
+    pageSizeChange(size) {
+      this.size = size;
+      this.toPage(1);
+      this.getStepLevels();
+    },
+    async stepChange(step) {
+      this.curStep = step;
+      // this.getStepLevels();
+      // this.toPage(1);
+      this.current = 1;
+      await this.getList();
+      this.getStepLevels();
+      if (this.papers.length) {
+        this.selectPaper(0);
+      } else {
+        this.curPaper = {};
+      }
+    },
+    async areaChange(curArea) {
+      this.curArea = curArea;
+      this.filter.questionId = curArea.id;
+      await this.getStepLevels();
+      this.toPage(1);
+      this.updateHistory();
+    },
+    toReview(index) {
+      this.isFullscreenMarking = true;
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      const lastPaper = { ...this.curPaper };
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+
+      // 待评时,检查当前试卷是否已经切换档位
+      if (
+        this.curStep.type === "undo" &&
+        this.curPaper["level"] &&
+        this.curPaper["level"] !== lastPaper["level"]
+      ) {
+        this.$Modal.info({
+          content: `即将打分档位:${this.curPaper.level}`
+        });
+      }
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        if (this.current > 1) {
+          this.current--;
+          this.curPaperIndex = this.size - 1;
+          await this.getList();
+        } else {
+          this.$Message.warning("当前已经是第一条数据了");
+          return;
+        }
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        if (this.current === this.totalPage) {
+          this.$Message.warning("当前已经是最后一条数据了");
+          return;
+        } else {
+          this.current++;
+          this.curPaperIndex = 0;
+          await this.getList();
+        }
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toActionNextPaper() {
+      if (this.current > 1 && this.papers.length === 1) {
+        this.current--;
+        this.curPaperIndex = this.size;
+      }
+
+      await this.getList();
+      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async gradingCurPaper({ selectedLevel }) {
+      await paperSelectLevelOrScore(
+        this.curPaper.id, // is taskId
+        selectedLevel,
+        "LEVEL"
+      );
+      this.updateStepLevel(this.curStep, "shiftScore");
+      this.toActionNextPaper();
+    },
+    async scoreCurPaper(info) {
+      const paper = await paperSelectLevelOrScore(
+        this.curPaper.id, // is taskId
+        info.score,
+        "SCORE",
+        info.manualScore
+      );
+      // this.getStepLevels();
+      this.updateStepLevel(this.curStep, this.curPaper.level);
+      this.updateCacheHistory([paper]);
+      this.toActionNextPaper();
+    },
+    async passCurPaper(level) {
+      await paperTaskPass(this.curPaper.id);
+      this.toActionNextPaper();
+    },
+    updateHistory() {
+      this.$refs.GradeHistoryPaper.updatePapers();
+    },
+    updateCacheHistory(papers) {
+      this.$refs.GradeHistoryPaper.updateCachePapers(papers);
+    },
+    // paper carousel
+    toViewCarouselPaper(paperIndex, papers) {
+      this.isFullscreenMarking = true;
+      this.carouselPapers = papers;
+      this.selectCarouselPaper(paperIndex);
+      this.$nextTick(() => {
+        this.$refs.CarouselPapersPreview.open();
+      });
+    },
+    selectCarouselPaper(index) {
+      this.curCarouselPaperIndex = index;
+      this.curPaper = { ...this.carouselPapers[index] };
+    },
+    toCarousePaper(type) {
+      if (type === "prev" && this.curCarouselPaperIndex > 0) {
+        this.curCarouselPaperIndex--;
+      } else if (
+        type === "next" &&
+        this.curCarouselPaperIndex < this.carouselPapers.length - 1
+      ) {
+        this.curCarouselPaperIndex++;
+      }
+      this.selectCarouselPaper(this.curCarouselPaperIndex);
+    },
+    carouseImagePreviewClose() {
+      this.isFullscreenMarking = false;
+      this.selectPaper(this.curPaperIndex);
+    }
+  }
+};
+</script>

+ 4 - 3
src/modules/mark/components/MarkAction.vue

@@ -131,7 +131,7 @@
         </p>
       </Form>
     </div>
-    <div class="action-grade-pass" v-if="rights.levelList" @click="toPass">
+    <div class="action-grade-pass" v-if="rights.levelPass" @click="toPass">
       跳过
     </div>
 
@@ -281,6 +281,7 @@ const initRights = {
   markInfo: false,
   gradeList: false,
   levelList: false,
+  levelPass: false,
   markHis: false
 };
 
@@ -328,9 +329,9 @@ export default {
         },
         MARKER: {
           done: ["levelList", "gradeInfo", "markInfo"],
-          undo: ["levelList", "gradeInfo"],
+          undo: ["levelList", "levelPass", "gradeInfo"],
           shift: ["gradeChange"],
-          shiftScore: ["levelList", "gradeInfo"]
+          shiftScore: ["levelList", "levelPass", "gradeInfo"]
         }
       },
       filter: {

+ 325 - 325
src/modules/quality/Quality.vue

@@ -1,325 +1,325 @@
-<template>
-  <div class="quality home">
-    <view-header> </view-header>
-
-    <div class="home-body">
-      <div class="home-main">
-        <div class="page-container-flex">
-          <div class="part-box part-box-filter">
-            <Form ref="FilterForm" label-position="left" inline>
-              <FormItem>
-                <Select
-                  v-model="filter.workId"
-                  @on-change="workChange"
-                  placeholder="工作文件夹"
-                  style="width: 150px"
-                >
-                  <Option
-                    v-for="(work, windex) in works"
-                    :key="windex"
-                    :value="work.id"
-                    :label="work.name"
-                  ></Option>
-                </Select>
-              </FormItem>
-              <FormItem>
-                <Select
-                  v-model="filter.subject"
-                  @on-change="subjectChange"
-                  placeholder="科目"
-                >
-                  <Option
-                    v-for="subject in subjects"
-                    :key="subject.id"
-                    :value="subject.subject"
-                    :label="subject.name"
-                  ></Option>
-                </Select>
-              </FormItem>
-              <FormItem>
-                <Select v-model="filter.areaCode" placeholder="考区">
-                  <Option
-                    v-for="area in areas"
-                    :key="area.id"
-                    :value="area.areaCode"
-                    :label="area.areaName"
-                  ></Option>
-                </Select>
-              </FormItem>
-              <FormItem>
-                <Input
-                  v-model="filter.startNumber"
-                  type="text"
-                  placeholder="输入开始编号"
-                  clearable
-                />
-              </FormItem>
-              <FormItem>
-                <Input
-                  v-model="filter.endNumber"
-                  type="text"
-                  placeholder="输入结束编号"
-                  clearable
-                />
-              </FormItem>
-              <FormItem>
-                <Select
-                  v-model="paperType"
-                  @on-change="typeChange"
-                  placeholder="类型"
-                >
-                  <Option
-                    v-for="(val, key) in CAFA_EXCEPTION_TYPE"
-                    :key="key"
-                    :value="key"
-                    :label="val"
-                  ></Option>
-                </Select>
-              </FormItem>
-              <FormItem>
-                <Input
-                  v-model.trim="filter.studentName"
-                  placeholder="输入姓名"
-                  clearable
-                ></Input>
-              </FormItem>
-              <FormItem>
-                <Select v-model="filter.sortBy" placeholder="排序方式">
-                  <Option
-                    v-for="(val, key) in SORT_RULE_TYPE"
-                    :key="key"
-                    :value="key"
-                    :label="val"
-                  ></Option>
-                </Select>
-              </FormItem>
-              <FormItem>
-                <Button
-                  class="btn-form-search"
-                  size="small"
-                  type="primary"
-                  @click="toPage(1)"
-                  >查询</Button
-                >
-              </FormItem>
-            </Form>
-          </div>
-
-          <image-action-list
-            v-if="papers.length"
-            :data="papers"
-            :column-number="4"
-            :actions="imageListActions"
-            @on-review="toReview"
-            ref="ImageActionList"
-          ></image-action-list>
-
-          <div class="part-page" v-if="total > size">
-            <Page
-              :current="current"
-              :total="total"
-              :page-size="size"
-              show-total
-              show-elevator
-              @on-change="toPage"
-            ></Page>
-          </div>
-        </div>
-
-        <!-- <view-footer></view-footer> -->
-      </div>
-    </div>
-
-    <!-- image-preview -->
-    <simple-image-preview
-      :cur-image="curPaper"
-      @on-prev="toPrevPaper"
-      @on-next="toNextPaper"
-      ref="SimpleImagePreview"
-    ></simple-image-preview>
-  </div>
-</template>
-
-<script>
-import { workList, areaList, paperPageList } from "@/api";
-import { SORT_RULE_TYPE, CAFA_EXCEPTION_TYPE } from "@/constants/enumerate";
-import ImageActionList from "../main/components/ImageActionList";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-
-export default {
-  name: "quality",
-  components: { ImageActionList, SimpleImagePreview },
-  data() {
-    return {
-      filter: {
-        workId: null,
-        subject: null,
-        areaCode: null,
-        startNumber: null,
-        endNumber: null,
-        isManual: null,
-        missing: null,
-        studentName: "",
-        sortBy: "1"
-      },
-      paperType: "2",
-      selectPaperType: "0",
-      SORT_RULE_TYPE,
-      CAFA_EXCEPTION_TYPE: {},
-      current: 1,
-      size: 8,
-      total: 0,
-      totalPage: 0,
-      papers: [],
-      works: [],
-      subjects: [],
-      areas: [],
-      curPaper: {},
-      curPaperIndex: 0
-    };
-  },
-  computed: {
-    imageListActions() {
-      return this.selectPaperType === "1" ? [] : ["rotate", "absent"];
-    }
-  },
-  mounted() {
-    this.CAFA_EXCEPTION_TYPE = { ...CAFA_EXCEPTION_TYPE, 2: "全部" };
-    this.initData();
-  },
-  methods: {
-    async initData() {
-      await this.getWorkList();
-      this.filter.workId = this.works[0].id;
-      this.workChange();
-      await this.getAreaList();
-      this.filter.areaCode = this.areas[0].areaCode;
-      this.getList();
-    },
-    async getWorkList() {
-      this.works = await workList();
-    },
-    async getAreaList() {
-      const data = await areaList({
-        workId: this.filter.workId,
-        subject: this.filter.subject
-      });
-      this.areas = data.map(item => {
-        return {
-          id: item.id,
-          areaName: item.areaName,
-          areaCode: item.areaCode
-        };
-      });
-      if (this.areas.length === 1) {
-        this.filter.areaCode = this.areas[0].areaCode;
-      }
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        page: this.current - 1,
-        size: this.size
-      };
-      this.papers = [];
-      const data = await paperPageList(datas);
-      this.papers = data.data.map(paper => {
-        return {
-          id: paper.id,
-          key: this.$randomCode(),
-          title: paper.examNumber,
-          imgSrc: paper.imgSrc,
-          thumbSrc: paper.thumbSrc,
-          missing: paper.missing,
-          stage: paper.stage,
-          styles: {},
-          deg: 0
-        };
-      });
-      this.total = data.totalCount;
-      this.totalPage = data.pageCount;
-      this.selectPaperType = this.paperType;
-    },
-    toPage(page) {
-      this.current = page;
-      this.papers = [];
-      this.getList();
-    },
-    workChange() {
-      this.filter.subject = null;
-      this.filter.areaCode = null;
-      const curWork = this.works.find(item => item.id === this.filter.workId);
-      this.subjects = curWork.subjects;
-      this.filter.subject = this.subjects[0].subject;
-      this.subjectChange();
-    },
-    subjectChange() {
-      this.areas = [];
-      this.filter.areaCode = null;
-      if (!this.filter.subject) return;
-      this.getAreaList();
-    },
-    typeChange() {
-      if (this.paperType === "1") {
-        this.filter.isManual = true;
-        this.filter.missing = null;
-      } else if (this.paperType === "0") {
-        this.filter.isManual = null;
-        this.filter.missing = true;
-      } else {
-        this.filter.isManual = null;
-        this.filter.missing = null;
-      }
-    },
-    // paper view
-    toReview(index) {
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        if (this.current > 1) {
-          this.current--;
-          this.curPaperIndex = this.size - 1;
-          await this.getList();
-        } else {
-          this.$Message.warning("当前已经是第一条数据了");
-          return;
-        }
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        if (this.current === this.totalPage) {
-          this.$Message.warning("当前已经是最后一条数据了");
-          return;
-        } else {
-          this.current++;
-          this.curPaperIndex = 0;
-          await this.getList();
-        }
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    }
-  }
-};
-</script>
+<template>
+  <div class="quality home">
+    <view-header> </view-header>
+
+    <div class="home-body">
+      <div class="home-main">
+        <div class="page-container-flex">
+          <div class="part-box part-box-filter">
+            <Form ref="FilterForm" label-position="left" inline>
+              <FormItem>
+                <Select
+                  v-model="filter.workId"
+                  @on-change="workChange"
+                  placeholder="工作文件夹"
+                  style="width: 150px"
+                >
+                  <Option
+                    v-for="(work, windex) in works"
+                    :key="windex"
+                    :value="work.id"
+                    :label="work.name"
+                  ></Option>
+                </Select>
+              </FormItem>
+              <FormItem>
+                <Select
+                  v-model="filter.subject"
+                  @on-change="subjectChange"
+                  placeholder="科目"
+                >
+                  <Option
+                    v-for="subject in subjects"
+                    :key="subject.id"
+                    :value="subject.subject"
+                    :label="subject.name"
+                  ></Option>
+                </Select>
+              </FormItem>
+              <FormItem>
+                <Select v-model="filter.areaCode" placeholder="考区">
+                  <Option
+                    v-for="area in areas"
+                    :key="area.id"
+                    :value="area.areaCode"
+                    :label="area.areaName"
+                  ></Option>
+                </Select>
+              </FormItem>
+              <FormItem>
+                <Input
+                  v-model="filter.startNumber"
+                  type="text"
+                  placeholder="输入开始编号"
+                  clearable
+                />
+              </FormItem>
+              <FormItem>
+                <Input
+                  v-model="filter.endNumber"
+                  type="text"
+                  placeholder="输入结束编号"
+                  clearable
+                />
+              </FormItem>
+              <FormItem>
+                <Select
+                  v-model="paperType"
+                  @on-change="typeChange"
+                  placeholder="类型"
+                >
+                  <Option
+                    v-for="(val, key) in CAFA_EXCEPTION_TYPE"
+                    :key="key"
+                    :value="key"
+                    :label="val"
+                  ></Option>
+                </Select>
+              </FormItem>
+              <FormItem>
+                <Input
+                  v-model.trim="filter.studentName"
+                  placeholder="输入姓名"
+                  clearable
+                ></Input>
+              </FormItem>
+              <FormItem>
+                <Select v-model="filter.sortBy" placeholder="排序方式">
+                  <Option
+                    v-for="(val, key) in SORT_RULE_TYPE"
+                    :key="key"
+                    :value="key"
+                    :label="val"
+                  ></Option>
+                </Select>
+              </FormItem>
+              <FormItem>
+                <Button
+                  class="btn-form-search"
+                  size="small"
+                  type="primary"
+                  @click="toPage(1)"
+                  >查询</Button
+                >
+              </FormItem>
+            </Form>
+          </div>
+
+          <image-action-list
+            v-if="papers.length"
+            :data="papers"
+            :column-number="4"
+            :actions="imageListActions"
+            @on-review="toReview"
+            ref="ImageActionList"
+          ></image-action-list>
+
+          <div class="part-page">
+            <Page
+              :current="current"
+              :total="total"
+              :page-size="size"
+              show-total
+              show-elevator
+              @on-change="toPage"
+            ></Page>
+          </div>
+        </div>
+
+        <!-- <view-footer></view-footer> -->
+      </div>
+    </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
+  </div>
+</template>
+
+<script>
+import { workList, areaList, paperPageList } from "@/api";
+import { SORT_RULE_TYPE, CAFA_EXCEPTION_TYPE } from "@/constants/enumerate";
+import ImageActionList from "../main/components/ImageActionList";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+
+export default {
+  name: "quality",
+  components: { ImageActionList, SimpleImagePreview },
+  data() {
+    return {
+      filter: {
+        workId: null,
+        subject: null,
+        areaCode: null,
+        startNumber: null,
+        endNumber: null,
+        isManual: null,
+        missing: null,
+        studentName: "",
+        sortBy: "1"
+      },
+      paperType: "2",
+      selectPaperType: "0",
+      SORT_RULE_TYPE,
+      CAFA_EXCEPTION_TYPE: {},
+      current: 1,
+      size: 8,
+      total: 0,
+      totalPage: 0,
+      papers: [],
+      works: [],
+      subjects: [],
+      areas: [],
+      curPaper: {},
+      curPaperIndex: 0
+    };
+  },
+  computed: {
+    imageListActions() {
+      return this.selectPaperType === "1" ? [] : ["rotate", "absent"];
+    }
+  },
+  mounted() {
+    this.CAFA_EXCEPTION_TYPE = { ...CAFA_EXCEPTION_TYPE, 2: "全部" };
+    this.initData();
+  },
+  methods: {
+    async initData() {
+      await this.getWorkList();
+      this.filter.workId = this.works[0].id;
+      this.workChange();
+      await this.getAreaList();
+      this.filter.areaCode = this.areas[0].areaCode;
+      this.getList();
+    },
+    async getWorkList() {
+      this.works = await workList();
+    },
+    async getAreaList() {
+      const data = await areaList({
+        workId: this.filter.workId,
+        subject: this.filter.subject
+      });
+      this.areas = data.map(item => {
+        return {
+          id: item.id,
+          areaName: item.areaName,
+          areaCode: item.areaCode
+        };
+      });
+      if (this.areas.length === 1) {
+        this.filter.areaCode = this.areas[0].areaCode;
+      }
+    },
+    async getList() {
+      const datas = {
+        ...this.filter,
+        page: this.current - 1,
+        size: this.size
+      };
+      this.papers = [];
+      const data = await paperPageList(datas);
+      this.papers = data.data.map(paper => {
+        return {
+          id: paper.id,
+          key: this.$randomCode(),
+          title: paper.examNumber,
+          imgSrc: paper.imgSrc,
+          thumbSrc: paper.thumbSrc,
+          missing: paper.missing,
+          stage: paper.stage,
+          styles: {},
+          deg: 0
+        };
+      });
+      this.total = data.totalCount;
+      this.totalPage = data.pageCount;
+      this.selectPaperType = this.paperType;
+    },
+    toPage(page) {
+      this.current = page;
+      this.papers = [];
+      this.getList();
+    },
+    workChange() {
+      this.filter.subject = null;
+      this.filter.areaCode = null;
+      const curWork = this.works.find(item => item.id === this.filter.workId);
+      this.subjects = curWork.subjects;
+      this.filter.subject = this.subjects[0].subject;
+      this.subjectChange();
+    },
+    subjectChange() {
+      this.areas = [];
+      this.filter.areaCode = null;
+      if (!this.filter.subject) return;
+      this.getAreaList();
+    },
+    typeChange() {
+      if (this.paperType === "1") {
+        this.filter.isManual = true;
+        this.filter.missing = null;
+      } else if (this.paperType === "0") {
+        this.filter.isManual = null;
+        this.filter.missing = true;
+      } else {
+        this.filter.isManual = null;
+        this.filter.missing = null;
+      }
+    },
+    // paper view
+    toReview(index) {
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        if (this.current > 1) {
+          this.current--;
+          this.curPaperIndex = this.size - 1;
+          await this.getList();
+        } else {
+          this.$Message.warning("当前已经是第一条数据了");
+          return;
+        }
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        if (this.current === this.totalPage) {
+          this.$Message.warning("当前已经是最后一条数据了");
+          return;
+        } else {
+          this.current++;
+          this.curPaperIndex = 0;
+          await this.getList();
+        }
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    }
+  }
+};
+</script>