zhangjie %!s(int64=4) %!d(string=hai) anos
pai
achega
d8b9718883

+ 1 - 0
package.json

@@ -13,6 +13,7 @@
     "core-js": "^3.6.4",
     "deepmerge": "^4.2.2",
     "echarts": "^4.7.0",
+    "js-md5": "^0.7.3",
     "view-design": "^4.2.0",
     "vue": "^2.6.11",
     "vue-echarts": "^5.0.0-beta.0",

+ 11 - 5
src/api.js

@@ -54,20 +54,22 @@ export const clientMonitorList = datas => {
 
 // student-manage
 export const studentPageList = datas => {
-  // TODO:考区-学校-考场 联动查询
   return $get("/api/students", datas);
 };
 export const updateStudent = datas => {
-  // TODO:考区-学校-考场 联动查询
   if (datas.id) {
-    return $put(`/api/students/${datas.id}`, datas);
+    return $put(`/api/students/${datas.id}`, datas, "json");
   } else {
-    return $post(`/api/students`, datas);
+    return $post(`/api/students`, datas, "json");
   }
 };
 export const deleteStudent = studentId => {
   return $del(`/api/students/${studentId}`, {});
 };
+export const areaSchoolRoomCascadeList = workId => {
+  // 考区-学校-考场 联动查询
+  return $get(`/api/students/select/${workId}`);
+};
 
 // client-set -------------------------->
 // client-user-set
@@ -139,7 +141,11 @@ export const updateScoreParams = datas => {
 export const levelsPropReport = datas => {
   return $get("/api/quality/levelsPropReport", datas);
 };
-// 差值和
+// 累计偏差(差值和)
+export const deviationReport = datas => {
+  return $get("/api/quality/deviationReport", datas);
+};
+// 累计误差(差值绝对值之和)
 export const distanceReport = datas => {
   return $get("/api/quality/distanceReport", datas);
 };

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

@@ -634,6 +634,11 @@
       }
     }
   }
+  .action-item-content-disabled {
+    background: #eee !important;
+    color: @btn-disable-color!important;
+    cursor: not-allowed !important;
+  }
   .action-grade-history {
     text-align: left;
     > h3 {

+ 14 - 21
src/components/UploadButton.vue

@@ -32,7 +32,7 @@
           'cc-tips-error': !res.success
         }
       ]"
-      v-if="res.msg"
+      v-if="res.msg && !res.success"
     >
       {{ res.msg }}
     </p>
@@ -40,6 +40,7 @@
 </template>
 
 <script>
+import { fileMD5 } from "../plugins/md5";
 const prefixCls = "cc-upload-button";
 
 export default {
@@ -72,12 +73,6 @@ export default {
         return {};
       }
     },
-    headers: {
-      type: Object,
-      default() {
-        return {};
-      }
-    },
     maxSize: {
       type: Number,
       default: 10 * 1024
@@ -96,6 +91,7 @@ export default {
       prefixCls,
       modalIsShow: false,
       loading: false,
+      headers: { md5: "" },
       uploadDataDict: {},
       file: null,
       res: {
@@ -125,8 +121,10 @@ export default {
         this.$refs.UploadComp.post(this.file);
       }
     },
-    handleBeforeUpload(file) {
-      this.uploadDataDict = { ...this.uploadData };
+    async handleBeforeUpload(file) {
+      const md5 = await fileMD5(file);
+      this.headers.md5 = md5;
+      this.uploadDataDict = { ...this.uploadData, md5 };
       if (this.addFilenameParam)
         this.uploadDataDict[this.addFilenameParam] = file.name;
       this.$emit("file-change", file);
@@ -148,30 +146,25 @@ export default {
     },
     handleSuccess(response) {
       this.loading = false;
-      if (response) {
-        this.res = {
-          success: true,
-          msg: "上传成功!"
-        };
-        this.$emit("upload-success", response);
-      } else {
-        this.res = {
-          success: false,
-          msg: response.message || "上传失败"
-        };
-      }
+      this.res = {
+        success: true,
+        msg: "上传成功!"
+      };
+      this.$emit("upload-success", response);
     },
     handleFormatError() {
       this.res = {
         success: false,
         msg: "只支持文件格式为" + this.format.join("/")
       };
+      this.loading = false;
     },
     handleExceededSize() {
       this.res = {
         success: false,
         msg: "文件大小不能超过" + Math.floor(this.maxSize / 1024) + "M"
       };
+      this.loading = false;
     },
     handleRemove() {
       this.resData = "";

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

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

+ 1 - 1
src/components/common/ImportFile/ImportFile.vue

@@ -147,7 +147,7 @@ export default {
     handleSuccess(response) {
       if (response) {
         this.res = this.uploadSuccessHandle(response);
-        this.$emit("upload-success", response);
+        this.$emit("upload-success", { success: true, data: response });
       } else {
         this.res = {
           success: false,

+ 5 - 1
src/modules/client-set/ClientAccountSet.vue

@@ -5,7 +5,7 @@
       type="success"
       icon="recode-white icon"
       shape="circle"
-      @click="toEdit({})"
+      @click="toAdd"
       >添加账号</Button
     >
     <Table
@@ -126,6 +126,10 @@ export default {
     getRowClassName(row) {
       return row.enabled ? "" : "row-disabled";
     },
+    toAdd() {
+      this.curUser = {};
+      this.$refs.ModifyClientUser.open();
+    },
     toEdit(row) {
       if (!row.enabled) return;
       this.curUser = row;

+ 0 - 1
src/modules/client-set/InspectionAccountSet.vue

@@ -4,7 +4,6 @@
       ref="TableList"
       :columns="columns"
       :data="users"
-      :row-class-name="getRowClassName"
       disabled-hover
       border
     ></Table>

+ 1 - 0
src/modules/client-set/components/ModifyClientUser.vue

@@ -88,6 +88,7 @@ export default {
   },
   methods: {
     initData(val) {
+      this.$refs.modalFormComp.resetFields();
       if (val.id) {
         this.modalForm = this.$objAssign(initModalForm, val);
       } else {

+ 2 - 9
src/modules/grading-set/UploadPaper.vue

@@ -11,16 +11,12 @@
         <td>{{ area.questionName }}</td>
         <td v-for="(subject, index) in area.subjects" :key="index">
           <upload-button
-            :btn-type="subject.paperUrl ? 'primary' : 'default'"
+            :btn-type="subject.url ? 'primary' : 'default'"
             btn-icon="md-cloud-upload"
             btn-content="上传试卷"
             :upload-url="subject.uploadUrl"
             :format="['pdf', 'png', 'jpg']"
-            @upload-success="
-              response => {
-                this.uploadSuccess(response, subject);
-              }
-            "
+            @upload-success="getData"
           ></upload-button>
         </td>
       </tr>
@@ -58,9 +54,6 @@ export default {
         return area;
       });
       this.subjects = this.papers[0].subjects;
-    },
-    uploadSuccess(response, subject) {
-      subject.paperUrl = response.data.url;
     }
   }
 };

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

@@ -279,7 +279,7 @@ export default {
 
       const data = await paperList(datas);
       this.papers = data.data.map(paper => {
-        paper.title = paper.examNumber;
+        paper.title = this.IS_ADMIN ? paper.examNumber : `NO.${paper.sn}`;
         return paper;
       });
       this.total = data.totalCount;
@@ -378,7 +378,9 @@ export default {
       this.current--;
       await this.getList();
       this.selectPaper(this.papers.length - 1);
-      if (this.papers.length) this.$refs.ImagePreview.initData();
+      this.$nextTick(() => {
+        if (this.papers.length) this.$refs.ImagePreview.initData();
+      });
     },
     async nextPage() {
       if (this.current === this.totalPage) {
@@ -394,7 +396,9 @@ export default {
       // 下一页时,继续获取当前页数据。
       await this.getList();
       this.selectPaper(0);
-      if (this.papers.length) this.$refs.ImagePreview.initData();
+      this.$nextTick(() => {
+        if (this.papers.length) this.$refs.ImagePreview.initData();
+      });
     },
     toNext() {
       this.$refs.ImagePreview.showNext();

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

@@ -369,7 +369,9 @@ export default {
       this.current--;
       await this.getList();
       this.selectPaper(this.papers.length - 1);
-      if (this.papers.length) this.$refs.ImagePreview.initData();
+      this.$nextTick(() => {
+        if (this.papers.length) this.$refs.ImagePreview.initData();
+      });
     },
     async nextPage() {
       if (this.current === this.totalPage) {
@@ -385,7 +387,9 @@ export default {
       // 下一页时,继续获取当前页数据。
       await this.getList();
       this.selectPaper(0);
-      if (this.papers.length) this.$refs.ImagePreview.initData();
+      this.$nextTick(() => {
+        if (this.papers.length) this.$refs.ImagePreview.initData();
+      });
     },
     async gradeCurPaper(level) {
       const data = await paperSelectLevelOrScore(

+ 8 - 4
src/modules/grading/GradingProgress.vue

@@ -93,14 +93,14 @@
     <!-- modify-unformal-grading-task -->
     <modify-unformal-grading-task
       :cur-subject="curSubject"
-      @modified="getData"
+      @modified="taskSubmitSuccess"
       ref="ModifyUnformalGradingTask"
       v-if="curSubject.id"
     ></modify-unformal-grading-task>
     <!-- modify-formal-grading-task -->
     <modify-formal-grading-task
       :subject-id="subjectId"
-      @modified="getData"
+      @modified="taskSubmitSuccess"
       ref="ModifyFormalGradingTask"
     ></modify-formal-grading-task>
   </div>
@@ -176,10 +176,10 @@ export default {
   },
   mounted() {
     this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
-    this.getData();
+    this.initData();
   },
   methods: {
-    async getData() {
+    async initData() {
       await this.getSubjectDetail();
       this.getProgressDetail();
     },
@@ -237,6 +237,10 @@ export default {
         }
       });
     },
+    taskSubmitSuccess() {
+      this.$parent.initData();
+      this.initData();
+    },
     toExportStandard() {
       window.open(
         `${this.GLOBAL.domain}/api/export/paper/${this.curSubject.workId}/${this.curSubject.subject}/sample`

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

@@ -62,7 +62,13 @@
         v-for="(level, index) in levels"
         :key="index"
       >
-        <div class="action-grade-item-content" @click="selectLevel(level)">
+        <div
+          :class="[
+            'action-grade-item-content',
+            { 'action-item-content-disabled': btnClicked }
+          ]"
+          @click="selectLevel(level)"
+        >
           <p>{{ level.name }}</p>
           <p>{{ level.minScore }}~{{ level.maxScore }}</p>
         </div>
@@ -220,7 +226,9 @@ export default {
       stepType: "",
       stepLabel: "",
       gradingHistory: [],
-      curLevel: {}
+      curLevel: {},
+      setT: null,
+      btnClicked: false
     };
   },
   computed: {
@@ -244,7 +252,7 @@ export default {
   },
   methods: {
     getStepType() {
-      const info = this.curinfoOrTask;
+      const info = this.curPaperOrTask;
       if (info.sample) return "sample";
       if (info.level) return "done";
       if (info.arbitrated) return "arbitrate";
@@ -291,6 +299,13 @@ export default {
       });
     },
     selectLevel(level) {
+      if (this.btnClicked) return;
+      this.btnClicked = true;
+
+      this.setT = setTimeout(() => {
+        this.btnClicked = false;
+      }, 500);
+
       if (this.IS_MARK_LEADER) {
         this.$emit(
           "on-leader-level",
@@ -308,6 +323,7 @@ export default {
         );
         return;
       }
+
       this.$emit("on-select-level", level);
     },
     toPass() {
@@ -316,6 +332,9 @@ export default {
     searchCode() {
       this.$emit("on-code-search", this.filter);
     }
+  },
+  beforeDestroy() {
+    if (this.setT) clearTimeout(this.setT);
   }
 };
 </script>

+ 1 - 2
src/modules/grading/components/GradeHistoryPaper.vue

@@ -37,8 +37,7 @@ export default {
   },
   computed: {
     title() {
-      // TODO:根据不同试卷状态,展示不同信息
-      return this.curPaper.title;
+      return this.curPaper.sn ? `NO.${this.curPaper.sn}` : "";
     }
   },
   watch: {

+ 1 - 0
src/modules/grading/components/ModifyFormalGradingTask.vue

@@ -98,6 +98,7 @@ export default {
   methods: {
     visibleChange(visible) {
       if (visible) {
+        this.$refs.modalFormComp.resetFields();
         this.getArea();
       }
     },

+ 1 - 0
src/modules/grading/components/ModifyGradingUser.vue

@@ -182,6 +182,7 @@ export default {
   },
   methods: {
     initData(val) {
+      this.$refs.modalFormComp.resetFields();
       this.modalForm = this.$objAssign(initModalForm, val);
     },
     visibleChange(visible) {

+ 9 - 1
src/modules/inspection/InspectionGrading.vue

@@ -113,7 +113,14 @@
 
       <div class="check-grade-body part-box">
         <div class="check-grade-list image-view-list image-view-list-4">
-          <div class="image-view" v-for="(image, index) in papers" :key="index">
+          <div
+            :class="[
+              'image-view',
+              { 'image-view-act': curPaperIndex === index }
+            ]"
+            v-for="(image, index) in papers"
+            :key="index"
+          >
             <h5 class="image-view-title">{{ image.title }}</h5>
             <div class="image-view-contain">
               <img
@@ -232,6 +239,7 @@ export default {
       });
       this.total = data.totalCount;
       this.totalPage = data.pageCount;
+      this.selectPaper(0);
     },
     toPage(page) {
       this.current = page;

+ 1 - 0
src/modules/login/ResetPwd.vue

@@ -122,6 +122,7 @@ export default {
   methods: {
     visibleChange(visible) {
       if (visible) {
+        this.$refs.resetForm.resetFields();
         this.reset = { ...initModalForm };
         this.userId = this.$ls.get("user", { id: "" }).id;
       }

+ 22 - 3
src/modules/main/PaperManage.vue

@@ -45,11 +45,16 @@
           ></InputNumber>
         </FormItem>
         <FormItem>
-          <Select v-model="filter.isAbsent" placeholder="试卷类型">
+          <Select
+            v-model="paperType"
+            @on-change="typeChange"
+            placeholder="类型"
+            clearable
+          >
             <Option
               v-for="(val, key) in CAFA_EXCEPTION_TYPE"
               :key="key"
-              :value="key * 1"
+              :value="key"
               :label="val"
             ></Option>
           </Select>
@@ -119,10 +124,12 @@ export default {
         endNumber: null,
         subject: "",
         sort: "",
-        isAbsent: ""
+        isManual: false,
+        missing: true
       },
       SORT_RULE_TYPE,
       CAFA_EXCEPTION_TYPE,
+      paperType: "0",
       current: 1,
       size: this.GLOBAL.pageSize,
       total: 0,
@@ -180,6 +187,18 @@ export default {
     async getSubjects() {
       const data = await subjectList(this.filter.workId);
       this.subjects = data.filter(item => item.enable && item.stage === "INIT");
+    },
+    typeChange() {
+      if (this.paperType === "1") {
+        this.filter.isManual = true;
+        this.filter.missing = false;
+      } else if (this.paperType === "0") {
+        this.filter.isManual = false;
+        this.filter.missing = true;
+      } else {
+        this.filter.isManual = false;
+        this.filter.missing = false;
+      }
     }
   }
 };

+ 9 - 10
src/modules/main/QualityAnalysis.vue

@@ -71,10 +71,10 @@
         </div>
       </Col>
       <Col span="12">
-        <div class="part-box" v-if="absReportData">
+        <div class="part-box" v-if="deviationReportData">
           <echart-render
             chart-title="累计偏差"
-            :chart-data="absReportData"
+            :chart-data="deviationReportData"
             :chart-color="['#FF7786']"
             chart-type="barReverse"
           ></echart-render>
@@ -110,6 +110,7 @@
 <script>
 import {
   levelsPropReport,
+  deviationReport,
   distanceReport,
   callbackReport,
   subjectList,
@@ -133,7 +134,7 @@ export default {
       searchTime: [],
       levelsPropReportData: null,
       distanceReportData: null,
-      absReportData: null,
+      deviationReportData: null,
       callbackReportData: null,
       subjects: [],
       areas: []
@@ -201,6 +202,7 @@ export default {
       });
       const requests = [
         levelsPropReport(datas),
+        deviationReport(datas),
         distanceReport(datas),
         callbackReport(datas)
       ];
@@ -208,14 +210,11 @@ export default {
 
       this.levelsPropReportData = this.parseGroupBarData(data[0]);
 
-      this.distanceReportData = this.parseBarData(data[1]);
-      // TODO:
-      this.absReportData = {
-        names: ["zj-pj-01", "zj-pj-02", "zj-pj-03", "zj-pj-04"],
-        dataList: [-2, 5, -4, 3]
-      };
+      this.deviationReportData = this.parseBarData(data[1]);
+
+      this.distanceReportData = this.parseBarData(data[2]);
 
-      this.callbackReportData = this.parseBarData(data[2]);
+      this.callbackReportData = this.parseBarData(data[3]);
     },
     searchTimeChange(val) {
       this.filter.startTime = val[0] || null;

+ 62 - 44
src/modules/main/StudentManage.vue

@@ -29,36 +29,40 @@
       <Form ref="FilterForm" label-position="left" inline>
         <FormItem>
           <Select
-            v-model="filter.subject"
-            @on-change="subjectChange"
-            placeholder="选择科目"
+            v-model="filter.areaCode"
+            @on-change="areaChange"
+            placeholder="选择考区"
           >
             <Option
-              v-for="(subject, index) in subjects"
-              :key="index"
-              :value="subject.subject"
-              >{{ subject.name }}</Option
-            >
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.areaCode" placeholder="选择考区">
-            <Option
-              v-for="area in areas"
-              :key="area.id"
+              v-for="area in cascadeList"
+              :key="area.areaCode"
               :value="area.areaCode"
               :label="area.areaName"
             ></Option>
           </Select>
         </FormItem>
         <FormItem>
-          <Select v-model="filter.schoolId" placeholder="选择学校">
-            <Option value=""></Option>
+          <Select
+            v-model="filter.school"
+            @on-change="schoolChange"
+            placeholder="学校"
+          >
+            <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="选择考场">
-            <Option value=""></Option>
+          <Select v-model="filter.examRoom" placeholder="考场">
+            <Option
+              v-for="(room, index) in rooms"
+              :key="index"
+              :value="room"
+              :label="room"
+            ></Option>
           </Select>
         </FormItem>
 
@@ -98,7 +102,7 @@
           </Select>
         </FormItem>
         <FormItem>
-          <Select v-model="filter.upload" placeholder="选择状态">
+          <Select v-model="filter.upload" placeholder="是否上传">
             <Option
               v-for="(val, key) in PAPER_UPLOAD_TYPE"
               :key="key"
@@ -166,6 +170,7 @@
     </import-file>
     <!-- modify-student -->
     <modify-student
+      :cascade-list="cascadeList"
       :instance="curStudent"
       @modified="getList"
       ref="ModifyStudent"
@@ -174,7 +179,12 @@
 </template>
 
 <script>
-import { areaList, subjectList, studentPageList, deleteStudent } from "@/api";
+import {
+  subjectList,
+  studentPageList,
+  deleteStudent,
+  areaSchoolRoomCascadeList
+} from "@/api";
 import ImportFile from "@/components/common/ImportFile";
 import ModifyStudent from "./components/ModifyStudent";
 import { BOOLEAN_TYPE, PAPER_UPLOAD_TYPE } from "@/constants/enumerate";
@@ -186,15 +196,15 @@ export default {
     return {
       filter: {
         workId: this.$route.params.workId,
-        name: "",
-        schoolId: "",
+        subject: null,
+        areaCode: null,
+        school: "",
         examRoom: "",
         startNumber: null,
         endNumber: null,
-        subject: null,
-        areaCode: null,
+        name: "",
         upload: null,
-        isAbsent: 0
+        isAbsent: null
       },
       current: 1,
       size: this.GLOBAL.pageSize,
@@ -202,7 +212,9 @@ export default {
       students: [],
       curStudent: {},
       subjects: [],
-      areas: [],
+      cascadeList: [],
+      schools: [],
+      rooms: [],
       BOOLEAN_TYPE,
       PAPER_UPLOAD_TYPE,
       columns: [
@@ -232,7 +244,7 @@ export default {
         },
         {
           title: "学校",
-          key: "sourceName",
+          key: "school",
           minWidth: 150
         },
         {
@@ -298,12 +310,12 @@ export default {
   methods: {
     async iniData() {
       await this.getSubjects();
+      this.getAreaList();
       this.getList();
     },
     async getList() {
       const datas = {
-        // ...this.filter,
-        workId: this.filter.workId,
+        ...this.filter,
         page: this.current - 1,
         size: this.size
       };
@@ -328,17 +340,7 @@ export default {
       this.getList();
     },
     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
-        };
-      });
+      this.cascadeList = await areaSchoolRoomCascadeList(this.filter.workId);
     },
     async getSubjects() {
       const data = await subjectList(this.filter.workId);
@@ -352,9 +354,24 @@ export default {
         this.columns.splice(this.columns.length - 1, 0, column);
       });
     },
-    subjectChange() {
-      this.filter.areaCode = "";
-      this.getAreaList();
+    areaChange() {
+      const curArea = this.cascadeList.find(
+        item => item.areaCode === this.filter.areaCode
+      );
+      this.schools = curArea.schools;
+      this.rooms = [];
+      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.rooms;
+      this.filter.examRoom = null;
     },
     toEdit(row) {
       this.curStudent = row;
@@ -390,6 +407,7 @@ export default {
     uploadSuccess(result) {
       if (!result.success) return;
       this.getList();
+      this.getAreaList();
     },
     toDelete(row) {
       this.$Modal.confirm({

+ 54 - 11
src/modules/main/components/ModifyStudent.vue

@@ -36,18 +36,30 @@
         <Select
           size="large"
           v-model="modalForm.areaCode"
+          @on-change="areaChange"
           placeholder="请选择考区"
         >
-          <Option value=""></Option>
+          <Option
+            v-for="area in cascadeList"
+            :key="area.areaCode"
+            :value="area.areaCode"
+            :label="area.areaName"
+          ></Option>
         </Select>
       </FormItem>
-      <FormItem prop="schoolId" label="学校">
+      <FormItem prop="school" label="学校">
         <Select
           size="large"
-          v-model="modalForm.schoolId"
+          v-model="modalForm.school"
+          @on-change="schoolChange"
           placeholder="请选择学校"
         >
-          <Option value=""></Option>
+          <Option
+            v-for="(item, index) in schools"
+            :key="index"
+            :value="item.school"
+            :label="item.school"
+          ></Option>
         </Select>
       </FormItem>
       <FormItem prop="examRoom" label="考场">
@@ -56,7 +68,12 @@
           v-model="modalForm.examRoom"
           placeholder="请选择考场"
         >
-          <Option value=""></Option>
+          <Option
+            v-for="(room, index) in rooms"
+            :key="index"
+            :value="room"
+            :label="room"
+          ></Option>
         </Select>
       </FormItem>
     </Form>
@@ -73,11 +90,11 @@
 import { updateStudent } from "@/api";
 
 const initModalForm = {
-  id: "",
+  id: null,
   name: "",
   examNumber: "",
   areaCode: "",
-  schoolID: "",
+  school: "",
   examRoom: ""
 };
 
@@ -89,6 +106,12 @@ export default {
       default() {
         return {};
       }
+    },
+    cascadeList: {
+      type: Array,
+      default() {
+        return [];
+      }
     }
   },
   computed: {
@@ -103,6 +126,8 @@ export default {
     return {
       modalIsShow: false,
       isSubmit: false,
+      schools: [],
+      rooms: [],
       modalForm: { ...initModalForm },
       rules: {
         name: [
@@ -145,6 +170,7 @@ export default {
   },
   methods: {
     initData(val) {
+      this.$refs.modalFormComp.resetFields();
       if (val.id) {
         this.modalForm = this.$objAssign(initModalForm, val);
       } else {
@@ -156,6 +182,25 @@ export default {
         this.initData(this.instance);
       }
     },
+    areaChange() {
+      const curArea = this.cascadeList.find(
+        item => item.areaCode === this.modalForm.areaCode
+      );
+      this.schools = curArea.schools;
+      this.rooms = [];
+      this.modalForm.examRoom = null;
+      if (curArea.schools.length === 1) {
+        this.modalForm.school = curArea.schools[0].school;
+        this.schoolChange();
+      }
+    },
+    schoolChange() {
+      const curSchool = this.schools.find(
+        item => item.school === this.modalForm.school
+      );
+      this.rooms = curSchool.rooms;
+      this.modalForm.examRoom = null;
+    },
     cancel() {
       this.modalIsShow = false;
     },
@@ -168,13 +213,11 @@ export default {
 
       if (this.isSubmit) return;
       this.isSubmit = true;
-      const data = await updateStudent(this.modalForm).catch(() => {
-        this.isSubmit = false;
-      });
+      const data = await updateStudent(this.modalForm).catch(() => {});
+      this.isSubmit = false;
 
       if (!data) return;
 
-      this.isSubmit = false;
       this.$Message.success(this.title + "成功!");
       this.$emit("modified");
       this.cancel();

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

@@ -266,7 +266,7 @@ export default {
         data = await changeLevelPaperList(datas);
       }
       this.papers = data.data.map(paper => {
-        paper.title = paper.examNumber;
+        paper.title = this.IS_ADMIN ? paper.examNumber : `NO.${paper.sn}`;
         return paper;
       });
       this.total = data.totalCount;
@@ -355,7 +355,9 @@ export default {
       this.current--;
       await this.getList();
       this.selectPaper(this.papers.length - 1);
-      if (this.papers.length) this.$refs.ImagePreview.initData();
+      this.$nextTick(() => {
+        if (this.papers.length) this.$refs.ImagePreview.initData();
+      });
     },
     async nextPage() {
       if (this.current === this.totalPage) {
@@ -371,7 +373,9 @@ export default {
       // 下一页时,继续获取当前页数据。
       await this.getList();
       this.selectPaper(0);
-      if (this.papers.length) this.$refs.ImagePreview.initData();
+      this.$nextTick(() => {
+        if (this.papers.length) this.$refs.ImagePreview.initData();
+      });
     },
     toNext() {
       this.$refs.ImagePreview.showNext();

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

@@ -375,7 +375,9 @@ export default {
       this.current--;
       await this.getList();
       this.selectPaper(this.papers.length - 1);
-      if (this.papers.length) this.$refs.ImagePreview.initData();
+      this.$nextTick(() => {
+        if (this.papers.length) this.$refs.ImagePreview.initData();
+      });
     },
     async nextPage() {
       if (this.current === this.totalPage) {
@@ -391,7 +393,9 @@ export default {
       // 下一页时,继续获取当前页数据。
       await this.getList();
       this.selectPaper(0);
-      if (this.papers.length) this.$refs.ImagePreview.initData();
+      this.$nextTick(() => {
+        if (this.papers.length) this.$refs.ImagePreview.initData();
+      });
     },
     async gradingCurPaper({ selectedLevel }) {
       const data = await paperSelectLevelOrScore(

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

@@ -275,6 +275,7 @@ export default {
       this.isSubmit = false;
       if (!result) return;
       this.$Message.success("任务创建成功!");
+      this.cancel();
       this.areaChange();
     }
   }

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

@@ -109,7 +109,13 @@
         v-for="(level, index) in levels"
         :key="index"
       >
-        <div class="action-grade-item-content" @click="selectLevel(level)">
+        <div
+          :class="[
+            'action-grade-item-content',
+            { 'action-item-content-disabled': btnClicked }
+          ]"
+          @click="selectLevel(level)"
+        >
           <p>{{ level.name }}</p>
           <p>{{ level.minScore }}~{{ level.maxScore }}</p>
         </div>
@@ -122,8 +128,14 @@
         v-for="(score, index) in scores"
         :key="index"
       >
-        <div class="action-mark-item-content">
-          <p @click="selectScore(score)">{{ score }}</p>
+        <div
+          :class="[
+            'action-mark-item-content',
+            { 'action-item-content-disabled': btnClicked }
+          ]"
+          @click="selectScore(score)"
+        >
+          <p>{{ score }}</p>
         </div>
       </div>
     </div>
@@ -283,7 +295,9 @@ export default {
       curPaperScore: "",
       scores: [],
       gradingHistory: [],
-      curLevel: {}
+      curLevel: {},
+      setT: null,
+      btnClicked: false
     };
   },
   computed: {
@@ -365,6 +379,14 @@ export default {
     },
     selectLevel(level) {
       if (this.curPaperOrTask.level === level.name) return;
+
+      if (this.btnClicked) return;
+      this.btnClicked = true;
+
+      this.setT = setTimeout(() => {
+        this.btnClicked = false;
+      }, 500);
+
       // 科组长改档
       this.$emit("on-leader-level", {
         paperId: this.curPaperOrTask.id,
@@ -373,6 +395,12 @@ export default {
       });
     },
     selectScore(score) {
+      if (this.btnClicked) return;
+      this.btnClicked = true;
+
+      this.setT = setTimeout(() => {
+        this.btnClicked = false;
+      }, 500);
       // 评卷员打分
       this.$emit("on-select-score", score * 1);
     },

+ 23 - 0
src/plugins/md5.js

@@ -0,0 +1,23 @@
+const md5 = require("js-md5");
+
+/**
+ *
+ * @param {any} str 字符串
+ */
+export const MD5 = content => {
+  return md5(content);
+};
+
+export const fileMD5 = file => {
+  return new Promise((resolve, reject) => {
+    const reader = new FileReader();
+    reader.onloadend = function() {
+      const arrayBuffer = reader.result;
+      resolve(md5(arrayBuffer));
+    };
+    reader.onerror = function(err) {
+      reject(err);
+    };
+    reader.readAsArrayBuffer(file);
+  });
+};

+ 5 - 0
yarn.lock

@@ -4951,6 +4951,11 @@ js-calendar@^1.2.3:
   resolved "https://registry.npm.taobao.org/js-calendar/download/js-calendar-1.2.3.tgz#a583b0644b4e695ba394f344d103dbcc7a7a7d3e"
   integrity sha1-pYOwZEtOaVujlPNE0QPbzHp6fT4=
 
+js-md5@^0.7.3:
+  version "0.7.3"
+  resolved "https://registry.npm.taobao.org/js-md5/download/js-md5-0.7.3.tgz#b4f2fbb0b327455f598d6727e38ec272cd09c3f2"
+  integrity sha1-tPL7sLMnRV9ZjWcn447Ccs0Jw/I=
+
 js-message@1.0.5:
   version "1.0.5"
   resolved "https://registry.npm.taobao.org/js-message/download/js-message-1.0.5.tgz#2300d24b1af08e89dd095bc1a4c9c9cfcb892d15"