zhangjie 5 роки тому
батько
коміт
4196e17fb8
34 змінених файлів з 601 додано та 538 видалено
  1. 4 4
      dev-proxy.copy.js
  2. 81 64
      src/api.js
  3. 15 8
      src/components/ViewHeader.vue
  4. 2 2
      src/components/common/ImagePreview/ImagePreview.vue
  5. 1 1
      src/config.js
  6. 8 8
      src/constants/apiTempData.js
  7. 4 4
      src/constants/chartOptions.js
  8. 63 51
      src/modules/client-set/ClientParamSet.vue
  9. 10 52
      src/modules/client-set/InspectionAccountSet.vue
  10. 5 4
      src/modules/client-set/components/ModifyClientUser.vue
  11. 7 7
      src/modules/grading-set/GradingLevelSet.vue
  12. 27 27
      src/modules/grading-set/GradingRuleSet.vue
  13. 1 1
      src/modules/grading/Grading.vue
  14. 69 70
      src/modules/grading/GradingDetail.vue
  15. 8 4
      src/modules/grading/GradingUserManage.vue
  16. 46 3
      src/modules/grading/components/GradeAction.vue
  17. 1 1
      src/modules/grading/components/GradeStandardPaper.vue
  18. 6 9
      src/modules/grading/components/ModifyGradingUser.vue
  19. 1 1
      src/modules/grading/components/PaperCarousel.vue
  20. 6 2
      src/modules/inspection/InspectionGrading.vue
  21. 15 8
      src/modules/login/ResetPwd.vue
  22. 1 1
      src/modules/main/ClientMonitor.vue
  23. 1 1
      src/modules/main/Main.vue
  24. 20 11
      src/modules/main/PaperManage.vue
  25. 58 23
      src/modules/main/QualityAnalysis.vue
  26. 32 15
      src/modules/main/StudentManage.vue
  27. 44 108
      src/modules/main/StudentScore.vue
  28. 3 9
      src/modules/main/WorkOverview.vue
  29. 6 6
      src/modules/main/components/ImageActionList.vue
  30. 19 22
      src/modules/mark-set/MarkRuleSet.vue
  31. 8 4
      src/modules/mark/MarkDetail.vue
  32. 1 1
      src/modules/quality/Quality.vue
  33. 27 6
      src/plugins/axios.js
  34. 1 0
      src/routers/grading.js

+ 4 - 4
dev-proxy.copy.js

@@ -1,9 +1,9 @@
 module.exports = {
   "/api/": {
     target: "http://192.168.10.239:9888",
-    changeOrigin: true,
-    pathRewrite: {
-      "^/api": "/"
-    }
+    changeOrigin: true
+    // pathRewrite: {
+    //   "^/api": "/"
+    // }
   }
 };

+ 81 - 64
src/api.js

@@ -2,18 +2,24 @@ import { $get, $post, $del, $patch, $put } from "@/plugins/axios";
 
 // login
 export const login = datas => {
-  return $post("/login", datas);
+  return $post("/api/login", datas);
 };
-export const modifyPwd = datas => {
-  return $post("/backend/sysuser/resetPwd", datas);
+export const logout = () => {
+  return $del("/api/logout");
 };
-export const resetPwd = datas => {
-  return $post("/backend/sysuser/resetPwd", datas);
+export const resetPwd = ({ userId, password }) => {
+  return $patch(`/api/${userId}/password`, { password }, "json");
 };
 
 // work-manage
 export const workList = () => {
-  return $get("/api/admin/works", {});
+  return $get("/api/admin/works");
+};
+export const workDetail = workId => {
+  return $get(`/api/admin/works/${workId}`);
+};
+export const updateWork = datas => {
+  return $put(`/api/admin/works/${datas.id}`, datas, "json");
 };
 export const createWork = datas => {
   return $post("/api/admin/works", datas);
@@ -22,12 +28,12 @@ export const activeWork = workId => {
   return $patch(`/api/admin/works/${workId}`, {});
 };
 export const deleteWork = workId => {
-  return $del(`/api/admin/works/${workId}`, {});
+  return $del(`/api/admin/works/${workId}`);
 };
 
 // work-overview
 export const workOverviewDetail = workId => {
-  return $get(`/api/admin/works/${workId}/overview`, {});
+  return $get(`/api/admin/works/${workId}/overview`);
 };
 
 // paper-manage
@@ -43,15 +49,18 @@ export const absentPaper = imageId => {
 
 // client-monitor
 export const clientMonitorList = datas => {
+  // TODO:
   // return $get("/api/papers/listByQuestion", datas);
   return Promise.resolve(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);
   } else {
@@ -69,99 +78,86 @@ export const clientUserPageList = datas => {
 };
 export const updateClientUser = datas => {
   if (datas.id) {
-    return $put(`/api/admin/users/collect/${datas.id}`, datas);
+    return $put(`/api/admin/users/collect/${datas.id}`, datas, "json");
   } else {
-    return $post("/api/admin/users/collect", datas);
+    return $post("/api/admin/users/collect", datas, "json");
   }
 };
 export const deleteClientUser = userId => {
   return $del(`/api/admin/users/collect/${userId}`, {});
 };
-// inspection-user-set  TODO:换成真是的账号
-export const inspectionUserPageList = datas => {
-  return $get("/api/admin/users/collect", datas);
-};
-export const updateInspectionUser = datas => {
-  if (datas.id) {
-    return $put(`/api/admin/users/collect/${datas.id}`, datas);
-  } else {
-    return $post("/api/admin/users/collect", datas);
-  }
+// inspection-user-set
+export const inspectionUserPageList = () => {
+  return $get("/api/admin/users/inspection");
 };
 export const deleteInspectionUser = userId => {
   return $del(`/api/admin/users/collect/${userId}`, {});
 };
 // client-param-set -------------------------->
 // subject-set
-export const subjectList = datas => {
-  // return $get("/api/admin/subjects", datas);
-  return Promise.resolve(datas);
+export const subjectList = workId => {
+  return $get(`/api/marksubjects/${workId}/subjects`);
 };
 export const subjectDetail = subjectId => {
-  // return $get("/api/admin/subjects", datas);
-  return Promise.resolve({ id: subjectId, name: "素描" });
+  return $get(`/api/marksubjects/${subjectId}`);
 };
 export const updateSubject = datas => {
   if (datas.id) {
-    return $put(`/api/admin/subject/${datas.id}`, datas);
+    return $post(`/api/marksubjects/${datas.id}/updateName`, datas);
   } else {
-    return $post("/api/admin/subject", datas);
+    return $post(`/api/marksubjects/${datas.id}`, datas);
   }
 };
-export const deleteSubject = subjectId => {
-  return $del(`/api/admin/subject/${subjectId}`, {});
+export const enableSubject = subjectId => {
+  return $post(`/api/marksubjects/${subjectId}/updateEnable`, {});
+};
+// param-set
+export const getParamsSet = workId => {
+  return $get("/api/param/getParam", { workId });
+};
+export const updateCollectParams = datas => {
+  return $post("/api/param/collect", datas);
 };
 
 // grading-set -------------------------->
 // grading-level-set
-export const levelList = workId => {
-  return $get(`/api/admin/works/${workId}`, {});
-};
-export const updateLevel = datas => {
-  return $put(`/api/admin/works/${datas.id}`, datas);
-};
+// TO workDetail and updateWork
+
 // grading-rule-set
-export const gradingRuleDetail = workId => {
-  // TODO:
-  return Promise.resolve({});
-  // return $get(`/api/admin/works/${workId}`, {});
-};
-export const saveGradingRule = datas => {
-  // TODO:
-  return $post(`/api/admin/works/${datas.id}`, datas);
+export const updateLevelParams = datas => {
+  return $post("/api/param/level", datas);
 };
 // update-paper
 // grading-rule-set
 export const updatePaperDetail = () => {
-  // TODO:
+  // TODO:获取试卷上传状态
   return Promise.resolve({});
   // return $get(`/api/admin/works/${workId}`, {});
 };
 
 // mark-set -------------------------->
 // mark-rule-set
-export const markRuleDetail = workId => {
-  // TODO:
-  return Promise.resolve({});
-  // return $get(`/api/admin/works/${workId}`, {});
-};
-export const saveMarkRule = datas => {
-  // TODO:
-  return $post(`/api/admin/works/${datas.id}`, datas);
+export const updateScoreParams = datas => {
+  return $post("/api/param/score", datas, "json");
 };
 
 // quality-analysis -------------------------->
-export const qualityAnalysisDetail = datas => {
-  // TODO:
-  return Promise.resolve(datas);
-  // return $get(`/api/admin/works/${workId}`, {});
+// 档位占比
+export const levelsPropReport = datas => {
+  return $get("/api/quality/levelsPropReport", datas);
+};
+// 差值和
+export const distanceReport = datas => {
+  return $get("/api/quality/distanceReport", datas);
+};
+// 打回次数
+export const callbackReport = datas => {
+  return $get("/api/quality/callbackReport", datas);
 };
 
 // student-score -------------------------->
 export const studentScoreList = datas => {
-  // TODO:
-  return Promise.resolve(datas);
-  // return $get(`/api/admin/works/${workId}`, {});
+  return $get(`/api/papers/studentScore`, datas);
 };
 
 // grading -------------------------->
@@ -171,10 +167,9 @@ export const gradingUserList = datas => {
 };
 export const updateGradingUser = datas => {
   if (datas.id) {
-    return $put(`/api/admin/users/${datas.id}`, datas);
-    // TODO:跟新之后没有返回任何东西,需要改一下
+    return $put(`/api/admin/users/${datas.id}`, datas, "json");
   } else {
-    return $post("/api/admin/users", datas);
+    return $post("/api/admin/users", datas, "json");
   }
 };
 export const deleteGradingUser = userId => {
@@ -188,10 +183,11 @@ export const updateGradingGroup = (subjectId, datas) => {
   if (datas.groupId) {
     return $patch(
       `/api/marksubjects/${subjectId}/markergroups/${datas.groupId}`,
-      datas
+      datas,
+      "json"
     );
   } else {
-    return $post(`/api/marksubjects/${subjectId}/markergroups`, datas);
+    return $post(`/api/marksubjects/${subjectId}/markergroups`, datas, "json");
   }
 };
 export const deleteGradingGroup = (subjectId, groupId) => {
@@ -213,6 +209,27 @@ export const createGradingTask = datas => {
   // TODO:
   return $post(`/api/marksubjects/${datas.subjectId}/markergroups`, datas);
 };
+// grading-detail
+// level relate
+export const workLevelList = workId => {
+  return $get(`/api/admin/works/${workId}/levels`);
+};
+export const levelStatData = (subjectId, questionId) => {
+  return $get(`/api/marksubjects/${subjectId}/stat/levels`, { questionId });
+};
+// area
+export const areaList = ({ workId, subject }) => {
+  return $get("/api/questions", { workId, subject });
+};
+// papers
+export const paperList = datas => {
+  // ?questionId=64&level=A&page=0&size=6&sort=secretNumber&isSample=true
+  return $get("/api/papers", datas);
+};
+// grade or mark history
+export const markHistoryList = (paperId, stage) => {
+  return $get(`/api/papers/${paperId}/marktasks`, { stage });
+};
 
 // mark -------------------------->
 // mark-progress

+ 15 - 8
src/components/ViewHeader.vue

@@ -9,7 +9,9 @@
       <span class="user-name"
         ><Icon type="md-person" size="16" /> {{ username }}</span
       >
-      <span class="user-name" @click="toResetPwd">修改密码</span>
+      <span class="user-name" @click="toResetPwd" v-if="showResetPwd"
+        >修改密码</span
+      >
       <span class="user-logout" title="退出登录" @click="logout">
         <Icon type="md-power" size="20" />
       </span>
@@ -24,23 +26,28 @@
 
 <script>
 import ResetPwd from "../modules/login/ResetPwd";
+import { logout } from "@/api";
 
 export default {
   name: "view-header",
   components: { ResetPwd },
-  data() {
-    return {};
-  },
-  computed: {
-    username() {
-      return this.$store.state.user.name;
+  props: {
+    showResetPwd: {
+      type: Boolean,
+      default: true
     }
   },
+  data() {
+    return {
+      username: this.$ls.get("user", { name: "" }).name
+    };
+  },
   methods: {
     toResetPwd() {
       this.$refs.ResetPwd.open();
     },
-    logout() {
+    async logout() {
+      await logout();
       this.$ls.clear();
       this.$router.push({ name: "Login" });
     }

+ 2 - 2
src/components/common/ImagePreview/ImagePreview.vue

@@ -41,7 +41,7 @@
         v-move-ele.prevent="{ mouseMove }"
         v-show="!loading"
       >
-        <img :src="curFile.url" :alt="curFile.name" ref="PreviewImgDetail" />
+        <img :src="curFile.imgSrc" :alt="curFile.name" ref="PreviewImgDetail" />
       </div>
     </div>
     <div :class="[`${prefixCls}-footer`]">
@@ -116,7 +116,7 @@ export default {
     return {
       prefixCls,
       modalIsShow: false,
-      curFile: { name: "", url: null },
+      curFile: { name: "", imgSrc: null },
       curIndex: 0,
       minScale: 0.2,
       maxScale: 3,

+ 1 - 1
src/config.js

@@ -1,5 +1,5 @@
 export default {
-  domain: process.env.VUE_APP_DOMAIN || window.location.origin + "/apis",
+  domain: process.env.VUE_APP_DOMAIN || window.location.origin,
   timeout: process.env.VUE_APP_TIMEOUT * 1,
   pageSize: process.env.VUE_APP_PAGE_SIZE * 1,
   authTimeout: process.env.VUE_APP_AUTH_TIMEOUT * 1

+ 8 - 8
src/constants/apiTempData.js

@@ -9,7 +9,7 @@ export const papers = [
     updatedOn: 1574665102000,
     url:
       "http://127.0.0.1:9000/api/file/image/download/31/1/734/1?random=676176fc-24cd-407a-a7bc-fabc49bd2dbc",
-    thumbUrl:
+    thumbSrc:
       "http://127.0.0.1:9000/api/file/image/download/31/1/734/2?random=d8d100c5-ac64-4b5a-a2fe-bce2dd8aed0f",
     markByLeader: false,
     markedLogic: false,
@@ -39,7 +39,7 @@ export const papers = [
     updatedOn: 1574665113000,
     url:
       "http://127.0.0.1:9000/api/file/image/download/31/1/733/1?random=e2966291-ffba-4b19-985d-0cad9ae1b75b",
-    thumbUrl:
+    thumbSrc:
       "http://127.0.0.1:9000/api/file/image/download/31/1/733/2?random=5d16ebc7-0e52-493c-93fa-4850db5e2632",
     markByLeader: false,
     markedLogic: false,
@@ -69,7 +69,7 @@ export const papers = [
     updatedOn: 1574753749000,
     url:
       "http://127.0.0.1:9000/api/file/image/download/31/1/731/1?random=b305c27c-76d0-4477-a1ef-c9b8554a4671",
-    thumbUrl:
+    thumbSrc:
       "http://127.0.0.1:9000/api/file/image/download/31/1/731/2?random=dd1a4e72-9314-4429-a5e8-dacfa5275397",
     markByLeader: false,
     markedLogic: false,
@@ -99,7 +99,7 @@ export const papers = [
     updatedOn: 1574665550000,
     url:
       "http://127.0.0.1:9000/api/file/image/download/31/1/736/1?random=d90a96e7-1d1a-426b-8428-b5c980589fe1",
-    thumbUrl:
+    thumbSrc:
       "http://127.0.0.1:9000/api/file/image/download/31/1/736/2?random=dc754e3b-7a92-4a59-a34c-e67a09253e7b",
     markByLeader: false,
     markedLogic: false,
@@ -129,7 +129,7 @@ export const papers = [
     updatedOn: 1577325078000,
     url:
       "http://127.0.0.1:9000/api/file/image/download/31/1/735/1?random=e6ea4c48-e2d0-470e-a0db-5e7642cad923",
-    thumbUrl:
+    thumbSrc:
       "http://127.0.0.1:9000/api/file/image/download/31/1/735/2?random=4ddc167d-8bb3-443d-8d5d-6a725fab9950",
     markByLeader: false,
     markedLogic: false,
@@ -159,7 +159,7 @@ export const papers = [
     updatedOn: 1574836896000,
     url:
       "http://127.0.0.1:9000/api/file/image/download/31/1/737/1?random=68a6e70f-8983-4445-82dd-f71499ad7441",
-    thumbUrl:
+    thumbSrc:
       "http://127.0.0.1:9000/api/file/image/download/31/1/737/2?random=33db53ee-04b2-4d46-89bc-7bf276d839e2",
     markByLeader: false,
     markedLogic: false,
@@ -189,7 +189,7 @@ export const papers = [
     updatedOn: 1577325083000,
     url:
       "http://127.0.0.1:9000/api/file/image/download/31/1/738/1?random=9f788228-2213-4a46-9461-b222e310950b",
-    thumbUrl:
+    thumbSrc:
       "http://127.0.0.1:9000/api/file/image/download/31/1/738/2?random=7adb5c94-b42a-4a50-8920-aaa88134b3f3",
     markByLeader: false,
     markedLogic: false,
@@ -219,7 +219,7 @@ export const papers = [
     updatedOn: 1573718404000,
     url:
       "http://127.0.0.1:9000/api/file/image/download/31/1/732/1?random=b1cdc3f5-8cae-4e8e-ba92-e1df640ba001",
-    thumbUrl:
+    thumbSrc:
       "http://127.0.0.1:9000/api/file/image/download/31/1/732/2?random=32b1cb60-a0d5-4253-9fb6-03863a88e2b2",
     markByLeader: true,
     markedLogic: false,

+ 4 - 4
src/constants/chartOptions.js

@@ -57,7 +57,7 @@ function getLineOption(datas, title) {
   };
 }
 
-function getPieOption(datas, title) {
+function getPieOption(datas) {
   if (!datas.chartLabels.length) return;
   var seriesData = datas.chartLabels.map(function(item, index) {
     return {
@@ -107,7 +107,7 @@ function getBarOption(datas, title) {
   if (!datas.names.length) return;
   return {
     title: {
-      text: title || "档位占比分析表",
+      text: title,
       left: 0
     },
     grid: {
@@ -196,7 +196,7 @@ function getBarGroupOption(datas, title) {
 
   var options = {
     title: {
-      text: title || "差值曲线分析表",
+      text: title,
       left: 0
     },
     grid: {
@@ -302,7 +302,7 @@ function getLineGroupOption(datas, title) {
   });
   return {
     title: {
-      text: title || "差值总和分析表",
+      text: title,
       left: 0
     },
     grid: {

+ 63 - 51
src/modules/client-set/ClientParamSet.vue

@@ -9,11 +9,12 @@
               <tr :key="index">
                 <td>
                   <Input
-                    v-model="subject.subjectName"
+                    v-model="subject.name"
                     @on-blur="checkSubjectValidate(subject)"
                     :disabled="!subject.enable"
                     :readonly="!subject.canEdit"
-                    clearable
+                    :clearable="subject.canEdit"
+                    :ref="subject.id"
                   ></Input>
                 </td>
                 <td style="width: 180px;">
@@ -45,7 +46,7 @@
                 v-if="subject.errors"
                 :key="index + '1'"
               >
-                <td>{{ subject.errors.subjectName }}</td>
+                <td>{{ subject.errors.name }}</td>
                 <td></td>
               </tr>
             </template>
@@ -57,7 +58,7 @@
           <h2 class="client-param-title">其他设置</h2>
           <Form ref="modalFormComp" :model="modalForm" :label-width="120">
             <FormItem label="是否整包扫描:">
-              <RadioGroup v-model="modalForm.isScanPackage">
+              <RadioGroup v-model="modalForm.packageScan">
                 <Radio
                   v-for="(val, key) in BOOLEAN_TYPE"
                   :key="key"
@@ -68,7 +69,7 @@
               </RadioGroup>
             </FormItem>
             <FormItem label="图片是否加密:">
-              <RadioGroup v-model="modalForm.isImageEncryption">
+              <RadioGroup v-model="modalForm.imageEncrypt">
                 <Radio
                   v-for="(val, key) in BOOLEAN_TYPE"
                   :key="key"
@@ -78,9 +79,9 @@
                 >
               </RadioGroup>
             </FormItem>
-            <FormItem prop="imageNameRule" label="图片命名规则:">
+            <FormItem label="图片命名规则:">
               <Select
-                v-model="modalForm.imageNameRule"
+                v-model="modalForm.nameRule"
                 placeholder="请选择图片命名规则"
               >
                 <Option
@@ -91,9 +92,9 @@
                 ></Option>
               </Select>
             </FormItem>
-            <FormItem prop="paperGrading" label="试卷档位:">
+            <FormItem label="试卷档位:">
               <Select
-                v-model="modalForm.imageNameRule"
+                v-model="modalForm.paperStage"
                 placeholder="请选择试卷档位"
               >
                 <Option
@@ -105,7 +106,9 @@
               </Select>
             </FormItem>
             <FormItem>
-              <Button type="primary" @click="toSubmit">保存</Button>
+              <Button type="primary" :disabled="isSubmit" @click="toSubmit"
+                >保存</Button
+              >
             </FormItem>
           </Form>
         </div>
@@ -115,7 +118,13 @@
 </template>
 
 <script>
-import { subjectList, updateSubject, deleteSubject } from "@/api";
+import {
+  subjectList,
+  updateSubject,
+  enableSubject,
+  getParamsSet,
+  updateCollectParams
+} from "@/api";
 import {
   BOOLEAN_TYPE,
   IMAGE_NAME_TYPE,
@@ -126,7 +135,7 @@ schema.warning = function() {};
 
 const initSubject = {
   id: "",
-  subjectName: "",
+  name: "",
   enable: true,
   canEdit: false,
   password: ""
@@ -139,40 +148,52 @@ export default {
       BOOLEAN_TYPE,
       IMAGE_NAME_TYPE,
       PAPER_LEVEL_KNOWN_TYPE,
+      workId: this.$route.params.workId,
       subjects: [],
       // other param
-      modalForm: {
-        isScanPackage: 0,
-        isImageEncryption: 0,
-        imageNameRule: 0,
-        paperGrading: 0
-      }
+      isSubmit: false,
+      initModalForm: {
+        workId: "",
+        packageScan: 0,
+        imageEncrypt: 0,
+        nameRule: 0,
+        paperStage: 0
+      },
+      modalForm: {}
     };
   },
   mounted() {
+    this.modalForm = { ...this.initModalForm };
     this.getList();
+    this.getParamsSetInfo();
   },
   methods: {
     async getList() {
-      const datas = {
-        workId: this.workId
-      };
-      const data = await subjectList(datas);
-
-      console.log(data);
-
-      if (!this.subjects.length) this.toAdd();
+      const data = await subjectList(this.workId);
+      this.subjects = data.map(item => {
+        return {
+          ...item,
+          canEdit: false
+        };
+      });
     },
+
     toAdd() {
       this.subjects.push({ ...initSubject });
     },
     toEdit(index) {
       const row = this.subjects[index];
       row.canEdit = true;
+      this.$refs[row.id][0].focus();
+    },
+    async toAble(index) {
+      const row = this.subjects[index];
+      await enableSubject(row.id);
+      row.enable = !row.enable;
     },
     checkSubjectValidate(subject) {
       const descriptor = {
-        subjectName: [
+        name: [
           {
             required: true,
             min: 2,
@@ -203,32 +224,23 @@ export default {
       row.canEdit = false;
       this.$Message.success("保存成功!");
     },
-    toAble(index) {
-      const row = this.subjects[index];
-      row.enable = !row.enable;
-      // TODO:
-      console.log(row);
+    // param-set
+    async getParamsSetInfo() {
+      const data = await getParamsSet(this.workId);
+      this.modalForm = this.$objAssign(this.modalForm, data);
     },
-    toDelete(index) {
-      const row = this.subjects[index];
-      if (!row.id) {
-        this.subjects.splice(index, 1);
-        return;
-      }
-      this.$Modal.confirm({
-        title: "删除警告",
-        content: "确定要删除当前科目吗?",
-        onOk: () => {
-          this.toDel(row.id);
-        }
+    async toSubmit() {
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+
+      let result = true;
+      await updateCollectParams(this.modalForm).catch(() => {
+        result = false;
       });
-    },
-    async toDel(id) {
-      await deleteSubject(id);
-      this.$Message.success("删除成功!");
-      this.getList();
-    },
-    toSubmit() {}
+      this.isSubmit = true;
+      if (!result) return;
+      this.$Message.success("保存成功!");
+    }
   }
 };
 </script>

+ 10 - 52
src/modules/client-set/InspectionAccountSet.vue

@@ -1,8 +1,5 @@
 <template>
   <div class="client-account-set ">
-    <div class="part-box-top">
-      <Button type="success" icon="md-add" @click="toAdd">新增</Button>
-    </div>
     <div class="part-box">
       <table class="table">
         <tr>
@@ -15,22 +12,12 @@
           <td style="width: 60px;">{{ index + 1 }}</td>
           <td>{{ user.roleName }}</td>
           <td style="width: 200px;">
-            <Input v-model="user.loginName" clearable></Input>
+            {{ user.loginName }}
           </td>
           <td>
-            <Button
-              size="small"
-              type="primary"
-              :disabled="!user.id"
-              @click="toSave(user)"
+            <Button size="small" type="primary" @click="toResetPwd(user)"
               >重置</Button
             >
-            <Button size="small" type="primary" @click="toSave(user)"
-              >保存</Button
-            >
-            <Button size="small" type="error" @click="toDelete(index)"
-              >删除</Button
-            >
           </td>
         </tr>
       </table>
@@ -39,11 +26,7 @@
 </template>
 
 <script>
-import {
-  inspectionUserPageList,
-  deleteInspectionUser,
-  updateInspectionUser
-} from "@/api";
+import { inspectionUserPageList, resetPwd } from "@/api";
 
 const initModalForm = {
   id: "",
@@ -85,39 +68,14 @@ export default {
     toAdd() {
       this.users.push({ ...initModalForm });
     },
-    async toSave(row) {
-      if (!row.loginName.match(new RegExp(`^[a-zA-Z0-9_]{3,20}$`))) {
-        this.$Message.error(
-          "当前账号名只能由数字、字母和下划线组成,长度3-20个字符"
-        );
-        return;
-      }
-      await updateInspectionUser({
-        id: row.id,
-        loginName: row.loginName,
-        password: "123456"
+    async toResetPwd(user) {
+      let result = true;
+      await resetPwd({ userId: user.id, password: "123456" }).catch(() => {
+        result = false;
       });
-      this.$Message.success("保存成功!");
-      this.getList();
-    },
-    toDelete(index) {
-      const row = this.users[index];
-      if (!row.id) {
-        this.users.splice(index, 1);
-        return;
-      }
-      this.$Modal.confirm({
-        title: "删除警告",
-        content: "确定要删除当前账号吗?",
-        onOk: () => {
-          this.toDel(row.id);
-        }
-      });
-    },
-    async toDel(id) {
-      await deleteInspectionUser(id);
-      this.$Message.success("删除成功!");
-      this.getList();
+
+      if (!result) return;
+      this.$Message.success("重置密码成功!");
     }
   }
 };

+ 5 - 4
src/modules/client-set/components/ModifyClientUser.vue

@@ -106,13 +106,14 @@ export default {
 
       if (this.isSubmit) return;
       this.isSubmit = true;
-      const data = await updateClientUser(this.modalForm).catch(() => {
-        this.isSubmit = false;
+      let result = true;
+      await updateClientUser(this.modalForm).catch(() => {
+        result = false;
       });
+      this.isSubmit = false;
 
-      if (!data) return;
+      if (!result) return;
 
-      this.isSubmit = false;
       this.$Message.success(this.title + "成功!");
       this.$emit("modified");
       this.cancel();

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

@@ -13,7 +13,7 @@
           <th>典型值</th>
           <th>类型</th>
           <th>给分项</th>
-          <th>考阀值%</th>
+          <th>考阀值%</th>
           <th>占比阀值%</th>
           <th>操作</th>
         </tr>
@@ -144,7 +144,7 @@
 </template>
 
 <script>
-import { levelList, updateLevel } from "@/api";
+import { workDetail, updateWork } from "@/api";
 import { LEVEL_TYPE } from "@/constants/enumerate";
 import schema from "async-validator";
 schema.warning = function() {};
@@ -186,10 +186,10 @@ export default {
         this.letterRelateNumber[item] = index + 1;
       });
 
-      this.getList();
+      this.getData();
     },
-    async getList() {
-      const data = await levelList(this.workId);
+    async getData() {
+      const data = await workDetail(this.workId);
       this.worKDetail = data;
       this.levels = data.levels;
     },
@@ -331,7 +331,7 @@ export default {
         kdpt: {
           type: "number",
           required: true,
-          message: "请输入考阀值"
+          message: "请输入考阀值"
         }
       };
       return new schema(descriptor)
@@ -364,7 +364,7 @@ export default {
 
       if (this.isSubmit) return;
       this.isSubmit = true;
-      const data = await updateLevel(this.worKDetail).catch(() => {
+      const data = await updateWork(this.worKDetail).catch(() => {
         this.isSubmit = false;
       });
 

+ 27 - 27
src/modules/grading-set/GradingRuleSet.vue

@@ -6,24 +6,24 @@
       :rules="rules"
       :label-width="200"
     >
-      <FormItem prop="arbitrateGradeIntervel" label="仲裁档位差:">
+      <FormItem prop="deviation" label="仲裁档位差:">
         <InputNumber
-          v-model="modalForm.arbitrateGradeIntervel"
+          v-model="modalForm.deviation"
           :min="1"
           :max="100"
           style="width: 160px;"
         ></InputNumber>
       </FormItem>
-      <FormItem prop="refuseTotalCount" label="打回累计误差:">
+      <FormItem prop="cumulativeError" label="打回累计误差:">
         <InputNumber
-          v-model="modalForm.refuseTotalCount"
+          v-model="modalForm.cumulativeError"
           :min="1"
           :max="100"
           style="width: 160px;"
         ></InputNumber>
       </FormItem>
       <FormItem prop="examNumber" label="系统自动打回:">
-        <RadioGroup v-model="modalForm.autoRefuse">
+        <RadioGroup v-model="modalForm.autoCallback">
           <Radio
             v-for="(val, key) in BOOLEAN_TYPE"
             :key="key"
@@ -34,7 +34,7 @@
         </RadioGroup>
       </FormItem>
       <FormItem prop="examNumber" label="是否过半定档:">
-        <RadioGroup v-model="modalForm.isOverHalfConfirm">
+        <RadioGroup v-model="modalForm.majority">
           <Radio
             v-for="(val, key) in BOOLEAN_TYPE"
             :key="key"
@@ -45,7 +45,7 @@
         </RadioGroup>
       </FormItem>
       <FormItem prop="examNumber" label="阅卷员是否显示所有试卷:">
-        <RadioGroup v-model="modalForm.isShowAllPaper">
+        <RadioGroup v-model="modalForm.levelShowAllPaper">
           <Radio
             v-for="(val, key) in BOOLEAN_TYPE"
             :key="key"
@@ -65,7 +65,7 @@
 </template>
 
 <script>
-import { gradingRuleDetail, saveGradingRule } from "@/api";
+import { getParamsSet, updateLevelParams } from "@/api";
 import { BOOLEAN_TYPE } from "@/constants/enumerate";
 import { numberValidator } from "@/plugins/formRules";
 
@@ -77,26 +77,28 @@ export default {
       workId: this.$route.params.workId,
       BOOLEAN_TYPE,
       initModalForm: {
-        arbitrateGradeIntervel: 3,
-        refuseTotalCount: null,
-        autoRefuse: 0,
-        isOverHalfConfirm: 0,
-        isShowAllPaper: 0
+        workId: "",
+        deviation: 3,
+        cumulativeError: null,
+        autoCallback: 0,
+        majority: 0,
+        levelShowAllPaper: 0
       },
       modalForm: {},
       rules: {
-        arbitrateGradeIntervel: numberValidator("请输入打回累计误差"),
-        refuseTotalCount: numberValidator("请输入仲裁档位差")
+        deviation: numberValidator("请输入打回累计误差"),
+        cumulativeError: numberValidator("请输入仲裁档位差")
       }
     };
   },
   mounted() {
-    this.getData();
+    this.modalForm = { ...this.initModalForm };
+    this.getParamsSetInfo();
   },
   methods: {
-    async getData() {
-      const data = await gradingRuleDetail(this.workId);
-      this.modalForm = Object.assign(data, this.initModalForm);
+    async getParamsSetInfo() {
+      const data = await getParamsSet(this.workId);
+      this.modalForm = this.$objAssign(this.modalForm, data);
     },
     async submit() {
       const valid = await this.$refs.modalFormComp.validate();
@@ -104,16 +106,14 @@ export default {
 
       if (this.isSubmit) return;
       this.isSubmit = true;
-      const data = await saveGradingRule(this.modalForm).catch(() => {
-        this.isSubmit = false;
+      let result = true;
+      await updateLevelParams(this.modalForm).catch(() => {
+        result = false;
       });
-
-      if (!data) return;
-
       this.isSubmit = false;
-      this.$Message.success(this.title + "成功!");
-      this.$emit("modified");
-      this.cancel();
+
+      if (!result) return;
+      this.$Message.success("保存成功!");
     }
   }
 };

+ 1 - 1
src/modules/grading/Grading.vue

@@ -39,7 +39,7 @@ export default {
       subjectId: this.$route.params.subjectId,
       navs: [],
       curNav: {},
-      curSubject: { name: "色彩" }
+      curSubject: { name: "" }
     };
   },
   watch: {

+ 69 - 70
src/modules/grading/GradingDetail.vue

@@ -9,8 +9,13 @@
       <div class="detail-filter">
         <Form ref="FilterForm" label-position="left" inline>
           <FormItem>
-            <Select v-model="filter.areaCode" placeholder="请选择考区">
-              <Option value=""></Option>
+            <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>
@@ -38,8 +43,12 @@
               :key="index"
             >
               <h5 class="image-view-title">{{ image.title }}</h5>
-              <div class="image-view-contain" @click="toReview(index)">
-                <img :src="image.thumbUrl" :alt="image.title" />
+              <div class="image-view-contain">
+                <img
+                  :src="image.thumbSrc"
+                  :alt="image.title"
+                  @click="toReview(index)"
+                />
               </div>
             </div>
           </div>
@@ -92,8 +101,7 @@
 </template>
 
 <script>
-import { papers, levels } from "@/constants/apiTempData";
-import { paperPageList } from "@/api";
+import { paperList, levelStatData, areaList, workLevelList } from "@/api";
 import ImagePreview from "@/components/common/ImagePreview";
 import GradeStep from "./components/GradeStep";
 import GradeStandardPaper from "./components/GradeStandardPaper";
@@ -119,10 +127,14 @@ export default {
   data() {
     return {
       filter: {
-        workId: this.$route.params.workId,
-        subjectId: this.$route.params.subjectId,
-        areaCode: ""
+        questionId: "",
+        level: "",
+        sort: "secretNumber",
+        isSample: false
       },
+      workId: this.$route.params.workId,
+      subjectId: this.$route.params.subjectId,
+      subject: "",
       curUserRoleType: "MARKER",
       current: 1,
       size: 6,
@@ -131,7 +143,8 @@ export default {
       curStep: {},
       curStandardGradeId: "",
       steps: [],
-      levels: levels,
+      levels: [],
+      areas: [],
       papers: [],
       curPaper: {},
       curPaperIndex: 0
@@ -155,56 +168,16 @@ export default {
     }
   },
   mounted() {
-    // this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
-    this.initData();
+    this.subject = this.subjectId.split("-")[1];
+    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
+    // this.initData();
   },
   methods: {
-    initData() {
-      this.papers = papers.slice(0, this.size).map((item, index) => {
-        return {
-          ...item,
-          title: item.examNumber,
-          score: "95",
-          grade: "A"
-        };
-      });
-      const levelStep = levels.map(item => {
-        return {
-          ...item,
-          type: "done",
-          typeName: "已评"
-        };
-      });
-      // TODO:后台获取的数据是已经拼装好的,试卷信息中也会携带试卷各种状态信息
-      // 所以操作盘只需要根据试卷信息来动态展示即可
-      this.steps = [
-        ...levelStep,
-        {
-          name: "待评",
-          type: "undo",
-          typeName: "待评",
-          gcount: 100,
-          gpercent: 10.1,
-          pt: 12,
-          count: 100,
-          percent: 8.1,
-          kdpt: 10
-        },
-        {
-          name: "打回",
-          type: "refuse",
-          typeName: "打回",
-          gcount: 100,
-          gpercent: 10.1,
-          pt: 12,
-          count: 100,
-          percent: 8.1,
-          kdpt: 10
-        }
-      ];
-      this.$refs.GradeStep.selectStep(this.steps[0]);
-      this.curPaper = { ...this.papers[0] };
-      this.curPaperIndex = 0;
+    async initData() {
+      await this.getAreaList();
+      this.filter.questionId = this.areas[0].id;
+      this.getStepLevels();
+      this.getWorkLevels();
     },
     async getList() {
       const datas = {
@@ -212,18 +185,10 @@ export default {
         page: this.current - 1,
         size: this.size
       };
-      const data = await paperPageList(datas);
+      const data = await paperList(datas);
       this.papers = data.data.map(paper => {
-        return {
-          id: paper.id,
-          title: paper.examNumber,
-          url: paper.imgSrc,
-          thumbUrl: paper.thumbSrc,
-          missing: paper.missing,
-          stage: paper.stage,
-          style: {},
-          deg: 0
-        };
+        paper.title = paper.examNumber;
+        return paper;
       });
       this.total = data.totalCount;
     },
@@ -231,9 +196,43 @@ export default {
       this.current = page;
       this.getList();
     },
+    async getStepLevels() {
+      const data = await levelStatData(this.subjectId, this.filter.questionId);
+      let levelMenu = data.map(item => {
+        return {
+          ...item,
+          name: item.id,
+          type: "level"
+        };
+      });
+      this.steps = levelMenu;
+      // TODO:根据角色构建不同的导航栏
+      // 切换默认导航
+    },
+    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 getAreaList() {
+      const data = await areaList(this.workId, this.subject);
+      this.areas = data.map(item => {
+        return {
+          id: item.id,
+          areaName: item.areaName,
+          areaCode: item.areaCode
+        };
+      });
+    },
     pageSizeChange(size) {
       this.size = size;
-      // this.toPage(1);
+      this.toPage(1);
       this.initData();
       this.$nextTick(() => {
         this.$refs.GradeStandardPaper.$refs.Carousel.handleResize();

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

@@ -37,6 +37,7 @@ export default {
     return {
       subjectId: this.$route.params.subjectId,
       workId: this.$route.params.workId,
+      subject: "",
       users: [],
       curUser: {},
       columns: [
@@ -104,13 +105,14 @@ export default {
     };
   },
   mounted() {
+    this.subject = this.subjectId.split("-")[1];
     this.getList();
   },
   methods: {
     async getList() {
       const datas = {
         workId: this.workId,
-        subject: this.subjectId.split("-")[1]
+        subject: this.subject
       };
       const data = await gradingUserList(datas);
       this.users = data.map(item => {
@@ -120,13 +122,13 @@ export default {
       });
     },
     async toResetPwd(row) {
-      await resetPwd(row.id);
+      await resetPwd({ userId: row.id, password: "123456" });
       this.$Message.success("重置密码成功!");
     },
     toAdd() {
       this.curUser = {
         workId: this.workId,
-        subjectId: this.subjectId
+        subject: this.subject
       };
       this.$refs.ModifyGradingUser.open();
     },
@@ -148,7 +150,9 @@ export default {
       this.$Message.success("删除成功!");
       this.getList();
     },
-    toExport() {}
+    toExport() {
+      window.open(`${this.GLOBAL.domain}/export/users?workId=${this.workId}`);
+    }
   }
 };
 </script>

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

@@ -35,9 +35,9 @@
     <div class="action-grade-info" v-if="rights.gradeInfo">
       <h3 class="grade-info-name">{{ curLevel.name }}</h3>
       <p class="grade-info-range">
-        <span>{{ curLevel.range[0] }}</span>
+        <span>{{ curLevel.minScore }}</span>
         <span>~</span>
-        <span>{{ curLevel.range[1] }}</span>
+        <span>{{ curLevel.maxScore }}</span>
       </p>
     </div>
     <!-- 选择档位 -->
@@ -48,7 +48,7 @@
         :key="index"
       >
         <p>{{ level.name }}</p>
-        <p>{{ level.range[0] }}~{{ level.range[1] }}</p>
+        <p>{{ level.minScore }}~{{ level.maxScore }}</p>
       </div>
     </div>
     <div class="action-grade-pass" v-if="rights.gradeList">
@@ -73,12 +73,45 @@
 </template>
 
 <script>
+import { markHistoryList } from "@/api";
 import { CODE_TYPE } from "@/constants/enumerate";
 // 三种情况:
 // 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
 // 管理员:查询,头部信息,评卷记录
 // 科组长:查询,头部信息,选择档位,评卷记录
 // 评卷员:头部信息,选择档位
+/*
+[curpaper sample]
+{
+  "id": 165,
+  "sn": "029947536",
+  "examNumber": "1901040084",
+  "level": "A",
+  "score": null,
+  "redoLevel": null,
+  "updatedOn": 1591767742000,
+  "imgSrc": "",
+  "thumbSrc": "",
+  "markByLeader": false,
+  "markedLogic": true,
+  "areaCode": "2",
+  "inspectScore": null,
+  "inspectLevel": null,
+  "inspector": null,
+  "sheetSrc": null,
+  "stage": "LEVEL",
+  "test": 0,
+  "paperTest": 0,
+  "markResults": [],
+  "rejected": false,
+  "arbitrated": false,
+  "sample": false,
+  "tagged": false,
+  "missing": false,
+  "manual": false
+}
+*/
+
 const initRights = {
   search: false,
   paperState: false,
@@ -210,6 +243,16 @@ export default {
         };
       }
     },
+    async getMarkHistory() {
+      const data = await markHistoryList(this.curPaper.id);
+      this.gradingHistory = data.map(item => {
+        return {
+          id: item.id,
+          name: item.marker,
+          value: item.result
+        };
+      });
+    },
     toPass() {
       this.$emit("on-pass");
     },

+ 1 - 1
src/modules/grading/components/GradeStandardPaper.vue

@@ -20,7 +20,7 @@
       >
         <CarouselItem v-for="(paper, pindex) in papers" :key="pindex">
           <div class="image-view-contain">
-            <img :src="paper.thumbUrl" :alt="paper.title" />
+            <img :src="paper.thumbSrc" :alt="paper.title" />
           </div>
         </CarouselItem>
       </Carousel>

+ 6 - 9
src/modules/grading/components/ModifyGradingUser.vue

@@ -170,11 +170,7 @@ export default {
   },
   methods: {
     initData(val) {
-      if (val.id) {
-        this.modalForm = this.$objAssign(initModalForm, val);
-      } else {
-        this.modalForm = { ...initModalForm };
-      }
+      this.modalForm = this.$objAssign(initModalForm, val);
     },
     visibleChange(visible) {
       if (visible) {
@@ -193,13 +189,14 @@ export default {
 
       if (this.isSubmit) return;
       this.isSubmit = true;
-      const data = await updateGradingUser(this.modalForm).catch(() => {
-        this.isSubmit = false;
+      let result = true;
+      await updateGradingUser(this.modalForm).catch(() => {
+        result = false;
       });
+      this.isSubmit = false;
 
-      if (!data) return;
+      if (!result) return;
 
-      this.isSubmit = false;
       this.$Message.success(this.title + "成功!");
       this.$emit("modified");
       this.cancel();

+ 1 - 1
src/modules/grading/components/PaperCarousel.vue

@@ -14,7 +14,7 @@
       >
         <CarouselItem v-for="(paper, pindex) in papers" :key="pindex">
           <div class="image-view-contain">
-            <img :src="paper.thumbUrl" :alt="paper.title" />
+            <img :src="paper.thumbSrc" :alt="paper.title" />
           </div>
         </CarouselItem>
       </Carousel>

+ 6 - 2
src/modules/inspection/InspectionGrading.vue

@@ -51,8 +51,12 @@
       <div class="check-grade-list image-view-list image-view-list-4">
         <div class="image-view" v-for="(image, index) in papers" :key="index">
           <h5 class="image-view-title">{{ image.title }}</h5>
-          <div class="image-view-contain" @click="toReview(index)">
-            <img :src="image.thumbUrl" :alt="image.title" />
+          <div class="image-view-contain">
+            <img
+              :src="image.thumbSrc"
+              :alt="image.title"
+              @click="toReview(index)"
+            />
           </div>
         </div>
       </div>

+ 15 - 8
src/modules/login/ResetPwd.vue

@@ -7,14 +7,14 @@
     @on-visible-change="visibleChange"
   >
     <Form ref="resetForm" :model="reset" :rules="resetRules">
-      <FormItem prop="password">
+      <!-- <FormItem prop="password">
         <Input
           type="password"
           v-model="reset.password"
           placeholder="请输入旧密码"
           clearable
         ></Input>
-      </FormItem>
+      </FormItem> -->
       <FormItem prop="newpswd">
         <Input
           type="password"
@@ -44,7 +44,7 @@ import { resetPwd } from "@/api";
 import { password } from "@/plugins/formRules";
 
 const initModalForm = {
-  password: "",
+  // password: "",
   newpswd: "",
   renewpswd: ""
 };
@@ -62,11 +62,12 @@ export default {
     return {
       modalIsShow: false,
       isSubmit: false,
+      userId: "",
       reset: {
         ...initModalForm
       },
       resetRules: {
-        password,
+        // password,
         newpswd: password,
         renewpswd: [
           ...password,
@@ -82,6 +83,7 @@ export default {
     visibleChange(visible) {
       if (visible) {
         this.reset = { ...initModalForm };
+        this.userId = this.$ls.get("user", { id: "" }).id;
       }
     },
     cancel() {
@@ -91,15 +93,20 @@ export default {
       this.modalIsShow = true;
     },
     async submit(name) {
-      const valid = await this.$refs[name].validate();
+      const valid = await this.$refs.resetForm.validate();
       if (!valid) return;
 
       if (this.isSubmit) return;
       this.isSubmit = true;
-      const data = await resetPwd(this.reset).catch(() => {});
+      let result = true;
+      await resetPwd({
+        userId: this.userId,
+        password: this.reset.newpswd
+      }).catch(() => {
+        result = false;
+      });
       this.isSubmit = false;
-      if (!data) return;
-
+      if (!result) return;
       this.cancel();
       this.$emit("confirm", this.reset.newpswd);
     }

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

@@ -57,7 +57,7 @@ export default {
             title: `Scan ${index}`,
             url:
               "http://127.0.0.1:9000/api/file/image/download/33/1/833/1?random=fa8244bb-8ec4-46c1-a16e-1bd6f3b8848e",
-            thumbUrl:
+            thumbSrc:
               "http://127.0.0.1:9000/api/file/image/download/33/1/833/2?random=497cc903-c01a-458a-9b4e-82b391cef176"
           };
         });

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

@@ -1,7 +1,7 @@
 <template>
   <div class="home admin-home">
     <div class="home-header">
-      <view-header>
+      <view-header :show-reset-pwd="false">
         <h1 slot="logo" @click="$router.push({ name: 'WorkManage' })">
           美术阅卷管理端
         </h1>

+ 20 - 11
src/modules/main/PaperManage.vue

@@ -4,11 +4,16 @@
       <Form ref="FilterForm" label-position="left" inline>
         <FormItem label="科目">
           <Select v-model="filter.subject" placeholder="请选择科目">
-            <Option value=""></Option>
+            <Option
+              v-for="(item, index) in subjects"
+              :key="index"
+              :value="item.subject"
+              :label="item.name"
+            ></Option>
           </Select>
         </FormItem>
-        <FormItem label="考点">
-          <Select v-model="filter.examRoom" placeholder="请选择考点">
+        <FormItem label="考">
+          <Select v-model="filter.areaCode" placeholder="请选择考区">
             <Option value=""></Option>
           </Select>
         </FormItem>
@@ -81,7 +86,7 @@
 </template>
 
 <script>
-import { paperPageList } from "@/api";
+import { paperPageList, subjectList } from "@/api";
 import { SORT_RULE_TYPE, CAFA_EXCEPTION_TYPE } from "@/constants/enumerate";
 import ImageActionList from "./components/ImageActionList";
 
@@ -94,12 +99,11 @@ export default {
         workId: this.$route.params.workId,
         name: "",
         schoolId: "",
-        examRoom: "",
+        areaCode: "",
         startNumber: null,
         endNumber: null,
-        subject: "SC",
-        areaCode: "1",
-        sort: "examNumber",
+        subject: "",
+        sort: "",
         isAbsent: ""
       },
       SORT_RULE_TYPE,
@@ -107,11 +111,12 @@ export default {
       current: 1,
       size: this.GLOBAL.pageSize,
       total: 0,
-      papers: []
+      papers: [],
+      subjects: []
     };
   },
   mounted() {
-    this.getList();
+    this.getSubjects();
   },
   methods: {
     async getList() {
@@ -126,7 +131,7 @@ export default {
           id: paper.id,
           title: paper.examNumber,
           url: paper.imgSrc,
-          thumbUrl: paper.thumbSrc,
+          thumbSrc: paper.thumbSrc,
           missing: paper.missing,
           stage: paper.stage,
           style: {},
@@ -138,6 +143,10 @@ export default {
     toPage(page) {
       this.current = page;
       this.getList();
+    },
+    async getSubjects() {
+      const data = await subjectList(this.filter.workId);
+      this.subjects = data.filter(item => item.enable && item.stage === "INIT");
     }
   }
 };

+ 58 - 23
src/modules/main/QualityAnalysis.vue

@@ -3,8 +3,13 @@
     <div class="part-box">
       <Form label-position="left" inline>
         <FormItem label="科目:">
-          <Select v-model="subjectId" placeholder="请选择科目">
-            <Option value=""></Option>
+          <Select v-model="filter.subject" placeholder="请选择科目">
+            <Option
+              v-for="(item, index) in subjects"
+              :key="index"
+              :value="item.subject"
+              :label="item.name"
+            ></Option>
           </Select>
         </FormItem>
         <FormItem label="查询时间段:">
@@ -26,30 +31,44 @@
         </FormItem>
       </Form>
 
-      <div class="analysis-part">
-        <v-chart :options="barOption" v-if="barOption" autoresize></v-chart>
+      <div class="analysis-part" v-if="levelsPropReportOption">
+        <v-chart :options="levelsPropReportOption" autoresize></v-chart>
       </div>
     </div>
   </div>
 </template>
 
 <script>
-import { qualityAnalysisDetail } from "@/api";
+import {
+  levelsPropReport,
+  distanceReport,
+  callbackReport,
+  subjectList
+} from "@/api";
 import chartOption from "@/constants/chartOptions";
 
 export default {
   name: "quality-analysis",
   data() {
     return {
-      subjectId: "",
+      filter: {
+        workId: this.$route.params.workId,
+        subject: ""
+      },
       searchTime: [],
-      barOption: {}
+      levelsPropReportOption: null,
+      distanceReportOption: null,
+      callbackReportOption: null,
+      subjects: []
     };
   },
   mounted() {
-    this.initData();
+    this.getSubjects();
   },
   methods: {
+    async getSubjects() {
+      this.subjects = await subjectList(this.filter.workId);
+    },
     parseGroupBarData(datas) {
       if (!datas.length) {
         return { names: [], dataList: [] };
@@ -70,27 +89,43 @@ export default {
         dataList: dataList
       };
     },
-    initData() {
-      const data = [
-        {
-          data: [{ prop: 37.5, markerId: 98, markerName: "pj001" }],
-          name: "A"
-        },
-        { data: [{ prop: 62.5, markerId: 98, markerName: "pj001" }], name: "B" }
-      ];
-      this.barOption = chartOption.getBarGroupOption(
-        this.parseGroupBarData(data),
-        "档位分布图"
-      );
+    parseBarData(datas) {
+      var names = [];
+      var dataList = [];
+      datas.map(function(item, index) {
+        names[index] = item.userName;
+        dataList[index] = item.sumCount;
+      });
+      return {
+        names: names,
+        dataList: dataList
+      };
     },
     async toSearch() {
       const datas = {
-        subjectId: this.subjectId,
+        ...this.filter,
         startTime: this.searchTime[0],
         endTime: this.searchTime[1]
       };
-      const data = await qualityAnalysisDetail(datas);
-      console.log(data);
+      const requests = [
+        levelsPropReport(datas),
+        distanceReport(datas),
+        callbackReport(datas)
+      ];
+      const data = await Promise.all(requests);
+
+      this.levelsPropReportOption = chartOption.getBarGroupOption(
+        this.parseGroupBarData(data[0]),
+        "档位分布图"
+      );
+      this.distanceReportOption = chartOption.getBarOption(
+        this.parseBarData(data[1]),
+        "差值和"
+      );
+      this.callbackReportOption = chartOption.getBarOption(
+        this.parseBarData(data[2]),
+        "打回次数"
+      );
     },
     toExport() {}
   }

+ 32 - 15
src/modules/main/StudentManage.vue

@@ -33,7 +33,12 @@
         </FormItem>
         <FormItem label="科目">
           <Select v-model="filter.subject" placeholder="请选择科目">
-            <Option value=""></Option>
+            <Option
+              v-for="(subject, index) in subjects"
+              :key="index"
+              :value="subject.subject"
+              >{{ subject.name }}</Option
+            >
           </Select>
         </FormItem>
         <FormItem label="起始考号">
@@ -140,7 +145,7 @@
 </template>
 
 <script>
-import { studentPageList, deleteStudent } from "@/api";
+import { subjectList, studentPageList, deleteStudent } from "@/api";
 import ImportFile from "@/components/common/ImportFile";
 import ModifyStudent from "./components/ModifyStudent";
 import { BOOLEAN_TYPE, PAPER_UPLOAD_TYPE } from "@/constants/enumerate";
@@ -167,7 +172,7 @@ export default {
       total: 0,
       students: [],
       curStudent: {},
-      isBuildColumn: false,
+      subjects: [],
       BOOLEAN_TYPE,
       PAPER_UPLOAD_TYPE,
       columns: [
@@ -220,6 +225,8 @@ export default {
                   this.toEdit(param.row);
                 }
               });
+            }
+            if (param.row.canDelete) {
               actions.push({
                 name: "删除",
                 type: "error",
@@ -249,9 +256,13 @@ export default {
     };
   },
   mounted() {
-    this.getList();
+    this.iniData();
   },
   methods: {
+    async iniData() {
+      await this.getSubjects();
+      this.getList();
+    },
     async getList() {
       const datas = {
         // ...this.filter,
@@ -266,25 +277,31 @@ export default {
           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;
+        });
         return student;
       });
-      if (data.data.length && !this.isBuildColumn) {
-        this.isBuildColumn = true;
-        data.data[0].uploadStatus.split(",").map(status => {
-          const subjectCode = status.split(":")[0];
-          const column = {
-            title: subjectCode,
-            key: subjectCode
-          };
-          this.columns.splice(this.columns.length - 1, 0, column);
-        });
-      }
       this.total = data.totalCount;
     },
     toPage(page) {
       this.current = page;
       this.getList();
     },
+    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: 80
+        };
+        this.columns.splice(this.columns.length - 1, 0, column);
+      });
+    },
     toUploadStudentPaper(row) {
       console.log(row);
     },

+ 44 - 108
src/modules/main/StudentScore.vue

@@ -17,20 +17,30 @@
           </Select>
         </FormItem>
         <FormItem label="考区:" v-if="IS_INSPECTION">
-          <Select v-model="filter.areaDode" placeholder="请选择考区">
+          <Select v-model="filter.areaCode" placeholder="请选择考区">
             <Option value=""></Option>
           </Select>
         </FormItem>
 
         <FormItem label="科目:">
-          <Select v-model="filter.subjectId" placeholder="请选择科目">
-            <Option value=""></Option>
+          <Select
+            v-model="filter.subject"
+            placeholder="请选择科目"
+            style="width: 100px;"
+            clearable
+          >
+            <Option
+              v-for="(item, index) in subjects"
+              :key="index"
+              :value="item.subject"
+              :label="item.name"
+            ></Option>
           </Select>
         </FormItem>
 
         <FormItem label="号码:">
           <Select
-            v-model="filter.codeType"
+            v-model="filter.type"
             placeholder="号码类型"
             style="width: 100px"
           >
@@ -44,14 +54,14 @@
         </FormItem>
         <FormItem>
           <Input
-            v-model.trim="filter.code"
+            v-model.trim="filter.number"
             placeholder="请输入号码"
             clearable
           ></Input>
         </FormItem>
         <FormItem label="姓名:">
           <Input
-            v-model.trim="filter.name"
+            v-model.trim="filter.studentName"
             placeholder="请输入姓名"
             clearable
           ></Input>
@@ -62,9 +72,9 @@
           >
         </FormItem>
       </Form>
-      <!--  -->
+
       <div class="student-score-content">
-        <table class="table" v-if="curStudent.id">
+        <table class="table" v-if="curStudent.name">
           <tr>
             <td></td>
             <td :colspan="curStudent.scores.length">
@@ -95,13 +105,13 @@
           <tr>
             <td>档位</td>
             <td v-for="(score, sindex) in curStudent.scores" :key="sindex">
-              {{ score.grade }}
+              {{ score.level || "空" }}
             </td>
           </tr>
           <tr>
             <td>分数</td>
             <td v-for="(score, sindex) in curStudent.scores" :key="sindex">
-              {{ score.score }}
+              {{ score.score || "空" }}
             </td>
           </tr>
         </table>
@@ -122,7 +132,7 @@
 </template>
 
 <script>
-import { studentScoreList, workList } from "@/api";
+import { studentScoreList, workList, subjectList } from "@/api";
 import { CODE_TYPE } from "@/constants/enumerate";
 import ImageActionList from "./components/ImageActionList";
 
@@ -133,112 +143,28 @@ export default {
     return {
       filter: {
         workId: this.$route.params && this.$route.params.workId,
-        areaDode: "",
-        subjectId: "",
-        codeType: "",
-        code: "",
-        name: ""
+        areaCode: "",
+        subject: "",
+        type: "",
+        number: "",
+        studentName: ""
       },
       CODE_TYPE,
       IS_INSPECTION: false,
       works: [],
+      subjects: [],
       current: 1,
-      total: 2,
+      total: 0,
       size: 1,
-      curUserRoleType: "",
-      curStudent: {},
-      students: [
-        {
-          id: "12",
-          name: "李刚",
-          examNumber: "2020105133",
-          sumScore: 240,
-          scores: [
-            {
-              id: "1",
-              subjectName: "素描",
-              title: "2020105133",
-              score: "95",
-              grade: "A",
-              url:
-                "http://127.0.0.1:9000/api/file/image/download/33/1/833/1?random=fa8244bb-8ec4-46c1-a16e-1bd6f3b8848e",
-              thumbUrl:
-                "http://127.0.0.1:9000/api/file/image/download/33/1/833/2?random=497cc903-c01a-458a-9b4e-82b391cef176"
-            },
-            {
-              id: "1",
-              subjectName: "速写",
-              title: "2020105133",
-              score: "85",
-              grade: "B",
-              url:
-                "http://127.0.0.1:9000/api/file/image/download/31/1/734/1?random=676176fc-24cd-407a-a7bc-fabc49bd2dbc",
-              thumbUrl:
-                "http://127.0.0.1:9000/api/file/image/download/31/1/734/2?random=d8d100c5-ac64-4b5a-a2fe-bce2dd8aed0f"
-            },
-            {
-              id: "1",
-              subjectName: "色彩",
-              title: "2020105133",
-              score: "90",
-              grade: "A",
-              url:
-                "http://127.0.0.1:9000/api/file/image/download/31/1/733/1?random=e2966291-ffba-4b19-985d-0cad9ae1b75b",
-              thumbUrl:
-                "http://127.0.0.1:9000/api/file/image/download/31/1/733/2?random=5d16ebc7-0e52-493c-93fa-4850db5e2632"
-            }
-          ]
-        },
-        {
-          id: "122",
-          name: "李刚1",
-          examNumber: "2020105132",
-          sumScore: 242,
-          scores: [
-            {
-              id: "1",
-              subjectName: "素描",
-              title: "2020105133",
-              score: "95",
-              grade: "A",
-              url:
-                "http://127.0.0.1:9000/api/file/image/download/33/1/833/1?random=fa8244bb-8ec4-46c1-a16e-1bd6f3b8848e",
-              thumbUrl:
-                "http://127.0.0.1:9000/api/file/image/download/33/1/833/2?random=497cc903-c01a-458a-9b4e-82b391cef176"
-            },
-            {
-              id: "1",
-              subjectName: "速写",
-              title: "2020105133",
-              score: "85",
-              grade: "B",
-              url:
-                "http://127.0.0.1:9000/api/file/image/download/33/1/833/1?random=fa8244bb-8ec4-46c1-a16e-1bd6f3b8848e",
-              thumbUrl:
-                "http://127.0.0.1:9000/api/file/image/download/33/1/833/2?random=497cc903-c01a-458a-9b4e-82b391cef176"
-            },
-            {
-              id: "1",
-              subjectName: "色彩",
-              title: "2020105133",
-              score: "90",
-              grade: "A",
-              url:
-                "http://127.0.0.1:9000/api/file/image/download/33/1/833/1?random=fa8244bb-8ec4-46c1-a16e-1bd6f3b8848e",
-              thumbUrl:
-                "http://127.0.0.1:9000/api/file/image/download/33/1/833/2?random=497cc903-c01a-458a-9b4e-82b391cef176"
-            }
-          ]
-        }
-      ]
+      curStudent: { name: "" },
+      students: []
     };
   },
   mounted() {
     this.IS_INSPECTION =
       this.$ls.get("user", { role: "" }).role === "INSPECTION";
-    this.total = this.students.length;
-    this.toPage(1);
     if (this.IS_INSPECTION) this.getWorkList();
+    this.getSubjects();
   },
   methods: {
     async getWorkList() {
@@ -250,14 +176,24 @@ export default {
         };
       });
     },
+    async getSubjects() {
+      const data = await subjectList(this.filter.workId);
+      this.subjects = data.filter(item => item.enable);
+    },
     async toSearch() {
-      if (!this.filter.code || !this.filter.name) {
+      if (!this.filter.number && !this.filter.studentName) {
         this.$Message.error("号码和姓名必须填写一个");
         return;
       }
       const data = await studentScoreList(this.filter);
-      console.log(data);
-      this.total = data.length;
+      data.map(student => {
+        student.scores.map(score => {
+          score.title = score.subjectName;
+        });
+      });
+      this.students = data;
+      this.total = this.students.length;
+      this.toPage(1);
     },
     toPage(page) {
       this.current = page;

+ 3 - 9
src/modules/main/WorkOverview.vue

@@ -125,16 +125,10 @@ export default {
       window.open(url);
     },
     toCommit(subject) {
-      console.log(subject);
-
-      // TODO:
-      // const routerName = subject.markStage === ''
+      const routerName = subject.markStage === "LEVEL" ? "Grading" : "Mark";
       this.$router.push({
-        name: "Grading",
-        params: {
-          workId: this.workId,
-          subjectId: subject.subjectId
-        }
+        name: routerName,
+        params: { workId: this.workId, subjectId: subject.subjectId }
       });
     }
   }

+ 6 - 6
src/modules/main/components/ImageActionList.vue

@@ -2,12 +2,12 @@
   <div :class="classes">
     <div class="image-view" v-for="(image, index) in data" :key="index">
       <h5 class="image-view-title">{{ image.title }}</h5>
-      <div
-        class="image-view-contain"
-        :style="image.styles"
-        @click="toReview(index)"
-      >
-        <img :src="image.thumbUrl" :alt="image.title" />
+      <div class="image-view-contain" :style="image.styles">
+        <img
+          :src="image.thumbSrc"
+          :alt="image.title"
+          @click="toReview(index)"
+        />
       </div>
       <div class="image-view-actions" v-if="actions.length">
         <Button

+ 19 - 22
src/modules/mark-set/MarkRuleSet.vue

@@ -2,7 +2,7 @@
   <div class="mark-rule-set part-box">
     <Form ref="modalFormComp" :model="modalForm" :label-width="180">
       <FormItem label="分数处理方式:">
-        <Select v-model="modalForm.scoreRule" style="width: 200px">
+        <Select v-model="modalForm.roundUp" style="width: 200px">
           <Option
             v-for="(val, key) in SCORE_HANDLE_TYPE"
             :key="key"
@@ -12,7 +12,7 @@
         </Select>
       </FormItem>
       <FormItem label="是否显示改档及改档打分:">
-        <RadioGroup v-model="modalForm.changeGradeMarkType">
+        <RadioGroup v-model="modalForm.changeStage">
           <Radio
             v-for="(val, key) in BOOLEAN_TYPE"
             :key="key"
@@ -23,7 +23,7 @@
         </RadioGroup>
       </FormItem>
       <FormItem label="阅卷员是否显示所有试卷:">
-        <RadioGroup v-model="modalForm.isShowAllPaper">
+        <RadioGroup v-model="modalForm.scoreShowAllPaper">
           <Radio
             v-for="(val, key) in BOOLEAN_TYPE"
             :key="key"
@@ -43,7 +43,7 @@
 </template>
 
 <script>
-import { markRuleDetail, saveMarkRule } from "@/api";
+import { getParamsSet, updateScoreParams } from "@/api";
 import { BOOLEAN_TYPE, SCORE_HANDLE_TYPE } from "@/constants/enumerate";
 
 export default {
@@ -55,37 +55,34 @@ export default {
       BOOLEAN_TYPE,
       SCORE_HANDLE_TYPE,
       initModalForm: {
-        scoreRule: 0,
-        changeGradeMarkType: 0,
-        isShowAllPaper: 0
+        workId: "",
+        roundUp: 0,
+        changeStage: 0,
+        scoreShowAllPaper: 0
       },
       modalForm: {}
     };
   },
   mounted() {
-    this.getData();
+    this.modalForm = { ...this.initModalForm };
+    this.getParamsSetInfo();
   },
   methods: {
-    async getData() {
-      const data = await markRuleDetail(this.workId);
-      this.modalForm = Object.assign(data, this.initModalForm);
+    async getParamsSetInfo() {
+      const data = await getParamsSet(this.workId);
+      this.modalForm = this.$objAssign(this.modalForm, data);
     },
     async submit() {
-      const valid = await this.$refs.modalFormComp.validate();
-      if (!valid) return;
-
       if (this.isSubmit) return;
       this.isSubmit = true;
-      const data = await saveMarkRule(this.modalForm).catch(() => {
-        this.isSubmit = false;
+      let result = true;
+      await updateScoreParams(this.modalForm).catch(() => {
+        result = false;
       });
-
-      if (!data) return;
-
       this.isSubmit = false;
-      this.$Message.success(this.title + "成功!");
-      this.$emit("modified");
-      this.cancel();
+
+      if (!result) return;
+      this.$Message.success("保存成功!");
     }
   }
 };

+ 8 - 4
src/modules/mark/MarkDetail.vue

@@ -32,8 +32,12 @@
               :key="index"
             >
               <h5 class="image-view-title">{{ image.title }}</h5>
-              <div class="image-view-contain" @click="toReview(index)">
-                <img :src="image.thumbUrl" :alt="image.title" />
+              <div class="image-view-contain">
+                <img
+                  :src="image.thumbSrc"
+                  :alt="image.title"
+                  @click="toReview(index)"
+                />
               </div>
             </div>
           </div>
@@ -164,7 +168,7 @@ export default {
             grade: "A",
             url:
               "http://127.0.0.1:9000/api/file/image/download/33/1/833/1?random=fa8244bb-8ec4-46c1-a16e-1bd6f3b8848e",
-            thumbUrl:
+            thumbSrc:
               "http://127.0.0.1:9000/api/file/image/download/33/1/833/2?random=497cc903-c01a-458a-9b4e-82b391cef176"
           };
         });
@@ -181,7 +185,7 @@ export default {
           id: paper.id,
           title: paper.examNumber,
           url: paper.imgSrc,
-          thumbUrl: paper.thumbSrc,
+          thumbSrc: paper.thumbSrc,
           missing: paper.missing,
           stage: paper.stage,
           style: {},

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

@@ -156,7 +156,7 @@ export default {
           id: paper.id,
           title: paper.examNumber,
           url: paper.imgSrc,
-          thumbUrl: paper.thumbSrc,
+          thumbSrc: paper.thumbSrc,
           missing: paper.missing,
           stage: paper.stage,
           style: {},

+ 27 - 6
src/plugins/axios.js

@@ -101,9 +101,16 @@ const $get = (url, datas) => {
  * @param {String} url 请求地址
  * @param {Object} datas 请求数据
  */
-const $post = (url, datas) => {
+const $post = (url, datas, dataType = "form") => {
+  let sqDatas = "";
+  if (datas.constructor === Object && dataType === "form") {
+    sqDatas = qs.stringify(datas, { allowDots: true });
+  } else {
+    sqDatas = datas;
+  }
+
   return axios
-    .post(url, datas)
+    .post(url, sqDatas)
     .then(rep => {
       return successCallback(rep.data);
     })
@@ -138,9 +145,16 @@ const $del = (url, datas) => {
  * @param {String} url 请求地址
  * @param {Object} datas 请求数据
  */
-const $put = (url, datas) => {
+const $put = (url, datas, dataType = "form") => {
+  let sqDatas = "";
+  if (datas.constructor === Object && dataType === "form") {
+    sqDatas = qs.stringify(datas, { allowDots: true });
+  } else {
+    sqDatas = datas;
+  }
+
   return axios
-    .put(url, datas)
+    .put(url, sqDatas)
     .then(rep => {
       return rep.data;
     })
@@ -154,9 +168,16 @@ const $put = (url, datas) => {
  * @param {String} url 请求地址
  * @param {Object} datas 请求数据
  */
-const $patch = (url, datas) => {
+const $patch = (url, datas, dataType = "form") => {
+  let sqDatas = "";
+  if (datas.constructor === Object && dataType === "form") {
+    sqDatas = qs.stringify(datas, { allowDots: true });
+  } else {
+    sqDatas = datas;
+  }
+
   return axios
-    .patch(url, datas)
+    .patch(url, sqDatas)
     .then(rep => {
       return successCallback(rep.data);
     })

+ 1 - 0
src/routers/grading.js

@@ -46,6 +46,7 @@ const gradingRoutes = [
 
 export const navs = getNavs(gradingRoutes);
 
+// tips: subjectId == `workId-subject`
 export default [
   {
     path: "/grading/:workId(\\d+)/:subjectId",