zhangjie 8 місяців тому
батько
коміт
e604afe23e
100 змінених файлів з 8711 додано та 8696 видалено
  1. 8 0
      .editorconfig
  2. 1 0
      .env
  3. 17 10
      .eslintrc.js
  4. 0 5
      .prettierrc
  5. 1 1
      babel.config.js
  6. 22 0
      jsconfig.json
  7. 16 18
      package.json
  8. 5 5
      src/App.vue
  9. 470 470
      src/api.js
  10. 179 179
      src/components/EchartRender.vue
  11. 111 111
      src/components/ImageViewContain.vue
  12. 7 7
      src/components/PaperCarousel.vue
  13. 21 21
      src/components/SimpleImagePreview.vue
  14. 24 24
      src/components/UploadButton.vue
  15. 1 1
      src/components/ViewFooter.vue
  16. 6 6
      src/components/ViewHeader.vue
  17. 31 31
      src/components/common/ImagePreview/ImagePreview.vue
  18. 4 4
      src/components/common/ImagePreview/move-ele.js
  19. 23 23
      src/components/common/ImportFile/ImportFile.vue
  20. 3 5
      src/components/common/StepsProgress/StepFour.vue
  21. 3 5
      src/components/common/StepsProgress/StepOne.vue
  22. 3 5
      src/components/common/StepsProgress/StepThree.vue
  23. 3 5
      src/components/common/StepsProgress/StepTwo.vue
  24. 12 12
      src/components/common/StepsProgress/StepsProgress.vue
  25. 4 4
      src/components/homeMenuMixins.js
  26. 1 1
      src/config.js
  27. 51 51
      src/constants/authority.js
  28. 25 25
      src/constants/enumerate.js
  29. 21 21
      src/constants/navs.js
  30. 8 8
      src/main.js
  31. 19 19
      src/modules/client-set/ClientAccountSet.vue
  32. 17 17
      src/modules/client-set/ClientParamSet.vue
  33. 5 5
      src/modules/client-set/ClientSet.vue
  34. 17 17
      src/modules/client-set/InspectionAccountSet.vue
  35. 10 10
      src/modules/client-set/components/ModifyClientUser.vue
  36. 426 427
      src/modules/grading-set/GradingLevelSet.vue
  37. 13 13
      src/modules/grading-set/GradingRuleSet.vue
  38. 5 5
      src/modules/grading-set/GradingSet.vue
  39. 6 6
      src/modules/grading-set/UploadPaper.vue
  40. 11 11
      src/modules/grading/Grading.vue
  41. 11 11
      src/modules/grading/GradingAnalysis.vue
  42. 653 653
      src/modules/grading/GradingDetail.vue
  43. 13 14
      src/modules/grading/GradingGroupManage.vue
  44. 33 33
      src/modules/grading/GradingOperation.vue
  45. 328 328
      src/modules/grading/GradingProgress.vue
  46. 19 17
      src/modules/grading/GradingStandardPaperManage.vue
  47. 30 30
      src/modules/grading/GradingUserManage.vue
  48. 7 7
      src/modules/grading/components/CleanGradingDataDialog.vue
  49. 438 438
      src/modules/grading/components/GradeAction.vue
  50. 22 22
      src/modules/grading/components/GradeAnalysis.vue
  51. 11 13
      src/modules/grading/components/GradeAnalysisExport.vue
  52. 10 10
      src/modules/grading/components/GradeFilter.vue
  53. 12 12
      src/modules/grading/components/GradeHistoryPaper.vue
  54. 4 6
      src/modules/grading/components/GradeImageList.vue
  55. 34 34
      src/modules/grading/components/GradeRibbon.vue
  56. 11 11
      src/modules/grading/components/GradeStandardPaper.vue
  57. 11 11
      src/modules/grading/components/GradeStep.vue
  58. 10 10
      src/modules/grading/components/ModifyFormalGradingTask.vue
  59. 27 27
      src/modules/grading/components/ModifyGradingUser.vue
  60. 8 8
      src/modules/grading/components/ModifyLeaderGrading.vue
  61. 11 11
      src/modules/grading/components/ModifyUnformalGradingTask.vue
  62. 7 7
      src/modules/grading/components/ProgressLine.vue
  63. 81 81
      src/modules/grading/components/RibbonSetDialog.vue
  64. 680 680
      src/modules/grading/leader/LeaderGrading.vue
  65. 8 8
      src/modules/grading/leader/LeaderProgress.vue
  66. 19 19
      src/modules/grading/leader/LeaderStatistics.vue
  67. 625 625
      src/modules/grading/marker/MarkerGrading.vue
  68. 561 561
      src/modules/grading/marker/MarkerHeader.vue
  69. 138 138
      src/modules/grading/marker/MarkerHistory.vue
  70. 158 158
      src/modules/grading/marker/MarkerImageView.vue
  71. 244 244
      src/modules/grading/marker/MarkerStandard.vue
  72. 11 11
      src/modules/grading/marker/MarkerStatistics.vue
  73. 77 77
      src/modules/grading/marker/store.js
  74. 4 4
      src/modules/inspection/Inspection.vue
  75. 19 19
      src/modules/inspection/InspectionActionLogs.vue
  76. 18 18
      src/modules/inspection/InspectionCollectLogs.vue
  77. 346 346
      src/modules/inspection/InspectionGrading.vue
  78. 2 4
      src/modules/inspection/InspectionScore.vue
  79. 21 21
      src/modules/login/LoginHome.vue
  80. 11 11
      src/modules/login/ResetPwd.vue
  81. 7 7
      src/modules/login/fetchSmsMixins.js
  82. 179 179
      src/modules/main/ClientMonitor.vue
  83. 5 5
      src/modules/main/ExamPaperView.vue
  84. 7 7
      src/modules/main/Main.vue
  85. 9 9
      src/modules/main/OrgManage.vue
  86. 373 373
      src/modules/main/PaperManage.vue
  87. 22 22
      src/modules/main/QualityAnalysis.vue
  88. 515 515
      src/modules/main/StudentManage.vue
  89. 327 327
      src/modules/main/StudentScore.vue
  90. 182 182
      src/modules/main/WorkManage.vue
  91. 9 9
      src/modules/main/WorkOverview.vue
  92. 164 164
      src/modules/main/components/ImageActionList.vue
  93. 19 19
      src/modules/main/components/ModifyOrg.vue
  94. 26 26
      src/modules/main/components/ModifyStudent.vue
  95. 17 19
      src/modules/main/components/QualityAnalysisExport.vue
  96. 1 1
      src/modules/main/components/UploadStudentPaper.vue
  97. 8 8
      src/modules/mark-set/ExportPaper.vue
  98. 6 6
      src/modules/mark-set/MarkRuleSet.vue
  99. 5 5
      src/modules/mark-set/MarkSet.vue
  100. 487 487
      src/modules/mark/MarkDetail.vue

+ 8 - 0
.editorconfig

@@ -0,0 +1,8 @@
+# http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf

+ 1 - 0
.env

@@ -3,3 +3,4 @@ VUE_APP_DOMAIN=
 VUE_APP_TIMEOUT=600000
 VUE_APP_PAGE_SIZE=10
 VUE_APP_AUTH_TIMEOUT=7200000
+VUE_APP_DEV_PROXY=http://192.168.13.76:9000 

+ 17 - 10
.eslintrc.js

@@ -1,25 +1,32 @@
 module.exports = {
   root: true,
   env: {
-    node: true
+    node: true,
   },
-  extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"],
+  extends: [
+    "plugin:vue/essential",
+    "eslint:recommended",
+    "plugin:prettier/recommended",
+  ],
   parserOptions: {
-    parser: "babel-eslint"
+    parser: "@babel/eslint-parser",
   },
   rules: {
-    "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
-    "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
+    "no-console": "off",
+    "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
+    "vue/multi-word-component-names": "off",
+    "vue/no-mutating-props": "off",
     "no-unused-vars": [
       "error",
-      { vars: "all", args: "none", ignoreRestSiblings: false }
+      { vars: "all", args: "none", ignoreRestSiblings: false },
     ],
     "vue/no-parsing-error": [2, { "x-invalid-end-tag": false }],
     "vue/no-use-v-if-with-v-for": [
       "error",
       {
-        allowUsingIterationVar: true
-      }
-    ]
-  }
+        allowUsingIterationVar: true,
+      },
+    ],
+  },
+  ignorePatterns: ["public/"],
 };

+ 0 - 5
.prettierrc

@@ -1,5 +0,0 @@
-{
-  "semi": true,
-  "singleQuote": false,
-  "jsxBracketSameLine": false
-}

+ 1 - 1
babel.config.js

@@ -1,3 +1,3 @@
 module.exports = {
-  presets: ["@vue/cli-plugin-babel/preset"]
+  presets: ["@vue/cli-plugin-babel/preset"],
 };

+ 22 - 0
jsconfig.json

@@ -0,0 +1,22 @@
+{
+  "compilerOptions": {
+    "target": "es5",
+    "module": "esnext",
+    "baseUrl": "./",
+    "moduleResolution": "node",
+    "paths": {
+      "@/*": [
+        "src/*"
+      ]
+    },
+    "lib": [
+      "esnext",
+      "dom",
+      "dom.iterable",
+      "scripthost"
+    ]
+  },
+  "vueCompilerOptions": {
+    "target": 2.7
+  }
+}

+ 16 - 18
package.json

@@ -1,7 +1,6 @@
 {
   "name": "msyj-admin",
-  "version": "2.0.0",
-  "private": true,
+  "version": "3.0.2",
   "scripts": {
     "start": "npm run serve",
     "serve": "vue-cli-service serve",
@@ -24,23 +23,22 @@
     "vuex": "^3.1.3"
   },
   "devDependencies": {
-    "@vue/cli-plugin-babel": "~4.3.0",
-    "@vue/cli-plugin-eslint": "~4.3.0",
-    "@vue/cli-plugin-router": "~4.3.0",
-    "@vue/cli-plugin-vuex": "~4.3.0",
-    "@vue/cli-service": "~4.3.0",
-    "@vue/eslint-config-prettier": "^6.0.0",
-    "babel-eslint": "^10.1.0",
-    "compression-webpack-plugin": "^4.0.0",
-    "eslint": "^6.7.2",
-    "eslint-plugin-prettier": "^3.1.1",
-    "eslint-plugin-vue": "^6.2.2",
+    "@babel/core": "^7.12.16",
+    "@babel/eslint-parser": "^7.12.16",
+    "@vue/cli-plugin-babel": "~5.0.0",
+    "@vue/cli-plugin-eslint": "~5.0.0",
+    "@vue/cli-plugin-router": "~5.0.0",
+    "@vue/cli-plugin-vuex": "~5.0.0",
+    "@vue/cli-service": "~5.0.0",
+    "eslint": "^7.32.0",
+    "eslint-config-prettier": "^8.3.0",
+    "eslint-plugin-prettier": "^4.0.0",
+    "eslint-plugin-vue": "^8.0.3",
+    "lint-staged": "^11.1.2",
     "less": "^3.0.4",
     "less-loader": "^5.0.0",
-    "lint-staged": "^9.5.0",
-    "prettier": "^1.19.1",
-    "terser-webpack-plugin": "^3.0.1",
-    "vue-template-compiler": "^2.6.11"
+    "prettier": "^2.4.1",
+    "vue-template-compiler": "^2.6.14"
   },
   "gitHooks": {
     "pre-commit": "lint-staged"
@@ -51,4 +49,4 @@
       "git add"
     ]
   }
-}
+}

+ 5 - 5
src/App.vue

@@ -14,13 +14,13 @@ export default {
     return {
       unactiveTime: 0,
       // unactiveTime: 10 * 60 * 1000,
-      timeIsOut: false
+      timeIsOut: false,
     };
   },
   computed: {
     IS_LOGIN() {
       return this.$route.name === "Login";
-    }
+    },
   },
   mounted() {
     if (process.env.NODE_ENV !== "production") return;
@@ -47,9 +47,9 @@ export default {
         onOk: () => {
           this.$router.push({ name: "Login" });
           this.timeIsOut = false;
-        }
+        },
       });
-    }
-  }
+    },
+  },
 };
 </script>

+ 470 - 470
src/api.js

@@ -1,470 +1,470 @@
-import { $get, $post, $del, $patch, $put } from "@/plugins/axios";
-
-// login
-export const login = datas => {
-  return $post("/api/login", datas);
-};
-export const logout = () => {
-  return $del("/api/logout");
-};
-export const resetPwd = ({ userId, password }) => {
-  return $patch(`/api/${userId}/password`, { password }, "json");
-};
-
-// org-manage
-export const orgList = datas => {
-  return $get("/api/admin/organization", datas);
-};
-export const orgDetail = organizationId => {
-  return $get(`/api/admin/organization/${organizationId}`);
-};
-export const createOrg = datas => {
-  return $post(`/api/admin/organization`, datas, "json");
-};
-export const updateOrgUser = datas => {
-  return $put(`/api/admin/organization`, datas, "json");
-};
-export const enableOrgUser = userId => {
-  return $post(`/api/admin/organization/${userId}`, {});
-};
-export const deleteOrg = orgId => {
-  return $del(`/api/admin/organization/${orgId}`);
-};
-
-// work-manage
-export const workList = () => {
-  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, "json");
-};
-export const activeWork = workId => {
-  return $patch(`/api/admin/works/${workId}`, {});
-};
-export const deleteWork = workId => {
-  return $del(`/api/admin/works/${workId}`);
-};
-
-// work-overview
-export const workOverviewDetail = workId => {
-  return $get(`/api/admin/works/${workId}/overview`);
-};
-
-// paper-manage
-export const paperPageList = datas => {
-  return $get("/api/papers/listByQuestion", datas);
-};
-export const rotatePaper = (imageId, degree) => {
-  return $get(`/api/images/${imageId}/rotate`, { degree });
-};
-export const absentPaper = imageId => {
-  return $post(`/api/score/missing/${imageId}`, {});
-};
-export const markPaper = ({ paperId, isMark, role }) => {
-  return $post(`/api/papers/mark_paper`, { paperId, isMark, role });
-};
-
-// client-monitor
-export const clientMonitorList = datas => {
-  return $get("/api/marklog/equipmentMonitor", datas);
-};
-
-// student-manage
-export const studentPageList = datas => {
-  return $get("/api/students", datas);
-};
-export const updateStudent = datas => {
-  if (datas.id) {
-    return $put(`/api/students/${datas.id}`, datas, "json");
-  } else {
-    return $post(`/api/students`, datas, "json");
-  }
-};
-export const deleteStudent = studentId => {
-  return $del(`/api/students/${studentId}`, {});
-};
-export const absentStudentSubject = datas => {
-  return $post(`/api/students/missing`, datas);
-};
-export const areaSchoolRoomCascadeList = workId => {
-  // 考区-学校-考场 联动查询
-  return $get(`/api/students/select/${workId}`);
-};
-
-// client-set -------------------------->
-// client-user-set
-export const clientUserPageList = datas => {
-  return $get("/api/admin/users/collect", datas);
-};
-export const clientUserQuery = workId => {
-  return $get("/api/admin/users/collect/all", { workId });
-};
-export const updateClientUser = datas => {
-  if (datas.id) {
-    return $put(`/api/admin/users/collect/${datas.id}`, datas, "json");
-  } else {
-    return $post("/api/admin/users/collect", datas, "json");
-  }
-};
-export const deleteClientUser = userId => {
-  return $del(`/api/admin/users/collect/${userId}`, {});
-};
-// 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 = workId => {
-  return $get(`/api/marksubjects/${workId}/subjects`);
-};
-export const subjectDetail = subjectId => {
-  return $get(`/api/marksubjects/${subjectId}`);
-};
-export const updateSubject = datas => {
-  if (datas.id) {
-    return $post(`/api/marksubjects/${datas.id}/updateName`, datas);
-  } else {
-    return $post(`/api/marksubjects/${datas.id}`, datas);
-  }
-};
-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
-// TO workDetail and updateWork
-
-// grading-rule-set
-export const updateLevelParams = datas => {
-  return $post("/api/param/level", datas);
-};
-export const enableSubjectUsers = subjectId => {
-  return $post(`/api/marksubjects/${subjectId}/updateLocking`, {});
-};
-// update-paper
-// grading-rule-set
-
-// mark-set -------------------------->
-// mark-rule-set
-export const updateScoreParams = datas => {
-  return $post("/api/param/score", datas, "json");
-};
-// export-paper
-export const exportScorePictures = datas => {
-  return $get("/api/file/image/exportScorePictures", datas);
-};
-export const exportDecryptPictures = datas => {
-  return $get("/api/file/image/exportDecryptPictures", datas);
-};
-
-// quality-analysis -------------------------->
-// 档位占比
-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);
-};
-// 打回次数
-export const callbackReport = datas => {
-  return $get("/api/quality/callbackReport", datas);
-};
-
-// student-score -------------------------->
-export const studentScoreList = datas => {
-  return $get(`/api/papers/studentScore`, datas);
-};
-// exam-paper-view
-export const uploadPaperList = workId => {
-  return $get(`/api/papers/${workId}/listUploadPaper`);
-};
-
-// grading -------------------------->
-// grading-user-manage
-export const gradingUserList = datas => {
-  return $get("/api/admin/users", datas);
-};
-export const updateGradingUser = datas => {
-  if (datas.id) {
-    return $put(`/api/admin/users/${datas.id}`, datas, "json");
-  } else {
-    return $post("/api/admin/users", datas, "json");
-  }
-};
-export const deleteGradingUser = userId => {
-  return $del(`/api/admin/users/${userId}`);
-};
-export const enableGradingUser = ({ userId, enable }) => {
-  return $post(`/api/admin/users/enable`, { userId, enable });
-};
-// grading-group-manage
-export const gradingGroupList = subjectId => {
-  return $get(`/api/marksubjects/${subjectId}/markergroups`, {});
-};
-export const updateGradingGroup = (subjectId, datas) => {
-  if (datas.groupId) {
-    return $patch(
-      `/api/marksubjects/${subjectId}/markergroups/${datas.groupId}`,
-      datas,
-      "json"
-    );
-  } else {
-    return $post(`/api/marksubjects/${subjectId}/markergroups`, datas, "json");
-  }
-};
-export const deleteGradingGroup = (subjectId, groupId) => {
-  return $del(`/api/marksubjects/${subjectId}/markergroups/${groupId}`);
-};
-export const markUserList = ({ workId, subjectId }) => {
-  return $get("/api/markers", { workId, subject: subjectId });
-};
-// grading-progress
-export const gradingProgressDetail = ({ workId, subject }) => {
-  return $get("/api/markers/stat/progress", { workId, subject });
-};
-export const areaStatProgress = subjectId => {
-  return $get(`/api/marksubjects/${subjectId}/areaProgress`);
-};
-export const createTryGradingTask = datas => {
-  // workId, subject
-  return $get(`/api/trial/startTrial`, datas);
-};
-export const finishTryGradingTask = datas => {
-  // workId, subject
-  return $get(`/api/trial/finishTrial`, datas);
-};
-export const cleanGradingData = datas => {
-  // workId, subject,stage,,loginName,password
-  return $post(`/api/markers/subject/reset`, datas);
-};
-// grade-task
-export const checkMissionStatus = ({ workId, subject }) => {
-  return $get("/api/trial/checkMissionStatus", { workId, subject });
-};
-export const checkCanPublishTask = subjectId => {
-  return $get(`/api/marksubjects/${subjectId}/canLevel`);
-};
-// 分档任务发布
-export const createGradingTask = ({ subjectId, taskCount, questionId }) => {
-  return $patch(
-    `/api/marksubjects/${subjectId}`,
-    {
-      taskCount,
-      questionId
-    },
-    "json"
-  );
-};
-// 进入打分阶段,和上面掉的同一个接口,分开是为了便于区分
-export const gotoScoreStep = subjectId => {
-  return $patch(`/api/marksubjects/${subjectId}`, {}, "json");
-};
-// 打分任务发布
-export const publishScoreTask = ({ subjectId, questionId, taskList }) => {
-  return $post(
-    `/api/marksubjects/${subjectId}/publishScore`,
-    {
-      questionId,
-      taskList
-    },
-    "json"
-  );
-};
-// grading-standard-paper-manage
-export const cancelStandardPaper = paperIds => {
-  return $patch(`/api/papers/batch/cancelSample`, { paperIds }, "json");
-};
-
-// grading-detail ------------------------->
-// grading-analysis
-export const gradingStatData = datas => {
-  return $get("/api/marktasks/levelStatDetail", datas);
-};
-// 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 });
-};
-export const scoreStatData = (subjectId, questionId) => {
-  return $get(`/api/marksubjects/${subjectId}/stat/scores`, { questionId });
-};
-export const markerLevelStatData = (userId, questionId) => {
-  return $get(`/api/markers/${userId}/stat/levels`, { questionId });
-};
-export const markerLevelTotalStatData = (userId, questionId) => {
-  return $get(`/api/markers/${userId}/stat/totalLevels`, { questionId });
-};
-// area
-export const areaList = ({ workId, subject }) => {
-  return $get("/api/questions", { workId, subject });
-};
-export const sampleAreaList = ({ workId, subject }) => {
-  return $get("/api/questions/sampleQuestions", { workId, subject });
-};
-// papers
-export const paperList = datas => {
-  // ?questionId=64&level=A&page=0&size=6&sort=secretNumber&isSample=true
-  return $get("/api/papers", datas);
-};
-export const paperManualScoreList = datas => {
-  // ?questionId=64&workId=73&page=0&size=6
-  return $get("/api/papers/manualScore", datas);
-};
-export const markerTaskList = datas => {
-  // ?stage=LEVEL&markerId=49&size=6&page=0&sort=updatedOn,desc&questionId=73&isSample=false&level=C
-  return $get("/api/marktasks", datas);
-};
-export const markTaskPaperList = datas => {
-  // ?workId=&stage=&subject=&markerId=
-  return $get("/api/marktasks/list_mark_task", datas);
-};
-// grading or scoring
-export const paperSelectLevelOrScore = (
-  taskId,
-  result,
-  stage,
-  manualScore = 0
-) => {
-  // stage => LEVEL or SCORE
-  return $patch(
-    `/api/marktasks/${taskId}`,
-    { stage, result, manualScore },
-    "json"
-  );
-};
-export const paperSelectLevelBatch = (taskIds, result, stage) => {
-  return $patch(`/api/marktasks/batch`, { taskIds, result, stage }, "json");
-};
-export const paperTaskPass = taskId => {
-  return $post(`/api/marktasks/${taskId}/skip`, {});
-};
-export const markTask = ({ markTaskId, isMark }) => {
-  return $post(`/api/marktasks/mark_task`, { markTaskId, isMark });
-};
-// grade or mark history
-export const markHistoryList = (paperId, stage) => {
-  return $get(`/api/papers/${paperId}/marktasks`, { stage });
-};
-// marker-status-info
-export const markerDetail = userId => {
-  return $get(`/api/markers/${userId}`);
-};
-// leader mark paper
-export const leaderGradingPaper = datas => {
-  // datas:{value: ,level:,range?, paperIds: '1,2'}
-  return $patch(`/api/papers/batch`, datas, "json");
-  // return $patch(`/api/papers/${paperId}`, datas, "json");
-};
-// review action history
-export const actionHistory = datas => {
-  return $get("/api/marktasks/reviewPaper", datas);
-};
-export const actionLeaderHistory = datas => {
-  return $get("/api/marktasks/kzzReviewPaper", datas);
-};
-// sn search
-export const taskSnSearch = (type, code, questionId) => {
-  if (type === "task") {
-    return $get(`/api/papers/search/byTaskSecretNumber`, {
-      sn: code,
-      questionId
-    });
-  } else {
-    const paramName = type === "examNumber" ? "examNumber" : "sn";
-    return $get(`/api/papers/one`, { [paramName]: code, questionId });
-  }
-};
-// mark step change level
-export const markStepChangeLevel = ({ subjectId, paperId, level, userId }) => {
-  // paperId,level
-  return $post(`/api/changelevel/${subjectId}/changeLevel`, {
-    paperId,
-    level,
-    userId
-  });
-};
-export const changeLevelPaperList = datas => {
-  // 纪检人员、超级管理员和科组长查询改档列表
-  // status => 0:未审核,1:已审核
-  // 科组长默认查询审核通过的
-  return $get("/api/changelevel/list", datas);
-};
-
-// mark -------------------------->
-// mark-progress
-// to see grading progress
-
-// mark-task-manage
-export const checkMarkTaskSubmitType = subjectId => {
-  return $get(`/api/marksubjects/${subjectId}/canScoreAll`);
-};
-export const checkMarkTaskCanSubmit = (subjectId, questionId) => {
-  let datas = questionId ? { questionId } : null;
-  return $get(`/api/marksubjects/${subjectId}/canScore`, datas);
-};
-export const markTaskInfo = (subjectId, questionId) => {
-  let datas = questionId ? { questionId } : null;
-  return $get(`/api/marksubjects/${subjectId}/scoreProgress`, datas);
-};
-// mark-detail
-export const markerScoreStatData = (userId, questionId) => {
-  return $get(`/api/markers/${userId}/stat/scores`, { questionId });
-};
-export const markerScoreTotalStatData = (userId, questionId) => {
-  return $get(`/api/markers/${userId}/stat/totalScores`, { questionId });
-};
-// mark-operation
-export const markerChangeLevelPaperList = datas => {
-  // ?markerId=49&size=6&page=0&isShift=true&isShiftScore=false&questionId=10
-  return $get(`/api/marktasks/shift`, datas);
-};
-export const markerManualScorePaperList = datas => {
-  // ?markerId=49&workId=22&questionId=10&size=6&page=0
-  return $get(`/api/marktasks/manualScore`, datas);
-};
-export const markerMarkPaperList = datas => {
-  // ?markerId=15&questionId=2&subject=SC&workId=25&stage=&page=0&size=12
-  return $get(`/api/marktasks/markedPapers`, datas);
-};
-
-// inspection -------------------------->
-// inspection-log
-export const inspectionActionLogPageList = datas => {
-  return $get(`/api/marklog/selectMarkLog`, datas);
-};
-export const inspectionCollectLogPageList = datas => {
-  return $get(`/api/marklog/selectCollectMarkLog`, datas);
-};
-export const inspectionConfirmCheckGrade = datas => {
-  // id,auditStatus
-  return $post(`/api/changelevel/changeLevelAudit`, datas);
-};
-export const logTypeList = () => {
-  return $get(`/api/marklog/listTypes`);
-};
+import { $get, $post, $del, $patch, $put } from "@/plugins/axios";
+
+// login
+export const login = (datas) => {
+  return $post("/api/login", datas);
+};
+export const logout = () => {
+  return $del("/api/logout");
+};
+export const resetPwd = ({ userId, password }) => {
+  return $patch(`/api/${userId}/password`, { password }, "json");
+};
+
+// org-manage
+export const orgList = (datas) => {
+  return $get("/api/admin/organization", datas);
+};
+export const orgDetail = (organizationId) => {
+  return $get(`/api/admin/organization/${organizationId}`);
+};
+export const createOrg = (datas) => {
+  return $post(`/api/admin/organization`, datas, "json");
+};
+export const updateOrgUser = (datas) => {
+  return $put(`/api/admin/organization`, datas, "json");
+};
+export const enableOrgUser = (userId) => {
+  return $post(`/api/admin/organization/${userId}`, {});
+};
+export const deleteOrg = (orgId) => {
+  return $del(`/api/admin/organization/${orgId}`);
+};
+
+// work-manage
+export const workList = () => {
+  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, "json");
+};
+export const activeWork = (workId) => {
+  return $patch(`/api/admin/works/${workId}`, {});
+};
+export const deleteWork = (workId) => {
+  return $del(`/api/admin/works/${workId}`);
+};
+
+// work-overview
+export const workOverviewDetail = (workId) => {
+  return $get(`/api/admin/works/${workId}/overview`);
+};
+
+// paper-manage
+export const paperPageList = (datas) => {
+  return $get("/api/papers/listByQuestion", datas);
+};
+export const rotatePaper = (imageId, degree) => {
+  return $get(`/api/images/${imageId}/rotate`, { degree });
+};
+export const absentPaper = (imageId) => {
+  return $post(`/api/score/missing/${imageId}`, {});
+};
+export const markPaper = ({ paperId, isMark, role }) => {
+  return $post(`/api/papers/mark_paper`, { paperId, isMark, role });
+};
+
+// client-monitor
+export const clientMonitorList = (datas) => {
+  return $get("/api/marklog/equipmentMonitor", datas);
+};
+
+// student-manage
+export const studentPageList = (datas) => {
+  return $get("/api/students", datas);
+};
+export const updateStudent = (datas) => {
+  if (datas.id) {
+    return $put(`/api/students/${datas.id}`, datas, "json");
+  } else {
+    return $post(`/api/students`, datas, "json");
+  }
+};
+export const deleteStudent = (studentId) => {
+  return $del(`/api/students/${studentId}`, {});
+};
+export const absentStudentSubject = (datas) => {
+  return $post(`/api/students/missing`, datas);
+};
+export const areaSchoolRoomCascadeList = (workId) => {
+  // 考区-学校-考场 联动查询
+  return $get(`/api/students/select/${workId}`);
+};
+
+// client-set -------------------------->
+// client-user-set
+export const clientUserPageList = (datas) => {
+  return $get("/api/admin/users/collect", datas);
+};
+export const clientUserQuery = (workId) => {
+  return $get("/api/admin/users/collect/all", { workId });
+};
+export const updateClientUser = (datas) => {
+  if (datas.id) {
+    return $put(`/api/admin/users/collect/${datas.id}`, datas, "json");
+  } else {
+    return $post("/api/admin/users/collect", datas, "json");
+  }
+};
+export const deleteClientUser = (userId) => {
+  return $del(`/api/admin/users/collect/${userId}`, {});
+};
+// 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 = (workId) => {
+  return $get(`/api/marksubjects/${workId}/subjects`);
+};
+export const subjectDetail = (subjectId) => {
+  return $get(`/api/marksubjects/${subjectId}`);
+};
+export const updateSubject = (datas) => {
+  if (datas.id) {
+    return $post(`/api/marksubjects/${datas.id}/updateName`, datas);
+  } else {
+    return $post(`/api/marksubjects/${datas.id}`, datas);
+  }
+};
+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
+// TO workDetail and updateWork
+
+// grading-rule-set
+export const updateLevelParams = (datas) => {
+  return $post("/api/param/level", datas);
+};
+export const enableSubjectUsers = (subjectId) => {
+  return $post(`/api/marksubjects/${subjectId}/updateLocking`, {});
+};
+// update-paper
+// grading-rule-set
+
+// mark-set -------------------------->
+// mark-rule-set
+export const updateScoreParams = (datas) => {
+  return $post("/api/param/score", datas, "json");
+};
+// export-paper
+export const exportScorePictures = (datas) => {
+  return $get("/api/file/image/exportScorePictures", datas);
+};
+export const exportDecryptPictures = (datas) => {
+  return $get("/api/file/image/exportDecryptPictures", datas);
+};
+
+// quality-analysis -------------------------->
+// 档位占比
+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);
+};
+// 打回次数
+export const callbackReport = (datas) => {
+  return $get("/api/quality/callbackReport", datas);
+};
+
+// student-score -------------------------->
+export const studentScoreList = (datas) => {
+  return $get(`/api/papers/studentScore`, datas);
+};
+// exam-paper-view
+export const uploadPaperList = (workId) => {
+  return $get(`/api/papers/${workId}/listUploadPaper`);
+};
+
+// grading -------------------------->
+// grading-user-manage
+export const gradingUserList = (datas) => {
+  return $get("/api/admin/users", datas);
+};
+export const updateGradingUser = (datas) => {
+  if (datas.id) {
+    return $put(`/api/admin/users/${datas.id}`, datas, "json");
+  } else {
+    return $post("/api/admin/users", datas, "json");
+  }
+};
+export const deleteGradingUser = (userId) => {
+  return $del(`/api/admin/users/${userId}`);
+};
+export const enableGradingUser = ({ userId, enable }) => {
+  return $post(`/api/admin/users/enable`, { userId, enable });
+};
+// grading-group-manage
+export const gradingGroupList = (subjectId) => {
+  return $get(`/api/marksubjects/${subjectId}/markergroups`, {});
+};
+export const updateGradingGroup = (subjectId, datas) => {
+  if (datas.groupId) {
+    return $patch(
+      `/api/marksubjects/${subjectId}/markergroups/${datas.groupId}`,
+      datas,
+      "json"
+    );
+  } else {
+    return $post(`/api/marksubjects/${subjectId}/markergroups`, datas, "json");
+  }
+};
+export const deleteGradingGroup = (subjectId, groupId) => {
+  return $del(`/api/marksubjects/${subjectId}/markergroups/${groupId}`);
+};
+export const markUserList = ({ workId, subjectId }) => {
+  return $get("/api/markers", { workId, subject: subjectId });
+};
+// grading-progress
+export const gradingProgressDetail = ({ workId, subject }) => {
+  return $get("/api/markers/stat/progress", { workId, subject });
+};
+export const areaStatProgress = (subjectId) => {
+  return $get(`/api/marksubjects/${subjectId}/areaProgress`);
+};
+export const createTryGradingTask = (datas) => {
+  // workId, subject
+  return $get(`/api/trial/startTrial`, datas);
+};
+export const finishTryGradingTask = (datas) => {
+  // workId, subject
+  return $get(`/api/trial/finishTrial`, datas);
+};
+export const cleanGradingData = (datas) => {
+  // workId, subject,stage,,loginName,password
+  return $post(`/api/markers/subject/reset`, datas);
+};
+// grade-task
+export const checkMissionStatus = ({ workId, subject }) => {
+  return $get("/api/trial/checkMissionStatus", { workId, subject });
+};
+export const checkCanPublishTask = (subjectId) => {
+  return $get(`/api/marksubjects/${subjectId}/canLevel`);
+};
+// 分档任务发布
+export const createGradingTask = ({ subjectId, taskCount, questionId }) => {
+  return $patch(
+    `/api/marksubjects/${subjectId}`,
+    {
+      taskCount,
+      questionId,
+    },
+    "json"
+  );
+};
+// 进入打分阶段,和上面掉的同一个接口,分开是为了便于区分
+export const gotoScoreStep = (subjectId) => {
+  return $patch(`/api/marksubjects/${subjectId}`, {}, "json");
+};
+// 打分任务发布
+export const publishScoreTask = ({ subjectId, questionId, taskList }) => {
+  return $post(
+    `/api/marksubjects/${subjectId}/publishScore`,
+    {
+      questionId,
+      taskList,
+    },
+    "json"
+  );
+};
+// grading-standard-paper-manage
+export const cancelStandardPaper = (paperIds) => {
+  return $patch(`/api/papers/batch/cancelSample`, { paperIds }, "json");
+};
+
+// grading-detail ------------------------->
+// grading-analysis
+export const gradingStatData = (datas) => {
+  return $get("/api/marktasks/levelStatDetail", datas);
+};
+// 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 });
+};
+export const scoreStatData = (subjectId, questionId) => {
+  return $get(`/api/marksubjects/${subjectId}/stat/scores`, { questionId });
+};
+export const markerLevelStatData = (userId, questionId) => {
+  return $get(`/api/markers/${userId}/stat/levels`, { questionId });
+};
+export const markerLevelTotalStatData = (userId, questionId) => {
+  return $get(`/api/markers/${userId}/stat/totalLevels`, { questionId });
+};
+// area
+export const areaList = ({ workId, subject }) => {
+  return $get("/api/questions", { workId, subject });
+};
+export const sampleAreaList = ({ workId, subject }) => {
+  return $get("/api/questions/sampleQuestions", { workId, subject });
+};
+// papers
+export const paperList = (datas) => {
+  // ?questionId=64&level=A&page=0&size=6&sort=secretNumber&isSample=true
+  return $get("/api/papers", datas);
+};
+export const paperManualScoreList = (datas) => {
+  // ?questionId=64&workId=73&page=0&size=6
+  return $get("/api/papers/manualScore", datas);
+};
+export const markerTaskList = (datas) => {
+  // ?stage=LEVEL&markerId=49&size=6&page=0&sort=updatedOn,desc&questionId=73&isSample=false&level=C
+  return $get("/api/marktasks", datas);
+};
+export const markTaskPaperList = (datas) => {
+  // ?workId=&stage=&subject=&markerId=
+  return $get("/api/marktasks/list_mark_task", datas);
+};
+// grading or scoring
+export const paperSelectLevelOrScore = (
+  taskId,
+  result,
+  stage,
+  manualScore = 0
+) => {
+  // stage => LEVEL or SCORE
+  return $patch(
+    `/api/marktasks/${taskId}`,
+    { stage, result, manualScore },
+    "json"
+  );
+};
+export const paperSelectLevelBatch = (taskIds, result, stage) => {
+  return $patch(`/api/marktasks/batch`, { taskIds, result, stage }, "json");
+};
+export const paperTaskPass = (taskId) => {
+  return $post(`/api/marktasks/${taskId}/skip`, {});
+};
+export const markTask = ({ markTaskId, isMark }) => {
+  return $post(`/api/marktasks/mark_task`, { markTaskId, isMark });
+};
+// grade or mark history
+export const markHistoryList = (paperId, stage) => {
+  return $get(`/api/papers/${paperId}/marktasks`, { stage });
+};
+// marker-status-info
+export const markerDetail = (userId) => {
+  return $get(`/api/markers/${userId}`);
+};
+// leader mark paper
+export const leaderGradingPaper = (datas) => {
+  // datas:{value: ,level:,range?, paperIds: '1,2'}
+  return $patch(`/api/papers/batch`, datas, "json");
+  // return $patch(`/api/papers/${paperId}`, datas, "json");
+};
+// review action history
+export const actionHistory = (datas) => {
+  return $get("/api/marktasks/reviewPaper", datas);
+};
+export const actionLeaderHistory = (datas) => {
+  return $get("/api/marktasks/kzzReviewPaper", datas);
+};
+// sn search
+export const taskSnSearch = (type, code, questionId) => {
+  if (type === "task") {
+    return $get(`/api/papers/search/byTaskSecretNumber`, {
+      sn: code,
+      questionId,
+    });
+  } else {
+    const paramName = type === "examNumber" ? "examNumber" : "sn";
+    return $get(`/api/papers/one`, { [paramName]: code, questionId });
+  }
+};
+// mark step change level
+export const markStepChangeLevel = ({ subjectId, paperId, level, userId }) => {
+  // paperId,level
+  return $post(`/api/changelevel/${subjectId}/changeLevel`, {
+    paperId,
+    level,
+    userId,
+  });
+};
+export const changeLevelPaperList = (datas) => {
+  // 纪检人员、超级管理员和科组长查询改档列表
+  // status => 0:未审核,1:已审核
+  // 科组长默认查询审核通过的
+  return $get("/api/changelevel/list", datas);
+};
+
+// mark -------------------------->
+// mark-progress
+// to see grading progress
+
+// mark-task-manage
+export const checkMarkTaskSubmitType = (subjectId) => {
+  return $get(`/api/marksubjects/${subjectId}/canScoreAll`);
+};
+export const checkMarkTaskCanSubmit = (subjectId, questionId) => {
+  let datas = questionId ? { questionId } : null;
+  return $get(`/api/marksubjects/${subjectId}/canScore`, datas);
+};
+export const markTaskInfo = (subjectId, questionId) => {
+  let datas = questionId ? { questionId } : null;
+  return $get(`/api/marksubjects/${subjectId}/scoreProgress`, datas);
+};
+// mark-detail
+export const markerScoreStatData = (userId, questionId) => {
+  return $get(`/api/markers/${userId}/stat/scores`, { questionId });
+};
+export const markerScoreTotalStatData = (userId, questionId) => {
+  return $get(`/api/markers/${userId}/stat/totalScores`, { questionId });
+};
+// mark-operation
+export const markerChangeLevelPaperList = (datas) => {
+  // ?markerId=49&size=6&page=0&isShift=true&isShiftScore=false&questionId=10
+  return $get(`/api/marktasks/shift`, datas);
+};
+export const markerManualScorePaperList = (datas) => {
+  // ?markerId=49&workId=22&questionId=10&size=6&page=0
+  return $get(`/api/marktasks/manualScore`, datas);
+};
+export const markerMarkPaperList = (datas) => {
+  // ?markerId=15&questionId=2&subject=SC&workId=25&stage=&page=0&size=12
+  return $get(`/api/marktasks/markedPapers`, datas);
+};
+
+// inspection -------------------------->
+// inspection-log
+export const inspectionActionLogPageList = (datas) => {
+  return $get(`/api/marklog/selectMarkLog`, datas);
+};
+export const inspectionCollectLogPageList = (datas) => {
+  return $get(`/api/marklog/selectCollectMarkLog`, datas);
+};
+export const inspectionConfirmCheckGrade = (datas) => {
+  // id,auditStatus
+  return $post(`/api/changelevel/changeLevelAudit`, datas);
+};
+export const logTypeList = () => {
+  return $get(`/api/marklog/listTypes`);
+};

+ 179 - 179
src/components/EchartRender.vue

@@ -30,29 +30,29 @@ export default {
             "line",
             "darkLines",
             "barGroup",
-            "lineGroup"
+            "lineGroup",
           ].indexOf(value) !== -1
         );
-      }
+      },
     },
     rendererType: {
       type: String,
       default: "canvas",
       validator(val) {
         return ["canvas", "svg"].indexOf(val) !== -1;
-      }
+      },
     },
     animationIsOpen: {
       type: Boolean,
-      default: true
+      default: true,
     },
     chartData: {
       type: [Object, Array],
-      required: true
+      required: true,
     },
     chartTitle: {
       type: String,
-      default: ""
+      default: "",
     },
     chartColor: {
       type: Array,
@@ -63,15 +63,15 @@ export default {
           "#FF7786",
           "#4E7CFF",
           "#6d32f9",
-          "#dd7755"
+          "#dd7755",
         ];
-      }
-    }
+      },
+    },
   },
   data() {
     return {
       chartOption: null,
-      initOptions: { renderer: "canvas" }
+      initOptions: { renderer: "canvas" },
     };
   },
   mounted() {
@@ -89,19 +89,19 @@ export default {
     getLineOption(datas) {
       let labels = [],
         vals = [];
-      datas.map(item => {
+      datas.map((item) => {
         labels.push(item.name);
         vals.push(item.value);
       });
       const linearColor = new echarts.graphic.LinearGradient(0, 1, 0, 0, [
         {
           offset: 1,
-          color: "rgba(34,192,255,1)"
+          color: "rgba(34,192,255,1)",
         },
         {
           offset: 0,
-          color: "rgba(34,192,255,0)"
-        }
+          color: "rgba(34,192,255,0)",
+        },
       ]);
 
       return {
@@ -110,13 +110,13 @@ export default {
           top: "10%",
           bottom: "12%",
           left: "5%",
-          right: "5%"
+          right: "5%",
         },
         tooltip: {
           show: true,
-          formatter: function(params) {
+          formatter: function (params) {
             return params.value + "%";
-          }
+          },
         },
         xAxis: {
           type: "category",
@@ -124,46 +124,46 @@ export default {
           splitLine: {
             show: true,
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLine: {
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLabel: {
             color: "#7C86A3",
             fontSize: 12,
-            fontWeight: "bold"
+            fontWeight: "bold",
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
         yAxis: {
           type: "value",
           splitLine: {
             show: true,
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLine: {
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLabel: {
             fontSize: 12,
             color: "#7C86A3",
-            formatter: function(value, index) {
+            formatter: function (value, index) {
               return value + "%";
-            }
+            },
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
         series: [
           {
@@ -172,21 +172,21 @@ export default {
             smooth: true,
             data: vals,
             itemStyle: {
-              color: "rgba(34, 192, 255, 1)"
+              color: "rgba(34, 192, 255, 1)",
             },
             lineStyle: {
-              color: "rgba(34, 192, 255, 1)"
+              color: "rgba(34, 192, 255, 1)",
             },
             areaStyle: {
-              color: linearColor
-            }
-          }
-        ]
+              color: linearColor,
+            },
+          },
+        ],
       };
     },
     getDarkLinesOption(datas) {
       if (!datas.length) return;
-      const labels = datas[0].data.map(item => item.name);
+      const labels = datas[0].data.map((item) => item.name);
       const colors = [
         {
           color: "rgba(21, 91, 146,1)",
@@ -194,14 +194,14 @@ export default {
           linearColor: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
             {
               offset: 1,
-              color: "rgba(21, 91, 146,1)"
+              color: "rgba(21, 91, 146,1)",
             },
             {
               offset: 0,
-              color: "rgba(21, 91, 146,0.2)"
-            }
+              color: "rgba(21, 91, 146,0.2)",
+            },
           ]),
-          z: 4
+          z: 4,
         },
         {
           color: "rgba(204, 70, 53,1)",
@@ -209,19 +209,19 @@ export default {
           linearColor: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
             {
               offset: 1,
-              color: "rgba(204, 70, 53,1)"
+              color: "rgba(204, 70, 53,1)",
             },
             {
               offset: 0,
-              color: "rgba(204, 70, 53,0)"
-            }
+              color: "rgba(204, 70, 53,0)",
+            },
           ]),
-          z: 3
-        }
+          z: 3,
+        },
       ];
 
-      const series = datas.map(function(item, index) {
-        const data = item.data.map(function(elem) {
+      const series = datas.map(function (item, index) {
+        const data = item.data.map(function (elem) {
           return elem.value;
         });
         const color = colors[index];
@@ -234,14 +234,14 @@ export default {
           symbolSize: 6,
           z: color.z,
           itemStyle: {
-            color: color.color
+            color: color.color,
           },
           lineStyle: {
-            color: color.lineColor
+            color: color.lineColor,
           },
           areaStyle: {
-            color: color.linearColor
-          }
+            color: color.linearColor,
+          },
         };
       });
 
@@ -251,22 +251,22 @@ export default {
           top: "10%",
           bottom: "12%",
           left: "3.5%",
-          right: "3%"
+          right: "3%",
         },
         tooltip: {
           show: true,
-          formatter: function(params) {
+          formatter: function (params) {
             return params.value + "%";
-          }
+          },
         },
         legend: {
-          data: datas.map(data => data.name),
+          data: datas.map((data) => data.name),
           right: "3%",
           itemWidth: 14,
           textStyle: {
             color: "#9d9c9c",
-            fontSize: 14
-          }
+            fontSize: 14,
+          },
         },
         xAxis: {
           type: "category",
@@ -274,73 +274,73 @@ export default {
           splitLine: {
             show: true,
             lineStyle: {
-              color: "#3d3f55"
-            }
+              color: "#3d3f55",
+            },
           },
           axisLine: {
             lineStyle: {
-              color: "#3d3f55"
-            }
+              color: "#3d3f55",
+            },
           },
           axisLabel: {
             color: "#9d9c9c",
             fontSize: 12,
-            fontWeight: "bold"
+            fontWeight: "bold",
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
         yAxis: {
           type: "value",
           splitLine: {
             show: true,
             lineStyle: {
-              color: "#3d3f55"
-            }
+              color: "#3d3f55",
+            },
           },
           axisLine: {
             lineStyle: {
-              color: "#3d3f55"
-            }
+              color: "#3d3f55",
+            },
           },
           axisLabel: {
             fontSize: 12,
             color: "#9d9c9c",
-            formatter: "{value}%"
+            formatter: "{value}%",
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
-        series: series
+        series: series,
       };
     },
     getPieOption(datas) {
       if (!datas.chartLabels.length) return;
-      const seriesData = datas.chartLabels.map(function(item, index) {
+      const seriesData = datas.chartLabels.map(function (item, index) {
         return {
           name: item,
-          value: datas.chartData[0][index]
+          value: datas.chartData[0][index],
         };
       });
       return {
         animation: this.animationIsOpen,
         grid: {
           top: "24%",
-          bottom: "10%"
+          bottom: "10%",
         },
         tooltip: {
           trigger: "item",
-          formatter: "{a} <br/>{b} : {c} ({d}%)"
+          formatter: "{a} <br/>{b} : {c} ({d}%)",
         },
         legend: {
           show: true,
           itemGap: 20,
           itemWidth: 20,
           textStyle: {
-            fontSize: 16
-          }
+            fontSize: 16,
+          },
         },
         series: [
           {
@@ -349,17 +349,17 @@ export default {
             radius: "70%",
             data: seriesData,
             label: {
-              show: false
+              show: false,
             },
             itemStyle: {
               emphasis: {
                 shadowBlur: 10,
                 shadowOffsetX: 0,
-                shadowColor: "rgba(0, 0, 0, 0.5)"
-              }
-            }
-          }
-        ]
+                shadowColor: "rgba(0, 0, 0, 0.5)",
+              },
+            },
+          },
+        ],
       };
     },
     getBarOption(datas) {
@@ -371,49 +371,49 @@ export default {
           top: "20%",
           bottom: "10%",
           left: "8%",
-          right: "5%"
+          right: "5%",
         },
         tooltip: {
-          show: true
+          show: true,
         },
         xAxis: {
           type: "category",
           data: datas.names,
           axisLine: {
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLabel: {
             color: "#7C86A3",
             fontSize: 12,
-            fontWeight: "bold"
+            fontWeight: "bold",
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
         yAxis: {
           type: "value",
           splitLine: {
             show: true,
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLine: {
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLabel: {
             color: "#7C86A3",
             fontSize: 12,
-            fontWeight: "bold"
+            fontWeight: "bold",
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
         series: [
           {
@@ -424,13 +424,13 @@ export default {
             label: {
               show: true,
               position: "top",
-              color: "#666"
+              color: "#666",
             },
             itemStyle: {
-              barBorderRadius: 4
-            }
-          }
-        ]
+              barBorderRadius: 4,
+            },
+          },
+        ],
       };
     },
     getBarReverseOption(datas) {
@@ -442,55 +442,55 @@ export default {
           top: "20%",
           bottom: "10%",
           left: "12%",
-          right: "5%"
+          right: "5%",
         },
         tooltip: {
-          show: true
+          show: true,
         },
         yAxis: {
           type: "category",
           data: datas.names,
           axisLine: {
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           splitLine: {
             show: true,
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLabel: {
             color: "#7C86A3",
             fontSize: 12,
-            fontWeight: "bold"
+            fontWeight: "bold",
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
         xAxis: {
           type: "value",
           splitLine: {
             show: false,
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLine: {
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLabel: {
             color: "#7C86A3",
             fontSize: 12,
-            fontWeight: "bold"
+            fontWeight: "bold",
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
         series: [
           {
@@ -501,22 +501,22 @@ export default {
             label: {
               show: true,
               position: "right",
-              color: "#666"
+              color: "#666",
             },
             itemStyle: {
-              barBorderRadius: 4
-            }
-          }
-        ]
+              barBorderRadius: 4,
+            },
+          },
+        ],
       };
     },
     getBarGroupOption(datas) {
       if (!datas.names.length) return;
-      const xAxis = datas.dataList.map(function(item) {
+      const xAxis = datas.dataList.map(function (item) {
         return item.name;
       });
-      const series = datas.names.map(function(name, index) {
-        const data = datas.dataList.map(function(item) {
+      const series = datas.names.map(function (name, index) {
+        const data = datas.dataList.map(function (item) {
           return item.data[index];
         });
         return {
@@ -525,8 +525,8 @@ export default {
           data: data,
           barMaxWidth: 12,
           itemStyle: {
-            barBorderRadius: 2
-          }
+            barBorderRadius: 2,
+          },
         };
       });
 
@@ -537,30 +537,30 @@ export default {
           top: "20%",
           bottom: "10%",
           left: "8%",
-          right: "5%"
+          right: "5%",
         },
         tooltip: {
           show: true,
           trigger: "axis",
           axisPointer: {
-            type: "shadow"
+            type: "shadow",
           },
-          formatter: function(params) {
+          formatter: function (params) {
             const label = params[0].axisValueLabel;
-            let infos = params.map(function(item) {
+            let infos = params.map(function (item) {
               return item.seriesName + ":" + item.value.toFixed(2) + "%";
             });
             infos.unshift(label);
             return infos.join("<br/>");
-          }
+          },
         },
         legend: {
           data: datas.names,
           right: 0,
           itemWidth: 14,
           textStyle: {
-            fontSize: 16
-          }
+            fontSize: 16,
+          },
         },
         xAxis: {
           type: "category",
@@ -568,52 +568,52 @@ export default {
           axisLabel: {
             color: "#7C86A3",
             fontSize: 12,
-            fontWeight: "bold"
+            fontWeight: "bold",
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
         yAxis: {
           type: "value",
           splitLine: {
             show: true,
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLine: {
             lineStyle: {
-              color: "rgba(231,234,241,1)"
-            }
+              color: "rgba(231,234,241,1)",
+            },
           },
           axisLabel: {
             color: "#7C86A3",
             fontSize: 12,
             fontWeight: "bold",
-            formatter: function(value, index) {
+            formatter: function (value, index) {
               return value + "%";
-            }
+            },
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
-        series: series
+        series: series,
       };
 
       return options;
     },
     getLineGroupOption(datas) {
       if (!datas.length) return;
-      const names = datas.map(function(item) {
+      const names = datas.map(function (item) {
         return item.name;
       });
-      const xaxis = datas[0].dataList.map(function(item, index) {
+      const xaxis = datas[0].dataList.map(function (item, index) {
         return index;
       });
 
-      const series = datas.map(function(item) {
+      const series = datas.map(function (item) {
         return {
           name: item.name,
           type: "line",
@@ -621,86 +621,86 @@ export default {
           smooth: true,
           itemStyle: {
             emphasis: {
-              color: "#333"
-            }
+              color: "#333",
+            },
           },
-          data: item.dataList.map(function(num) {
+          data: item.dataList.map(function (num) {
             return num * num;
-          })
+          }),
         };
       });
       return {
         animation: this.animationIsOpen,
         grid: {
           top: "15%",
-          bottom: "12%"
+          bottom: "12%",
         },
         tooltip: {
           show: true,
           trigger: "axis",
           axisPointer: {
-            type: "shadow"
+            type: "shadow",
           },
-          formatter: function(params) {
+          formatter: function (params) {
             const label = params[0].axisValueLabel;
-            let infos = params.map(function(item) {
+            let infos = params.map(function (item) {
               return item.seriesName + ":" + Math.sqrt(item.value);
             });
             infos.unshift(label);
             return infos.join("<br/>");
-          }
+          },
         },
         legend: {
           data: names,
           right: 0,
           itemWidth: 14,
           textStyle: {
-            fontSize: 16
-          }
+            fontSize: 16,
+          },
         },
         xAxis: {
           type: "category",
           data: xaxis,
           axisLabel: {
             show: false,
-            fontSize: 14
+            fontSize: 14,
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
         yAxis: {
           type: "value",
           interval: 1,
           splitLine: {
-            show: false
+            show: false,
           },
           axisLabel: {
             fontSize: 14,
-            formatter: function(value) {
+            formatter: function (value) {
               const num = Math.sqrt(value);
               return num % 1 ? "" : parseInt(num);
-            }
+            },
           },
           axisTick: {
-            show: false
-          }
+            show: false,
+          },
         },
         dataZoom: [
           {
             type: "inside",
             start: 0,
-            end: 30
+            end: 30,
           },
           {
             type: "slider",
             start: 0,
-            end: 30
-          }
+            end: 30,
+          },
         ],
-        series: series
+        series: series,
       };
-    }
-  }
+    },
+  },
 };
 </script>

+ 111 - 111
src/components/ImageViewContain.vue

@@ -1,111 +1,111 @@
-<template>
-  <div :class="['image-view-contain', { 'image-view-none': !image.thumbSrc }]">
-    <div class="image-view-image" :style="styles">
-      <img
-        v-if="image.thumbSrc"
-        :src="image.thumbSrc"
-        :alt="image.title"
-        @click="toReview"
-        @load="resizeImage"
-      />
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  name: "image-view-contain",
-  props: {
-    image: {
-      type: Object,
-      default() {
-        return {};
-      }
-    }
-  },
-  data() {
-    return {
-      styles: { width: "", height: "", top: "", left: "", transform: "" },
-      deg: 0
-    };
-  },
-  mounted() {
-    this.registWinResize();
-  },
-  beforeDestroy() {
-    window.removeEventListener("resize", () => {
-      this.resizeImage(this.deg);
-    });
-  },
-  methods: {
-    toReview() {
-      this.$emit("to-review");
-    },
-    registWinResize() {
-      window.addEventListener("resize", () => {
-        this.resizeImage(this.deg);
-      });
-    },
-    resizeImage(deg = 0) {
-      this.deg = deg;
-      const box = this.$el;
-      const imgDom = box.firstChild.firstChild;
-      const { naturalWidth, naturalHeight } = imgDom;
-      const imageSize = this.getImageSizePos({
-        win: {
-          width: box.clientWidth,
-          height: box.clientHeight
-        },
-        img: {
-          width: naturalWidth,
-          height: naturalHeight
-        },
-        rotate: deg
-      });
-      this.styles = Object.assign(this.styles, {
-        width: imageSize.width + "px",
-        height: imageSize.height + "px",
-        top: imageSize.top + "px",
-        left: imageSize.left + "px",
-        transform: `rotate(${deg}deg)`
-      });
-    },
-    getImageSizePos({ win, img, rotate }) {
-      const imageSize = {
-        width: 0,
-        height: 0,
-        top: 0,
-        left: 0
-      };
-      const isHorizontal = !!(rotate % 180);
-
-      const rateWin = isHorizontal
-        ? win.height / win.width
-        : win.width / win.height;
-      const hwin = isHorizontal
-        ? {
-            width: win.height,
-            height: win.width
-          }
-        : win;
-
-      const rateImg = img.width / img.height;
-
-      if (rateImg <= rateWin) {
-        imageSize.height = Math.min(hwin.height, img.height);
-        imageSize.width = Math.floor(
-          (imageSize.height * img.width) / img.height
-        );
-      } else {
-        imageSize.width = Math.min(hwin.width, img.width);
-        imageSize.height = Math.floor(
-          (imageSize.width * img.height) / img.width
-        );
-      }
-      imageSize.left = (win.width - imageSize.width) / 2;
-      imageSize.top = (win.height - imageSize.height) / 2;
-      return imageSize;
-    }
-  }
-};
-</script>
+<template>
+  <div :class="['image-view-contain', { 'image-view-none': !image.thumbSrc }]">
+    <div class="image-view-image" :style="styles">
+      <img
+        v-if="image.thumbSrc"
+        :src="image.thumbSrc"
+        :alt="image.title"
+        @click="toReview"
+        @load="resizeImage"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "image-view-contain",
+  props: {
+    image: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      styles: { width: "", height: "", top: "", left: "", transform: "" },
+      deg: 0,
+    };
+  },
+  mounted() {
+    this.registWinResize();
+  },
+  beforeDestroy() {
+    window.removeEventListener("resize", () => {
+      this.resizeImage(this.deg);
+    });
+  },
+  methods: {
+    toReview() {
+      this.$emit("to-review");
+    },
+    registWinResize() {
+      window.addEventListener("resize", () => {
+        this.resizeImage(this.deg);
+      });
+    },
+    resizeImage(deg = 0) {
+      this.deg = deg;
+      const box = this.$el;
+      const imgDom = box.firstChild.firstChild;
+      const { naturalWidth, naturalHeight } = imgDom;
+      const imageSize = this.getImageSizePos({
+        win: {
+          width: box.clientWidth,
+          height: box.clientHeight,
+        },
+        img: {
+          width: naturalWidth,
+          height: naturalHeight,
+        },
+        rotate: deg,
+      });
+      this.styles = Object.assign(this.styles, {
+        width: imageSize.width + "px",
+        height: imageSize.height + "px",
+        top: imageSize.top + "px",
+        left: imageSize.left + "px",
+        transform: `rotate(${deg}deg)`,
+      });
+    },
+    getImageSizePos({ win, img, rotate }) {
+      const imageSize = {
+        width: 0,
+        height: 0,
+        top: 0,
+        left: 0,
+      };
+      const isHorizontal = !!(rotate % 180);
+
+      const rateWin = isHorizontal
+        ? win.height / win.width
+        : win.width / win.height;
+      const hwin = isHorizontal
+        ? {
+            width: win.height,
+            height: win.width,
+          }
+        : win;
+
+      const rateImg = img.width / img.height;
+
+      if (rateImg <= rateWin) {
+        imageSize.height = Math.min(hwin.height, img.height);
+        imageSize.width = Math.floor(
+          (imageSize.height * img.width) / img.height
+        );
+      } else {
+        imageSize.width = Math.min(hwin.width, img.width);
+        imageSize.height = Math.floor(
+          (imageSize.width * img.height) / img.width
+        );
+      }
+      imageSize.left = (win.width - imageSize.width) / 2;
+      imageSize.top = (win.height - imageSize.height) / 2;
+      return imageSize;
+    },
+  },
+};
+</script>

+ 7 - 7
src/components/PaperCarousel.vue

@@ -31,17 +31,17 @@ export default {
       type: Array,
       default() {
         return [];
-      }
+      },
     },
     loop: {
       type: Boolean,
-      default: false
-    }
+      default: false,
+    },
   },
   data() {
     return {
       curPaper: {},
-      curIndex: 0
+      curIndex: 0,
     };
   },
   computed: {
@@ -53,7 +53,7 @@ export default {
     },
     lastIndex() {
       return this.papers.length ? this.papers.length - 1 : 0;
-    }
+    },
   },
   methods: {
     initIndex() {
@@ -105,7 +105,7 @@ export default {
     },
     clickHandle() {
       this.$emit("on-paper-click", this.curIndex, this.papers);
-    }
-  }
+    },
+  },
 };
 </script>

+ 21 - 21
src/components/SimpleImagePreview.vue

@@ -29,7 +29,7 @@
       <div
         :class="[
           `${prefixCls}-imgs`,
-          { [`${prefixCls}-imgs-nosition`]: nosition }
+          { [`${prefixCls}-imgs-nosition`]: nosition },
         ]"
         :style="styles"
         v-move-ele.prevent.stop="{ mouseMove, click: cancel }"
@@ -62,7 +62,7 @@
           title="放大"
           @click="toMagnify"
           :class="{
-            'li-disabled': transform.scale === maxScale
+            'li-disabled': transform.scale === maxScale,
           }"
         >
           <Icon type="md-add-circle" />
@@ -71,7 +71,7 @@
           title="缩小"
           @click="toShrink"
           :class="{
-            'li-disabled': transform.scale === minScale
+            'li-disabled': transform.scale === minScale,
           }"
         >
           <Icon type="md-remove-circle" />
@@ -95,8 +95,8 @@ export default {
       type: Object,
       default() {
         return {};
-      }
-    }
+      },
+    },
   },
   directives: { MoveEle },
   data() {
@@ -109,11 +109,11 @@ export default {
       maxScale: 5,
       transform: {
         scale: 1,
-        rotate: 0
+        rotate: 0,
       },
       loading: false,
       loadingSetT: null,
-      nosition: false
+      nosition: false,
     };
   },
   // watch: {
@@ -159,13 +159,13 @@ export default {
       const imageSize = this.getImageSizePos({
         win: {
           width: this.$refs.ReviewBody.clientWidth,
-          height: this.$refs.ReviewBody.clientHeight
+          height: this.$refs.ReviewBody.clientHeight,
         },
         img: {
           width: naturalWidth,
-          height: naturalHeight
+          height: naturalHeight,
         },
-        rotate: 0
+        rotate: 0,
       });
 
       this.styles = Object.assign(this.styles, {
@@ -174,11 +174,11 @@ export default {
         top: imageSize.top + "px",
         left: imageSize.left + "px",
         marginLeft: "auto",
-        transform: "none"
+        transform: "none",
       });
       this.transform = {
         scale: 1,
-        rotate: 0
+        rotate: 0,
       };
       this.loading = false;
       setTimeout(() => {
@@ -190,7 +190,7 @@ export default {
         width: 0,
         height: 0,
         top: 0,
-        left: 0
+        left: 0,
       };
       const isHorizontal = !!(rotate % 180);
 
@@ -200,7 +200,7 @@ export default {
       const hwin = isHorizontal
         ? {
             width: win.height,
-            height: win.width
+            height: win.width,
           }
         : win;
 
@@ -238,7 +238,7 @@ export default {
     },
     // dome-move
     registWheelHandle() {
-      this.$refs.ReviewBody.addEventListener("wheel", e => {
+      this.$refs.ReviewBody.addEventListener("wheel", (e) => {
         e.preventDefault();
         this.mouseWheel(e.wheelDeltaY);
       });
@@ -281,20 +281,20 @@ export default {
       const imageSize = this.getImageSizePos({
         win: {
           width: this.$refs.ReviewBody.clientWidth,
-          height: this.$refs.ReviewBody.clientHeight
+          height: this.$refs.ReviewBody.clientHeight,
         },
         img: {
           width: naturalWidth,
-          height: naturalHeight
+          height: naturalHeight,
         },
-        rotate: this.transform.rotate
+        rotate: this.transform.rotate,
       });
 
       this.styles = Object.assign(this.styles, {
         width: imageSize.width + "px",
         height: imageSize.height + "px",
         top: imageSize.top + "px",
-        left: imageSize.left + "px"
+        left: imageSize.left + "px",
       });
       // 360度无缝切换到0度
       if (this.transform.rotate >= 360) {
@@ -308,7 +308,7 @@ export default {
         }, 200);
         // 200ms当次旋转动画持续时间
       }
-    }
-  }
+    },
+  },
 };
 </script>

+ 24 - 24
src/components/UploadButton.vue

@@ -29,8 +29,8 @@
       :class="[
         {
           'cc-tips-success': res.success,
-          'cc-tips-error': !res.success
-        }
+          'cc-tips-error': !res.success,
+        },
       ]"
       v-if="res.msg && !res.success"
     >
@@ -47,44 +47,44 @@ export default {
   name: "upload-button",
   props: {
     btnIcon: {
-      type: String
+      type: String,
     },
     btnType: {
       type: String,
-      default: "default"
+      default: "default",
     },
     btnContent: {
       type: String,
-      default: "上传文件"
+      default: "上传文件",
     },
     format: {
       type: Array,
       default() {
         return ["jpg", "png"];
-      }
+      },
     },
     uploadUrl: {
       type: String,
-      required: true
+      required: true,
     },
     uploadData: {
       type: Object,
       default() {
         return {};
-      }
+      },
     },
     maxSize: {
       type: Number,
-      default: 10 * 1024
+      default: 10 * 1024,
     },
     addFilenameParam: {
       type: String,
-      default: "fileName"
+      default: "fileName",
     },
     autoUpload: {
       type: Boolean,
-      default: true
-    }
+      default: true,
+    },
   },
   data() {
     const user = this.$ls.get("user", { token: "", id: "" });
@@ -97,21 +97,21 @@ export default {
       file: null,
       res: {
         success: true,
-        msg: ""
-      }
+        msg: "",
+      },
     };
   },
   computed: {
     accept() {
-      return this.format.map(el => `.${el}`).join();
-    }
+      return this.format.map((el) => `.${el}`).join();
+    },
   },
   methods: {
     visibleChange(visible) {
       if (!visible) {
         this.res = {
           success: true,
-          msg: ""
+          msg: "",
         };
         this.$refs.UploadComp.clearFiles();
       }
@@ -130,7 +130,7 @@ export default {
         this.uploadDataDict[this.addFilenameParam] = file.name;
       this.res = {
         success: true,
-        msg: ""
+        msg: "",
       };
       this.$emit("file-change", file);
 
@@ -146,28 +146,28 @@ export default {
       this.loading = false;
       this.res = {
         success: false,
-        msg: response.message
+        msg: response.message,
       };
     },
     handleSuccess(response) {
       this.loading = false;
       this.res = {
         success: true,
-        msg: "上传成功!"
+        msg: "上传成功!",
       };
       this.$emit("upload-success", response);
     },
     handleFormatError() {
       this.res = {
         success: false,
-        msg: "只支持文件格式为" + this.format.join("/")
+        msg: "只支持文件格式为" + this.format.join("/"),
       };
       this.loading = false;
     },
     handleExceededSize() {
       this.res = {
         success: false,
-        msg: "文件大小不能超过" + Math.floor(this.maxSize / 1024) + "M"
+        msg: "文件大小不能超过" + Math.floor(this.maxSize / 1024) + "M",
       };
       this.loading = false;
     },
@@ -179,7 +179,7 @@ export default {
     },
     open() {
       this.modalIsShow = true;
-    }
-  }
+    },
+  },
 };
 </script>

+ 1 - 1
src/components/ViewFooter.vue

@@ -10,6 +10,6 @@
 
 <script>
 export default {
-  name: "view-footer"
+  name: "view-footer",
 };
 </script>

+ 6 - 6
src/components/ViewHeader.vue

@@ -53,17 +53,17 @@ export default {
   props: {
     showResetPwd: {
       type: Boolean,
-      default: true
-    }
+      default: true,
+    },
   },
   computed: {
     classes() {
       return ["view-header"];
-    }
+    },
   },
   data() {
     return {
-      username: this.$ls.get("user", { loginName: "" }).loginName
+      username: this.$ls.get("user", { loginName: "" }).loginName,
     };
   },
   methods: {
@@ -79,7 +79,7 @@ export default {
       await logout();
       this.$ls.clear();
       this.$router.push({ name: "Login" });
-    }
-  }
+    },
+  },
 };
 </script>

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

@@ -35,7 +35,7 @@
       <div
         :class="[
           `${prefixCls}-imgs`,
-          { [`${prefixCls}-imgs-nosition`]: nosition }
+          { [`${prefixCls}-imgs-nosition`]: nosition },
         ]"
         :style="styles"
         v-move-ele.prevent="{ mouseMove }"
@@ -53,7 +53,7 @@
           title="放大"
           @click="toMagnify"
           :class="{
-            'li-disabled': transform.scale === maxScale
+            'li-disabled': transform.scale === maxScale,
           }"
         >
           <Icon type="md-add-circle" />
@@ -62,7 +62,7 @@
           title="缩小"
           @click="toShrink"
           :class="{
-            'li-disabled': transform.scale === minScale
+            'li-disabled': transform.scale === minScale,
           }"
         >
           <Icon type="md-remove-circle" />
@@ -94,23 +94,23 @@ export default {
       type: Array,
       default() {
         return [];
-      }
+      },
     },
     initIndex: {
       type: Number,
-      default: 0
+      default: 0,
     },
     headerHide: {
       type: Boolean,
-      default: false
+      default: false,
     },
     loop: {
       type: Boolean,
-      default: false
-    }
+      default: false,
+    },
   },
   directives: {
-    MoveEle
+    MoveEle,
   },
   data() {
     return {
@@ -124,12 +124,12 @@ export default {
       initWidth: 500,
       transform: {
         scale: 1,
-        rotate: 0
+        rotate: 0,
       },
       preLoadFiles: [],
       loading: false,
       loadingSetT: null,
-      nosition: false
+      nosition: false,
     };
   },
   computed: {
@@ -141,7 +141,7 @@ export default {
     },
     lastIndex() {
       return this.imageList.length - 1;
-    }
+    },
   },
   // watch: {
   //   curIndex: {
@@ -171,11 +171,11 @@ export default {
           height: "",
           top: "",
           left: "",
-          transform: ""
+          transform: "",
         };
         this.transform = {
           scale: 1,
-          rotate: 0
+          rotate: 0,
         };
         this.preLoadFiles = [];
         this.loading = false;
@@ -201,13 +201,13 @@ export default {
         const imageSize = this.getImageSizePos({
           win: {
             width: this.$refs.ReviewBody.clientWidth,
-            height: this.$refs.ReviewBody.clientHeight
+            height: this.$refs.ReviewBody.clientHeight,
           },
           img: {
             width: naturalWidth,
-            height: naturalHeight
+            height: naturalHeight,
           },
-          rotate: 0
+          rotate: 0,
         });
 
         this.styles = Object.assign(this.styles, {
@@ -215,11 +215,11 @@ export default {
           height: imageSize.height + "px",
           top: imageSize.top + "px",
           left: imageSize.left + "px",
-          transform: ""
+          transform: "",
         });
         this.transform = {
           scale: 1,
-          rotate: 0
+          rotate: 0,
         };
         if (this.loadingSetT) clearTimeout(this.loadingSetT);
         this.loading = false;
@@ -233,24 +233,24 @@ export default {
       if (this.loop) {
         preLoadIndexs = [
           curIndex === 0 ? this.lastIndex : curIndex - 1,
-          curIndex === this.lastIndex ? 0 : curIndex + 1
+          curIndex === this.lastIndex ? 0 : curIndex + 1,
         ];
       } else {
         preLoadIndexs = [
           curIndex === 0 ? null : curIndex - 1,
-          curIndex === this.lastIndex ? null : curIndex + 1
+          curIndex === this.lastIndex ? null : curIndex + 1,
         ];
       }
       this.preLoadFiles = preLoadIndexs
-        .filter(item => item !== null)
-        .map(item => this.imageList[item]);
+        .filter((item) => item !== null)
+        .map((item) => this.imageList[item]);
     },
     getImageSizePos({ win, img, rotate }) {
       const imageSize = {
         width: 0,
         height: 0,
         top: 0,
-        left: 0
+        left: 0,
       };
       const isHorizontal = !!(rotate % 180);
 
@@ -260,7 +260,7 @@ export default {
       const hwin = isHorizontal
         ? {
             width: win.height,
-            height: win.width
+            height: win.width,
           }
         : win;
 
@@ -347,20 +347,20 @@ export default {
       const imageSize = this.getImageSizePos({
         win: {
           width: this.$refs.ReviewBody.clientWidth,
-          height: this.$refs.ReviewBody.clientHeight
+          height: this.$refs.ReviewBody.clientHeight,
         },
         img: {
           width: naturalWidth,
-          height: naturalHeight
+          height: naturalHeight,
         },
-        rotate: this.transform.rotate
+        rotate: this.transform.rotate,
       });
 
       this.styles = Object.assign(this.styles, {
         width: imageSize.width + "px",
         height: imageSize.height + "px",
         top: imageSize.top + "px",
-        left: imageSize.left + "px"
+        left: imageSize.left + "px",
       });
       // 360度无缝切换到0度
       if (this.transform.rotate >= 360) {
@@ -373,10 +373,10 @@ export default {
           }, 100);
         }, 200);
       }
-    }
+    },
   },
   beforeDestroy() {
     if (this.loadingSetT) clearTimeout(this.loadingSetT);
-  }
+  },
 };
 </script>

+ 4 - 4
src/components/common/ImagePreview/move-ele.js

@@ -7,7 +7,7 @@ export default {
     let [left, top] = [0, 0];
     let isDrag = false;
 
-    let moveHandle = function(e) {
+    let moveHandle = function (e) {
       isDrag = true;
       if (modifiers.prevent) {
         e.preventDefault();
@@ -23,7 +23,7 @@ export default {
       }
     };
 
-    let upHandle = function(e) {
+    let upHandle = function (e) {
       if (modifiers.prevent) {
         e.preventDefault();
       }
@@ -39,7 +39,7 @@ export default {
       isDrag = false;
     };
 
-    el.addEventListener("mousedown", function(e) {
+    el.addEventListener("mousedown", function (e) {
       if (modifiers.prevent) {
         e.preventDefault();
       }
@@ -52,5 +52,5 @@ export default {
       document.addEventListener("mousemove", moveHandle);
       document.addEventListener("mouseup", upHandle);
     });
-  }
+  },
 };

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

@@ -36,8 +36,8 @@
             `${prefixCls}-tips`,
             {
               'cc-tips-success': res.success,
-              'cc-tips-error': !res.success
-            }
+              'cc-tips-error': !res.success,
+            },
           ]"
           v-if="res.msg"
         >
@@ -60,43 +60,43 @@ export default {
   props: {
     title: {
       type: String,
-      default: "文件上传"
+      default: "文件上传",
     },
     downloadUrl: {
       type: String,
-      default: ""
+      default: "",
     },
     downloadFilename: String,
     format: {
       type: Array,
       default() {
         return ["jpg", "png"];
-      }
+      },
     },
     uploadUrl: {
       type: String,
-      required: true
+      required: true,
     },
     uploadData: {
       type: Object,
       default() {
         return {};
-      }
+      },
     },
     headers: {
       type: Object,
       default() {
         return {};
-      }
+      },
     },
     maxSize: {
       type: Number,
-      default: 10 * 1024
+      default: 10 * 1024,
     },
     addFilenameParam: {
       type: String,
-      default: "fileName"
-    }
+      default: "fileName",
+    },
   },
   data() {
     return {
@@ -104,9 +104,9 @@ export default {
       modalIsShow: false,
       res: {
         success: true,
-        msg: ""
+        msg: "",
       },
-      load: null
+      load: null,
     };
   },
   computed: {
@@ -114,15 +114,15 @@ export default {
       return this.downloadFilename || this.downloadUrl.split("/").pop();
     },
     accept() {
-      return this.format.map(el => `.${el}`).join();
-    }
+      return this.format.map((el) => `.${el}`).join();
+    },
   },
   methods: {
     visibleChange(visible) {
       if (!visible) {
         this.res = {
           success: true,
-          msg: ""
+          msg: "",
         };
         this.$refs.UploadComp.clearFiles();
       }
@@ -134,12 +134,12 @@ export default {
 
       this.res = {
         success: true,
-        msg: ""
+        msg: "",
       };
 
       this.load = this.$Message.loading({
         content: "Loading...",
-        duration: 0
+        duration: 0,
       });
     },
     handleError(error, response) {
@@ -147,7 +147,7 @@ export default {
       this.load = null;
       this.res = {
         success: false,
-        msg: response.message
+        msg: response.message,
       };
     },
     handleSuccess(response) {
@@ -159,13 +159,13 @@ export default {
     handleFormatError() {
       this.res = {
         success: false,
-        msg: "只支持文件格式为" + this.format.join("/")
+        msg: "只支持文件格式为" + this.format.join("/"),
       };
     },
     handleExceededSize() {
       this.res = {
         success: false,
-        msg: "文件大小不能超过" + Math.floor(this.maxSize / 1024) + "M"
+        msg: "文件大小不能超过" + Math.floor(this.maxSize / 1024) + "M",
       };
     },
     handleRemove() {
@@ -176,7 +176,7 @@ export default {
     },
     open() {
       this.modalIsShow = true;
-    }
-  }
+    },
+  },
 };
 </script>

+ 3 - 5
src/components/common/StepsProgress/StepFour.vue

@@ -1,7 +1,5 @@
 <template>
-  <div class="step-four">
-    step-four
-  </div>
+  <div class="step-four">step-four</div>
 </template>
 
 <script>
@@ -22,7 +20,7 @@ export default {
 
       // 提交可执行下一步操作事件
       this.$emit("on-next");
-    }
-  }
+    },
+  },
 };
 </script>

+ 3 - 5
src/components/common/StepsProgress/StepOne.vue

@@ -1,7 +1,5 @@
 <template>
-  <div class="step-one">
-    step-one
-  </div>
+  <div class="step-one">step-one</div>
 </template>
 
 <script>
@@ -22,7 +20,7 @@ export default {
 
       // 提交可执行下一步操作事件
       this.$emit("on-next");
-    }
-  }
+    },
+  },
 };
 </script>

+ 3 - 5
src/components/common/StepsProgress/StepThree.vue

@@ -1,7 +1,5 @@
 <template>
-  <div class="step-three">
-    step-three
-  </div>
+  <div class="step-three">step-three</div>
 </template>
 
 <script>
@@ -22,7 +20,7 @@ export default {
 
       // 提交可执行下一步操作事件
       this.$emit("on-next");
-    }
-  }
+    },
+  },
 };
 </script>

+ 3 - 5
src/components/common/StepsProgress/StepTwo.vue

@@ -1,7 +1,5 @@
 <template>
-  <div class="step-two">
-    step-two
-  </div>
+  <div class="step-two">step-two</div>
 </template>
 
 <script>
@@ -22,7 +20,7 @@ export default {
 
       // 提交可执行下一步操作事件
       this.$emit("on-next");
-    }
-  }
+    },
+  },
 };
 </script>

+ 12 - 12
src/components/common/StepsProgress/StepsProgress.vue

@@ -23,7 +23,7 @@
         type="primary"
         @click="prevStep"
         :disabled="isFirstStep"
-        style="margin-right: 20px;"
+        style="margin-right: 20px"
         >上一步</Button
       >
       <Button
@@ -45,20 +45,20 @@ import StepFour from "./StepFour";
 const STEPS_LIST = [
   {
     name: "step-one",
-    title: "步骤1"
+    title: "步骤1",
   },
   {
     name: "step-two",
-    title: "步骤2"
+    title: "步骤2",
   },
   {
     name: "step-three",
-    title: "步骤3"
+    title: "步骤3",
   },
   {
     name: "step-four",
-    title: "步骤4"
-  }
+    title: "步骤4",
+  },
 ];
 
 export default {
@@ -67,14 +67,14 @@ export default {
     StepOne,
     StepTwo,
     StepThree,
-    StepFour
+    StepFour,
   },
   data() {
     return {
       STEPS_LIST,
       current: 0,
       nextHolder: true,
-      dataReady: true
+      dataReady: true,
     };
   },
   computed: {
@@ -89,13 +89,13 @@ export default {
     },
     lastStep() {
       return this.STEPS_LIST.length - 1;
-    }
+    },
   },
   watch: {
     current() {
       // 滚动条置顶
       // document.getElementById("home-body").scrollTop = 0;
-    }
+    },
   },
   methods: {
     prevStep() {
@@ -113,8 +113,8 @@ export default {
     },
     stepReady() {
       this.nextHolder = false;
-    }
-  }
+    },
+  },
 };
 </script>
 

+ 4 - 4
src/components/homeMenuMixins.js

@@ -5,11 +5,11 @@ export default {
 
       this.curNav = item;
       this.$router.push({
-        name: item.name
+        name: item.name,
       });
     },
     actCurNav(router) {
-      this.curNav = this.navs.find(item => item.name === router.name);
-    }
-  }
+      this.curNav = this.navs.find((item) => item.name === router.name);
+    },
+  },
 };

+ 1 - 1
src/config.js

@@ -2,5 +2,5 @@ export default {
   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
+  authTimeout: process.env.VUE_APP_AUTH_TIMEOUT * 1,
 };

+ 51 - 51
src/constants/authority.js

@@ -2,47 +2,47 @@ export const main = [
   {
     name: "OrgManage",
     title: "机构管理",
-    icon: "ivu-icon-task"
+    icon: "ivu-icon-task",
   },
   {
     name: "WorkManage",
     title: "工作文件夹",
-    icon: "ivu-icon-files"
+    icon: "ivu-icon-files",
   },
   {
     name: "WorkOverview",
     title: "总览",
-    icon: "ivu-icon-overview"
+    icon: "ivu-icon-overview",
   },
   {
     name: "PaperManage",
     title: "试卷管理",
-    icon: "ivu-icon-paper"
+    icon: "ivu-icon-paper",
   },
   {
     name: "ClientMonitor",
     title: "设备监控",
-    icon: "ivu-icon-monitor"
+    icon: "ivu-icon-monitor",
   },
   {
     name: "StudentManage",
     title: "考生管理",
-    icon: "ivu-icon-student"
+    icon: "ivu-icon-student",
   },
   {
     name: "ClientSet",
     title: "采集设置",
-    icon: "ivu-icon-recode"
+    icon: "ivu-icon-recode",
   },
   {
     name: "GradingSet",
     title: "分档设置",
-    icon: "ivu-icon-grade-set"
+    icon: "ivu-icon-grade-set",
   },
   {
     name: "MarkSet",
     title: "打分设置",
-    icon: "ivu-icon-score-set"
+    icon: "ivu-icon-score-set",
   },
   // {
   //   name: "QualityAnalysis",
@@ -52,139 +52,139 @@ export const main = [
   {
     name: "StudentScore",
     title: "成绩查询",
-    icon: "ivu-icon-score"
-  }
+    icon: "ivu-icon-score",
+  },
 ];
 
 export const clientSet = [
   {
     name: "ClientAccountSet",
-    title: "账号设置"
+    title: "账号设置",
   },
   {
     name: "ClientParamSet",
-    title: "参数设置"
+    title: "参数设置",
   },
   {
     name: "InspectionAccountSet",
-    title: "纪检/质检账号"
-  }
+    title: "纪检/质检账号",
+  },
 ];
 
 export const gradingSet = [
   {
     name: "GradingLevelSet",
-    title: "档位设置"
+    title: "档位设置",
   },
   {
     name: "GradingRuleSet",
-    title: "定档规则"
+    title: "定档规则",
   },
   {
     name: "UploadPaper",
-    title: "上传试题"
-  }
+    title: "上传试题",
+  },
 ];
 
 export const markSet = [
   {
     name: "MarkRuleSet",
-    title: "打分设置"
-  }
+    title: "打分设置",
+  },
 ];
 
 export const grading = [
   {
     name: "GradingProgress",
     title: "分档进度",
-    icon: "ivu-icon-progress"
+    icon: "ivu-icon-progress",
   },
   {
     name: "GradingDetail",
     title: "分档详情",
-    icon: "ivu-icon-score-detail"
+    icon: "ivu-icon-score-detail",
   },
   {
     name: "GradingAnalysis",
     title: "分档统计",
-    icon: "ivu-icon-score-detail"
+    icon: "ivu-icon-score-detail",
   },
   {
     name: "GradingUserManage",
     title: "用户管理",
-    icon: "ivu-icon-student"
+    icon: "ivu-icon-student",
   },
   {
     name: "GradingGroupManage",
     title: "分档分组",
-    icon: "ivu-icon-group"
+    icon: "ivu-icon-group",
   },
   {
     name: "GradingStandardPaperManage",
     title: "标准卷管理",
-    icon: "ivu-icon-score"
+    icon: "ivu-icon-score",
   },
   {
     name: "ExamPaperView",
     title: "查看试卷",
-    icon: "ivu-icon-view"
-  }
+    icon: "ivu-icon-view",
+  },
 ];
 
 export const mark = [
   {
     name: "MarkProgress",
     title: "打分进度",
-    icon: "ivu-icon-progress"
+    icon: "ivu-icon-progress",
   },
   {
     name: "MarkTaskManage",
     title: "任务发布",
-    icon: "ivu-icon-task"
+    icon: "ivu-icon-task",
   },
   {
     name: "MarkDetail",
     title: "打分详情",
-    icon: "ivu-icon-score-detail"
+    icon: "ivu-icon-score-detail",
   },
   {
     name: "MarkUserManage",
     title: "用户管理",
-    icon: "ivu-icon-student"
+    icon: "ivu-icon-student",
   },
   {
     name: "MarkGroupManage",
     title: "打分分组",
-    icon: "ivu-icon-group"
+    icon: "ivu-icon-group",
   },
   {
     name: "MarkExamPaperView",
     title: "查看试卷",
-    icon: "ivu-icon-view"
-  }
+    icon: "ivu-icon-view",
+  },
 ];
 
 export const inspection = [
   {
     name: "InspectionActionLogs",
     title: "操作日志",
-    icon: "ivu-icon-logs"
+    icon: "ivu-icon-logs",
   },
   {
     name: "InspectionCollectLogs",
     title: "采集日志",
-    icon: "ivu-icon-recode"
+    icon: "ivu-icon-recode",
   },
   {
     name: "InspectionGrading",
     title: "改档处理",
-    icon: "ivu-icon-change"
+    icon: "ivu-icon-change",
   },
   {
     name: "InspectionScore",
     title: "成绩查询",
-    icon: "ivu-icon-score"
-  }
+    icon: "ivu-icon-score",
+  },
 ];
 
 // const getLeadRouter = () => {
@@ -196,17 +196,17 @@ export const inspection = [
 //   return [...leadGrade, ...leadMark];
 // };
 
-const getAdminRouter = isSuper => {
-  let leadGrade = grading.map(item => item.name).slice(0, -1);
-  let leadMark = mark.map(item => item.name).slice(0, -1);
-  let leadMain = main.map(item => item.name).slice(isSuper ? 0 : 1);
+const getAdminRouter = (isSuper) => {
+  let leadGrade = grading.map((item) => item.name).slice(0, -1);
+  let leadMark = mark.map((item) => item.name).slice(0, -1);
+  let leadMain = main.map((item) => item.name).slice(isSuper ? 0 : 1);
   return [
     ...leadMain,
     ...leadGrade,
     ...leadMark,
-    ...clientSet.map(item => item.name),
-    ...gradingSet.map(item => item.name),
-    ...markSet.map(item => item.name)
+    ...clientSet.map((item) => item.name),
+    ...gradingSet.map((item) => item.name),
+    ...markSet.map((item) => item.name),
   ];
 };
 
@@ -219,11 +219,11 @@ export const checkRouterValid = (roleCode, routerName) => {
       "GradingOperation",
       "MarkOperation",
       "MarkerGrading",
-      "MarkerMarking"
+      "MarkerMarking",
     ],
     MARK_LEADER: () => ["LeaderGrading", "LeaderMarking"],
-    INSPECTION: () => inspection.map(item => item.name),
-    QC: () => ["Quality"]
+    INSPECTION: () => inspection.map((item) => item.name),
+    QC: () => ["Quality"],
   };
 
   const validList = func[roleCode]();

+ 25 - 25
src/constants/enumerate.js

@@ -1,62 +1,62 @@
 // 启用/禁用
 export const ABLE_TYPE = {
   DISABLE: "禁用",
-  ENABLE: "启用"
+  ENABLE: "启用",
 };
 
 // 性别
 export const GENDER_TYPE = {
   MALE: "男",
-  FEMALE: "女"
+  FEMALE: "女",
 };
 
 export const BOOLEAN_TYPE = {
   0: "否",
-  1: "是"
+  1: "是",
 };
 
 // subject step
 export const SUBJECT_STAGE = {
   INIT: "采集阶段",
   LEVEL: "分档阶段",
-  SCORE: "打分阶段"
+  SCORE: "打分阶段",
 };
 
 // grading level
 export const LEVEL_TYPE = {
   ADMITED: "间隔给分",
-  UNADMIT: "手动给分"
+  UNADMIT: "手动给分",
 };
 export const PROP_DENOMINATOR_TYPE = {
   1: "全部考生数",
-  2: "去掉缺考考生数"
+  2: "去掉缺考考生数",
 };
 
 // student score
 export const CODE_TYPE = {
   examNumber: "试卷考号",
   paper: "试卷密号",
-  task: "任务密号"
+  task: "任务密号",
 };
 
 // role type
 export const ROLE_TYPE = {
   MARKER: "评卷员",
-  MARK_LEADER: "科组长"
+  MARK_LEADER: "科组长",
 };
 export const MARK_LEADER_RIGHTS = {
   oneClickLevel: {
     name: "一键定档",
-    action: "leveling"
+    action: "leveling",
   },
   standardVolume: {
     name: "设立标准卷",
-    action: "sampling"
+    action: "sampling",
   },
   levelCallback: {
     name: "建议档位打回",
-    action: "reject"
-  }
+    action: "reject",
+  },
 };
 // system role type
 export const SYSTEM_ROLE_TYPE = {
@@ -66,27 +66,27 @@ export const SYSTEM_ROLE_TYPE = {
   QC: "质检员",
   COLLECTOR: "采集员",
   ADMIN: "管理员",
-  SUPER_ADMIN: "超级管理员"
+  SUPER_ADMIN: "超级管理员",
 };
 
 export const MARKER_RIGHT_TYPE = {
   ALLOW_LEVELING: "只允许分档",
   ALLOW_SCORING: "只允许打分",
-  ALLOW_ALL: "允许分档打分"
+  ALLOW_ALL: "允许分档打分",
 };
 // sort
 export const SORT_ORDER_TYPE = {
   0: "乱序",
-  1: "定序"
+  1: "定序",
 };
 export const SORT_RULE_TYPE = {
   1: "按时间",
-  2: "按考号"
+  2: "按考号",
 };
 // cafa-exception
 export const CAFA_EXCEPTION_TYPE = {
   0: "缺考",
-  1: "手工绑定"
+  1: "手工绑定",
   // 2: "关联考号"
 };
 
@@ -104,43 +104,43 @@ export const ACTION_TYPE = {
   10: "系统自动打回",
   11: "重评",
   12: "手动打回",
-  13: "档位落差"
+  13: "档位落差",
 };
 
 // image-name-type
 export const IMAGE_NAME_TYPE = {
   0: "按考号命名",
-  1: "随机码命名"
+  1: "随机码命名",
 };
 export const EXPORT_IMAGE_NAME_TYPE = {
   1: "考号+姓名",
-  2: "流水号"
+  2: "流水号",
 };
 // image-type
 export const IMAGE_TYPE = {
   1: "原图",
-  2: "裁切图"
+  2: "裁切图",
 };
 
 // paper-level-known-type
 export const PAPER_LEVEL_KNOWN_TYPE = {
   0: "未知",
-  1: "已知"
+  1: "已知",
 };
 // paper-upload-type
 export const PAPER_UPLOAD_TYPE = {
   0: "未上传",
-  1: "已上传"
+  1: "已上传",
 };
 
 // score-handle-type
 export const SCORE_HANDLE_TYPE = {
   0: "非零进一",
-  1: "四舍五入"
+  1: "四舍五入",
 };
 
 // apply-change-level-status
 export const CHANGE_LEVEL_STATUS = {
   0: "未处理",
-  1: "已处理"
+  1: "已处理",
 };

+ 21 - 21
src/constants/navs.js

@@ -6,9 +6,9 @@ const navs = [
     children: [
       {
         title: "通用数据管理模板",
-        router: "DataManage"
-      }
-    ]
+        router: "DataManage",
+      },
+    ],
   },
   {
     title: "通用组件",
@@ -17,45 +17,45 @@ const navs = [
     children: [
       {
         title: "树形结构编辑",
-        router: "TreeEditIntance"
+        router: "TreeEditIntance",
       },
       {
         title: "树形结构双选",
-        router: "TransferTreeInstance"
+        router: "TransferTreeInstance",
       },
       {
         title: "文件上传",
-        router: "ImportFileInstance"
+        router: "ImportFileInstance",
       },
       {
         title: "图片编辑上传",
-        router: "ImageEditUploadInstance"
+        router: "ImageEditUploadInstance",
       },
       {
         title: "图片相册预览",
-        router: "ImagePreviewInstance"
+        router: "ImagePreviewInstance",
       },
       {
         title: "日历备忘",
-        router: "CalendarMenoInstance"
+        router: "CalendarMenoInstance",
       },
       {
         title: "富文本编辑器",
-        router: "RichEditInstance"
+        router: "RichEditInstance",
       },
       {
         title: "echart图表",
-        router: "VueEchartsInstance"
+        router: "VueEchartsInstance",
       },
       {
         title: "树形编辑",
-        router: "TreeListEditInstance"
+        router: "TreeListEditInstance",
       },
       {
         title: "多流程控制器",
-        router: "StepsProgressInstance"
-      }
-    ]
+        router: "StepsProgressInstance",
+      },
+    ],
   },
   {
     title: "个人中心",
@@ -64,18 +64,18 @@ const navs = [
     children: [
       {
         title: "个人设置",
-        router: "UserSet"
+        router: "UserSet",
       },
       {
         title: "重置密码",
-        router: "ResetPswd"
+        router: "ResetPswd",
       },
       {
         title: "绑定手机",
-        router: "BindMobile"
-      }
-    ]
-  }
+        router: "BindMobile",
+      },
+    ],
+  },
 ];
 
 export default navs;

+ 8 - 8
src/main.js

@@ -18,10 +18,10 @@ import { checkRouterValid } from "./constants/authority";
 
 Vue.use(ViewUI);
 ViewUI.Message.config({
-  duration: 3
+  duration: 3,
 });
 ViewUI.Notice.config({
-  duration: 3
+  duration: 3,
 });
 Vue.use(VueLocalStorage, { storage: "session" });
 Vue.use(globalVuePlugins);
@@ -54,12 +54,12 @@ var load = "";
 // 同一时间有多个请求时,会形成队列。在第一个请求创建loading,在最后一个响应关闭loading
 var queue = [];
 axios.interceptors.request.use(
-  config => {
+  (config) => {
     // 显示loading提示
     if (!queue.length) {
       load = ViewUI.Message.loading({
         content: "Loading...",
-        duration: 0
+        duration: 0,
       });
     }
 
@@ -86,7 +86,7 @@ axios.interceptors.request.use(
     config.timeout = GLOBAL.timeout;
     return config;
   },
-  error => {
+  (error) => {
     // 关闭loading提示
     // 继发请求,延时处理是为防止出现多个loading实例
     setTimeout(() => {
@@ -97,7 +97,7 @@ axios.interceptors.request.use(
   }
 );
 axios.interceptors.response.use(
-  response => {
+  (response) => {
     // 关闭loading提示
     setTimeout(() => {
       queue.shift();
@@ -105,7 +105,7 @@ axios.interceptors.response.use(
     }, 100);
     return response;
   },
-  error => {
+  (error) => {
     // 关闭loading提示
     setTimeout(() => {
       queue.shift();
@@ -118,5 +118,5 @@ axios.interceptors.response.use(
 new Vue({
   router,
   store,
-  render: h => h(App)
+  render: (h) => h(App),
 }).$mount("#app");

+ 19 - 19
src/modules/client-set/ClientAccountSet.vue

@@ -59,17 +59,17 @@ export default {
           title: "序号",
           width: 100,
           align: "center",
-          indexMethod: row => {
+          indexMethod: (row) => {
             return (this.current - 1) * this.size + row._index + 1;
-          }
+          },
         },
         {
           title: "账号",
-          key: "loginName"
+          key: "loginName",
         },
         {
           title: "密码",
-          key: "password"
+          key: "password",
         },
         {
           title: "操作",
@@ -82,28 +82,28 @@ export default {
               {
                 icon: param.row.enabled ? "enable icon" : "disable icon",
                 attrs: {
-                  title: param.row.enabled ? "禁用" : "启用"
+                  title: param.row.enabled ? "禁用" : "启用",
                 },
                 action: () => {
                   this.toAble(param.row);
-                }
+                },
               },
               {
                 icon: "md-create",
                 classes: [param.row.enabled ? "" : "btn-disabled"],
                 attrs: {
-                  title: "编辑"
+                  title: "编辑",
                 },
                 action: () => {
                   this.toEdit(param.row);
-                }
-              }
+                },
+              },
             ];
 
             return h("div", this.$tableIconAction(h, actions));
-          }
-        }
-      ]
+          },
+        },
+      ],
     };
   },
   mounted() {
@@ -114,10 +114,10 @@ export default {
       const datas = {
         workId: this.workId,
         page: this.current - 1,
-        size: this.size
+        size: this.size,
       };
       const data = await clientUserPageList(datas);
-      this.users = data.data.map(item => {
+      this.users = data.data.map((item) => {
         item.roleName = SYSTEM_ROLE_TYPE[item.role];
         return item;
       });
@@ -134,7 +134,7 @@ export default {
       this.curUser = {
         role: "COLLECTOR",
         roleName: "采集员",
-        workId: this.workId
+        workId: this.workId,
       };
       this.$refs.ModifyClientUser.open();
     },
@@ -147,7 +147,7 @@ export default {
       await updateClientUser({
         id: row.id,
         loginName: row.loginName,
-        enabled: !row.enabled
+        enabled: !row.enabled,
       });
       this.users[row._index].enabled = !row.enabled;
     },
@@ -157,14 +157,14 @@ export default {
         content: "确定要删除当前账号吗?",
         onOk: () => {
           this.toDel(row.id);
-        }
+        },
       });
     },
     async toDel(id) {
       await deleteClientUser(id);
       this.$Message.success("删除成功!");
       this.deletePageLastItem();
-    }
-  }
+    },
+  },
 };
 </script>

+ 17 - 17
src/modules/client-set/ClientParamSet.vue

@@ -17,7 +17,7 @@
                     :ref="subject.id"
                   ></Input>
                 </td>
-                <td style="width: 220px;">
+                <td style="width: 220px">
                   <Button
                     size="small"
                     :disabled="!subject.enable"
@@ -114,14 +114,14 @@
             <FormItem>
               <Button
                 shape="circle"
-                style="width: 80px;"
+                style="width: 80px"
                 @click="modalFormCanEdit = true"
                 >编辑</Button
               >
               <Button
                 shape="circle"
                 type="primary"
-                style="width: 80px;"
+                style="width: 80px"
                 :disabled="isSubmit"
                 @click="toSubmit"
                 >保存</Button
@@ -140,22 +140,22 @@ import {
   updateSubject,
   enableSubject,
   getParamsSet,
-  updateCollectParams
+  updateCollectParams,
 } from "@/api";
 import {
   BOOLEAN_TYPE,
   IMAGE_NAME_TYPE,
-  PAPER_LEVEL_KNOWN_TYPE
+  PAPER_LEVEL_KNOWN_TYPE,
 } from "@/constants/enumerate";
 import schema from "async-validator";
-schema.warning = function() {};
+schema.warning = function () {};
 
 const initSubject = {
   id: "",
   name: "",
   enable: true,
   canEdit: false,
-  password: ""
+  password: "",
 };
 
 export default {
@@ -174,10 +174,10 @@ export default {
         packageScan: 0,
         imageEncrypt: 0,
         nameRule: 0,
-        paperStage: 0
+        paperStage: 0,
       },
       modalFormCanEdit: false,
-      modalForm: {}
+      modalForm: {},
     };
   },
   mounted() {
@@ -188,10 +188,10 @@ export default {
   methods: {
     async getList() {
       const data = await subjectList(this.workId);
-      this.subjects = data.map(item => {
+      this.subjects = data.map((item) => {
         return {
           ...item,
-          canEdit: false
+          canEdit: false,
         };
       });
     },
@@ -216,9 +216,9 @@ export default {
             required: true,
             min: 2,
             max: 20,
-            message: "科目名称长度只能介于2到20之间"
-          }
-        ]
+            message: "科目名称长度只能介于2到20之间",
+          },
+        ],
       };
       return new schema(descriptor)
         .validate(subject)
@@ -227,7 +227,7 @@ export default {
         })
         .catch(({ errors, fields }) => {
           let errorMsgs = {};
-          errors.map(error => {
+          errors.map((error) => {
             errorMsgs[error.field] = error.message;
           });
           this.$set(subject, "errors", errorMsgs);
@@ -259,7 +259,7 @@ export default {
       if (!result) return;
       this.modalFormCanEdit = false;
       this.$Message.success("保存成功!");
-    }
-  }
+    },
+  },
 };
 </script>

+ 5 - 5
src/modules/client-set/ClientSet.vue

@@ -4,7 +4,7 @@
       <div
         :class="[
           'set-navs-item',
-          { 'set-navs-item-act': curNav.name === nav.name }
+          { 'set-navs-item-act': curNav.name === nav.name },
         ]"
         v-for="(nav, index) in navs"
         :key="index"
@@ -28,19 +28,19 @@ export default {
   data() {
     return {
       navs: clientSet,
-      curNav: {}
+      curNav: {},
     };
   },
   watch: {
     $route: {
       handler(val) {
         this.actCurNav(val);
-      }
-    }
+      },
+    },
   },
   mounted() {
     this.actCurNav(this.$route);
   },
-  methods: {}
+  methods: {},
 };
 </script>

+ 17 - 17
src/modules/client-set/InspectionAccountSet.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="client-account-set ">
+  <div class="client-account-set">
     <Table
       ref="TableList"
       :columns="columns"
@@ -36,21 +36,21 @@ export default {
           title: "序号",
           width: 100,
           align: "center",
-          indexMethod: row => {
+          indexMethod: (row) => {
             return row._index + 1;
-          }
+          },
         },
         {
           title: "角色",
-          key: "roleName"
+          key: "roleName",
         },
         {
           title: "账号",
-          key: "loginName"
+          key: "loginName",
         },
         {
           title: "密码",
-          key: "password"
+          key: "password",
         },
         {
           title: "操作",
@@ -63,18 +63,18 @@ export default {
               {
                 icon: "md-create",
                 attrs: {
-                  title: "编辑"
+                  title: "编辑",
                 },
                 action: () => {
                   this.toEdit(param.row);
-                }
-              }
+                },
+              },
             ];
 
             return h("div", this.$tableIconAction(h, actions));
-          }
-        }
-      ]
+          },
+        },
+      ],
     };
   },
   mounted() {
@@ -83,17 +83,17 @@ export default {
   methods: {
     async getList() {
       const datas = {
-        workId: this.workId
+        workId: this.workId,
       };
       const data = await inspectionUserPageList(datas);
 
-      this.users = data.map(item => {
+      this.users = data.map((item) => {
         return {
           id: item.id,
           loginName: item.loginName,
           role: item.role,
           password: item.password,
-          roleName: SYSTEM_ROLE_TYPE[item.role]
+          roleName: SYSTEM_ROLE_TYPE[item.role],
         };
       });
     },
@@ -109,7 +109,7 @@ export default {
 
       if (!result) return;
       this.$Message.success("重置密码成功!");
-    }
-  }
+    },
+  },
 };
 </script>

+ 10 - 10
src/modules/client-set/components/ModifyClientUser.vue

@@ -53,7 +53,7 @@ const initModalForm = {
   role: "",
   roleName: "",
   loginName: "",
-  password: ""
+  password: "",
 };
 
 export default {
@@ -63,8 +63,8 @@ export default {
       type: Object,
       default() {
         return {};
-      }
-    }
+      },
+    },
   },
   computed: {
     isEdit() {
@@ -72,7 +72,7 @@ export default {
     },
     title() {
       return (this.isEdit ? "编辑" : "新增") + this.instance.roleName + "账号";
-    }
+    },
   },
   data() {
     return {
@@ -87,11 +87,11 @@ export default {
             required: true,
             pattern: /^[a-zA-Z0-9_-]{3,20}$/,
             message: "账号只能包含字母、数字、下划线以及短横线,长度3-20位",
-            trigger: "change"
-          }
+            trigger: "change",
+          },
         ],
-        password
-      }
+        password,
+      },
     };
   },
   created() {
@@ -140,7 +140,7 @@ export default {
       this.$Message.success(this.title + "成功!");
       this.$emit("modified");
       this.cancel();
-    }
-  }
+    },
+  },
 };
 </script>

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

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

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

@@ -8,7 +8,7 @@
             :model="modalForm"
             :rules="rules"
             :label-width="230"
-            style="width: 400px;"
+            style="width: 400px"
           >
             <FormItem prop="deviation" label="仲裁档位差:">
               <InputNumber
@@ -16,7 +16,7 @@
                 :min="1"
                 :max="100"
                 :disabled="!modalFormCanEdit"
-                style="width: 160px;"
+                style="width: 160px"
               ></InputNumber>
             </FormItem>
             <FormItem label="系统自动打回:">
@@ -43,7 +43,7 @@
                 :min="1"
                 :max="100"
                 :disabled="!modalFormCanEdit"
-                style="width: 160px;"
+                style="width: 160px"
               ></InputNumber>
             </FormItem>
             <FormItem
@@ -164,14 +164,14 @@
             <FormItem>
               <Button
                 shape="circle"
-                style="width: 80px;"
+                style="width: 80px"
                 @click="modalFormCanEdit = true"
                 >编辑</Button
               >
               <Button
                 type="primary"
                 shape="circle"
-                style="width: 80px;"
+                style="width: 80px"
                 :disabled="isSubmit"
                 @click="submit"
                 >保存</Button
@@ -193,7 +193,7 @@
                   type="text"
                   :class="[
                     'icon ivu-icon',
-                    !subject.locking ? 'ivu-icon-enable' : 'ivu-icon-disable'
+                    !subject.locking ? 'ivu-icon-enable' : 'ivu-icon-disable',
                   ]"
                   @click="toAble(subject)"
                 >
@@ -212,7 +212,7 @@ import {
   getParamsSet,
   updateLevelParams,
   subjectList,
-  enableSubjectUsers
+  enableSubjectUsers,
 } from "@/api";
 import { BOOLEAN_TYPE, PROP_DENOMINATOR_TYPE } from "@/constants/enumerate";
 import { numberValidator } from "@/plugins/formRules";
@@ -237,15 +237,15 @@ export default {
         showPaperCount: 1,
         propDenominator: 1,
         showSample: 1,
-        allowTaskOverlay: 1
+        allowTaskOverlay: 1,
       },
       modalFormCanEdit: false,
       modalForm: {},
       rules: {
         deviation: numberValidator("请输入仲裁档位差"),
-        cumulativeError: numberValidator("请输入打回累计误差")
+        cumulativeError: numberValidator("请输入打回累计误差"),
       },
-      subjects: []
+      subjects: [],
     };
   },
   mounted() {
@@ -285,9 +285,9 @@ export default {
         onOk: async () => {
           await enableSubjectUsers(row.id);
           row.locking = !row.locking;
-        }
+        },
       });
-    }
-  }
+    },
+  },
 };
 </script>

+ 5 - 5
src/modules/grading-set/GradingSet.vue

@@ -4,7 +4,7 @@
       <div
         :class="[
           'set-navs-item',
-          { 'set-navs-item-act': curNav.name === nav.name }
+          { 'set-navs-item-act': curNav.name === nav.name },
         ]"
         v-for="(nav, index) in navs"
         :key="index"
@@ -28,18 +28,18 @@ export default {
   data() {
     return {
       navs: gradingSet,
-      curNav: {}
+      curNav: {},
     };
   },
   watch: {
     $route: {
       handler(val) {
         this.actCurNav(val);
-      }
-    }
+      },
+    },
   },
   mounted() {
     this.actCurNav(this.$route);
-  }
+  },
 };
 </script>

+ 6 - 6
src/modules/grading-set/UploadPaper.vue

@@ -35,7 +35,7 @@ export default {
     return {
       workId: this.$route.params.workId,
       papers: [],
-      subjects: []
+      subjects: [],
     };
   },
   mounted() {
@@ -44,17 +44,17 @@ export default {
   methods: {
     async getData() {
       const data = await uploadPaperList(this.workId);
-      this.papers = data.map(area => {
+      this.papers = data.map((area) => {
         area.subjects = area.subjects
-          .filter(item => item.enable)
-          .map(subject => {
+          .filter((item) => item.enable)
+          .map((subject) => {
             subject.uploadUrl = `${this.GLOBAL.domain}/api/papers/${this.workId}/${area.questionId}/${subject.subject}/uploadPaperFile`;
             return subject;
           });
         return area;
       });
       this.subjects = this.papers[0].subjects;
-    }
-  }
+    },
+  },
 };
 </script>

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

@@ -22,7 +22,7 @@
               <i
                 :class="[
                   'icon',
-                  curNav.name === nav.name ? `${nav.icon}-act` : nav.icon
+                  curNav.name === nav.name ? `${nav.icon}-act` : nav.icon,
                 ]"
                 v-if="nav.icon"
               ></i>
@@ -44,7 +44,7 @@
             <i
               :class="[
                 'icon',
-                curNav.name === nav.name ? `${nav.icon}-act` : nav.icon
+                curNav.name === nav.name ? `${nav.icon}-act` : nav.icon,
               ]"
               v-if="nav.icon"
             ></i>
@@ -84,15 +84,15 @@ export default {
       IS_ADMIN: false,
       IS_SUPER_ADMIN: false,
       stepName: "",
-      stepProgress: ""
+      stepProgress: "",
     };
   },
   watch: {
     $route: {
       handler(val) {
         this.actSubNav();
-      }
-    }
+      },
+    },
   },
   mounted() {
     const curUserRoleType = this.$ls.get("user", { role: "" }).role;
@@ -109,8 +109,8 @@ export default {
             name: "Mark",
             params: {
               workId: this.subjectId.split("-")[0],
-              subjectId: this.subjectId
-            }
+              subjectId: this.subjectId,
+            },
           });
           return;
         }
@@ -130,7 +130,7 @@ export default {
     async getProgressDetail() {
       const data = await gradingProgressDetail({
         workId: this.curSubject.workId,
-        subject: this.curSubject.subject
+        subject: this.curSubject.subject,
       });
       this.stepProgress = data.totalProgress.progress.toFixed(2) + "%";
     },
@@ -148,10 +148,10 @@ export default {
     },
     actSubNav() {
       const router = this.$route.matched.filter(
-        item => item.name !== "Grading"
+        (item) => item.name !== "Grading"
       )[0];
       this.actCurNav(router);
-    }
-  }
+    },
+  },
 };
 </script>

+ 11 - 11
src/modules/grading/GradingAnalysis.vue

@@ -66,7 +66,7 @@ export default {
     return {
       filter: {
         questionId: "",
-        sort: "secretNumber"
+        sort: "secretNumber",
       },
       workId: this.$route.params.workId,
       subjectId: this.$route.params.subjectId,
@@ -77,7 +77,7 @@ export default {
       renderExportPage: false,
       renderChartData: {},
       renderPageInfo: {},
-      isDownload: false
+      isDownload: false,
     };
   },
   computed: {
@@ -89,7 +89,7 @@ export default {
         this.curUserRoleType === "ADMIN" ||
         this.curUserRoleType === "SUPER_ADMIN"
       );
-    }
+    },
   },
   mounted() {
     this.subject = this.subjectId.split("-")[1];
@@ -113,13 +113,13 @@ export default {
     async getAreaList() {
       const data = await areaList({
         workId: this.workId,
-        subject: this.subject
+        subject: this.subject,
       });
-      this.areas = data.map(item => {
+      this.areas = data.map((item) => {
         return {
           id: item.id,
           areaName: item.areaName,
-          areaCode: item.areaCode
+          areaCode: item.areaCode,
         };
       });
     },
@@ -130,15 +130,15 @@ export default {
     toExport() {
       this.isDownload = true;
       const curArea = this.areas.find(
-        item => item.id === this.filter.questionId
+        (item) => item.id === this.filter.questionId
       );
       this.renderPageInfo = {
         subjectName: this.curSubject.name,
-        areaName: curArea.areaName
+        areaName: curArea.areaName,
       };
       this.renderChartData = {
         levelData: this.$refs.GradeAnalysis.levelData,
-        lineChartData: this.$refs.GradeAnalysis.lineChartData
+        lineChartData: this.$refs.GradeAnalysis.lineChartData,
       };
       this.renderExportPage = true;
     },
@@ -148,7 +148,7 @@ export default {
       }
       this.renderExportPage = false;
       this.isDownload = false;
-    }
-  }
+    },
+  },
 };
 </script>

+ 653 - 653
src/modules/grading/GradingDetail.vue

@@ -1,653 +1,653 @@
-<template>
-  <div :class="compClasses">
-    <grade-filter
-      ref="GradeFilter"
-      :data="workSubject"
-      @change="areaChange"
-    ></grade-filter>
-    <grade-step
-      :steps="steps"
-      :init-step="curStep"
-      :show-count="showPaperRelateCount"
-      @on-change="stepChange"
-      ref="GradeStep"
-      v-if="steps.levelStep"
-    ></grade-step>
-    <div class="detail-body">
-      <!-- detail-papers -->
-      <div :class="detailPapersClasses">
-        <div class="detail-papers-carousel">
-          <grade-standard-paper
-            :levels="levels"
-            :question-id="filter.questionId"
-            @on-paper-click="
-              (index, papers) => {
-                toViewCarouselPaper(index, papers, 'sample');
-              }
-            "
-            @on-paper-change="standardPaperChange"
-            v-if="
-              levels.length &&
-                filter.questionId &&
-                ((IS_MARK_LEADER && paramsSet.showSample) || IS_ADMIN)
-            "
-            ref="GradeStandardPaper"
-          ></grade-standard-paper>
-          <!-- TODO:科组长的操作记录 -->
-          <grade-history-paper
-            :question-id="filter.questionId"
-            @on-paper-click="
-              (index, papers) => {
-                toViewCarouselPaper(index, papers, 'history');
-              }
-            "
-            v-if="filter.questionId && !IS_ADMIN"
-            ref="GradeHistoryPaper"
-          ></grade-history-paper>
-        </div>
-        <div class="detail-papers-list" v-if="papers.length">
-          <div :class="imageViewClasses">
-            <div
-              :class="[
-                'image-view',
-                { 'image-view-act': curPaperIndex === index || image.selected }
-              ]"
-              v-for="(image, index) in papers"
-              :key="index"
-            >
-              <div class="image-view-container">
-                <h5 class="image-view-title">{{ image.title }}</h5>
-                <div class="image-view-contain">
-                  <img
-                    :src="image.thumbSrc"
-                    :alt="image.title"
-                    @click="toReview(index)"
-                  />
-                </div>
-                <div class="image-view-actions" v-if="ACTION_CAN_BATCH">
-                  <div
-                    :class="[
-                      'image-view-multibar',
-                      { 'image-view-selected': image.selected },
-                      { 'image-view-disabled': image.sample }
-                    ]"
-                    :title="image.sample ? '标准卷' : '选中批量操作'"
-                    @click="selectMultiplePaper(image)"
-                  ></div>
-                </div>
-              </div>
-            </div>
-          </div>
-          <div
-            :class="[
-              'part-page',
-              { 'part-page-simple': !showPaperRelateCount }
-            ]"
-          >
-            <Page
-              :current="current"
-              :total="total"
-              :page-size="size"
-              :show-total="!!showPaperRelateCount"
-              show-elevator
-              @on-change="toPage"
-            ></Page>
-          </div>
-        </div>
-        <div class="detail-papers-list" v-else>
-          <p class="detail-papers-none">暂无数据</p>
-        </div>
-      </div>
-      <!-- detail-aciton -->
-      <div
-        :class="[
-          'detail-action',
-          { 'detail-action-fullscreen': isFullscreenMarking }
-        ]"
-        v-show="!multipleGradingList.length"
-      >
-        <grade-action
-          :cur-paper-or-task="curPaper"
-          :levels="levels"
-          :params-set="paramsSet"
-          @on-leader-level="leaderSelectLevel"
-          @on-code-search="serachPaperByCode"
-          ref="GradeAction"
-          v-if="curPaper.id"
-        ></grade-action>
-      </div>
-      <!-- 占位 -->
-      <div class="detail-action" v-if="isFullscreenMarking"></div>
-      <!-- detail-aciton multiple grading action -->
-      <div class="detail-action" v-show="multipleGradingList.length">
-        <div class="grade-action">
-          <div class="action-paper-state">
-            <p class="paper-state-cont">批量操作</p>
-          </div>
-          <div class="action-paper-info">
-            <p><span>任务密号:</span><span>--</span></p>
-          </div>
-          <h3
-            class="action-grade-info-title"
-            v-if="IS_MARK_LEADER && markLeaderOnlyRight"
-          >
-            当前操作:{{ markLeaderOnlyRight.name }}
-          </h3>
-          <div class="action-grade-list">
-            <div
-              class="action-grade-item"
-              v-for="(level, index) in levels"
-              :key="index"
-            >
-              <div
-                :class="[
-                  'action-grade-item-content',
-                  { 'action-item-content-disabled': multiplebtnClicked }
-                ]"
-                @click="multipleSelectLevel(level)"
-              >
-                <p>{{ level.name }}</p>
-                <p>{{ level.minScore }}~{{ level.maxScore }}</p>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <!-- image-preview -->
-    <simple-image-preview
-      :class="imagePreviewClasses"
-      :cur-image="curPaper"
-      @on-prev="toPrevPaper"
-      @on-next="toNextPaper"
-      @on-close="isFullscreenMarking = false"
-      ref="SimpleImagePreview"
-    ></simple-image-preview>
-    <!-- carousel paper review -->
-    <simple-image-preview
-      :class="imagePreviewClasses"
-      :cur-image="curPaper"
-      @on-prev="toCarousePaper('prev')"
-      @on-next="toCarousePaper('next')"
-      @on-close="carouseImagePreviewClose"
-      ref="CarouselPapersPreview"
-    ></simple-image-preview>
-    <!-- modify-leader-grading -->
-    <modify-leader-grading
-      :level-info="levelInfo"
-      :markers="markers"
-      @modified="leaderGradingSuccess"
-      ref="ModifyLeaderGrading"
-    ></modify-leader-grading>
-  </div>
-</template>
-
-<script>
-import {
-  paperList,
-  levelStatData,
-  workLevelList,
-  taskSnSearch,
-  subjectDetail,
-  markHistoryList,
-  getParamsSet,
-  leaderGradingPaper
-} from "@/api";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-import GradeFilter from "./components/GradeFilter";
-import GradeStep from "./components/GradeStep";
-import GradeStandardPaper from "./components/GradeStandardPaper";
-import GradeHistoryPaper from "./components/GradeHistoryPaper";
-import GradeAction from "./components/GradeAction";
-import ModifyLeaderGrading from "./components/ModifyLeaderGrading";
-// 三种情况:
-// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
-// 管理员:标准卷,试卷列表,操作盘
-// 科组长:标准卷,操作记录,试卷列表,操作盘(定档,标准卷,打回)
-
-// TIP:不考虑评卷员的情况
-// 评卷员:标准卷,操作记录,试卷列表,操作盘(只分档)
-
-export default {
-  name: "grading-detail",
-  components: {
-    SimpleImagePreview,
-    GradeFilter,
-    GradeStep,
-    GradeHistoryPaper,
-    GradeStandardPaper,
-    GradeAction,
-    ModifyLeaderGrading
-  },
-  data() {
-    return {
-      filter: {
-        questionId: "",
-        sort: "secretNumber"
-      },
-      typeFilter: {
-        done: {
-          level: ""
-        },
-        reject: {
-          reject: true
-        },
-        arbitrate: {
-          arbi: true
-        }
-      },
-      workId: this.$route.params.workId,
-      subjectId: this.$route.params.subjectId,
-      subject: "",
-      workSubject: {},
-      curSubject: {},
-      curUserRoleType: "MARKER",
-      current: 1,
-      size: 6,
-      total: 0,
-      totalPage: 1,
-      curStep: { type: "", name: "" },
-      steps: {},
-      levels: [],
-      curArea: {},
-      papers: [],
-      curPaper: {},
-      curPaperIndex: 0,
-      paramsSet: {},
-      // leader-grade
-      levelInfo: {},
-      markers: [],
-      // carousel paper review,
-      carouselType: "",
-      carouselPapers: [],
-      curCarouselPaperIndex: 0,
-      isFullscreenMarking: false,
-      // multiple grading
-      multiplebtnClicked: false,
-      multipleGradingList: [],
-      // 科组长权限
-      markLeaderOnlyRight: null
-    };
-  },
-  computed: {
-    compClasses() {
-      return [
-        "page-container-flex",
-        "grading-detail",
-        { "grading-operation": this.IS_MARK_LEADER }
-      ];
-    },
-    detailPapersClasses() {
-      return ["detail-papers", `detail-papers-col-${1 + this.size / 2}`];
-    },
-    imageViewClasses() {
-      return ["image-view-list", `image-view-list-${this.size / 2}`];
-    },
-    showPaperRelateCount() {
-      return this.IS_ADMIN || !!this.paramsSet["showPaperCount"];
-    },
-    IS_ADMIN() {
-      return (
-        this.curUserRoleType === "ADMIN" ||
-        this.curUserRoleType === "SUPER_ADMIN"
-      );
-    },
-    IS_MARK_LEADER() {
-      return this.curUserRoleType === "MARK_LEADER";
-    },
-    IS_TEST() {
-      return this.curSubject.test === 2;
-    },
-    ACTION_CAN_BATCH() {
-      return (
-        this.curStep.type === "done" &&
-        this.IS_MARK_LEADER &&
-        !this.paramsSet.paperStage
-      );
-    },
-    imagePreviewClasses() {
-      return this.IS_ADMIN
-        ? "grading-detail-image-preview"
-        : "grading-operation-image-preview";
-    }
-  },
-  created() {
-    this.subject = this.subjectId.split("-")[1];
-    this.workSubject = {
-      workId: this.workId,
-      subject: this.subject
-    };
-    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
-
-    this.markLeaderOnlyRight = this.$ls.get("user", {
-      markLeaderOnlyRight: null
-    }).markLeaderOnlyRight;
-
-    this.initData();
-  },
-  methods: {
-    async initData() {
-      await this.getParamsSetInfo();
-      await this.getSubjectDetail();
-      // 获取档位列表
-      this.getWorkLevels();
-    },
-    async getParamsSetInfo() {
-      this.paramsSet = await getParamsSet(this.workId);
-    },
-    async getList() {
-      this.multipleGradingList = [];
-      const datas = {
-        ...this.filter,
-        ...this.typeFilter[this.curStep.type],
-        page: this.current - 1,
-        size: this.size
-      };
-      if (this.curStep.type === "done") datas.level = this.curStep.name;
-
-      const data = await paperList(datas);
-      this.papers = data.data.map(paper => {
-        paper.title = this.IS_ADMIN ? paper.examNumber : `NO.${paper.sn}`;
-        paper.selected = false;
-        return paper;
-      });
-      this.total = data.totalCount;
-      this.totalPage = data.pageCount;
-    },
-    async toPage(page) {
-      this.current = page;
-      await this.getList();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async getSubjectDetail() {
-      this.curSubject = await subjectDetail(this.subjectId);
-    },
-    async getStepLevels() {
-      const data = await levelStatData(this.subjectId, this.filter.questionId);
-      const undoIndex = data.findIndex(item => item.id === null);
-      let otherStep = [];
-      let undo = {
-        count: 0,
-        rejected: 0,
-        arbitrated: 0
-      };
-      if (undoIndex !== -1) {
-        undo = { ...data[undoIndex] };
-        data.splice(undoIndex, 1);
-      }
-
-      if (this.IS_MARK_LEADER && this.IS_TEST) {
-        otherStep.push({
-          name: "待评",
-          count: undo.count,
-          type: "undo"
-        });
-      }
-      otherStep.push({
-        name: "打回",
-        count: undo.rejected,
-        type: "reject"
-      });
-      otherStep.push({
-        name: "仲裁",
-        count: undo.arbitrated,
-        type: "arbitrate"
-      });
-
-      let levelStep = data.map(item => {
-        return {
-          ...item,
-          name: item.id,
-          type: "done"
-        };
-      });
-      this.steps = { levelStep, otherStep };
-
-      if (!this.curStep.type) {
-        this.curStep = levelStep[0];
-      }
-    },
-    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 stepChange(step) {
-      this.curStep = step;
-      // this.toPage(1);
-      this.current = 1;
-      await this.getList();
-      if (this.papers.length) {
-        this.selectPaper(0);
-      } else {
-        this.curPaper = {};
-      }
-    },
-    async areaChange(curArea) {
-      this.curArea = curArea;
-      this.filter.questionId = curArea.id;
-      await this.getStepLevels();
-      this.toPage(1);
-    },
-    // selectMultiplePaper
-    selectMultiplePaper(paper) {
-      if (paper.sample) return;
-      paper.selected = !paper.selected;
-      this.multipleGradingList = this.papers.filter(paper => paper.selected);
-    },
-    async multipleSelectLevel(level) {
-      if (!this.multipleGradingList.length) return;
-      if (this.multiplebtnClicked) return;
-      this.multiplebtnClicked = true;
-
-      const data = await markHistoryList(
-        this.multipleGradingList[0].id,
-        "LEVEL"
-      ).catch(() => {
-        this.multiplebtnClicked = false;
-      });
-
-      if (!data) return;
-
-      const markers = data.map(item => {
-        return {
-          id: item.markerId,
-          name: item.marker
-        };
-      });
-      const levelInfo = {
-        paperIds: this.multipleGradingList.map(item => item.id).join(),
-        curLevel: this.curStep.name,
-        selectedLevel: level.name,
-        markLeaderOnlyRight: this.markLeaderOnlyRight
-      };
-
-      await this.leaderSelectLevel(levelInfo, markers).catch(() => {});
-      this.multiplebtnClicked = false;
-    },
-    // to review
-    toReview(index) {
-      this.isFullscreenMarking = true;
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        if (this.current > 1) {
-          this.current--;
-          this.curPaperIndex = this.size - 1;
-          await this.getList();
-        } else {
-          this.$Message.warning("当前已经是第一条数据了");
-          return;
-        }
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        if (this.current === this.totalPage) {
-          this.$Message.warning("当前已经是最后一条数据了");
-          return;
-        } else {
-          this.current++;
-          this.curPaperIndex = 0;
-          await this.getList();
-        }
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toActionNextPaper() {
-      if (this.current > 1 && this.papers.length === 1) {
-        this.current--;
-        this.curPaperIndex = this.size;
-      }
-
-      await this.getList();
-      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
-      this.selectPaper(this.curPaperIndex);
-    },
-    updateHistory() {
-      this.$refs.GradeHistoryPaper.updatePapers();
-    },
-    async serachPaperByCode(params) {
-      const data = await taskSnSearch(
-        params.codeType,
-        params.code,
-        this.filter.questionId
-      );
-      if (!data) {
-        this.$Message.error("没有查找到结果!");
-        return;
-      }
-      data.title = this.IS_ADMIN ? data.examNumber : `NO.${data.sn}`;
-      data.key = this.$randomCode();
-      this.papers = [data];
-      this.total = 1;
-      this.selectPaper(0);
-    },
-    async leaderSelectLevel(levelInfo, markers) {
-      // 唯一权限时,直接操作
-      if (levelInfo.markLeaderOnlyRight && !this.paramsSet.leaderConfirm) {
-        const datas = {
-          action: levelInfo.markLeaderOnlyRight.action,
-          level: levelInfo.selectedLevel,
-          originLevel: levelInfo.curLevel,
-          paperIds: levelInfo.paperIds
-        };
-        if (datas.action === "reject") {
-          datas.range = markers.map(item => item.id).join();
-        }
-        let result = true;
-        const paper = await leaderGradingPaper(datas).catch(() => {
-          result = false;
-        });
-        if (!result) return;
-
-        this.leaderGradingSuccess(datas, paper);
-        return;
-      }
-
-      this.levelInfo = levelInfo;
-      this.markers = markers;
-      this.$refs.ModifyLeaderGrading.open();
-    },
-    async leaderGradingSuccess(datas, paper) {
-      if (datas.action === "sampling" && this.$refs.GradeStandardPaper) {
-        this.$refs.GradeStandardPaper.updateLevelPapers(datas.level);
-      }
-      this.getStepLevels();
-      this.updateHistory();
-
-      if (this.multipleGradingList && this.multipleGradingList.length) {
-        // 批量处理逻辑
-        if (
-          this.current > 1 &&
-          this.current === this.pageCount &&
-          this.papers.length === this.multipleGradingList.length
-        ) {
-          this.current--;
-        }
-
-        this.multipleGradingList = [];
-        await this.getList();
-        this.selectPaper(this.curPaperIndex);
-      } else {
-        // 单张处理逻辑
-        this.toActionNextPaper();
-      }
-    },
-    // paper carousel
-    toViewCarouselPaper(paperIndex, papers, type) {
-      this.carouselType = type;
-      this.isFullscreenMarking = true;
-      this.carouselPapers = papers;
-      this.selectCarouselPaper(paperIndex);
-      this.$nextTick(() => {
-        this.$refs.CarouselPapersPreview.open();
-      });
-    },
-    selectCarouselPaper(index) {
-      this.curCarouselPaperIndex = index;
-      this.curPaper = { ...this.carouselPapers[index] };
-    },
-    toCarousePaper(type) {
-      if (this.carouselType === "sample") {
-        this.toSampleCarousePaper(type);
-        return;
-      }
-      if (type === "prev" && this.curCarouselPaperIndex > 0) {
-        this.curCarouselPaperIndex--;
-      } else if (
-        type === "next" &&
-        this.curCarouselPaperIndex < this.carouselPapers.length - 1
-      ) {
-        this.curCarouselPaperIndex++;
-      }
-      this.selectCarouselPaper(this.curCarouselPaperIndex);
-    },
-    toSampleCarousePaper(type) {
-      if (!this.$refs.GradeStandardPaper) return;
-      if (type === "prev") {
-        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleLeft();
-      } else if (type === "next") {
-        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleRight();
-      }
-    },
-    carouseImagePreviewClose() {
-      this.isFullscreenMarking = false;
-      this.carouselType = "";
-      this.selectPaper(this.curPaperIndex);
-    },
-    standardPaperChange(curPaper) {
-      if (!this.isFullscreenMarking) return;
-      this.curPaper = { ...curPaper };
-    }
-  }
-};
-</script>
+<template>
+  <div :class="compClasses">
+    <grade-filter
+      ref="GradeFilter"
+      :data="workSubject"
+      @change="areaChange"
+    ></grade-filter>
+    <grade-step
+      :steps="steps"
+      :init-step="curStep"
+      :show-count="showPaperRelateCount"
+      @on-change="stepChange"
+      ref="GradeStep"
+      v-if="steps.levelStep"
+    ></grade-step>
+    <div class="detail-body">
+      <!-- detail-papers -->
+      <div :class="detailPapersClasses">
+        <div class="detail-papers-carousel">
+          <grade-standard-paper
+            :levels="levels"
+            :question-id="filter.questionId"
+            @on-paper-click="
+              (index, papers) => {
+                toViewCarouselPaper(index, papers, 'sample');
+              }
+            "
+            @on-paper-change="standardPaperChange"
+            v-if="
+              levels.length &&
+              filter.questionId &&
+              ((IS_MARK_LEADER && paramsSet.showSample) || IS_ADMIN)
+            "
+            ref="GradeStandardPaper"
+          ></grade-standard-paper>
+          <!-- TODO:科组长的操作记录 -->
+          <grade-history-paper
+            :question-id="filter.questionId"
+            @on-paper-click="
+              (index, papers) => {
+                toViewCarouselPaper(index, papers, 'history');
+              }
+            "
+            v-if="filter.questionId && !IS_ADMIN"
+            ref="GradeHistoryPaper"
+          ></grade-history-paper>
+        </div>
+        <div class="detail-papers-list" v-if="papers.length">
+          <div :class="imageViewClasses">
+            <div
+              :class="[
+                'image-view',
+                { 'image-view-act': curPaperIndex === index || image.selected },
+              ]"
+              v-for="(image, index) in papers"
+              :key="index"
+            >
+              <div class="image-view-container">
+                <h5 class="image-view-title">{{ image.title }}</h5>
+                <div class="image-view-contain">
+                  <img
+                    :src="image.thumbSrc"
+                    :alt="image.title"
+                    @click="toReview(index)"
+                  />
+                </div>
+                <div class="image-view-actions" v-if="ACTION_CAN_BATCH">
+                  <div
+                    :class="[
+                      'image-view-multibar',
+                      { 'image-view-selected': image.selected },
+                      { 'image-view-disabled': image.sample },
+                    ]"
+                    :title="image.sample ? '标准卷' : '选中批量操作'"
+                    @click="selectMultiplePaper(image)"
+                  ></div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div
+            :class="[
+              'part-page',
+              { 'part-page-simple': !showPaperRelateCount },
+            ]"
+          >
+            <Page
+              :current="current"
+              :total="total"
+              :page-size="size"
+              :show-total="!!showPaperRelateCount"
+              show-elevator
+              @on-change="toPage"
+            ></Page>
+          </div>
+        </div>
+        <div class="detail-papers-list" v-else>
+          <p class="detail-papers-none">暂无数据</p>
+        </div>
+      </div>
+      <!-- detail-aciton -->
+      <div
+        :class="[
+          'detail-action',
+          { 'detail-action-fullscreen': isFullscreenMarking },
+        ]"
+        v-show="!multipleGradingList.length"
+      >
+        <grade-action
+          :cur-paper-or-task="curPaper"
+          :levels="levels"
+          :params-set="paramsSet"
+          @on-leader-level="leaderSelectLevel"
+          @on-code-search="serachPaperByCode"
+          ref="GradeAction"
+          v-if="curPaper.id"
+        ></grade-action>
+      </div>
+      <!-- 占位 -->
+      <div class="detail-action" v-if="isFullscreenMarking"></div>
+      <!-- detail-aciton multiple grading action -->
+      <div class="detail-action" v-show="multipleGradingList.length">
+        <div class="grade-action">
+          <div class="action-paper-state">
+            <p class="paper-state-cont">批量操作</p>
+          </div>
+          <div class="action-paper-info">
+            <p><span>任务密号:</span><span>--</span></p>
+          </div>
+          <h3
+            class="action-grade-info-title"
+            v-if="IS_MARK_LEADER && markLeaderOnlyRight"
+          >
+            当前操作:{{ markLeaderOnlyRight.name }}
+          </h3>
+          <div class="action-grade-list">
+            <div
+              class="action-grade-item"
+              v-for="(level, index) in levels"
+              :key="index"
+            >
+              <div
+                :class="[
+                  'action-grade-item-content',
+                  { 'action-item-content-disabled': multiplebtnClicked },
+                ]"
+                @click="multipleSelectLevel(level)"
+              >
+                <p>{{ level.name }}</p>
+                <p>{{ level.minScore }}~{{ level.maxScore }}</p>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      :class="imagePreviewClasses"
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      @on-close="isFullscreenMarking = false"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
+    <!-- carousel paper review -->
+    <simple-image-preview
+      :class="imagePreviewClasses"
+      :cur-image="curPaper"
+      @on-prev="toCarousePaper('prev')"
+      @on-next="toCarousePaper('next')"
+      @on-close="carouseImagePreviewClose"
+      ref="CarouselPapersPreview"
+    ></simple-image-preview>
+    <!-- modify-leader-grading -->
+    <modify-leader-grading
+      :level-info="levelInfo"
+      :markers="markers"
+      @modified="leaderGradingSuccess"
+      ref="ModifyLeaderGrading"
+    ></modify-leader-grading>
+  </div>
+</template>
+
+<script>
+import {
+  paperList,
+  levelStatData,
+  workLevelList,
+  taskSnSearch,
+  subjectDetail,
+  markHistoryList,
+  getParamsSet,
+  leaderGradingPaper,
+} from "@/api";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+import GradeFilter from "./components/GradeFilter";
+import GradeStep from "./components/GradeStep";
+import GradeStandardPaper from "./components/GradeStandardPaper";
+import GradeHistoryPaper from "./components/GradeHistoryPaper";
+import GradeAction from "./components/GradeAction";
+import ModifyLeaderGrading from "./components/ModifyLeaderGrading";
+// 三种情况:
+// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
+// 管理员:标准卷,试卷列表,操作盘
+// 科组长:标准卷,操作记录,试卷列表,操作盘(定档,标准卷,打回)
+
+// TIP:不考虑评卷员的情况
+// 评卷员:标准卷,操作记录,试卷列表,操作盘(只分档)
+
+export default {
+  name: "grading-detail",
+  components: {
+    SimpleImagePreview,
+    GradeFilter,
+    GradeStep,
+    GradeHistoryPaper,
+    GradeStandardPaper,
+    GradeAction,
+    ModifyLeaderGrading,
+  },
+  data() {
+    return {
+      filter: {
+        questionId: "",
+        sort: "secretNumber",
+      },
+      typeFilter: {
+        done: {
+          level: "",
+        },
+        reject: {
+          reject: true,
+        },
+        arbitrate: {
+          arbi: true,
+        },
+      },
+      workId: this.$route.params.workId,
+      subjectId: this.$route.params.subjectId,
+      subject: "",
+      workSubject: {},
+      curSubject: {},
+      curUserRoleType: "MARKER",
+      current: 1,
+      size: 6,
+      total: 0,
+      totalPage: 1,
+      curStep: { type: "", name: "" },
+      steps: {},
+      levels: [],
+      curArea: {},
+      papers: [],
+      curPaper: {},
+      curPaperIndex: 0,
+      paramsSet: {},
+      // leader-grade
+      levelInfo: {},
+      markers: [],
+      // carousel paper review,
+      carouselType: "",
+      carouselPapers: [],
+      curCarouselPaperIndex: 0,
+      isFullscreenMarking: false,
+      // multiple grading
+      multiplebtnClicked: false,
+      multipleGradingList: [],
+      // 科组长权限
+      markLeaderOnlyRight: null,
+    };
+  },
+  computed: {
+    compClasses() {
+      return [
+        "page-container-flex",
+        "grading-detail",
+        { "grading-operation": this.IS_MARK_LEADER },
+      ];
+    },
+    detailPapersClasses() {
+      return ["detail-papers", `detail-papers-col-${1 + this.size / 2}`];
+    },
+    imageViewClasses() {
+      return ["image-view-list", `image-view-list-${this.size / 2}`];
+    },
+    showPaperRelateCount() {
+      return this.IS_ADMIN || !!this.paramsSet["showPaperCount"];
+    },
+    IS_ADMIN() {
+      return (
+        this.curUserRoleType === "ADMIN" ||
+        this.curUserRoleType === "SUPER_ADMIN"
+      );
+    },
+    IS_MARK_LEADER() {
+      return this.curUserRoleType === "MARK_LEADER";
+    },
+    IS_TEST() {
+      return this.curSubject.test === 2;
+    },
+    ACTION_CAN_BATCH() {
+      return (
+        this.curStep.type === "done" &&
+        this.IS_MARK_LEADER &&
+        !this.paramsSet.paperStage
+      );
+    },
+    imagePreviewClasses() {
+      return this.IS_ADMIN
+        ? "grading-detail-image-preview"
+        : "grading-operation-image-preview";
+    },
+  },
+  created() {
+    this.subject = this.subjectId.split("-")[1];
+    this.workSubject = {
+      workId: this.workId,
+      subject: this.subject,
+    };
+    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
+
+    this.markLeaderOnlyRight = this.$ls.get("user", {
+      markLeaderOnlyRight: null,
+    }).markLeaderOnlyRight;
+
+    this.initData();
+  },
+  methods: {
+    async initData() {
+      await this.getParamsSetInfo();
+      await this.getSubjectDetail();
+      // 获取档位列表
+      this.getWorkLevels();
+    },
+    async getParamsSetInfo() {
+      this.paramsSet = await getParamsSet(this.workId);
+    },
+    async getList() {
+      this.multipleGradingList = [];
+      const datas = {
+        ...this.filter,
+        ...this.typeFilter[this.curStep.type],
+        page: this.current - 1,
+        size: this.size,
+      };
+      if (this.curStep.type === "done") datas.level = this.curStep.name;
+
+      const data = await paperList(datas);
+      this.papers = data.data.map((paper) => {
+        paper.title = this.IS_ADMIN ? paper.examNumber : `NO.${paper.sn}`;
+        paper.selected = false;
+        return paper;
+      });
+      this.total = data.totalCount;
+      this.totalPage = data.pageCount;
+    },
+    async toPage(page) {
+      this.current = page;
+      await this.getList();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async getSubjectDetail() {
+      this.curSubject = await subjectDetail(this.subjectId);
+    },
+    async getStepLevels() {
+      const data = await levelStatData(this.subjectId, this.filter.questionId);
+      const undoIndex = data.findIndex((item) => item.id === null);
+      let otherStep = [];
+      let undo = {
+        count: 0,
+        rejected: 0,
+        arbitrated: 0,
+      };
+      if (undoIndex !== -1) {
+        undo = { ...data[undoIndex] };
+        data.splice(undoIndex, 1);
+      }
+
+      if (this.IS_MARK_LEADER && this.IS_TEST) {
+        otherStep.push({
+          name: "待评",
+          count: undo.count,
+          type: "undo",
+        });
+      }
+      otherStep.push({
+        name: "打回",
+        count: undo.rejected,
+        type: "reject",
+      });
+      otherStep.push({
+        name: "仲裁",
+        count: undo.arbitrated,
+        type: "arbitrate",
+      });
+
+      let levelStep = data.map((item) => {
+        return {
+          ...item,
+          name: item.id,
+          type: "done",
+        };
+      });
+      this.steps = { levelStep, otherStep };
+
+      if (!this.curStep.type) {
+        this.curStep = levelStep[0];
+      }
+    },
+    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 stepChange(step) {
+      this.curStep = step;
+      // this.toPage(1);
+      this.current = 1;
+      await this.getList();
+      if (this.papers.length) {
+        this.selectPaper(0);
+      } else {
+        this.curPaper = {};
+      }
+    },
+    async areaChange(curArea) {
+      this.curArea = curArea;
+      this.filter.questionId = curArea.id;
+      await this.getStepLevels();
+      this.toPage(1);
+    },
+    // selectMultiplePaper
+    selectMultiplePaper(paper) {
+      if (paper.sample) return;
+      paper.selected = !paper.selected;
+      this.multipleGradingList = this.papers.filter((paper) => paper.selected);
+    },
+    async multipleSelectLevel(level) {
+      if (!this.multipleGradingList.length) return;
+      if (this.multiplebtnClicked) return;
+      this.multiplebtnClicked = true;
+
+      const data = await markHistoryList(
+        this.multipleGradingList[0].id,
+        "LEVEL"
+      ).catch(() => {
+        this.multiplebtnClicked = false;
+      });
+
+      if (!data) return;
+
+      const markers = data.map((item) => {
+        return {
+          id: item.markerId,
+          name: item.marker,
+        };
+      });
+      const levelInfo = {
+        paperIds: this.multipleGradingList.map((item) => item.id).join(),
+        curLevel: this.curStep.name,
+        selectedLevel: level.name,
+        markLeaderOnlyRight: this.markLeaderOnlyRight,
+      };
+
+      await this.leaderSelectLevel(levelInfo, markers).catch(() => {});
+      this.multiplebtnClicked = false;
+    },
+    // to review
+    toReview(index) {
+      this.isFullscreenMarking = true;
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        if (this.current > 1) {
+          this.current--;
+          this.curPaperIndex = this.size - 1;
+          await this.getList();
+        } else {
+          this.$Message.warning("当前已经是第一条数据了");
+          return;
+        }
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        if (this.current === this.totalPage) {
+          this.$Message.warning("当前已经是最后一条数据了");
+          return;
+        } else {
+          this.current++;
+          this.curPaperIndex = 0;
+          await this.getList();
+        }
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toActionNextPaper() {
+      if (this.current > 1 && this.papers.length === 1) {
+        this.current--;
+        this.curPaperIndex = this.size;
+      }
+
+      await this.getList();
+      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
+      this.selectPaper(this.curPaperIndex);
+    },
+    updateHistory() {
+      this.$refs.GradeHistoryPaper.updatePapers();
+    },
+    async serachPaperByCode(params) {
+      const data = await taskSnSearch(
+        params.codeType,
+        params.code,
+        this.filter.questionId
+      );
+      if (!data) {
+        this.$Message.error("没有查找到结果!");
+        return;
+      }
+      data.title = this.IS_ADMIN ? data.examNumber : `NO.${data.sn}`;
+      data.key = this.$randomCode();
+      this.papers = [data];
+      this.total = 1;
+      this.selectPaper(0);
+    },
+    async leaderSelectLevel(levelInfo, markers) {
+      // 唯一权限时,直接操作
+      if (levelInfo.markLeaderOnlyRight && !this.paramsSet.leaderConfirm) {
+        const datas = {
+          action: levelInfo.markLeaderOnlyRight.action,
+          level: levelInfo.selectedLevel,
+          originLevel: levelInfo.curLevel,
+          paperIds: levelInfo.paperIds,
+        };
+        if (datas.action === "reject") {
+          datas.range = markers.map((item) => item.id).join();
+        }
+        let result = true;
+        const paper = await leaderGradingPaper(datas).catch(() => {
+          result = false;
+        });
+        if (!result) return;
+
+        this.leaderGradingSuccess(datas, paper);
+        return;
+      }
+
+      this.levelInfo = levelInfo;
+      this.markers = markers;
+      this.$refs.ModifyLeaderGrading.open();
+    },
+    async leaderGradingSuccess(datas, paper) {
+      if (datas.action === "sampling" && this.$refs.GradeStandardPaper) {
+        this.$refs.GradeStandardPaper.updateLevelPapers(datas.level);
+      }
+      this.getStepLevels();
+      this.updateHistory();
+
+      if (this.multipleGradingList && this.multipleGradingList.length) {
+        // 批量处理逻辑
+        if (
+          this.current > 1 &&
+          this.current === this.pageCount &&
+          this.papers.length === this.multipleGradingList.length
+        ) {
+          this.current--;
+        }
+
+        this.multipleGradingList = [];
+        await this.getList();
+        this.selectPaper(this.curPaperIndex);
+      } else {
+        // 单张处理逻辑
+        this.toActionNextPaper();
+      }
+    },
+    // paper carousel
+    toViewCarouselPaper(paperIndex, papers, type) {
+      this.carouselType = type;
+      this.isFullscreenMarking = true;
+      this.carouselPapers = papers;
+      this.selectCarouselPaper(paperIndex);
+      this.$nextTick(() => {
+        this.$refs.CarouselPapersPreview.open();
+      });
+    },
+    selectCarouselPaper(index) {
+      this.curCarouselPaperIndex = index;
+      this.curPaper = { ...this.carouselPapers[index] };
+    },
+    toCarousePaper(type) {
+      if (this.carouselType === "sample") {
+        this.toSampleCarousePaper(type);
+        return;
+      }
+      if (type === "prev" && this.curCarouselPaperIndex > 0) {
+        this.curCarouselPaperIndex--;
+      } else if (
+        type === "next" &&
+        this.curCarouselPaperIndex < this.carouselPapers.length - 1
+      ) {
+        this.curCarouselPaperIndex++;
+      }
+      this.selectCarouselPaper(this.curCarouselPaperIndex);
+    },
+    toSampleCarousePaper(type) {
+      if (!this.$refs.GradeStandardPaper) return;
+      if (type === "prev") {
+        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleLeft();
+      } else if (type === "next") {
+        this.$refs.GradeStandardPaper.$refs.PaperCarousel.handleRight();
+      }
+    },
+    carouseImagePreviewClose() {
+      this.isFullscreenMarking = false;
+      this.carouselType = "";
+      this.selectPaper(this.curPaperIndex);
+    },
+    standardPaperChange(curPaper) {
+      if (!this.isFullscreenMarking) return;
+      this.curPaper = { ...curPaper };
+    },
+  },
+};
+</script>

+ 13 - 14
src/modules/grading/GradingGroupManage.vue

@@ -57,7 +57,7 @@ import {
   gradingGroupList,
   markUserList,
   updateGradingGroup,
-  deleteGradingGroup
+  deleteGradingGroup,
 } from "@/api";
 import draggable from "vuedraggable";
 
@@ -70,14 +70,14 @@ export default {
       subjectId: this.$route.params.subjectId,
       groups: [],
       users: [],
-      isSubmit: false
+      isSubmit: false,
     };
   },
   computed: {
     groupListClasses() {
       const num = this.groups.length;
       return ["group-list", `group-list-${num}`];
-    }
+    },
   },
   mounted() {
     this.initData();
@@ -93,13 +93,13 @@ export default {
     async getMarkUserList() {
       const data = await markUserList({
         workId: this.workId,
-        subjectId: this.subjectId.split("-")[1]
+        subjectId: this.subjectId.split("-")[1],
       });
-      this.users = data.filter(user => !user.groupId);
+      this.users = data.filter((user) => !user.groupId);
     },
     submit() {
       if (this.isSubmit) return;
-      const hasNoneGroup = this.groups.some(group => !group.markers.length);
+      const hasNoneGroup = this.groups.some((group) => !group.markers.length);
       if (hasNoneGroup) {
         this.$Message.error("当前分组列表中存在空组!");
         // this.$Modal.confirm({
@@ -116,10 +116,9 @@ export default {
       this.isSubmit = true;
       for (let i = 0; i < this.groups.length; i++) {
         const group = this.groups[i];
-        let result = await updateGradingGroup(
-          this.subjectId,
-          group
-        ).catch(() => {});
+        let result = await updateGradingGroup(this.subjectId, group).catch(
+          () => {}
+        );
         if (!result) {
           this.isSubmit = false;
           this.$Message.error("保存失败,请重新尝试!");
@@ -137,7 +136,7 @@ export default {
         name: "评卷组" + (this.groups.length + 1),
         markers: [],
         subject: this.subjectId.split("-")[1],
-        workId: this.workId
+        workId: this.workId,
       });
     },
     removeGroupUser(uindex, group) {
@@ -157,7 +156,7 @@ export default {
           await deleteGradingGroup(this.subjectId, group.id);
           this.removeGroup(gindex);
           this.$Message.success("删除成功!");
-        }
+        },
       });
     },
     removeGroup(gindex) {
@@ -167,7 +166,7 @@ export default {
       this.groups.map((group, index) => {
         group.name = "评卷组" + (index + 1);
       });
-    }
-  }
+    },
+  },
 };
 </script>

+ 33 - 33
src/modules/grading/GradingOperation.vue

@@ -53,8 +53,8 @@
                       'image-view',
                       {
                         'image-view-act':
-                          curPaperIndex === index || image.selected
-                      }
+                          curPaperIndex === index || image.selected,
+                      },
                     ]"
                     v-for="(image, index) in papers"
                     :key="index"
@@ -73,7 +73,7 @@
                           :class="[
                             'image-view-multibar',
                             { 'image-view-selected': image.selected },
-                            { 'image-view-disabled': image.sample }
+                            { 'image-view-disabled': image.sample },
                           ]"
                           :title="image.sample ? '标准卷' : '选中批量分档'"
                           @click="selectMultiplePaper(image)"
@@ -85,7 +85,7 @@
                 <div
                   :class="[
                     'part-page',
-                    { 'part-page-simple': !showPaperRelateCount }
+                    { 'part-page-simple': !showPaperRelateCount },
                   ]"
                 >
                   <Page
@@ -109,7 +109,7 @@
             <div
               :class="[
                 'detail-action',
-                { 'detail-action-fullscreen': isFullscreenMarking }
+                { 'detail-action-fullscreen': isFullscreenMarking },
               ]"
               v-show="!multipleGradingList.length"
             >
@@ -140,7 +140,7 @@
                     <div
                       :class="[
                         'action-grade-item-content',
-                        { 'action-item-content-disabled': multiplebtnClicked }
+                        { 'action-item-content-disabled': multiplebtnClicked },
                       ]"
                       @click="multipleSelectLevel(level)"
                     >
@@ -188,7 +188,7 @@ import {
   paperSelectLevelOrScore,
   paperSelectLevelBatch,
   paperTaskPass,
-  getParamsSet
+  getParamsSet,
 } from "@/api";
 import SimpleImagePreview from "@/components/SimpleImagePreview";
 import GradeStep from "./components/GradeStep";
@@ -212,7 +212,7 @@ export default {
     GradeFilter,
     GradeHistoryPaper,
     GradeStandardPaper,
-    GradeAction
+    GradeAction,
   },
   data() {
     return {
@@ -220,16 +220,16 @@ export default {
         markerId: this.$ls.get("user").id,
         questionId: "",
         sort: "randomSeq,asc",
-        stage: "LEVEL"
+        stage: "LEVEL",
       },
       typeFilter: {
         done: {
-          level: ""
+          level: "",
         },
         undo: {},
         reject: {
-          reject: true
-        }
+          reject: true,
+        },
       },
       workId: this.$route.params.workId,
       subjectId: this.$route.params.subjectId,
@@ -257,7 +257,7 @@ export default {
       carouselType: "",
       carouselPapers: [],
       curCarouselPaperIndex: 0,
-      isFullscreenMarking: false
+      isFullscreenMarking: false,
     };
   },
   computed: {
@@ -269,13 +269,13 @@ export default {
     },
     showPaperRelateCount() {
       return !!this.paramsSet["showPaperCount"];
-    }
+    },
   },
   created() {
     this.subject = this.subjectId.split("-")[1];
     this.workSubject = {
       workId: this.workId,
-      subject: this.subject
+      subject: this.subject,
     };
     this.initData();
   },
@@ -294,7 +294,7 @@ export default {
         ...this.typeFilter[this.curStep.type],
         workId: this.workId,
         page: this.current - 1,
-        size: this.size
+        size: this.size,
       };
       if (this.curStep.type === "done") {
         datas.level = this.curStep.name;
@@ -302,7 +302,7 @@ export default {
       }
 
       const data = await markerTaskList(datas);
-      this.papers = data.data.map(paper => {
+      this.papers = data.data.map((paper) => {
         paper.title = `NO.${paper.sn}`;
         paper.selected = false;
         return paper;
@@ -320,11 +320,11 @@ export default {
         this.filter.markerId,
         this.filter.questionId
       );
-      const undoIndex = data.findIndex(item => item.id === null);
+      const undoIndex = data.findIndex((item) => item.id === null);
       let otherStep = [];
       let undo = {
         count: 0,
-        rejected: 0
+        rejected: 0,
       };
       if (undoIndex !== -1) {
         undo = { ...data[undoIndex] };
@@ -334,20 +334,20 @@ export default {
       otherStep.push({
         name: "待评",
         count: undo.count,
-        type: "undo"
+        type: "undo",
       });
       otherStep.push({
         name: "打回",
         count: undo.rejected,
-        type: "reject"
+        type: "reject",
       });
-      let levelStep = data.map(item => {
+      let levelStep = data.map((item) => {
         // 评卷员不展示kdpt
         item.kdpt = null;
         return {
           ...item,
           name: item.id,
-          type: "done"
+          type: "done",
         };
       });
       this.steps = { levelStep, otherStep };
@@ -365,22 +365,22 @@ export default {
     updateStepLevel(curStep, curLevel, count) {
       if (curStep.type === "done") {
         const lpos = this.steps.levelStep.findIndex(
-          item => item.name === curStep.name
+          (item) => item.name === curStep.name
         );
         this.steps.levelStep[lpos].count -= count;
       } else {
         const opos = this.steps.otherStep.findIndex(
-          item => item.type === curStep.type
+          (item) => item.type === curStep.type
         );
         this.steps.otherStep[opos].count -= count;
       }
 
       const pos = this.steps.levelStep.findIndex(
-        item => item.name === curLevel
+        (item) => item.name === curLevel
       );
       this.steps.levelStep[pos].count += count;
 
-      this.steps.levelStep.forEach(item => {
+      this.steps.levelStep.forEach((item) => {
         item.percent =
           item.finalKdTotal && item.count
             ? ((100 * item.count) / item.finalKdTotal).toFixed(3)
@@ -389,12 +389,12 @@ export default {
     },
     async getWorkLevels() {
       const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
+      this.levels = data.map((item) => {
         return {
           id: item.id,
           name: item.code,
           minScore: item.minScore,
-          maxScore: item.maxScore
+          maxScore: item.maxScore,
         };
       });
     },
@@ -428,7 +428,7 @@ export default {
     selectMultiplePaper(paper) {
       if (paper.sample) return;
       paper.selected = !paper.selected;
-      this.multipleGradingList = this.papers.filter(paper => paper.selected);
+      this.multipleGradingList = this.papers.filter((paper) => paper.selected);
     },
     async multipleSelectLevel(level) {
       if (!this.multipleGradingList.length) return;
@@ -438,7 +438,7 @@ export default {
 
       let result = true;
       const papers = await paperSelectLevelBatch(
-        this.multipleGradingList.map(item => item.id).join(), // is taskId
+        this.multipleGradingList.map((item) => item.id).join(), // is taskId
         level.name,
         "LEVEL"
       ).catch(() => {
@@ -590,7 +590,7 @@ export default {
     standardPaperChange(curPaper) {
       if (!this.isFullscreenMarking) return;
       this.curPaper = { ...curPaper };
-    }
-  }
+    },
+  },
 };
 </script>

+ 328 - 328
src/modules/grading/GradingProgress.vue

@@ -1,328 +1,328 @@
-<template>
-  <div class="grading-progress">
-    <div class="part-box-head" v-if="IS_ADMIN">
-      <div class="part-box-head-right">
-        <Button
-          type="error"
-          shape="circle"
-          icon="area icon"
-          @click="toCleanData"
-          v-if="IS_LEVEL || IS_SCORE"
-          >清除当前阅卷数据</Button
-        >
-        <Button
-          type="success"
-          shape="circle"
-          icon="recode-white icon"
-          @click="toGrading"
-          v-if="showGradingBtn"
-          >正评任务创建</Button
-        >
-        <Button
-          type="warning"
-          shape="circle"
-          icon="recode-white icon"
-          @click="toTryGrading"
-          v-if="showTryGradingBtn"
-          >试评任务创建</Button
-        >
-        <Button shape="circle" @click="toMark" v-if="showMarkBtn"
-          >进入打分阶段
-          <Icon type="arrow-right-long icon" style="margin-left:8px;" />
-        </Button>
-      </div>
-      <div class="part-box-head-left" v-if="IS_LEVEL">
-        <Button shape="circle" icon="md-download" @click="toExportStandard"
-          >导出标准卷信息</Button
-        >
-        <Button shape="circle" icon="md-download" @click="toExportGrading"
-          >导出一键定档信息</Button
-        >
-      </div>
-      <div v-if="IS_SCORE" class="part-box-head-left">
-        <Button shape="circle" icon="md-download" @click="toExportChangeLevel"
-          >导出改档信息</Button
-        >
-      </div>
-    </div>
-    <Row :gutter="20" type="flex">
-      <Col span="12">
-        <div class="part-box progress-table">
-          <table class="table table-noborder">
-            <tr v-for="(item, aindex) in areaProgress" :key="aindex">
-              <td>{{ item.areaName }}</td>
-              <td>
-                <progress-line
-                  :sum="item.totalCount"
-                  :current="item.successCount"
-                  :show-count="showPaperRelateCount"
-                ></progress-line>
-              </td>
-              <td>进度:{{ item.progress }}%</td>
-              <td></td>
-            </tr>
-          </table>
-        </div>
-      </Col>
-      <Col span="12">
-        <div class="part-box progress-table">
-          <table
-            class="table table-noborder"
-            v-if="IS_LEVEL && markerProgress.length"
-          >
-            <tr>
-              <td>{{ kzzInfo.loginName }}</td>
-              <td colspan="3" style="text-align:left">
-                仲裁:{{ kzzInfo.arbitrated }}
-              </td>
-            </tr>
-            <tr v-for="(item, aindex) in markerProgress" :key="aindex">
-              <td>{{ item.loginName }}</td>
-              <td>
-                <progress-line
-                  :sum="item.totalCount"
-                  :current="item.successCount"
-                  :show-count="showPaperRelateCount"
-                ></progress-line>
-              </td>
-              <td>进度:{{ item.progress }}%</td>
-              <td>打回:{{ item.rejectedCount }}</td>
-            </tr>
-          </table>
-
-          <table class="table table-noborder" v-if="IS_SCORE">
-            <tr v-for="(item, aindex) in markerProgress" :key="aindex">
-              <td>{{ item.loginName }}</td>
-              <td>
-                <progress-line
-                  :sum="item.totalCount"
-                  :current="item.successCount"
-                  :show-count="showPaperRelateCount"
-                ></progress-line>
-              </td>
-              <td>进度:{{ item.progress }}%</td>
-              <td>改档:{{ item.shiftCount }}</td>
-              <td>改档打分:{{ item.shiftScoreCount }}</td>
-            </tr>
-          </table>
-        </div>
-      </Col>
-    </Row>
-
-    <!-- clean-grading-data-dialog -->
-    <clean-grading-data-dialog
-      :cur-subject="curSubject"
-      @modified="initData"
-      ref="CleanGradingDataDialog"
-    ></clean-grading-data-dialog>
-    <!-- modify-unformal-grading-task -->
-    <modify-unformal-grading-task
-      :cur-subject="curSubject"
-      @modified="taskSubmitSuccess"
-      ref="ModifyUnformalGradingTask"
-      v-if="curSubject.id"
-    ></modify-unformal-grading-task>
-    <!-- modify-formal-grading-task -->
-    <modify-formal-grading-task
-      :subject-id="subjectId"
-      @modified="taskSubmitSuccess"
-      ref="ModifyFormalGradingTask"
-    ></modify-formal-grading-task>
-  </div>
-</template>
-
-<script>
-import ProgressLine from "./components/ProgressLine";
-import ModifyUnformalGradingTask from "./components/ModifyUnformalGradingTask";
-import ModifyFormalGradingTask from "./components/ModifyFormalGradingTask";
-import CleanGradingDataDialog from "./components/CleanGradingDataDialog";
-import {
-  gradingProgressDetail,
-  subjectDetail,
-  gotoScoreStep,
-  getParamsSet
-} from "@/api";
-import { SUBJECT_STAGE } from "@/constants/enumerate";
-
-export default {
-  name: "grading-progress",
-  components: {
-    ProgressLine,
-    ModifyUnformalGradingTask,
-    ModifyFormalGradingTask,
-    CleanGradingDataDialog
-  },
-  data() {
-    return {
-      subjectId: this.$route.params.subjectId,
-      workId: this.$route.params.workId,
-      paramsSet: {},
-      curSubject: {},
-      SUBJECT_STAGE,
-      kzzInfo: {},
-      totalProgress: {},
-      areaProgress: [],
-      markerProgress: [],
-      curUserRoleType: "",
-      password: ""
-    };
-  },
-  computed: {
-    showGradingBtn() {
-      // 采集时已知档位,则不显示正评任务按钮
-      if (this.paramsSet.paperStage) return false;
-
-      return (
-        (this.curSubject.stage == "INIT" &&
-          this.curSubject.test !== 2 &&
-          !this.curSubject.formal &&
-          this.totalProgress.progress > 0) ||
-        (this.curSubject.stage == "LEVEL" &&
-          this.totalProgress.progress !== 100 &&
-          this.curSubject.test === 0 &&
-          this.curSubject.formal)
-      );
-    },
-    showTryGradingBtn() {
-      return false;
-      // // 采集时已知档位,则不显示试评任务按钮
-      // if (this.paramsSet.paperStage) return false;
-
-      // return (
-      //   (this.curSubject.stage == "INIT" &&
-      //     this.curSubject.test !== 2 &&
-      //     !this.curSubject.formal &&
-      //     this.totalProgress.progress > 0) ||
-      //   (this.curSubject.stage == "LEVEL" && this.curSubject.test === 2)
-      // );
-    },
-    showMarkBtn() {
-      // 采集时已知档位,分档阶段则可直接进入打分
-      if (this.paramsSet.paperStage) return this.curSubject.stage == "LEVEL";
-
-      // 若不知档位,则必须分档进度为100时,才能进入打分
-      return (
-        (this.curSubject.stage == "LEVEL" &&
-          this.totalProgress.progress === 100) ||
-        (this.curSubject.stage == "SCORE" && !this.curSubject.allLevel)
-      );
-    },
-    showPaperRelateCount() {
-      return this.IS_ADMIN || !!this.paramsSet["showPaperCount"];
-    },
-    IS_ADMIN() {
-      return (
-        this.curUserRoleType === "ADMIN" ||
-        this.curUserRoleType === "SUPER_ADMIN"
-      );
-    },
-    IS_MARK_LEADER() {
-      return this.curUserRoleType === "MARK_LEADER";
-    },
-    IS_LEVEL() {
-      return this.curSubject.stage === "LEVEL";
-    },
-    IS_SCORE() {
-      return this.curSubject.stage === "SCORE";
-    }
-  },
-  mounted() {
-    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
-    this.initData();
-  },
-  methods: {
-    async initData() {
-      await this.getSubjectDetail();
-      this.getParamsSetInfo();
-      this.getProgressDetail();
-    },
-    async getParamsSetInfo() {
-      this.paramsSet = await getParamsSet(this.workId);
-    },
-    async getProgressDetail() {
-      const data = await gradingProgressDetail({
-        workId: this.curSubject.workId,
-        subject: this.curSubject.subject
-      });
-      this.kzzInfo = data.kzz || {};
-      this.totalProgress = data.totalProgress;
-      const totalInfo = {
-        successCount: data.totalProgress.successCount,
-        totalCount: data.totalProgress.totalCount,
-        progress: data.totalProgress.progress.toFixed(2),
-        areaName: "总体进度"
-      };
-      if (this.curSubject.stage === "INIT") {
-        this.areaProgress = [totalInfo];
-        this.markerProgress = [];
-      } else {
-        this.areaProgress = [totalInfo, ...this.addProgress(data.areaProgress)];
-        this.markerProgress = this.addProgress(data.markerProgress);
-      }
-      this.$parent.setProgress &&
-        this.$parent.setProgress(data.totalProgress.progress);
-    },
-    addProgress(data) {
-      return data.map(item => {
-        item.successCount = item.totalCount - item.leftCount;
-        item.progress = item.totalCount
-          ? ((100 * item.successCount) / item.totalCount).toFixed(2)
-          : "0.00";
-        return item;
-      });
-    },
-    async getSubjectDetail() {
-      this.curSubject = await subjectDetail(this.subjectId);
-    },
-    toCleanData() {
-      this.$refs.CleanGradingDataDialog.open();
-    },
-    toGrading() {
-      this.$refs.ModifyFormalGradingTask.open();
-    },
-    toTryGrading() {
-      this.$refs.ModifyUnformalGradingTask.open();
-    },
-    toMark() {
-      this.$Modal.confirm({
-        content: "确定要进入打分阶段吗?",
-        onOk: async () => {
-          await gotoScoreStep(this.subjectId);
-          this.$router.replace({
-            name: "Mark",
-            params: {
-              workId: this.curSubject.workId,
-              subjectId: this.subjectId
-            }
-          });
-        }
-      });
-    },
-    taskSubmitSuccess() {
-      this.$parent.initData();
-      this.initData();
-    },
-    toExportStandard() {
-      window.open(
-        this.urlAddAuthor(
-          `${this.GLOBAL.domain}/api/export/paper/${this.curSubject.workId}/${this.curSubject.subject}/sample`
-        )
-      );
-    },
-    toExportGrading() {
-      window.open(
-        this.urlAddAuthor(
-          `${this.GLOBAL.domain}/api/export/paper/${this.curSubject.workId}/${this.curSubject.subject}/oneClick`
-        )
-      );
-    },
-    toExportChangeLevel() {
-      window.open(
-        this.urlAddAuthor(
-          `${this.GLOBAL.domain}/api/export/paper/${this.curSubject.workId}/${this.curSubject.subject}/changeLevel`
-        )
-      );
-    }
-  }
-};
-</script>
+<template>
+  <div class="grading-progress">
+    <div class="part-box-head" v-if="IS_ADMIN">
+      <div class="part-box-head-right">
+        <Button
+          type="error"
+          shape="circle"
+          icon="area icon"
+          @click="toCleanData"
+          v-if="IS_LEVEL || IS_SCORE"
+          >清除当前阅卷数据</Button
+        >
+        <Button
+          type="success"
+          shape="circle"
+          icon="recode-white icon"
+          @click="toGrading"
+          v-if="showGradingBtn"
+          >正评任务创建</Button
+        >
+        <Button
+          type="warning"
+          shape="circle"
+          icon="recode-white icon"
+          @click="toTryGrading"
+          v-if="showTryGradingBtn"
+          >试评任务创建</Button
+        >
+        <Button shape="circle" @click="toMark" v-if="showMarkBtn"
+          >进入打分阶段
+          <Icon type="arrow-right-long icon" style="margin-left: 8px" />
+        </Button>
+      </div>
+      <div class="part-box-head-left" v-if="IS_LEVEL">
+        <Button shape="circle" icon="md-download" @click="toExportStandard"
+          >导出标准卷信息</Button
+        >
+        <Button shape="circle" icon="md-download" @click="toExportGrading"
+          >导出一键定档信息</Button
+        >
+      </div>
+      <div v-if="IS_SCORE" class="part-box-head-left">
+        <Button shape="circle" icon="md-download" @click="toExportChangeLevel"
+          >导出改档信息</Button
+        >
+      </div>
+    </div>
+    <Row :gutter="20" type="flex">
+      <Col span="12">
+        <div class="part-box progress-table">
+          <table class="table table-noborder">
+            <tr v-for="(item, aindex) in areaProgress" :key="aindex">
+              <td>{{ item.areaName }}</td>
+              <td>
+                <progress-line
+                  :sum="item.totalCount"
+                  :current="item.successCount"
+                  :show-count="showPaperRelateCount"
+                ></progress-line>
+              </td>
+              <td>进度:{{ item.progress }}%</td>
+              <td></td>
+            </tr>
+          </table>
+        </div>
+      </Col>
+      <Col span="12">
+        <div class="part-box progress-table">
+          <table
+            class="table table-noborder"
+            v-if="IS_LEVEL && markerProgress.length"
+          >
+            <tr>
+              <td>{{ kzzInfo.loginName }}</td>
+              <td colspan="3" style="text-align: left">
+                仲裁:{{ kzzInfo.arbitrated }}
+              </td>
+            </tr>
+            <tr v-for="(item, aindex) in markerProgress" :key="aindex">
+              <td>{{ item.loginName }}</td>
+              <td>
+                <progress-line
+                  :sum="item.totalCount"
+                  :current="item.successCount"
+                  :show-count="showPaperRelateCount"
+                ></progress-line>
+              </td>
+              <td>进度:{{ item.progress }}%</td>
+              <td>打回:{{ item.rejectedCount }}</td>
+            </tr>
+          </table>
+
+          <table class="table table-noborder" v-if="IS_SCORE">
+            <tr v-for="(item, aindex) in markerProgress" :key="aindex">
+              <td>{{ item.loginName }}</td>
+              <td>
+                <progress-line
+                  :sum="item.totalCount"
+                  :current="item.successCount"
+                  :show-count="showPaperRelateCount"
+                ></progress-line>
+              </td>
+              <td>进度:{{ item.progress }}%</td>
+              <td>改档:{{ item.shiftCount }}</td>
+              <td>改档打分:{{ item.shiftScoreCount }}</td>
+            </tr>
+          </table>
+        </div>
+      </Col>
+    </Row>
+
+    <!-- clean-grading-data-dialog -->
+    <clean-grading-data-dialog
+      :cur-subject="curSubject"
+      @modified="initData"
+      ref="CleanGradingDataDialog"
+    ></clean-grading-data-dialog>
+    <!-- modify-unformal-grading-task -->
+    <modify-unformal-grading-task
+      :cur-subject="curSubject"
+      @modified="taskSubmitSuccess"
+      ref="ModifyUnformalGradingTask"
+      v-if="curSubject.id"
+    ></modify-unformal-grading-task>
+    <!-- modify-formal-grading-task -->
+    <modify-formal-grading-task
+      :subject-id="subjectId"
+      @modified="taskSubmitSuccess"
+      ref="ModifyFormalGradingTask"
+    ></modify-formal-grading-task>
+  </div>
+</template>
+
+<script>
+import ProgressLine from "./components/ProgressLine";
+import ModifyUnformalGradingTask from "./components/ModifyUnformalGradingTask";
+import ModifyFormalGradingTask from "./components/ModifyFormalGradingTask";
+import CleanGradingDataDialog from "./components/CleanGradingDataDialog";
+import {
+  gradingProgressDetail,
+  subjectDetail,
+  gotoScoreStep,
+  getParamsSet,
+} from "@/api";
+import { SUBJECT_STAGE } from "@/constants/enumerate";
+
+export default {
+  name: "grading-progress",
+  components: {
+    ProgressLine,
+    ModifyUnformalGradingTask,
+    ModifyFormalGradingTask,
+    CleanGradingDataDialog,
+  },
+  data() {
+    return {
+      subjectId: this.$route.params.subjectId,
+      workId: this.$route.params.workId,
+      paramsSet: {},
+      curSubject: {},
+      SUBJECT_STAGE,
+      kzzInfo: {},
+      totalProgress: {},
+      areaProgress: [],
+      markerProgress: [],
+      curUserRoleType: "",
+      password: "",
+    };
+  },
+  computed: {
+    showGradingBtn() {
+      // 采集时已知档位,则不显示正评任务按钮
+      if (this.paramsSet.paperStage) return false;
+
+      return (
+        (this.curSubject.stage == "INIT" &&
+          this.curSubject.test !== 2 &&
+          !this.curSubject.formal &&
+          this.totalProgress.progress > 0) ||
+        (this.curSubject.stage == "LEVEL" &&
+          this.totalProgress.progress !== 100 &&
+          this.curSubject.test === 0 &&
+          this.curSubject.formal)
+      );
+    },
+    showTryGradingBtn() {
+      return false;
+      // // 采集时已知档位,则不显示试评任务按钮
+      // if (this.paramsSet.paperStage) return false;
+
+      // return (
+      //   (this.curSubject.stage == "INIT" &&
+      //     this.curSubject.test !== 2 &&
+      //     !this.curSubject.formal &&
+      //     this.totalProgress.progress > 0) ||
+      //   (this.curSubject.stage == "LEVEL" && this.curSubject.test === 2)
+      // );
+    },
+    showMarkBtn() {
+      // 采集时已知档位,分档阶段则可直接进入打分
+      if (this.paramsSet.paperStage) return this.curSubject.stage == "LEVEL";
+
+      // 若不知档位,则必须分档进度为100时,才能进入打分
+      return (
+        (this.curSubject.stage == "LEVEL" &&
+          this.totalProgress.progress === 100) ||
+        (this.curSubject.stage == "SCORE" && !this.curSubject.allLevel)
+      );
+    },
+    showPaperRelateCount() {
+      return this.IS_ADMIN || !!this.paramsSet["showPaperCount"];
+    },
+    IS_ADMIN() {
+      return (
+        this.curUserRoleType === "ADMIN" ||
+        this.curUserRoleType === "SUPER_ADMIN"
+      );
+    },
+    IS_MARK_LEADER() {
+      return this.curUserRoleType === "MARK_LEADER";
+    },
+    IS_LEVEL() {
+      return this.curSubject.stage === "LEVEL";
+    },
+    IS_SCORE() {
+      return this.curSubject.stage === "SCORE";
+    },
+  },
+  mounted() {
+    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
+    this.initData();
+  },
+  methods: {
+    async initData() {
+      await this.getSubjectDetail();
+      this.getParamsSetInfo();
+      this.getProgressDetail();
+    },
+    async getParamsSetInfo() {
+      this.paramsSet = await getParamsSet(this.workId);
+    },
+    async getProgressDetail() {
+      const data = await gradingProgressDetail({
+        workId: this.curSubject.workId,
+        subject: this.curSubject.subject,
+      });
+      this.kzzInfo = data.kzz || {};
+      this.totalProgress = data.totalProgress;
+      const totalInfo = {
+        successCount: data.totalProgress.successCount,
+        totalCount: data.totalProgress.totalCount,
+        progress: data.totalProgress.progress.toFixed(2),
+        areaName: "总体进度",
+      };
+      if (this.curSubject.stage === "INIT") {
+        this.areaProgress = [totalInfo];
+        this.markerProgress = [];
+      } else {
+        this.areaProgress = [totalInfo, ...this.addProgress(data.areaProgress)];
+        this.markerProgress = this.addProgress(data.markerProgress);
+      }
+      this.$parent.setProgress &&
+        this.$parent.setProgress(data.totalProgress.progress);
+    },
+    addProgress(data) {
+      return data.map((item) => {
+        item.successCount = item.totalCount - item.leftCount;
+        item.progress = item.totalCount
+          ? ((100 * item.successCount) / item.totalCount).toFixed(2)
+          : "0.00";
+        return item;
+      });
+    },
+    async getSubjectDetail() {
+      this.curSubject = await subjectDetail(this.subjectId);
+    },
+    toCleanData() {
+      this.$refs.CleanGradingDataDialog.open();
+    },
+    toGrading() {
+      this.$refs.ModifyFormalGradingTask.open();
+    },
+    toTryGrading() {
+      this.$refs.ModifyUnformalGradingTask.open();
+    },
+    toMark() {
+      this.$Modal.confirm({
+        content: "确定要进入打分阶段吗?",
+        onOk: async () => {
+          await gotoScoreStep(this.subjectId);
+          this.$router.replace({
+            name: "Mark",
+            params: {
+              workId: this.curSubject.workId,
+              subjectId: this.subjectId,
+            },
+          });
+        },
+      });
+    },
+    taskSubmitSuccess() {
+      this.$parent.initData();
+      this.initData();
+    },
+    toExportStandard() {
+      window.open(
+        this.urlAddAuthor(
+          `${this.GLOBAL.domain}/api/export/paper/${this.curSubject.workId}/${this.curSubject.subject}/sample`
+        )
+      );
+    },
+    toExportGrading() {
+      window.open(
+        this.urlAddAuthor(
+          `${this.GLOBAL.domain}/api/export/paper/${this.curSubject.workId}/${this.curSubject.subject}/oneClick`
+        )
+      );
+    },
+    toExportChangeLevel() {
+      window.open(
+        this.urlAddAuthor(
+          `${this.GLOBAL.domain}/api/export/paper/${this.curSubject.workId}/${this.curSubject.subject}/changeLevel`
+        )
+      );
+    },
+  },
+};
+</script>

+ 19 - 17
src/modules/grading/GradingStandardPaperManage.vue

@@ -107,8 +107,8 @@
             'level-item',
             {
               'level-item-act': level === curSelectLevel,
-              'level-item-disabled': level === curChangePaper.level
-            }
+              'level-item-disabled': level === curChangePaper.level,
+            },
           ]"
           @click="selectLevel(level)"
         >
@@ -136,7 +136,7 @@ import {
   sampleAreaList,
   workLevelList,
   cancelStandardPaper,
-  leaderGradingPaper
+  leaderGradingPaper,
 } from "@/api";
 import SimpleImagePreview from "@/components/SimpleImagePreview";
 
@@ -163,7 +163,7 @@ export default {
       modalIsShow: false,
       curChangePaper: {},
       curSelectLevel: null,
-      isSubmit: false
+      isSubmit: false,
     };
   },
   mounted() {
@@ -180,18 +180,18 @@ export default {
     },
     async getWorkLevels() {
       const data = await workLevelList(this.workId);
-      this.levels = data.map(item => item.code);
+      this.levels = data.map((item) => item.code);
     },
     async getAreaList() {
       const data = await sampleAreaList({
         workId: this.workId,
-        subject: this.subject
+        subject: this.subject,
       });
-      this.areas = data.map(item => {
+      this.areas = data.map((item) => {
         return {
           id: item.id,
           areaName: `${item.areaName}-${item.name}`,
-          areaCode: item.areaCode
+          areaCode: item.areaCode,
         };
       });
     },
@@ -203,7 +203,7 @@ export default {
     updatePapers() {
       if (this.curLevel) {
         this.papers = this.paperList.filter(
-          paper => paper.level === this.curLevel
+          (paper) => paper.level === this.curLevel
         );
       } else {
         this.papers = this.paperList;
@@ -216,10 +216,10 @@ export default {
         sort: "secretNumber",
         isSample: true,
         page: 0,
-        size: 100
+        size: 100,
       };
       const data = await paperList(datas);
-      this.paperList = data.data.map(item => {
+      this.paperList = data.data.map((item) => {
         item.title = `NO.${item.sn}`;
         item.loading = false;
         return item;
@@ -248,10 +248,12 @@ export default {
           if (!res) return;
 
           this.paperList = this.paperList.filter(
-            item => paper.level !== item.level
+            (item) => paper.level !== item.level
           );
-          this.papers = this.papers.filter(item => paper.level !== item.level);
-        }
+          this.papers = this.papers.filter(
+            (item) => paper.level !== item.level
+          );
+        },
       });
     },
     // change standard paper
@@ -272,7 +274,7 @@ export default {
         action: "sampling",
         level: this.curSelectLevel,
         originLevel: this.curChangePaper.level,
-        paperIds: this.curChangePaper.id
+        paperIds: this.curChangePaper.id,
       };
       let result = true;
       await leaderGradingPaper(datas).catch(() => {
@@ -346,7 +348,7 @@ export default {
       }
 
       this.selectPaper(this.curPaperIndex);
-    }
-  }
+    },
+  },
 };
 </script>

+ 30 - 30
src/modules/grading/GradingUserManage.vue

@@ -42,7 +42,7 @@ import {
   deleteGradingUser,
   resetPwd,
   subjectDetail,
-  enableGradingUser
+  enableGradingUser,
 } from "@/api";
 import ModifyGradingUser from "./components/ModifyGradingUser";
 import { ROLE_TYPE, MARKER_RIGHT_TYPE } from "@/constants/enumerate";
@@ -63,31 +63,31 @@ export default {
           type: "index",
           title: "序号",
           width: 80,
-          align: "center"
+          align: "center",
         },
         {
           title: "科目",
-          key: "subject"
+          key: "subject",
         },
         {
           title: "账号",
-          key: "loginName"
+          key: "loginName",
         },
         {
           title: "姓名",
-          key: "name"
+          key: "name",
         },
         {
           title: "角色",
-          key: "roleName"
+          key: "roleName",
         },
         {
           title: "权限",
-          key: "rightName"
+          key: "rightName",
         },
         {
           title: "权重",
-          key: "weight"
+          key: "weight",
         },
         {
           title: "启用/禁用",
@@ -103,10 +103,10 @@ export default {
               on: {
                 click: () => {
                   this.toEnable(param.row);
-                }
-              }
+                },
+              },
             });
-          }
+          },
         },
         {
           title: "操作",
@@ -119,38 +119,38 @@ export default {
               {
                 icon: "md-settings",
                 attrs: {
-                  title: "重置密码"
+                  title: "重置密码",
                 },
                 action: () => {
                   this.toResetPwd(param.row);
-                }
+                },
               },
               {
                 icon: "md-create",
                 attrs: {
-                  title: "编辑"
+                  title: "编辑",
                 },
                 action: () => {
                   this.toEdit(param.row);
-                }
-              }
+                },
+              },
             ];
             if (param.row.role !== "MARK_LEADER") {
               actions.push({
                 icon: "md-trash",
                 classes: ["icon-danger"],
                 attrs: {
-                  title: "删除"
+                  title: "删除",
                 },
                 action: () => {
                   this.toDelete(param.row);
-                }
+                },
               });
             }
             return h("div", this.$tableIconAction(h, actions));
-          }
-        }
-      ]
+          },
+        },
+      ],
     };
   },
   mounted() {
@@ -162,10 +162,10 @@ export default {
     async getList() {
       const datas = {
         workId: this.workId,
-        subject: this.subject
+        subject: this.subject,
       };
       const data = await gradingUserList(datas);
-      this.users = data.map(item => {
+      this.users = data.map((item) => {
         item.roleName = ROLE_TYPE[item.role];
         item.rightName =
           item.role === "MARK_LEADER"
@@ -178,10 +178,10 @@ export default {
       const roles = {
         oneClickLevel: "一键定档",
         standardVolume: "设立标准卷",
-        levelCallback: "打回"
+        levelCallback: "打回",
       };
       let roleNames = [];
-      Object.keys(roles).map(k => {
+      Object.keys(roles).map((k) => {
         if (item[k]) roleNames.push(roles[k]);
       });
       return roleNames.join(",");
@@ -189,7 +189,7 @@ export default {
     async toEnable(row) {
       await enableGradingUser({
         userId: row.id,
-        enable: !row.enabled
+        enable: !row.enabled,
       });
       row.enabled = !row.enabled;
     },
@@ -203,7 +203,7 @@ export default {
     toAdd() {
       this.curUser = {
         workId: this.workId,
-        subject: this.subject
+        subject: this.subject,
       };
       this.$refs.ModifyGradingUser.open();
     },
@@ -216,7 +216,7 @@ export default {
         content: "确定要删除当前账号吗?",
         onOk: () => {
           this.toDel(row.id);
-        }
+        },
       });
     },
     async toDel(id) {
@@ -230,7 +230,7 @@ export default {
           `${this.GLOBAL.domain}/api/export/users?workId=${this.workId}&subject=${this.subject}`
         )
       );
-    }
-  }
+    },
+  },
 };
 </script>

+ 7 - 7
src/modules/grading/components/CleanGradingDataDialog.vue

@@ -42,8 +42,8 @@ export default {
       type: Object,
       default() {
         return {};
-      }
-    }
+      },
+    },
   },
   data() {
     return {
@@ -51,8 +51,8 @@ export default {
       isSubmit: false,
       modalForm: { password: "" },
       rules: {
-        password
-      }
+        password,
+      },
     };
   },
   methods: {
@@ -80,7 +80,7 @@ export default {
         subject: this.curSubject.subject,
         stage: this.curSubject.stage,
         loginName: this.$ls.get("user", { loginName: "" }).loginName,
-        password: this.modalForm.password
+        password: this.modalForm.password,
       }).catch(() => {
         result = false;
       });
@@ -91,7 +91,7 @@ export default {
       this.$Modal.success({ content: "操作成功!" });
       this.$emit("modified");
       this.cancel();
-    }
-  }
+    },
+  },
 };
 </script>

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

@@ -1,438 +1,438 @@
-<template>
-  <div class="grade-action">
-    <!-- 头部信息 ------ -->
-    <!-- 试卷状态 -->
-    <!-- 状态:已评,待评,打回,仲裁 -->
-    <div class="action-paper-state" v-if="stepType === 'reject'">
-      <p class="paper-state-cont">
-        {{ curPaperOrTask.isRejectedByLeader ? "科组长打回" : "自动打回" }}
-      </p>
-      <p class="paper-state-intro">
-        <span v-if="curPaperOrTask.rejectedCount"
-          >共打回{{ curPaperOrTask.rejectedCount }}次</span
-        >
-      </p>
-    </div>
-    <div class="action-paper-state" v-else>
-      <p class="paper-state-cont">{{ stepLabel }}</p>
-    </div>
-    <!-- 试卷信息 -->
-    <div class="action-paper-info">
-      <p v-if="IS_ADMIN">
-        <span>试卷考号:</span><span>{{ curPaperOrTask.examNumber }}</span>
-      </p>
-      <p>
-        <span v-if="IS_MARKER">任务密号:</span>
-        <span v-else>试卷密号:</span>
-        <span>NO.{{ curPaperOrTask.sn }}</span>
-      </p>
-    </div>
-
-    <!-- 选择档位 -->
-    <h3
-      class="action-grade-info-title"
-      v-if="IS_MARK_LEADER && markLeaderOnlyRight && rights.gradeList"
-    >
-      当前操作:{{ markLeaderOnlyRight.name }}
-    </h3>
-    <div class="action-grade-list" v-if="rights.gradeList">
-      <div
-        class="action-grade-item"
-        v-for="(level, index) in levels"
-        :key="index"
-      >
-        <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>
-      </div>
-    </div>
-    <!-- 档位信息 -->
-    <!-- 已评(已评档位),打回(建议档位) -->
-    <h3
-      class="action-grade-info-title"
-      v-if="IS_MARKER && stepType === 'reject'"
-    >
-      <span>原分档档位:{{ curPaperOrTask.originLevel || "" }}</span>
-      <span
-        v-if="
-          paramsSet.autoCallbackShowDeviation &&
-            curPaperOrTask.deviationDirection &&
-            curPaperOrTask.deviationDirection !== '0'
-        "
-        :class="[
-          'grade-info-deviation',
-          {
-            'grade-info-deviation-error':
-              curPaperOrTask.deviationDirection * 1 > 0
-          }
-        ]"
-        >{{ curPaperOrTask.deviationDirection * 1 > 0 ? "偏高" : "偏低" }}</span
-      >
-    </h3>
-    <h3 class="action-grade-info-title">
-      <span v-if="curPaperOrTask.rejected && curPaperOrTask.isRejectedByLeader"
-        >建议档位:</span
-      >
-      <span v-if="stepType === 'done' || stepType === 'sample'"
-        >已评档位:</span
-      >
-    </h3>
-    <div class="action-grade-info" v-if="rights.gradeInfo && curLevel.name">
-      <h3 class="grade-info-name">{{ curLevel.name }}</h3>
-      <div class="grade-info-range">
-        <p>分数范围</p>
-        <p>
-          <span>{{ curLevel.minScore }}</span>
-          <span>~</span>
-          <span>{{ curLevel.maxScore }}</span>
-        </p>
-      </div>
-    </div>
-    <!-- 跳过 -->
-    <div
-      class="action-grade-pass"
-      v-if="rights.gradePass && IS_MARKER"
-      @click="toPass"
-    >
-      跳过
-    </div>
-
-    <!-- 评卷记录 -->
-    <div class="action-grade-history" v-if="rights.gradeHis">
-      <h3>评卷记录:</h3>
-      <div class="grade-history-list">
-        <div
-          class="grade-history-item"
-          v-for="his in gradingHistory"
-          :key="his.id"
-        >
-          <p>{{ his.loginName }}</p>
-          <p>{{ his.value }}</p>
-        </div>
-      </div>
-    </div>
-
-    <!-- 查询 -->
-    <div class="action-search" v-if="rights.search">
-      <Select
-        class="search-select"
-        v-model="filter.codeType"
-        placeholder="密号类型"
-      >
-        <Option
-          v-for="item in codeTypes"
-          :key="item.key"
-          :value="item.key"
-          :label="item.val"
-        ></Option>
-      </Select>
-      <Input
-        class="search-input"
-        v-model.trim="filter.code"
-        placeholder="输入密号"
-        clearable
-      >
-      </Input>
-      <Button size="small" type="primary" class="search-btn" @click="searchCode"
-        >查询</Button
-      >
-    </div>
-  </div>
-</template>
-
-<script>
-import { markHistoryList } from "@/api";
-import { CODE_TYPE } from "@/constants/enumerate";
-// 三种情况:
-// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
-// 管理员:查询,头部信息,评卷记录
-// 科组长:查询,头部信息,选择档位,评卷记录
-// 评卷员:头部信息,选择档位
-
-// MARK_LEADER / ADMIN: curPaperOrTask => paper
-// MARKER: curPaperOrTask => task
-//
-/*
-[paper template]
-{
-  "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
-}
-[marktask template]
-{
-  "id": 511,
-  "sn": "4929446110",
-  "redoLevel": null,
-  "level": "A",
-  "score": null,
-  "result": "100",
-  "originLevel": null,
-  "markerId": 49,
-  "marker": "pj061001",
-  "updatedOn": 1594775592000,
-  "imgSrc": "",
-  "thumbSrc": "",
-  "markByLeader": true,
-  "oldRejected": false,
-  "paperId": 168,
-  "randomSeqNew": 9446110,
-  "randomSeq": null,
-  "rejected": false,
-  "sample": true
-}
-*/
-
-const initRights = {
-  search: false,
-  gradeInfo: false,
-  gradeList: false,
-  gradePass: false,
-  gradeHis: false
-};
-
-export default {
-  name: "grade-action",
-  props: {
-    curPaperOrTask: {
-      type: Object,
-      default() {
-        return {};
-      }
-    },
-    levels: {
-      type: Array,
-      default() {
-        return [];
-      }
-    },
-    paramsSet: {
-      type: Object,
-      default() {
-        return {};
-      }
-    }
-  },
-  data() {
-    return {
-      curUserRoleType: this.$ls.get("user", { role: "" }).role,
-      rights: {
-        ...initRights
-      },
-      roleRight: {
-        SUPER_ADMIN: {
-          done: ["search", "gradeHis", "gradeInfo"],
-          reject: ["search", "gradeInfo", "gradeHis"],
-          arbitrate: ["search", "gradeHis"]
-        },
-        ADMIN: {
-          done: ["search", "gradeHis", "gradeInfo"],
-          reject: ["search", "gradeInfo", "gradeHis"],
-          arbitrate: ["search", "gradeHis"]
-        },
-        MARK_LEADER: {
-          undo: ["gradeList", "gradePass", "gradeInfo"],
-          done: ["gradeList", "gradeHis", "gradeInfo"],
-          reject: ["gradeList", "gradePass", "gradeInfo", "gradeHis"],
-          arbitrate: ["gradeList", "gradePass", "gradeHis"]
-        },
-        MARKER: {
-          done: ["gradeList", "gradeInfo"],
-          undo: ["gradeList", "gradePass"],
-          reject: ["gradeList", "gradePass", "gradeInfo"]
-        },
-        STANDARD: ["gradeInfo"]
-      },
-      filter: {
-        codeType: "examNumber",
-        code: ""
-      },
-      codeTypes: [],
-      stepDict: {
-        undo: "待评",
-        done: "已评",
-        reject: "打回",
-        arbitrate: "待仲裁",
-        sample: "标准卷"
-      },
-      stepType: "",
-      stepLabel: "",
-      gradingHistory: [],
-      curLevel: {},
-      setT: null,
-      btnClicked: false,
-      // 科组长权限
-      markLeaderOnlyRight: null,
-      leaderConfirm: true
-    };
-  },
-  computed: {
-    IS_ADMIN() {
-      return (
-        this.curUserRoleType === "ADMIN" ||
-        this.curUserRoleType === "SUPER_ADMIN"
-      );
-    },
-    IS_MARKER() {
-      return this.curUserRoleType === "MARKER";
-    },
-    IS_MARK_LEADER() {
-      return this.curUserRoleType === "MARK_LEADER";
-    }
-  },
-  watch: {
-    curPaperOrTask(val) {
-      this.rebuildRight();
-    }
-  },
-  mounted() {
-    const userRight = this.$ls.get("user", {
-      markLeaderOnlyRight: null,
-      leaderConfirm: true
-    });
-    this.markLeaderOnlyRight = userRight.markLeaderOnlyRight;
-    this.leaderConfirm = userRight.leaderConfirm;
-
-    this.codeTypes = Object.entries(CODE_TYPE)
-      .map(([key, val]) => {
-        return {
-          key,
-          val
-        };
-      })
-      .filter(item => this.IS_ADMIN || item.key !== "examNumber");
-    this.rebuildRight();
-  },
-  methods: {
-    getStepType() {
-      const info = this.curPaperOrTask;
-      if (info.sample) return "sample";
-      if (info.level) return "done";
-      if (info.arbitrated) return "arbitrate";
-      if (info.rejected) return "reject";
-      if (!info.rejected && !info.arbitrated && !info.level) return "undo";
-      return;
-    },
-    rebuildRight() {
-      let roleRights = [];
-      this.stepType = this.getStepType();
-      this.stepLabel = this.stepDict[this.stepType];
-      if (this.stepType === "sample") {
-        roleRights = this.roleRight.STANDARD;
-      } else {
-        roleRights = this.roleRight[this.curUserRoleType][this.stepType] || [];
-      }
-      this.rights = { ...initRights };
-      roleRights.map(key => {
-        this.rights[key] = true;
-      });
-      this.getCurLevel();
-      if (this.rights.gradeHis) {
-        this.getMarkHistory();
-      }
-      this.btnClicked = false;
-    },
-    getCurLevel() {
-      const levelName = this.curPaperOrTask.rejected
-        ? this.curPaperOrTask.redoLevel
-        : this.curPaperOrTask.level;
-      if (levelName) {
-        this.curLevel = this.levels.find(item => item.name === levelName);
-      } else {
-        this.curLevel = {};
-      }
-    },
-    async getMarkHistory() {
-      // 只有科组长和超管才会展示评卷记录
-      const data = await markHistoryList(this.curPaperOrTask.id, "LEVEL");
-      this.gradingHistory = data.map(item => {
-        let level = item.result || "未评";
-        if (this.stepType === "reject" && !item.result) {
-          level = `${level}(${item.originLevel})`;
-        }
-        return {
-          id: item.id,
-          markerId: item.markerId,
-          name: item.marker,
-          loginName: item.loginName,
-          value: level
-        };
-      });
-    },
-    selectLevel(level) {
-      if (this.IS_MARKER && this.curPaperOrTask.level === level.name) return;
-      if (this.btnClicked) return;
-      this.btnClicked = true;
-
-      this.setT = setTimeout(() => {
-        this.btnClicked = false;
-      }, 500);
-
-      if (this.IS_MARK_LEADER) {
-        this.$emit(
-          "on-leader-level",
-          {
-            paperIds: this.curPaperOrTask.id + "",
-            curLevel: this.curPaperOrTask.level,
-            selectedLevel: level.name,
-            markLeaderOnlyRight: this.markLeaderOnlyRight,
-            leaderConfirm: this.leaderConfirm
-          },
-          this.gradingHistory.map(item => {
-            return {
-              id: item.markerId,
-              name: item.loginName
-            };
-          })
-        );
-        return;
-      }
-
-      this.$emit("on-select-level", level);
-    },
-    toPass() {
-      this.$emit("on-pass");
-    },
-    searchCode() {
-      if (!this.filter.code || !this.filter.codeType) {
-        this.$Message.error("请设置密号类型和密号!");
-        return;
-      }
-      this.$emit("on-code-search", this.filter);
-    }
-  },
-  beforeDestroy() {
-    if (this.setT) clearTimeout(this.setT);
-  }
-};
-</script>
+<template>
+  <div class="grade-action">
+    <!-- 头部信息 ------ -->
+    <!-- 试卷状态 -->
+    <!-- 状态:已评,待评,打回,仲裁 -->
+    <div class="action-paper-state" v-if="stepType === 'reject'">
+      <p class="paper-state-cont">
+        {{ curPaperOrTask.isRejectedByLeader ? "科组长打回" : "自动打回" }}
+      </p>
+      <p class="paper-state-intro">
+        <span v-if="curPaperOrTask.rejectedCount"
+          >共打回{{ curPaperOrTask.rejectedCount }}次</span
+        >
+      </p>
+    </div>
+    <div class="action-paper-state" v-else>
+      <p class="paper-state-cont">{{ stepLabel }}</p>
+    </div>
+    <!-- 试卷信息 -->
+    <div class="action-paper-info">
+      <p v-if="IS_ADMIN">
+        <span>试卷考号:</span><span>{{ curPaperOrTask.examNumber }}</span>
+      </p>
+      <p>
+        <span v-if="IS_MARKER">任务密号:</span>
+        <span v-else>试卷密号:</span>
+        <span>NO.{{ curPaperOrTask.sn }}</span>
+      </p>
+    </div>
+
+    <!-- 选择档位 -->
+    <h3
+      class="action-grade-info-title"
+      v-if="IS_MARK_LEADER && markLeaderOnlyRight && rights.gradeList"
+    >
+      当前操作:{{ markLeaderOnlyRight.name }}
+    </h3>
+    <div class="action-grade-list" v-if="rights.gradeList">
+      <div
+        class="action-grade-item"
+        v-for="(level, index) in levels"
+        :key="index"
+      >
+        <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>
+      </div>
+    </div>
+    <!-- 档位信息 -->
+    <!-- 已评(已评档位),打回(建议档位) -->
+    <h3
+      class="action-grade-info-title"
+      v-if="IS_MARKER && stepType === 'reject'"
+    >
+      <span>原分档档位:{{ curPaperOrTask.originLevel || "" }}</span>
+      <span
+        v-if="
+          paramsSet.autoCallbackShowDeviation &&
+          curPaperOrTask.deviationDirection &&
+          curPaperOrTask.deviationDirection !== '0'
+        "
+        :class="[
+          'grade-info-deviation',
+          {
+            'grade-info-deviation-error':
+              curPaperOrTask.deviationDirection * 1 > 0,
+          },
+        ]"
+        >{{ curPaperOrTask.deviationDirection * 1 > 0 ? "偏高" : "偏低" }}</span
+      >
+    </h3>
+    <h3 class="action-grade-info-title">
+      <span v-if="curPaperOrTask.rejected && curPaperOrTask.isRejectedByLeader"
+        >建议档位:</span
+      >
+      <span v-if="stepType === 'done' || stepType === 'sample'"
+        >已评档位:</span
+      >
+    </h3>
+    <div class="action-grade-info" v-if="rights.gradeInfo && curLevel.name">
+      <h3 class="grade-info-name">{{ curLevel.name }}</h3>
+      <div class="grade-info-range">
+        <p>分数范围</p>
+        <p>
+          <span>{{ curLevel.minScore }}</span>
+          <span>~</span>
+          <span>{{ curLevel.maxScore }}</span>
+        </p>
+      </div>
+    </div>
+    <!-- 跳过 -->
+    <div
+      class="action-grade-pass"
+      v-if="rights.gradePass && IS_MARKER"
+      @click="toPass"
+    >
+      跳过
+    </div>
+
+    <!-- 评卷记录 -->
+    <div class="action-grade-history" v-if="rights.gradeHis">
+      <h3>评卷记录:</h3>
+      <div class="grade-history-list">
+        <div
+          class="grade-history-item"
+          v-for="his in gradingHistory"
+          :key="his.id"
+        >
+          <p>{{ his.loginName }}</p>
+          <p>{{ his.value }}</p>
+        </div>
+      </div>
+    </div>
+
+    <!-- 查询 -->
+    <div class="action-search" v-if="rights.search">
+      <Select
+        class="search-select"
+        v-model="filter.codeType"
+        placeholder="密号类型"
+      >
+        <Option
+          v-for="item in codeTypes"
+          :key="item.key"
+          :value="item.key"
+          :label="item.val"
+        ></Option>
+      </Select>
+      <Input
+        class="search-input"
+        v-model.trim="filter.code"
+        placeholder="输入密号"
+        clearable
+      >
+      </Input>
+      <Button size="small" type="primary" class="search-btn" @click="searchCode"
+        >查询</Button
+      >
+    </div>
+  </div>
+</template>
+
+<script>
+import { markHistoryList } from "@/api";
+import { CODE_TYPE } from "@/constants/enumerate";
+// 三种情况:
+// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
+// 管理员:查询,头部信息,评卷记录
+// 科组长:查询,头部信息,选择档位,评卷记录
+// 评卷员:头部信息,选择档位
+
+// MARK_LEADER / ADMIN: curPaperOrTask => paper
+// MARKER: curPaperOrTask => task
+//
+/*
+[paper template]
+{
+  "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
+}
+[marktask template]
+{
+  "id": 511,
+  "sn": "4929446110",
+  "redoLevel": null,
+  "level": "A",
+  "score": null,
+  "result": "100",
+  "originLevel": null,
+  "markerId": 49,
+  "marker": "pj061001",
+  "updatedOn": 1594775592000,
+  "imgSrc": "",
+  "thumbSrc": "",
+  "markByLeader": true,
+  "oldRejected": false,
+  "paperId": 168,
+  "randomSeqNew": 9446110,
+  "randomSeq": null,
+  "rejected": false,
+  "sample": true
+}
+*/
+
+const initRights = {
+  search: false,
+  gradeInfo: false,
+  gradeList: false,
+  gradePass: false,
+  gradeHis: false,
+};
+
+export default {
+  name: "grade-action",
+  props: {
+    curPaperOrTask: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    levels: {
+      type: Array,
+      default() {
+        return [];
+      },
+    },
+    paramsSet: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      curUserRoleType: this.$ls.get("user", { role: "" }).role,
+      rights: {
+        ...initRights,
+      },
+      roleRight: {
+        SUPER_ADMIN: {
+          done: ["search", "gradeHis", "gradeInfo"],
+          reject: ["search", "gradeInfo", "gradeHis"],
+          arbitrate: ["search", "gradeHis"],
+        },
+        ADMIN: {
+          done: ["search", "gradeHis", "gradeInfo"],
+          reject: ["search", "gradeInfo", "gradeHis"],
+          arbitrate: ["search", "gradeHis"],
+        },
+        MARK_LEADER: {
+          undo: ["gradeList", "gradePass", "gradeInfo"],
+          done: ["gradeList", "gradeHis", "gradeInfo"],
+          reject: ["gradeList", "gradePass", "gradeInfo", "gradeHis"],
+          arbitrate: ["gradeList", "gradePass", "gradeHis"],
+        },
+        MARKER: {
+          done: ["gradeList", "gradeInfo"],
+          undo: ["gradeList", "gradePass"],
+          reject: ["gradeList", "gradePass", "gradeInfo"],
+        },
+        STANDARD: ["gradeInfo"],
+      },
+      filter: {
+        codeType: "examNumber",
+        code: "",
+      },
+      codeTypes: [],
+      stepDict: {
+        undo: "待评",
+        done: "已评",
+        reject: "打回",
+        arbitrate: "待仲裁",
+        sample: "标准卷",
+      },
+      stepType: "",
+      stepLabel: "",
+      gradingHistory: [],
+      curLevel: {},
+      setT: null,
+      btnClicked: false,
+      // 科组长权限
+      markLeaderOnlyRight: null,
+      leaderConfirm: true,
+    };
+  },
+  computed: {
+    IS_ADMIN() {
+      return (
+        this.curUserRoleType === "ADMIN" ||
+        this.curUserRoleType === "SUPER_ADMIN"
+      );
+    },
+    IS_MARKER() {
+      return this.curUserRoleType === "MARKER";
+    },
+    IS_MARK_LEADER() {
+      return this.curUserRoleType === "MARK_LEADER";
+    },
+  },
+  watch: {
+    curPaperOrTask(val) {
+      this.rebuildRight();
+    },
+  },
+  mounted() {
+    const userRight = this.$ls.get("user", {
+      markLeaderOnlyRight: null,
+      leaderConfirm: true,
+    });
+    this.markLeaderOnlyRight = userRight.markLeaderOnlyRight;
+    this.leaderConfirm = userRight.leaderConfirm;
+
+    this.codeTypes = Object.entries(CODE_TYPE)
+      .map(([key, val]) => {
+        return {
+          key,
+          val,
+        };
+      })
+      .filter((item) => this.IS_ADMIN || item.key !== "examNumber");
+    this.rebuildRight();
+  },
+  methods: {
+    getStepType() {
+      const info = this.curPaperOrTask;
+      if (info.sample) return "sample";
+      if (info.level) return "done";
+      if (info.arbitrated) return "arbitrate";
+      if (info.rejected) return "reject";
+      if (!info.rejected && !info.arbitrated && !info.level) return "undo";
+      return;
+    },
+    rebuildRight() {
+      let roleRights = [];
+      this.stepType = this.getStepType();
+      this.stepLabel = this.stepDict[this.stepType];
+      if (this.stepType === "sample") {
+        roleRights = this.roleRight.STANDARD;
+      } else {
+        roleRights = this.roleRight[this.curUserRoleType][this.stepType] || [];
+      }
+      this.rights = { ...initRights };
+      roleRights.map((key) => {
+        this.rights[key] = true;
+      });
+      this.getCurLevel();
+      if (this.rights.gradeHis) {
+        this.getMarkHistory();
+      }
+      this.btnClicked = false;
+    },
+    getCurLevel() {
+      const levelName = this.curPaperOrTask.rejected
+        ? this.curPaperOrTask.redoLevel
+        : this.curPaperOrTask.level;
+      if (levelName) {
+        this.curLevel = this.levels.find((item) => item.name === levelName);
+      } else {
+        this.curLevel = {};
+      }
+    },
+    async getMarkHistory() {
+      // 只有科组长和超管才会展示评卷记录
+      const data = await markHistoryList(this.curPaperOrTask.id, "LEVEL");
+      this.gradingHistory = data.map((item) => {
+        let level = item.result || "未评";
+        if (this.stepType === "reject" && !item.result) {
+          level = `${level}(${item.originLevel})`;
+        }
+        return {
+          id: item.id,
+          markerId: item.markerId,
+          name: item.marker,
+          loginName: item.loginName,
+          value: level,
+        };
+      });
+    },
+    selectLevel(level) {
+      if (this.IS_MARKER && this.curPaperOrTask.level === level.name) return;
+      if (this.btnClicked) return;
+      this.btnClicked = true;
+
+      this.setT = setTimeout(() => {
+        this.btnClicked = false;
+      }, 500);
+
+      if (this.IS_MARK_LEADER) {
+        this.$emit(
+          "on-leader-level",
+          {
+            paperIds: this.curPaperOrTask.id + "",
+            curLevel: this.curPaperOrTask.level,
+            selectedLevel: level.name,
+            markLeaderOnlyRight: this.markLeaderOnlyRight,
+            leaderConfirm: this.leaderConfirm,
+          },
+          this.gradingHistory.map((item) => {
+            return {
+              id: item.markerId,
+              name: item.loginName,
+            };
+          })
+        );
+        return;
+      }
+
+      this.$emit("on-select-level", level);
+    },
+    toPass() {
+      this.$emit("on-pass");
+    },
+    searchCode() {
+      if (!this.filter.code || !this.filter.codeType) {
+        this.$Message.error("请设置密号类型和密号!");
+        return;
+      }
+      this.$emit("on-code-search", this.filter);
+    },
+  },
+  beforeDestroy() {
+    if (this.setT) clearTimeout(this.setT);
+  },
+};
+</script>

+ 22 - 22
src/modules/grading/components/GradeAnalysis.vue

@@ -28,16 +28,16 @@ export default {
   props: {
     questionId: {
       type: Number,
-      required: true
+      required: true,
     },
     subjectId: {
       type: String,
-      required: true
+      required: true,
     },
     showCount: {
       type: Boolean,
-      default: true
-    }
+      default: true,
+    },
   },
   data() {
     return {
@@ -46,59 +46,59 @@ export default {
       columns: [
         {
           title: "科目",
-          key: "subjectName"
+          key: "subjectName",
         },
         {
           title: "档位",
-          key: "code"
+          key: "code",
         },
         {
           title: "范围",
           render: (h, param) => {
             return h("div", `${param.row.minScore}~${param.row.maxScore}`);
-          }
+          },
         },
         {
           title: "数量",
-          key: "levelCount"
+          key: "levelCount",
         },
         {
           title: "占比",
           key: "levelProp",
           render: (h, param) => {
             return h("div", `${param.row.levelProp}%`);
-          }
+          },
         },
         {
           title: "预设占比",
           key: "examLevelProp",
           render: (h, param) => {
             return h("div", `${param.row.examLevelProp}%`);
-          }
+          },
         },
         {
           title: "差值",
           key: "diffProp",
           render: (h, param) => {
             return h("div", `${param.row.diffProp}%`);
-          }
+          },
         },
         {
           title: "累计数量",
-          key: "cumulateCount"
+          key: "cumulateCount",
         },
         {
           title: "累计占比",
           key: "cumulateProp",
           render: (h, param) => {
             return h("div", `${param.row.cumulateProp}%`);
-          }
+          },
         },
         {
           title: "调整",
-          key: "adjustmentCount"
-        }
-      ]
+          key: "adjustmentCount",
+        },
+      ],
     };
   },
   mounted() {
@@ -111,19 +111,19 @@ export default {
       this.levelData = await gradingStatData({
         questionId: this.questionId,
         workId: subs[0],
-        subject: subs[1]
+        subject: subs[1],
       });
-      this.levelData = this.levelData.map(item => {
+      this.levelData = this.levelData.map((item) => {
         item.levelCount = this.showCount ? item.levelCount : "";
         item.cumulateCount = this.showCount ? item.cumulateCount : "";
         item.adjustmentCount = this.showCount ? item.adjustmentCount : "";
         return item;
       });
 
-      this.lineChartData = this.levelData.map(item => {
+      this.lineChartData = this.levelData.map((item) => {
         return {
           name: item.code,
-          value: item.levelProp
+          value: item.levelProp,
         };
       });
     },
@@ -134,7 +134,7 @@ export default {
         return { rowspan: 0, colspan: 0 };
       }
     },
-    toExport() {}
-  }
+    toExport() {},
+  },
 };
 </script>

+ 11 - 13
src/modules/grading/components/GradeAnalysisExport.vue

@@ -1,9 +1,7 @@
 <template>
   <div class="grade-analysis-export analysis-export-modal">
     <div class="print-box">
-      <h1>
-        分档详情数据
-      </h1>
+      <h1>分档详情数据</h1>
       <div class="quality-info">
         <p>科目:{{ pageInfo.subjectName }}</p>
         <p>考区:{{ pageInfo.areaName }}</p>
@@ -68,25 +66,25 @@ export default {
       type: Object,
       default() {
         return {};
-      }
+      },
     },
     pageInfo: {
       type: Object,
       default() {
         return {};
-      }
-    }
+      },
+    },
   },
   data() {
     return {
       currentTime: formatDate(),
-      showImg: false
+      showImg: false,
     };
   },
   mounted() {
     this.$nextTick(() => {
       this.$refs.lineChartImg.src = this.$refs.lineChart.getDataURL({
-        backgroundColor: "#fff"
+        backgroundColor: "#fff",
       });
 
       this.showImg = true;
@@ -98,7 +96,7 @@ export default {
   methods: {
     async toExport() {
       const canvas = await html2canvas(this.$el.childNodes[0], {
-        allowTaint: true
+        allowTaint: true,
       }).catch(() => {});
 
       if (!canvas) {
@@ -113,15 +111,15 @@ export default {
         url: `${this.GLOBAL.domain}/api/exportPdf`,
         header: { Authorization: user.token, userId: user.id },
         data: {
-          content: [canvas.toDataURL().split(",")[1]]
+          content: [canvas.toDataURL().split(",")[1]],
         },
-        fileName: `${this.pageInfo.subjectName}-${this.pageInfo.areaName}-分档详情分析.pdf`
+        fileName: `${this.pageInfo.subjectName}-${this.pageInfo.areaName}-分档详情分析.pdf`,
       }).catch(() => {
         result = false;
       });
 
       this.$emit("on-exported", result);
-    }
-  }
+    },
+  },
 };
 </script>

+ 10 - 10
src/modules/grading/components/GradeFilter.vue

@@ -44,17 +44,17 @@ export default {
       default() {
         return {
           workId: "",
-          subject: ""
+          subject: "",
         };
-      }
-    }
+      },
+    },
   },
   data() {
     return {
       questionId: "",
       areas: [],
       curArea: {},
-      selectIsShow: false
+      selectIsShow: false,
     };
   },
   mounted() {
@@ -64,13 +64,13 @@ export default {
     async getAreaList() {
       const data = await areaList({
         workId: this.data.workId,
-        subject: this.data.subject
+        subject: this.data.subject,
       });
-      this.areas = data.map(item => {
+      this.areas = data.map((item) => {
         return {
           id: item.id,
           areaName: item.areaName,
-          areaCode: item.areaCode
+          areaCode: item.areaCode,
         };
       });
 
@@ -81,14 +81,14 @@ export default {
       }
     },
     confrim() {
-      const curArea = this.areas.find(item => item.id === this.questionId);
+      const curArea = this.areas.find((item) => item.id === this.questionId);
       this.curArea = curArea;
       this.selectIsShow = false;
       this.$emit("change", this.curArea);
     },
     cancel() {
       this.selectIsShow = false;
-    }
-  }
+    },
+  },
 };
 </script>

+ 12 - 12
src/modules/grading/components/GradeHistoryPaper.vue

@@ -29,12 +29,12 @@ export default {
   components: { PaperCarousel },
   props: {
     questionId: {
-      type: Number
+      type: Number,
     },
     stage: {
       type: String,
-      default: "LEVEL"
-    }
+      default: "LEVEL",
+    },
   },
   data() {
     return {
@@ -44,7 +44,7 @@ export default {
       userId: "",
       curPaper: {},
       papers: [],
-      IS_MARK_LEADER: false
+      IS_MARK_LEADER: false,
     };
   },
   computed: {
@@ -53,13 +53,13 @@ export default {
         return this.curPaper.level ? `一键定档  ${this.curPaper.level}` : "";
       return this.curPaper.result ? `已评  ${this.curPaper.result}` : "";
       // return this.curPaper.sn ? `NO.${this.curPaper.sn}` : "";
-    }
+    },
   },
   watch: {
     questionId(val) {
       this.papers = [];
       this.updatePapers();
-    }
+    },
   },
   mounted() {
     this.userId = this.$ls.get("user", { id: "" }).id;
@@ -77,7 +77,7 @@ export default {
         const datas = {
           workId: this.workId,
           subject: this.subject,
-          questionId: this.questionId
+          questionId: this.questionId,
         };
 
         data = await actionLeaderHistory(datas);
@@ -85,7 +85,7 @@ export default {
         const datas = {
           markerId: this.userId,
           stage: this.stage,
-          questionId: this.questionId
+          questionId: this.questionId,
         };
 
         data = await actionHistory(datas);
@@ -98,9 +98,9 @@ export default {
       });
     },
     updateCachePapers(papers) {
-      papers.forEach(paper => {
+      papers.forEach((paper) => {
         const paperIndex = this.papers.findIndex(
-          item => item.paperId === paper.paperId
+          (item) => item.paperId === paper.paperId
         );
         if (paperIndex !== -1) {
           this.papers.splice(paperIndex, 1);
@@ -118,7 +118,7 @@ export default {
     },
     paperClick(paperIndex, papers) {
       this.$emit("on-paper-click", paperIndex, papers);
-    }
-  }
+    },
+  },
 };
 </script>

+ 4 - 6
src/modules/grading/components/GradeImageList.vue

@@ -1,7 +1,5 @@
 <template>
-  <div class="grade-image-list">
-    grade-image-list
-  </div>
+  <div class="grade-image-list">grade-image-list</div>
 </template>
 
 <script>
@@ -11,13 +9,13 @@ export default {
     return {
       filter: {
         workId: this.$route.params.workId,
-        subjectId: this.$route.params.subjectId
+        subjectId: this.$route.params.subjectId,
       },
       current: 1,
       size: 6,
-      total: 0
+      total: 0,
     };
   },
-  methods: {}
+  methods: {},
 };
 </script>

+ 34 - 34
src/modules/grading/components/GradeRibbon.vue

@@ -1,34 +1,34 @@
-<template>
-  <div class="grade-ribbon">
-    <div class="ribbon-list">
-      <div class="ribbon-item" title="设置" @click="toSet">
-        <Icon type="md-settings" />
-      </div>
-    </div>
-
-    <!-- RibbonSetDialog -->
-    <ribbon-set-dialog ref="RibbonSetDialog"></ribbon-set-dialog>
-  </div>
-</template>
-
-<script>
-import RibbonSetDialog from "./RibbonSetDialog";
-
-export default {
-  name: "grade-ribbon",
-  components: {
-    RibbonSetDialog
-  },
-  data() {
-    return {};
-  },
-  methods: {
-    toNotice() {
-      this.$refs.NoticeDialog.open();
-    },
-    toSet() {
-      this.$refs.RibbonSetDialog.open();
-    }
-  }
-};
-</script>
+<template>
+  <div class="grade-ribbon">
+    <div class="ribbon-list">
+      <div class="ribbon-item" title="设置" @click="toSet">
+        <Icon type="md-settings" />
+      </div>
+    </div>
+
+    <!-- RibbonSetDialog -->
+    <ribbon-set-dialog ref="RibbonSetDialog"></ribbon-set-dialog>
+  </div>
+</template>
+
+<script>
+import RibbonSetDialog from "./RibbonSetDialog";
+
+export default {
+  name: "grade-ribbon",
+  components: {
+    RibbonSetDialog,
+  },
+  data() {
+    return {};
+  },
+  methods: {
+    toNotice() {
+      this.$refs.NoticeDialog.open();
+    },
+    toSet() {
+      this.$refs.RibbonSetDialog.open();
+    },
+  },
+};
+</script>

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

@@ -34,14 +34,14 @@ export default {
   components: { PaperCarousel },
   props: {
     questionId: {
-      type: Number
+      type: Number,
     },
     levels: {
       type: Array,
       default() {
         return [];
-      }
-    }
+      },
+    },
   },
   data() {
     return {
@@ -49,7 +49,7 @@ export default {
       curLevelIndex: 0,
       papers: [],
       paperMap: {},
-      isLoading: false
+      isLoading: false,
     };
   },
   computed: {
@@ -61,14 +61,14 @@ export default {
     },
     lastLevelIndex() {
       return this.levels.length ? this.levels.length - 1 : 0;
-    }
+    },
   },
   watch: {
     questionId(val) {
       this.paperMap = {};
       this.papers = [];
       this.updatePapers();
-    }
+    },
   },
   mounted() {
     this.setCurLevel(this.curLevelIndex);
@@ -80,7 +80,7 @@ export default {
     },
     curLevelChange() {
       this.curLevelIndex = this.levels.findIndex(
-        item => item.name === this.curLevel
+        (item) => item.name === this.curLevel
       );
       this.updatePapers();
     },
@@ -100,7 +100,7 @@ export default {
         sort: "secretNumber",
         isSample: true,
         page: 0,
-        size: 100
+        size: 100,
       };
       const data = await paperList(datas).catch(() => {});
       this.isLoading = false;
@@ -115,7 +115,7 @@ export default {
         sort: "secretNumber",
         isSample: true,
         page: 0,
-        size: 100
+        size: 100,
       };
       const data = await paperList(datas).catch(() => {});
       this.isLoading = false;
@@ -144,7 +144,7 @@ export default {
     },
     paperChange(curPaper) {
       this.$emit("on-paper-change", curPaper);
-    }
-  }
+    },
+  },
 };
 </script>

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

@@ -11,8 +11,8 @@
           'step-item',
           {
             'step-act': curStep.name === step.name,
-            'step-other': step.type !== 'done'
-          }
+            'step-other': step.type !== 'done',
+          },
         ]"
         @click="selectStep(step)"
       >
@@ -29,8 +29,8 @@
           'step-item',
           {
             'step-act': curStep.name === step.name,
-            'step-other': step.type !== 'done'
-          }
+            'step-other': step.type !== 'done',
+          },
         ]"
         @click="selectStep(step)"
       >
@@ -58,22 +58,22 @@ export default {
       type: Object,
       default() {
         return { levelStep: [], otherStep: [] };
-      }
+      },
     },
     initStep: {
       type: Object,
       default() {
         return { type: "analysis", name: "analysis" };
-      }
+      },
     },
     showCount: {
       type: Boolean,
-      default: true
-    }
+      default: true,
+    },
   },
   data() {
     return {
-      curStep: {}
+      curStep: {},
     };
   },
   mounted() {
@@ -83,7 +83,7 @@ export default {
     selectStep(step) {
       this.curStep = { ...step };
       this.$emit("on-change", this.curStep);
-    }
-  }
+    },
+  },
 };
 </script>

+ 10 - 10
src/modules/grading/components/ModifyFormalGradingTask.vue

@@ -79,7 +79,7 @@ import {
   checkMissionStatus,
   checkCanPublishTask,
   createGradingTask,
-  areaStatProgress
+  areaStatProgress,
 } from "@/api";
 import { numberValidator } from "@/plugins/formRules";
 
@@ -90,7 +90,7 @@ const initModalForm = {
   waitCount: 0,
   progress: 0,
   waitPublishCount: 0,
-  taskCount: null
+  taskCount: null,
 };
 
 export default {
@@ -98,8 +98,8 @@ export default {
   props: {
     subjectId: {
       type: String,
-      required: true
-    }
+      required: true,
+    },
   },
   data() {
     return {
@@ -110,8 +110,8 @@ export default {
       areas: [],
       rules: {
         questionId: numberValidator("请选择考区"),
-        taskCount: numberValidator("请输入分配任务数量")
-      }
+        taskCount: numberValidator("请输入分配任务数量"),
+      },
     };
   },
   methods: {
@@ -136,7 +136,7 @@ export default {
     },
     areaChange() {
       const curArea = this.areas.find(
-        item => item.questionId === this.modalForm.questionId
+        (item) => item.questionId === this.modalForm.questionId
       );
       this.modalForm = Object.assign({}, initModalForm, curArea);
       this.modalForm.progress += "%";
@@ -162,7 +162,7 @@ export default {
         subjectId: this.subjectId,
         taskCount: this.modalForm.taskCount,
         questionId:
-          this.modalForm.questionId === -1 ? null : this.modalForm.questionId
+          this.modalForm.questionId === -1 ? null : this.modalForm.questionId,
       }).catch(() => {
         result = false;
       });
@@ -173,7 +173,7 @@ export default {
       this.$Modal.success({ content: "评卷任务创建成功" });
       this.$emit("modified");
       this.cancel();
-    }
-  }
+    },
+  },
 };
 </script>

+ 27 - 27
src/modules/grading/components/ModifyGradingUser.vue

@@ -82,8 +82,8 @@
         label="权重"
         v-if="
           modalForm.role === 'MARKER' &&
-            modalForm.markRight &&
-            modalForm.markRight !== 'ALLOW_SCORING'
+          modalForm.markRight &&
+          modalForm.markRight !== 'ALLOW_SCORING'
         "
       >
         <InputNumber
@@ -125,12 +125,12 @@
             v-for="(val, key) in MARK_LEADER_RIGHTS"
             :key="key"
             :label="key"
-            style="line-height: 40px;"
+            style="line-height: 40px"
           >
             {{ val.name }}
           </Checkbox>
         </CheckboxGroup>
-        <RadioGroup v-else v-model="leaderRights" style="line-height: 40px;">
+        <RadioGroup v-else v-model="leaderRights" style="line-height: 40px">
           <Radio
             v-for="(val, key) in MARK_LEADER_RIGHTS"
             :key="key"
@@ -156,7 +156,7 @@ import {
   BOOLEAN_TYPE,
   ROLE_TYPE,
   MARKER_RIGHT_TYPE,
-  MARK_LEADER_RIGHTS
+  MARK_LEADER_RIGHTS,
 } from "@/constants/enumerate";
 
 const initModalForm = {
@@ -172,7 +172,7 @@ const initModalForm = {
   oneClickLevel: false,
   standardVolume: false,
   levelCallback: false,
-  leaderConfirm: 1
+  leaderConfirm: 1,
 };
 
 export default {
@@ -182,14 +182,14 @@ export default {
       type: Object,
       default() {
         return {};
-      }
+      },
     },
     subject: {
       type: Object,
       default() {
         return {};
-      }
-    }
+      },
+    },
   },
   computed: {
     isEdit() {
@@ -197,7 +197,7 @@ export default {
     },
     title() {
       return (this.isEdit ? "编辑" : "新增") + "账号";
-    }
+    },
   },
   data() {
     return {
@@ -220,22 +220,22 @@ export default {
             min: 2,
             max: 20,
             message: "请输入姓名,长度2-20个字符",
-            trigger: "change"
-          }
+            trigger: "change",
+          },
         ],
         role: [
           {
             required: true,
             message: "请选择角色",
-            trigger: "change"
-          }
+            trigger: "change",
+          },
         ],
         markRight: [
           {
             required: true,
             message: "请选择权限",
-            trigger: "change"
-          }
+            trigger: "change",
+          },
         ],
         weight: numberValidator("请输入权重"),
         leaderConfirm: numberValidator("请选择操作是否需要确认"),
@@ -252,10 +252,10 @@ export default {
                 return callback();
               }
             },
-            trigger: "change"
-          }
-        ]
-      }
+            trigger: "change",
+          },
+        ],
+      },
     };
   },
   created() {
@@ -264,15 +264,15 @@ export default {
   methods: {
     initData(val) {
       this.$refs.modalFormComp.resetFields();
-      this.roleTypes = Object.keys(ROLE_TYPE).map(key => {
+      this.roleTypes = Object.keys(ROLE_TYPE).map((key) => {
         return {
           key,
-          val: ROLE_TYPE[key]
+          val: ROLE_TYPE[key],
         };
       });
       if (!this.isEdit) {
         this.roleTypes.filter(
-          item => this.subject.stage === "INIT" || item.key === "MARK_LEADER"
+          (item) => this.subject.stage === "INIT" || item.key === "MARK_LEADER"
         );
       }
       this.modalForm = this.$objAssign(initModalForm, val);
@@ -281,7 +281,7 @@ export default {
         this.modalForm.workId
       }-`;
       this.leaderRights = Object.keys(MARK_LEADER_RIGHTS).filter(
-        right => this.modalForm[right]
+        (right) => this.modalForm[right]
       );
       if (!this.modalForm.leaderConfirm)
         this.leaderRights = this.leaderRights[0];
@@ -320,7 +320,7 @@ export default {
       const rights = datas.leaderConfirm
         ? this.leaderRights
         : [this.leaderRights];
-      Object.keys(MARK_LEADER_RIGHTS).forEach(right => {
+      Object.keys(MARK_LEADER_RIGHTS).forEach((right) => {
         datas[right] = rights.includes(right);
       });
 
@@ -336,7 +336,7 @@ export default {
       this.$Message.success(this.title + "成功!");
       this.$emit("modified");
       this.cancel();
-    }
-  }
+    },
+  },
 };
 </script>

+ 8 - 8
src/modules/grading/components/ModifyLeaderGrading.vue

@@ -62,16 +62,16 @@ export default {
         return {
           paperIds: "",
           curLevel: "",
-          selectedLevel: ""
+          selectedLevel: "",
         };
-      }
+      },
     },
     markers: {
       type: Array,
       default() {
         return [];
-      }
-    }
+      },
+    },
   },
   data() {
     return {
@@ -82,7 +82,7 @@ export default {
       levelCallback: false,
       noneedLevelOrReject: false,
       actionType: null,
-      selectedMarkers: []
+      selectedMarkers: [],
     };
   },
   methods: {
@@ -124,7 +124,7 @@ export default {
         action: this.actionType,
         level: this.levelInfo.selectedLevel,
         originLevel: this.levelInfo.curLevel,
-        paperIds: this.levelInfo.paperIds
+        paperIds: this.levelInfo.paperIds,
       };
       if (this.actionType === "reject")
         datas.range = this.selectedMarkers.join();
@@ -142,7 +142,7 @@ export default {
       this.$Message.success("操作成功!");
       this.$emit("modified", datas, paper);
       this.cancel();
-    }
-  }
+    },
+  },
 };
 </script>

+ 11 - 11
src/modules/grading/components/ModifyUnformalGradingTask.vue

@@ -67,8 +67,8 @@ export default {
       type: Object,
       default() {
         return {};
-      }
-    }
+      },
+    },
   },
   data() {
     return {
@@ -78,18 +78,18 @@ export default {
       headers: {
         Authorization: this.$ls.get("user", { token: "" }).token,
         workId: this.$route.params.workId,
-        userId: this.$ls.get("user", { id: "" }).id
+        userId: this.$ls.get("user", { id: "" }).id,
       },
       uploadBtnName: "导入考生数据",
       uploadUrl: this.GLOBAL.domain + "/api/import/students/batchAllForTrial",
       uploadFileIsSuccess: false,
-      unformalGradingIsRunning: false
+      unformalGradingIsRunning: false,
     };
   },
   created() {
     this.uploadData = {
       workId: this.curSubject.workId,
-      subject: this.curSubject.subject
+      subject: this.curSubject.subject,
     };
   },
   methods: {
@@ -138,9 +138,9 @@ export default {
       this.$Modal.confirm({
         content: "确定要结束试评任务并清空所有试评数据吗?",
         onOk: async () => {
-          const data = await finishTryGradingTask(
-            this.uploadData
-          ).catch(() => {});
+          const data = await finishTryGradingTask(this.uploadData).catch(
+            () => {}
+          );
           this.isSubmit = false;
           if (!data) return;
 
@@ -150,9 +150,9 @@ export default {
         },
         onCancel: () => {
           this.isSubmit = false;
-        }
+        },
       });
-    }
-  }
+    },
+  },
 };
 </script>

+ 7 - 7
src/modules/grading/components/ProgressLine.vue

@@ -19,20 +19,20 @@ export default {
   props: {
     sum: {
       type: Number,
-      default: 0
+      default: 0,
     },
     current: {
       type: Number,
-      default: 0
+      default: 0,
     },
     minRate: {
       type: Number,
-      default: 1
+      default: 1,
     },
     showCount: {
       type: Boolean,
-      default: true
-    }
+      default: true,
+    },
   },
   data() {
     return {};
@@ -42,8 +42,8 @@ export default {
       const rate = this.sum ? (this.current / this.sum).toFixed(4) * 100 : 0;
 
       return rate || this.minRate;
-    }
+    },
   },
-  methods: {}
+  methods: {},
 };
 </script>

+ 81 - 81
src/modules/grading/components/RibbonSetDialog.vue

@@ -1,81 +1,81 @@
-<template>
-  <Modal
-    class="ribbon-set-dialog marker-modal"
-    v-model="modalIsShow"
-    title="设置"
-    :mask-closable="false"
-    @on-visible-change="visibleChange"
-  >
-    <Form
-      ref="modalFormComp"
-      class="ribbon-set-form"
-      :model="ribbonSetModal"
-      :label-width="140"
-    >
-      <FormItem label="显示快捷档位导航">
-        <i-switch v-model="ribbonSetModal.fastLevelNav"></i-switch>
-      </FormItem>
-    </Form>
-
-    <div slot="footer">
-      <Button shape="circle" type="primary" @click="submit">确认</Button>
-      <Button shape="circle" @click="cancel">取消</Button>
-    </div>
-  </Modal>
-</template>
-
-<script>
-import { mapState, mapMutations } from "vuex";
-
-export default {
-  name: "ribbon-set-dialog",
-  data() {
-    return {
-      modalIsShow: false,
-      ribbonSetModal: {}
-    };
-  },
-  computed: {
-    ...mapState("marker", ["ribbonSet"])
-  },
-  mounted() {
-    const userId = this.$ls.get("user", { id: "" }).id;
-    const cacheRibbonSet = window.localStorage.getItem("ribbonSet");
-    const ribbonSet = cacheRibbonSet ? JSON.parse(cacheRibbonSet) : {};
-    if (ribbonSet[userId]) this.setRibbonSet(ribbonSet[userId]);
-  },
-  methods: {
-    ...mapMutations("marker", ["setRibbonSet"]),
-    initData() {
-      this.ribbonSetModal = { ...this.ribbonSet };
-    },
-    visibleChange(visible) {
-      if (visible) {
-        this.initData();
-      }
-    },
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    },
-    submit() {
-      const lastFastLevelNav = this.ribbonSet.fastLevelNav;
-      const userId = this.$ls.get("user", { id: "" }).id;
-      const cacheRibbonSet = window.localStorage.getItem("ribbonSet");
-      const ribbonSet = cacheRibbonSet ? JSON.parse(cacheRibbonSet) : {};
-      ribbonSet[userId] = this.ribbonSetModal;
-      this.setRibbonSet(this.ribbonSetModal);
-      window.localStorage.setItem("ribbonSet", JSON.stringify(ribbonSet));
-      this.cancel();
-      if (lastFastLevelNav !== this.ribbonSetModal.fastLevelNav) {
-        setTimeout(() => {
-          const resizeEvent = new Event("resize");
-          window.dispatchEvent(resizeEvent);
-        });
-      }
-    }
-  }
-};
-</script>
+<template>
+  <Modal
+    class="ribbon-set-dialog marker-modal"
+    v-model="modalIsShow"
+    title="设置"
+    :mask-closable="false"
+    @on-visible-change="visibleChange"
+  >
+    <Form
+      ref="modalFormComp"
+      class="ribbon-set-form"
+      :model="ribbonSetModal"
+      :label-width="140"
+    >
+      <FormItem label="显示快捷档位导航">
+        <i-switch v-model="ribbonSetModal.fastLevelNav"></i-switch>
+      </FormItem>
+    </Form>
+
+    <div slot="footer">
+      <Button shape="circle" type="primary" @click="submit">确认</Button>
+      <Button shape="circle" @click="cancel">取消</Button>
+    </div>
+  </Modal>
+</template>
+
+<script>
+import { mapState, mapMutations } from "vuex";
+
+export default {
+  name: "ribbon-set-dialog",
+  data() {
+    return {
+      modalIsShow: false,
+      ribbonSetModal: {},
+    };
+  },
+  computed: {
+    ...mapState("marker", ["ribbonSet"]),
+  },
+  mounted() {
+    const userId = this.$ls.get("user", { id: "" }).id;
+    const cacheRibbonSet = window.localStorage.getItem("ribbonSet");
+    const ribbonSet = cacheRibbonSet ? JSON.parse(cacheRibbonSet) : {};
+    if (ribbonSet[userId]) this.setRibbonSet(ribbonSet[userId]);
+  },
+  methods: {
+    ...mapMutations("marker", ["setRibbonSet"]),
+    initData() {
+      this.ribbonSetModal = { ...this.ribbonSet };
+    },
+    visibleChange(visible) {
+      if (visible) {
+        this.initData();
+      }
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    submit() {
+      const lastFastLevelNav = this.ribbonSet.fastLevelNav;
+      const userId = this.$ls.get("user", { id: "" }).id;
+      const cacheRibbonSet = window.localStorage.getItem("ribbonSet");
+      const ribbonSet = cacheRibbonSet ? JSON.parse(cacheRibbonSet) : {};
+      ribbonSet[userId] = this.ribbonSetModal;
+      this.setRibbonSet(this.ribbonSetModal);
+      window.localStorage.setItem("ribbonSet", JSON.stringify(ribbonSet));
+      this.cancel();
+      if (lastFastLevelNav !== this.ribbonSetModal.fastLevelNav) {
+        setTimeout(() => {
+          const resizeEvent = new Event("resize");
+          window.dispatchEvent(resizeEvent);
+        });
+      }
+    },
+  },
+};
+</script>

+ 680 - 680
src/modules/grading/leader/LeaderGrading.vue

@@ -1,680 +1,680 @@
-<template>
-  <div class="marker-grading">
-    <marker-header
-      v-if="curSubject.id"
-      ref="MarkerHeader"
-      show-select-all
-      @area-change="areaChange"
-      @step-change="stepChange"
-      @page-set-change="pageSetChange"
-      @to-progress="toProgress"
-      @to-select-all="toSelectAll"
-      @to-history="toHistory"
-      @to-standard="toStandard"
-      @to-statistics="toStatistics"
-      @on-code-search="serachPaperByCode"
-      @on-mark-search="serachMarkPaper"
-    ></marker-header>
-
-    <div
-      :class="[
-        'marker-action',
-        { 'marker-action-fullscreen': isFullscreenMarking }
-      ]"
-      v-show="!multipleGradingList.length"
-    >
-      <grade-action
-        :cur-paper-or-task="curPaper"
-        :levels="levels"
-        :params-set="paramsSet"
-        :key="curPaper.key"
-        @on-leader-level="leaderSelectLevel"
-        @on-code-search="serachPaperByCode"
-        ref="GradeAction"
-        v-if="curPaper.id"
-      ></grade-action>
-      <grade-ribbon ref="GradeRibbon"></grade-ribbon>
-    </div>
-    <!-- multiple grading action -->
-    <div class="marker-action" v-show="multipleGradingList.length">
-      <div class="grade-action">
-        <div class="action-paper-state">
-          <p class="paper-state-cont">批量操作</p>
-        </div>
-        <div class="action-paper-info">
-          <p><span>试卷密号:</span><span>--</span></p>
-        </div>
-        <h3 class="action-grade-info-title" v-if="markLeaderOnlyRight">
-          当前操作:{{ markLeaderOnlyRight.name }}
-        </h3>
-        <div class="action-grade-list">
-          <div
-            class="action-grade-item"
-            v-for="(level, index) in levels"
-            :key="index"
-          >
-            <div
-              :class="[
-                'action-grade-item-content',
-                { 'action-item-content-disabled': multiplebtnClicked }
-              ]"
-              @click="multipleSelectLevel(level)"
-            >
-              <p>{{ level.name }}</p>
-              <p>{{ level.minScore }}~{{ level.maxScore }}</p>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <div
-      :class="['marker-body', { 'marker-body-low': ribbonSet.fastLevelNav }]"
-    >
-      <div :class="markerImageListClasses" v-if="papers.length">
-        <div
-          v-for="(paper, index) in papers"
-          :key="paper.key"
-          :class="[
-            'marker-image-item',
-            {
-              'marker-image-item-act': curPaperIndex === index
-            }
-          ]"
-        >
-          <div class="marker-image-content">
-            <marker-image-view
-              ref="MarkerImageView"
-              :data="paper"
-              :can-select="ACTION_CAN_BATCH"
-              @to-review="toReview(index)"
-              @to-select="selectMultiplePaper"
-            ></marker-image-view>
-          </div>
-        </div>
-      </div>
-      <div v-else class="marker-image-none">暂无数据</div>
-    </div>
-
-    <!-- LeaderStatistics -->
-    <leader-statistics
-      :question-id="filter.questionId"
-      ref="LeaderStatistics"
-    ></leader-statistics>
-    <!-- LeaderProgress -->
-    <leader-progress ref="LeaderProgress"></leader-progress>
-    <!-- MarkerHistory -->
-    <marker-history
-      :question-id="filter.questionId"
-      @on-paper-click="
-        (index, papers) => {
-          toViewCarouselPaper(index, papers, 'history');
-        }
-      "
-      ref="MarkerHistory"
-    ></marker-history>
-    <!-- MarkerStandard -->
-    <marker-standard
-      :question-id="filter.questionId"
-      :levels="levels"
-      @on-paper-click="
-        (index, papers) => {
-          toViewCarouselPaper(index, papers, 'sample');
-        }
-      "
-      ref="MarkerStandard"
-      v-if="levels.length && filter.questionId && paramsSet.showSample"
-    ></marker-standard>
-    <!-- modify-leader-grading -->
-    <modify-leader-grading
-      class="marker-modal"
-      :level-info="levelInfo"
-      :markers="markers"
-      @modified="leaderGradingSuccess"
-      ref="ModifyLeaderGrading"
-    ></modify-leader-grading>
-    <!-- image-preview -->
-    <simple-image-preview
-      class="grading-operation-image-preview"
-      :cur-image="curPaper"
-      @on-prev="toPrevPaper"
-      @on-next="toNextPaper"
-      @on-close="isFullscreenMarking = false"
-      ref="SimpleImagePreview"
-    ></simple-image-preview>
-    <!-- carousel paper review -->
-    <simple-image-preview
-      class="grading-operation-image-preview"
-      :cur-image="curPaper"
-      @on-prev="toCarousePaper('prev')"
-      @on-next="toCarousePaper('next')"
-      @on-close="carouseImagePreviewClose"
-      ref="CarouselPapersPreview"
-    ></simple-image-preview>
-  </div>
-</template>
-
-<script>
-import { mapState, mapMutations } from "vuex";
-import MarkerHeader from "../marker/MarkerHeader";
-import MarkerImageView from "../marker/MarkerImageView";
-import MarkerHistory from "../marker/MarkerHistory";
-import MarkerStandard from "../marker/MarkerStandard";
-import LeaderProgress from "./LeaderProgress";
-import LeaderStatistics from "./LeaderStatistics";
-import GradeAction from "../components/GradeAction";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-import ModifyLeaderGrading from "../components/ModifyLeaderGrading";
-import GradeRibbon from "../components/GradeRibbon";
-
-import {
-  paperList,
-  markTaskPaperList,
-  levelStatData,
-  workLevelList,
-  taskSnSearch,
-  subjectDetail,
-  markHistoryList,
-  getParamsSet,
-  leaderGradingPaper
-} from "@/api";
-
-export default {
-  name: "marker-grading",
-  components: {
-    MarkerHeader,
-    MarkerImageView,
-    MarkerHistory,
-    MarkerStandard,
-    LeaderProgress,
-    LeaderStatistics,
-    GradeAction,
-    SimpleImagePreview,
-    ModifyLeaderGrading,
-    GradeRibbon
-  },
-  data() {
-    return {
-      filter: {
-        questionId: "",
-        sort: "secretNumber"
-      },
-      typeFilter: {
-        done: {
-          level: ""
-        },
-        reject: {
-          reject: true
-        },
-        arbitrate: {
-          arbi: true
-        }
-      },
-      speFilter: null,
-      workId: this.$route.params.workId,
-      subjectId: this.$route.params.subjectId,
-      subject: "",
-      levels: [],
-      papers: [],
-      curPaper: {},
-      curPaperIndex: 0,
-      // leader-grade
-      levelInfo: {},
-      markers: [],
-      // carousel paper review,
-      carouselType: "",
-      carouselPapers: [],
-      curCarouselPaperIndex: 0,
-      isFullscreenMarking: false,
-      // multiple grading
-      multiplebtnClicked: false,
-      multipleGradingList: [],
-      // 科组长权限
-      markLeaderOnlyRight: null
-    };
-  },
-  computed: {
-    ...mapState("marker", [
-      "paramsSet",
-      "page",
-      "steps",
-      "curStep",
-      "curArea",
-      "curSubject",
-      "ribbonSet"
-    ]),
-    markerImageListClasses() {
-      return ["marker-image-list", `marker-image-list-${this.page.size}`];
-    },
-    IS_TEST() {
-      return this.curSubject.test === 2;
-    },
-    ACTION_CAN_BATCH() {
-      return this.curStep.type === "done" && !this.paramsSet.paperStage;
-    }
-  },
-  created() {
-    this.markLeaderOnlyRight = this.$ls.get("user", {
-      markLeaderOnlyRight: null
-    }).markLeaderOnlyRight;
-
-    const curUserRoleType = this.$ls.get("user", { role: "" }).role;
-    this.setCurUserRoleType(curUserRoleType);
-    this.initData();
-    this.subject = this.subjectId.split("-")[1];
-  },
-  methods: {
-    ...mapMutations("marker", [
-      "setParamSet",
-      "setPage",
-      "setSteps",
-      "setCurStep",
-      "setCurArea",
-      "setCurSubject",
-      "setCurUserRoleType",
-      "clearState"
-    ]),
-    initData() {
-      this.getParamsSetInfo();
-      this.getSubjectDetail();
-      this.getWorkLevels();
-    },
-    async getParamsSetInfo() {
-      const data = await getParamsSet(this.workId);
-      this.setParamSet(data || {});
-    },
-    async getSubjectDetail() {
-      const curSubject = await subjectDetail(this.subjectId);
-      this.setCurSubject(curSubject || {});
-    },
-    async getList() {
-      this.clearMultiplePaper();
-
-      let data = {
-        data: [],
-        totalCount: 0,
-        pageCount: 0
-      };
-      if (this.speFilter) {
-        const { type, params } = this.speFilter;
-        if (type === "mark") {
-          data = await this.getMarkList(params);
-        }
-      } else {
-        data = await this.getCommonList();
-      }
-
-      this.papers = data.data.map(paper => {
-        paper.key = this.$randomCode();
-        paper.title = `NO.${paper.sn}`;
-        paper.selected = false;
-        return paper;
-      });
-
-      this.setPage({
-        total: data.totalCount,
-        totalPage: data.pageCount
-      });
-    },
-    async getCommonList() {
-      const datas = {
-        ...this.filter,
-        ...this.typeFilter[this.curStep.type],
-        page: this.page.current - 1,
-        size: this.page.size
-      };
-      if (this.curStep.type === "done") datas.level = this.curStep.name;
-
-      const data = await paperList(datas);
-      return data;
-    },
-    async getMarkList(params) {
-      const userId = this.$ls.get("user", { id: "" }).id;
-      const markDisabled = userId !== params.markerId;
-
-      const datas = {
-        ...params,
-        workId: this.workId,
-        subject: this.subject,
-        stage: "LEVEL",
-        page: this.page.current - 1,
-        size: this.page.size
-      };
-
-      const data = await markTaskPaperList(datas);
-      data.data.forEach(item => {
-        item.markDisabled = markDisabled;
-        item.mark = true;
-      });
-      return data;
-    },
-    async toPage(page) {
-      this.setPage({
-        current: page
-      });
-      await this.getList();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async getStepLevels() {
-      const data = await levelStatData(this.subjectId, this.filter.questionId);
-      const undoIndex = data.findIndex(item => item.id === null);
-      let otherStep = [];
-      let undo = {
-        count: 0,
-        rejected: 0,
-        arbitrated: 0
-      };
-      if (undoIndex !== -1) {
-        undo = { ...data[undoIndex] };
-        data.splice(undoIndex, 1);
-      }
-
-      if (this.IS_TEST) {
-        otherStep.push({
-          name: "待评",
-          count: undo.count,
-          type: "undo"
-        });
-      }
-      otherStep.push({
-        name: "打回",
-        count: undo.rejected,
-        type: "reject"
-      });
-      otherStep.push({
-        name: "仲裁",
-        count: undo.arbitrated,
-        type: "arbitrate"
-      });
-
-      let levelStep = data.map(item => {
-        return {
-          ...item,
-          name: item.id,
-          type: "done"
-        };
-      });
-      this.setSteps({ levelStep, otherStep });
-
-      if (!this.curStep.name) {
-        const firstStep = otherStep.find(item => item.count);
-        const curStep = firstStep || levelStep[0];
-        this.setCurStep(curStep);
-      } else {
-        const curStep = [...levelStep, ...otherStep].find(
-          item => item.name === this.curStep.name
-        );
-        this.setCurStep(curStep);
-      }
-    },
-    async getWorkLevels() {
-      const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          id: item.id,
-          name: item.code,
-          minScore: item.minScore,
-          maxScore: item.maxScore
-        };
-      });
-    },
-    async pageSetChange() {
-      await this.getList();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async stepChange(step) {
-      this.speFilter = null;
-      this.setCurStep(step);
-      this.setPage({ current: 1 });
-      this.isFullscreenMarking = false;
-      await this.getList();
-      // this.getStepLevels();
-      if (this.papers.length) {
-        this.selectPaper(0);
-      } else {
-        this.curPaper = {};
-      }
-    },
-    async areaChange(curArea) {
-      this.speFilter = null;
-      this.setCurArea(curArea);
-      this.filter.questionId = curArea.id;
-      await this.getStepLevels();
-      this.toPage(1);
-    },
-    // selectMultiplePaper
-    selectMultiplePaper(paper) {
-      if (paper.sample) return;
-      const curPaper = this.papers.find(p => p.id === paper.id);
-      curPaper.selected = paper.selected;
-      this.multipleGradingList = this.papers.filter(paper => paper.selected);
-    },
-    clearMultiplePaper() {
-      this.multipleGradingList = [];
-      this.papers.forEach(paper => {
-        paper.selected = false;
-      });
-      this.$refs.MarkerHeader.changeAllSelect(false);
-    },
-    async multipleSelectLevel(level) {
-      if (!this.multipleGradingList.length) return;
-      if (this.multiplebtnClicked) return;
-
-      this.multiplebtnClicked = true;
-
-      const data = await markHistoryList(
-        this.multipleGradingList[0].id,
-        "LEVEL"
-      ).catch(() => {
-        this.multiplebtnClicked = false;
-      });
-
-      if (!data) return;
-
-      const markers = data.map(item => {
-        return {
-          id: item.markerId,
-          name: item.marker
-        };
-      });
-      const levelInfo = {
-        paperIds: this.multipleGradingList.map(item => item.id).join(),
-        curLevel: this.curStep.name,
-        selectedLevel: level.name,
-        markLeaderOnlyRight: this.markLeaderOnlyRight
-      };
-
-      await this.leaderSelectLevel(levelInfo, markers).catch(() => {});
-      this.multiplebtnClicked = false;
-    },
-    // paper view action
-    toReview(index) {
-      this.isFullscreenMarking = true;
-      this.clearMultiplePaper();
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        if (this.page.current > 1) {
-          this.setPage({ current: this.page.current - 1 });
-          this.curPaperIndex = this.page.size - 1;
-          await this.getList();
-        } else {
-          this.$Message.warning("当前已经是第一条数据了");
-          return;
-        }
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        if (this.page.current === this.page.totalPage) {
-          this.$Message.warning("当前已经是最后一条数据了");
-          return;
-        } else {
-          this.setPage({ current: this.page.current + 1 });
-          this.curPaperIndex = 0;
-          await this.getList();
-        }
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toActionNextPaper() {
-      if (this.page.current > 1 && this.papers.length === 1) {
-        this.setPage({ current: this.page.current - 1 });
-        this.curPaperIndex = this.page.size;
-      }
-
-      await this.getList();
-      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async serachPaperByCode(params) {
-      this.speFilter = null;
-      this.papers = [];
-      const data = await taskSnSearch(
-        params.codeType,
-        params.code,
-        this.filter.questionId
-      );
-      if (!data) {
-        this.$Message.error("没有查找到结果!");
-        return;
-      }
-      data.title = `NO.${data.sn}`;
-      data.key = this.$randomCode();
-      this.papers = [data];
-      this.setPage({ current: 1, total: 1, totalPage: 1 });
-      this.selectPaper(0);
-    },
-    serachMarkPaper(data) {
-      console.log(data);
-      this.speFilter = { type: data.type, params: data.params };
-      this.toPage(1);
-    },
-    async leaderSelectLevel(levelInfo, markers) {
-      // 唯一权限时,直接操作
-      if (levelInfo.markLeaderOnlyRight && !levelInfo.leaderConfirm) {
-        const datas = {
-          action: levelInfo.markLeaderOnlyRight.action,
-          level: levelInfo.selectedLevel,
-          originLevel: levelInfo.curLevel,
-          paperIds: levelInfo.paperIds,
-          leaderConfirm: levelInfo.leaderConfirm
-        };
-        if (datas.action === "reject") {
-          datas.range = markers.map(item => item.id).join();
-        }
-        let result = true;
-        const paper = await leaderGradingPaper(datas).catch(() => {
-          result = false;
-        });
-        if (!result) return;
-
-        this.leaderGradingSuccess(datas, paper);
-        return;
-      }
-
-      this.levelInfo = levelInfo;
-      this.markers = markers;
-      this.$refs.ModifyLeaderGrading.open();
-    },
-    async leaderGradingSuccess(datas, paper) {
-      this.getStepLevels();
-      if (this.carouselType) {
-        this.$refs.CarouselPapersPreview.cancel();
-        this.$refs.MarkerHistory.updatePapers();
-        return;
-      }
-
-      if (this.multipleGradingList && this.multipleGradingList.length) {
-        // 批量处理逻辑
-        if (
-          this.page.current > 1 &&
-          this.page.current === this.page.totalPage &&
-          this.papers.length === this.multipleGradingList.length
-        ) {
-          this.setPage({ current: this.page.current - 1 });
-        }
-
-        this.multipleGradingList = [];
-        await this.getList();
-        this.selectPaper(this.curPaperIndex);
-      } else {
-        // 单张处理逻辑
-        this.toActionNextPaper();
-      }
-    },
-    // paper carousel
-    toViewCarouselPaper(paperIndex, papers, type) {
-      this.carouselType = type;
-      this.isFullscreenMarking = true;
-      this.carouselPapers = papers;
-      this.selectCarouselPaper(paperIndex);
-      this.$nextTick(() => {
-        this.$refs.CarouselPapersPreview.open();
-      });
-    },
-    selectCarouselPaper(index) {
-      this.curCarouselPaperIndex = index;
-      this.curPaper = { ...this.carouselPapers[index] };
-    },
-    toCarousePaper(type) {
-      if (type === "prev" && this.curCarouselPaperIndex > 0) {
-        this.curCarouselPaperIndex--;
-      } else if (
-        type === "next" &&
-        this.curCarouselPaperIndex < this.carouselPapers.length - 1
-      ) {
-        this.curCarouselPaperIndex++;
-      }
-      this.selectCarouselPaper(this.curCarouselPaperIndex);
-    },
-    carouseImagePreviewClose() {
-      this.isFullscreenMarking = false;
-      this.carouselType = "";
-      this.selectPaper(this.curPaperIndex);
-    },
-    // header
-    toHistory() {
-      this.$refs.MarkerHistory.open();
-    },
-    toStandard() {
-      this.$refs.MarkerStandard.open();
-    },
-    toProgress() {
-      this.$refs.LeaderProgress.open();
-    },
-    toSelectAll(allSelected) {
-      this.$refs.MarkerImageView.forEach(item => {
-        item.changeSelect(allSelected);
-      });
-    },
-    toStatistics() {
-      this.$refs.LeaderStatistics.open();
-    }
-  },
-  beforeDestroy() {
-    this.clearState();
-  }
-};
-</script>
+<template>
+  <div class="marker-grading">
+    <marker-header
+      v-if="curSubject.id"
+      ref="MarkerHeader"
+      show-select-all
+      @area-change="areaChange"
+      @step-change="stepChange"
+      @page-set-change="pageSetChange"
+      @to-progress="toProgress"
+      @to-select-all="toSelectAll"
+      @to-history="toHistory"
+      @to-standard="toStandard"
+      @to-statistics="toStatistics"
+      @on-code-search="serachPaperByCode"
+      @on-mark-search="serachMarkPaper"
+    ></marker-header>
+
+    <div
+      :class="[
+        'marker-action',
+        { 'marker-action-fullscreen': isFullscreenMarking },
+      ]"
+      v-show="!multipleGradingList.length"
+    >
+      <grade-action
+        :cur-paper-or-task="curPaper"
+        :levels="levels"
+        :params-set="paramsSet"
+        :key="curPaper.key"
+        @on-leader-level="leaderSelectLevel"
+        @on-code-search="serachPaperByCode"
+        ref="GradeAction"
+        v-if="curPaper.id"
+      ></grade-action>
+      <grade-ribbon ref="GradeRibbon"></grade-ribbon>
+    </div>
+    <!-- multiple grading action -->
+    <div class="marker-action" v-show="multipleGradingList.length">
+      <div class="grade-action">
+        <div class="action-paper-state">
+          <p class="paper-state-cont">批量操作</p>
+        </div>
+        <div class="action-paper-info">
+          <p><span>试卷密号:</span><span>--</span></p>
+        </div>
+        <h3 class="action-grade-info-title" v-if="markLeaderOnlyRight">
+          当前操作:{{ markLeaderOnlyRight.name }}
+        </h3>
+        <div class="action-grade-list">
+          <div
+            class="action-grade-item"
+            v-for="(level, index) in levels"
+            :key="index"
+          >
+            <div
+              :class="[
+                'action-grade-item-content',
+                { 'action-item-content-disabled': multiplebtnClicked },
+              ]"
+              @click="multipleSelectLevel(level)"
+            >
+              <p>{{ level.name }}</p>
+              <p>{{ level.minScore }}~{{ level.maxScore }}</p>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div
+      :class="['marker-body', { 'marker-body-low': ribbonSet.fastLevelNav }]"
+    >
+      <div :class="markerImageListClasses" v-if="papers.length">
+        <div
+          v-for="(paper, index) in papers"
+          :key="paper.key"
+          :class="[
+            'marker-image-item',
+            {
+              'marker-image-item-act': curPaperIndex === index,
+            },
+          ]"
+        >
+          <div class="marker-image-content">
+            <marker-image-view
+              ref="MarkerImageView"
+              :data="paper"
+              :can-select="ACTION_CAN_BATCH"
+              @to-review="toReview(index)"
+              @to-select="selectMultiplePaper"
+            ></marker-image-view>
+          </div>
+        </div>
+      </div>
+      <div v-else class="marker-image-none">暂无数据</div>
+    </div>
+
+    <!-- LeaderStatistics -->
+    <leader-statistics
+      :question-id="filter.questionId"
+      ref="LeaderStatistics"
+    ></leader-statistics>
+    <!-- LeaderProgress -->
+    <leader-progress ref="LeaderProgress"></leader-progress>
+    <!-- MarkerHistory -->
+    <marker-history
+      :question-id="filter.questionId"
+      @on-paper-click="
+        (index, papers) => {
+          toViewCarouselPaper(index, papers, 'history');
+        }
+      "
+      ref="MarkerHistory"
+    ></marker-history>
+    <!-- MarkerStandard -->
+    <marker-standard
+      :question-id="filter.questionId"
+      :levels="levels"
+      @on-paper-click="
+        (index, papers) => {
+          toViewCarouselPaper(index, papers, 'sample');
+        }
+      "
+      ref="MarkerStandard"
+      v-if="levels.length && filter.questionId && paramsSet.showSample"
+    ></marker-standard>
+    <!-- modify-leader-grading -->
+    <modify-leader-grading
+      class="marker-modal"
+      :level-info="levelInfo"
+      :markers="markers"
+      @modified="leaderGradingSuccess"
+      ref="ModifyLeaderGrading"
+    ></modify-leader-grading>
+    <!-- image-preview -->
+    <simple-image-preview
+      class="grading-operation-image-preview"
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      @on-close="isFullscreenMarking = false"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
+    <!-- carousel paper review -->
+    <simple-image-preview
+      class="grading-operation-image-preview"
+      :cur-image="curPaper"
+      @on-prev="toCarousePaper('prev')"
+      @on-next="toCarousePaper('next')"
+      @on-close="carouseImagePreviewClose"
+      ref="CarouselPapersPreview"
+    ></simple-image-preview>
+  </div>
+</template>
+
+<script>
+import { mapState, mapMutations } from "vuex";
+import MarkerHeader from "../marker/MarkerHeader";
+import MarkerImageView from "../marker/MarkerImageView";
+import MarkerHistory from "../marker/MarkerHistory";
+import MarkerStandard from "../marker/MarkerStandard";
+import LeaderProgress from "./LeaderProgress";
+import LeaderStatistics from "./LeaderStatistics";
+import GradeAction from "../components/GradeAction";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+import ModifyLeaderGrading from "../components/ModifyLeaderGrading";
+import GradeRibbon from "../components/GradeRibbon";
+
+import {
+  paperList,
+  markTaskPaperList,
+  levelStatData,
+  workLevelList,
+  taskSnSearch,
+  subjectDetail,
+  markHistoryList,
+  getParamsSet,
+  leaderGradingPaper,
+} from "@/api";
+
+export default {
+  name: "marker-grading",
+  components: {
+    MarkerHeader,
+    MarkerImageView,
+    MarkerHistory,
+    MarkerStandard,
+    LeaderProgress,
+    LeaderStatistics,
+    GradeAction,
+    SimpleImagePreview,
+    ModifyLeaderGrading,
+    GradeRibbon,
+  },
+  data() {
+    return {
+      filter: {
+        questionId: "",
+        sort: "secretNumber",
+      },
+      typeFilter: {
+        done: {
+          level: "",
+        },
+        reject: {
+          reject: true,
+        },
+        arbitrate: {
+          arbi: true,
+        },
+      },
+      speFilter: null,
+      workId: this.$route.params.workId,
+      subjectId: this.$route.params.subjectId,
+      subject: "",
+      levels: [],
+      papers: [],
+      curPaper: {},
+      curPaperIndex: 0,
+      // leader-grade
+      levelInfo: {},
+      markers: [],
+      // carousel paper review,
+      carouselType: "",
+      carouselPapers: [],
+      curCarouselPaperIndex: 0,
+      isFullscreenMarking: false,
+      // multiple grading
+      multiplebtnClicked: false,
+      multipleGradingList: [],
+      // 科组长权限
+      markLeaderOnlyRight: null,
+    };
+  },
+  computed: {
+    ...mapState("marker", [
+      "paramsSet",
+      "page",
+      "steps",
+      "curStep",
+      "curArea",
+      "curSubject",
+      "ribbonSet",
+    ]),
+    markerImageListClasses() {
+      return ["marker-image-list", `marker-image-list-${this.page.size}`];
+    },
+    IS_TEST() {
+      return this.curSubject.test === 2;
+    },
+    ACTION_CAN_BATCH() {
+      return this.curStep.type === "done" && !this.paramsSet.paperStage;
+    },
+  },
+  created() {
+    this.markLeaderOnlyRight = this.$ls.get("user", {
+      markLeaderOnlyRight: null,
+    }).markLeaderOnlyRight;
+
+    const curUserRoleType = this.$ls.get("user", { role: "" }).role;
+    this.setCurUserRoleType(curUserRoleType);
+    this.initData();
+    this.subject = this.subjectId.split("-")[1];
+  },
+  methods: {
+    ...mapMutations("marker", [
+      "setParamSet",
+      "setPage",
+      "setSteps",
+      "setCurStep",
+      "setCurArea",
+      "setCurSubject",
+      "setCurUserRoleType",
+      "clearState",
+    ]),
+    initData() {
+      this.getParamsSetInfo();
+      this.getSubjectDetail();
+      this.getWorkLevels();
+    },
+    async getParamsSetInfo() {
+      const data = await getParamsSet(this.workId);
+      this.setParamSet(data || {});
+    },
+    async getSubjectDetail() {
+      const curSubject = await subjectDetail(this.subjectId);
+      this.setCurSubject(curSubject || {});
+    },
+    async getList() {
+      this.clearMultiplePaper();
+
+      let data = {
+        data: [],
+        totalCount: 0,
+        pageCount: 0,
+      };
+      if (this.speFilter) {
+        const { type, params } = this.speFilter;
+        if (type === "mark") {
+          data = await this.getMarkList(params);
+        }
+      } else {
+        data = await this.getCommonList();
+      }
+
+      this.papers = data.data.map((paper) => {
+        paper.key = this.$randomCode();
+        paper.title = `NO.${paper.sn}`;
+        paper.selected = false;
+        return paper;
+      });
+
+      this.setPage({
+        total: data.totalCount,
+        totalPage: data.pageCount,
+      });
+    },
+    async getCommonList() {
+      const datas = {
+        ...this.filter,
+        ...this.typeFilter[this.curStep.type],
+        page: this.page.current - 1,
+        size: this.page.size,
+      };
+      if (this.curStep.type === "done") datas.level = this.curStep.name;
+
+      const data = await paperList(datas);
+      return data;
+    },
+    async getMarkList(params) {
+      const userId = this.$ls.get("user", { id: "" }).id;
+      const markDisabled = userId !== params.markerId;
+
+      const datas = {
+        ...params,
+        workId: this.workId,
+        subject: this.subject,
+        stage: "LEVEL",
+        page: this.page.current - 1,
+        size: this.page.size,
+      };
+
+      const data = await markTaskPaperList(datas);
+      data.data.forEach((item) => {
+        item.markDisabled = markDisabled;
+        item.mark = true;
+      });
+      return data;
+    },
+    async toPage(page) {
+      this.setPage({
+        current: page,
+      });
+      await this.getList();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async getStepLevels() {
+      const data = await levelStatData(this.subjectId, this.filter.questionId);
+      const undoIndex = data.findIndex((item) => item.id === null);
+      let otherStep = [];
+      let undo = {
+        count: 0,
+        rejected: 0,
+        arbitrated: 0,
+      };
+      if (undoIndex !== -1) {
+        undo = { ...data[undoIndex] };
+        data.splice(undoIndex, 1);
+      }
+
+      if (this.IS_TEST) {
+        otherStep.push({
+          name: "待评",
+          count: undo.count,
+          type: "undo",
+        });
+      }
+      otherStep.push({
+        name: "打回",
+        count: undo.rejected,
+        type: "reject",
+      });
+      otherStep.push({
+        name: "仲裁",
+        count: undo.arbitrated,
+        type: "arbitrate",
+      });
+
+      let levelStep = data.map((item) => {
+        return {
+          ...item,
+          name: item.id,
+          type: "done",
+        };
+      });
+      this.setSteps({ levelStep, otherStep });
+
+      if (!this.curStep.name) {
+        const firstStep = otherStep.find((item) => item.count);
+        const curStep = firstStep || levelStep[0];
+        this.setCurStep(curStep);
+      } else {
+        const curStep = [...levelStep, ...otherStep].find(
+          (item) => item.name === this.curStep.name
+        );
+        this.setCurStep(curStep);
+      }
+    },
+    async getWorkLevels() {
+      const data = await workLevelList(this.workId);
+      this.levels = data.map((item) => {
+        return {
+          id: item.id,
+          name: item.code,
+          minScore: item.minScore,
+          maxScore: item.maxScore,
+        };
+      });
+    },
+    async pageSetChange() {
+      await this.getList();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async stepChange(step) {
+      this.speFilter = null;
+      this.setCurStep(step);
+      this.setPage({ current: 1 });
+      this.isFullscreenMarking = false;
+      await this.getList();
+      // this.getStepLevels();
+      if (this.papers.length) {
+        this.selectPaper(0);
+      } else {
+        this.curPaper = {};
+      }
+    },
+    async areaChange(curArea) {
+      this.speFilter = null;
+      this.setCurArea(curArea);
+      this.filter.questionId = curArea.id;
+      await this.getStepLevels();
+      this.toPage(1);
+    },
+    // selectMultiplePaper
+    selectMultiplePaper(paper) {
+      if (paper.sample) return;
+      const curPaper = this.papers.find((p) => p.id === paper.id);
+      curPaper.selected = paper.selected;
+      this.multipleGradingList = this.papers.filter((paper) => paper.selected);
+    },
+    clearMultiplePaper() {
+      this.multipleGradingList = [];
+      this.papers.forEach((paper) => {
+        paper.selected = false;
+      });
+      this.$refs.MarkerHeader.changeAllSelect(false);
+    },
+    async multipleSelectLevel(level) {
+      if (!this.multipleGradingList.length) return;
+      if (this.multiplebtnClicked) return;
+
+      this.multiplebtnClicked = true;
+
+      const data = await markHistoryList(
+        this.multipleGradingList[0].id,
+        "LEVEL"
+      ).catch(() => {
+        this.multiplebtnClicked = false;
+      });
+
+      if (!data) return;
+
+      const markers = data.map((item) => {
+        return {
+          id: item.markerId,
+          name: item.marker,
+        };
+      });
+      const levelInfo = {
+        paperIds: this.multipleGradingList.map((item) => item.id).join(),
+        curLevel: this.curStep.name,
+        selectedLevel: level.name,
+        markLeaderOnlyRight: this.markLeaderOnlyRight,
+      };
+
+      await this.leaderSelectLevel(levelInfo, markers).catch(() => {});
+      this.multiplebtnClicked = false;
+    },
+    // paper view action
+    toReview(index) {
+      this.isFullscreenMarking = true;
+      this.clearMultiplePaper();
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        if (this.page.current > 1) {
+          this.setPage({ current: this.page.current - 1 });
+          this.curPaperIndex = this.page.size - 1;
+          await this.getList();
+        } else {
+          this.$Message.warning("当前已经是第一条数据了");
+          return;
+        }
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        if (this.page.current === this.page.totalPage) {
+          this.$Message.warning("当前已经是最后一条数据了");
+          return;
+        } else {
+          this.setPage({ current: this.page.current + 1 });
+          this.curPaperIndex = 0;
+          await this.getList();
+        }
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toActionNextPaper() {
+      if (this.page.current > 1 && this.papers.length === 1) {
+        this.setPage({ current: this.page.current - 1 });
+        this.curPaperIndex = this.page.size;
+      }
+
+      await this.getList();
+      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async serachPaperByCode(params) {
+      this.speFilter = null;
+      this.papers = [];
+      const data = await taskSnSearch(
+        params.codeType,
+        params.code,
+        this.filter.questionId
+      );
+      if (!data) {
+        this.$Message.error("没有查找到结果!");
+        return;
+      }
+      data.title = `NO.${data.sn}`;
+      data.key = this.$randomCode();
+      this.papers = [data];
+      this.setPage({ current: 1, total: 1, totalPage: 1 });
+      this.selectPaper(0);
+    },
+    serachMarkPaper(data) {
+      console.log(data);
+      this.speFilter = { type: data.type, params: data.params };
+      this.toPage(1);
+    },
+    async leaderSelectLevel(levelInfo, markers) {
+      // 唯一权限时,直接操作
+      if (levelInfo.markLeaderOnlyRight && !levelInfo.leaderConfirm) {
+        const datas = {
+          action: levelInfo.markLeaderOnlyRight.action,
+          level: levelInfo.selectedLevel,
+          originLevel: levelInfo.curLevel,
+          paperIds: levelInfo.paperIds,
+          leaderConfirm: levelInfo.leaderConfirm,
+        };
+        if (datas.action === "reject") {
+          datas.range = markers.map((item) => item.id).join();
+        }
+        let result = true;
+        const paper = await leaderGradingPaper(datas).catch(() => {
+          result = false;
+        });
+        if (!result) return;
+
+        this.leaderGradingSuccess(datas, paper);
+        return;
+      }
+
+      this.levelInfo = levelInfo;
+      this.markers = markers;
+      this.$refs.ModifyLeaderGrading.open();
+    },
+    async leaderGradingSuccess(datas, paper) {
+      this.getStepLevels();
+      if (this.carouselType) {
+        this.$refs.CarouselPapersPreview.cancel();
+        this.$refs.MarkerHistory.updatePapers();
+        return;
+      }
+
+      if (this.multipleGradingList && this.multipleGradingList.length) {
+        // 批量处理逻辑
+        if (
+          this.page.current > 1 &&
+          this.page.current === this.page.totalPage &&
+          this.papers.length === this.multipleGradingList.length
+        ) {
+          this.setPage({ current: this.page.current - 1 });
+        }
+
+        this.multipleGradingList = [];
+        await this.getList();
+        this.selectPaper(this.curPaperIndex);
+      } else {
+        // 单张处理逻辑
+        this.toActionNextPaper();
+      }
+    },
+    // paper carousel
+    toViewCarouselPaper(paperIndex, papers, type) {
+      this.carouselType = type;
+      this.isFullscreenMarking = true;
+      this.carouselPapers = papers;
+      this.selectCarouselPaper(paperIndex);
+      this.$nextTick(() => {
+        this.$refs.CarouselPapersPreview.open();
+      });
+    },
+    selectCarouselPaper(index) {
+      this.curCarouselPaperIndex = index;
+      this.curPaper = { ...this.carouselPapers[index] };
+    },
+    toCarousePaper(type) {
+      if (type === "prev" && this.curCarouselPaperIndex > 0) {
+        this.curCarouselPaperIndex--;
+      } else if (
+        type === "next" &&
+        this.curCarouselPaperIndex < this.carouselPapers.length - 1
+      ) {
+        this.curCarouselPaperIndex++;
+      }
+      this.selectCarouselPaper(this.curCarouselPaperIndex);
+    },
+    carouseImagePreviewClose() {
+      this.isFullscreenMarking = false;
+      this.carouselType = "";
+      this.selectPaper(this.curPaperIndex);
+    },
+    // header
+    toHistory() {
+      this.$refs.MarkerHistory.open();
+    },
+    toStandard() {
+      this.$refs.MarkerStandard.open();
+    },
+    toProgress() {
+      this.$refs.LeaderProgress.open();
+    },
+    toSelectAll(allSelected) {
+      this.$refs.MarkerImageView.forEach((item) => {
+        item.changeSelect(allSelected);
+      });
+    },
+    toStatistics() {
+      this.$refs.LeaderStatistics.open();
+    },
+  },
+  beforeDestroy() {
+    this.clearState();
+  },
+};
+</script>

+ 8 - 8
src/modules/grading/leader/LeaderProgress.vue

@@ -36,7 +36,7 @@
     </div>
 
     <div class="leader-progress-part">
-      <div v-if="IS_LEVEL" colspan="3" style="text-align:left">
+      <div v-if="IS_LEVEL" colspan="3" style="text-align: left">
         仲裁:{{ kzzInfo.arbitrated }}
       </div>
       <table class="table table-dark" v-if="IS_LEVEL && markerProgress.length">
@@ -113,7 +113,7 @@ export default {
       kzzInfo: {},
       totalProgress: {},
       areaProgress: [],
-      markerProgress: []
+      markerProgress: [],
     };
   },
   computed: {
@@ -129,7 +129,7 @@ export default {
     },
     showPaperRelateCount() {
       return !!this.paramsSet["showPaperCount"];
-    }
+    },
   },
   methods: {
     visibleChange(visible) {
@@ -141,7 +141,7 @@ export default {
       const subjectId = this.$route.params.subjectId.split("-");
       const data = await gradingProgressDetail({
         workId: subjectId[0],
-        subject: subjectId[1]
+        subject: subjectId[1],
       });
       this.kzzInfo = data.kzz || {};
       this.totalProgress = data.totalProgress;
@@ -149,7 +149,7 @@ export default {
         successCount: data.totalProgress.successCount,
         totalCount: data.totalProgress.totalCount,
         progress: data.totalProgress.progress.toFixed(2),
-        areaName: "总体进度"
+        areaName: "总体进度",
       };
       if (this.curSubject.stage === "INIT") {
         this.areaProgress = [totalInfo];
@@ -160,7 +160,7 @@ export default {
       }
     },
     addProgress(data) {
-      return data.map(item => {
+      return data.map((item) => {
         item.successCount = item.totalCount - item.leftCount;
         item.progress = item.totalCount
           ? ((100 * item.successCount) / item.totalCount).toFixed(2)
@@ -173,7 +173,7 @@ export default {
     },
     open() {
       this.modalIsShow = true;
-    }
-  }
+    },
+  },
 };
 </script>

+ 19 - 19
src/modules/grading/leader/LeaderStatistics.vue

@@ -84,8 +84,8 @@ export default {
   props: {
     questionId: {
       type: [Number, String],
-      required: true
-    }
+      required: true,
+    },
   },
   data() {
     return {
@@ -96,7 +96,7 @@ export default {
       renderExportPage: false,
       renderChartData: {},
       renderPageInfo: {},
-      isDownload: false
+      isDownload: false,
     };
   },
   computed: {
@@ -105,11 +105,11 @@ export default {
       "curSubject",
       "curArea",
       "steps",
-      "areas"
+      "areas",
     ]),
     showPaperRelateCount() {
       return !!this.paramsSet["showPaperCount"];
-    }
+    },
   },
   methods: {
     visibleChange(visible) {
@@ -121,16 +121,16 @@ export default {
     },
     async initData() {
       let levelSteps = {};
-      this.steps.levelStep.forEach(element => {
+      this.steps.levelStep.forEach((element) => {
         levelSteps[element.name] = element;
       });
       const subs = this.$route.params.subjectId.split("-");
       this.levelData = await gradingStatData({
         questionId: this.questionId,
         workId: subs[0],
-        subject: subs[1]
+        subject: subs[1],
       });
-      this.levelData = this.levelData.map(item => {
+      this.levelData = this.levelData.map((item) => {
         item.levelCount = this.showPaperRelateCount ? item.levelCount : "";
         item.cumulateCount = this.showPaperRelateCount
           ? item.cumulateCount
@@ -148,24 +148,24 @@ export default {
       const groups = [
         {
           key: "levelProp",
-          label: "考区"
+          label: "考区",
         },
         {
           key: "gpercent",
-          label: "全部"
-        }
+          label: "全部",
+        },
       ];
       const groupList = this.areas.length === 1 ? groups.slice(0, 1) : groups;
-      this.lineChartData = groupList.map(group => {
-        const data = this.levelData.map(item => {
+      this.lineChartData = groupList.map((group) => {
+        const data = this.levelData.map((item) => {
           return {
             name: item.code,
-            value: item[group.key]
+            value: item[group.key],
           };
         });
         return {
           name: group.label,
-          data
+          data,
         };
       });
     },
@@ -174,11 +174,11 @@ export default {
       this.isDownload = true;
       this.renderPageInfo = {
         subjectName: this.curSubject.name,
-        areaName: this.curArea.areaName
+        areaName: this.curArea.areaName,
       };
       this.renderChartData = {
         levelData: this.levelData,
-        lineChartData: this.lineChartData
+        lineChartData: this.lineChartData,
       };
       this.renderExportPage = true;
     },
@@ -194,7 +194,7 @@ export default {
     },
     open() {
       this.modalIsShow = true;
-    }
-  }
+    },
+  },
 };
 </script>

+ 625 - 625
src/modules/grading/marker/MarkerGrading.vue

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

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

@@ -1,561 +1,561 @@
-<template>
-  <div class="marker-header">
-    <div class="header-main">
-      <!-- left action -->
-      <div class="header-group">
-        <div class="header-part">
-          <Dropdown
-            v-if="areas.length > 1"
-            placement="bottom"
-            transfer
-            trigger="click"
-            transfer-class-name="marker-dropdown"
-            @on-click="areaClick"
-          >
-            <span class="el-dropdown-link">
-              {{ curArea.areaName }} <Icon type="ios-arrow-down"></Icon>
-            </span>
-            <DropdownMenu slot="list">
-              <DropdownItem
-                v-for="area in areas"
-                :key="area.id"
-                :name="area.id"
-                >{{ area.areaName }}</DropdownItem
-              >
-            </DropdownMenu>
-          </Dropdown>
-          <p v-else>{{ curArea.areaName }}</p>
-        </div>
-        <div v-if="showStatistics" class="header-part" @click="toStatistics">
-          <p>统计分析 <Icon type="ios-arrow-down"></Icon></p>
-        </div>
-      </div>
-      <!-- header-page -->
-      <div class="header-group header-page">
-        <div v-if="showPaperRelateCount" class="page-total">
-          共{{ page.total }}张
-        </div>
-        <div class="page-item" @click="toFirstPage" title="首页">
-          <Icon type="ios-skip-backward" />
-        </div>
-        <div class="page-item" @click="toPrevPage" title="上一页">
-          <Icon type="md-arrow-dropleft" />
-        </div>
-        <Poptip
-          v-if="showPaperRelateCount"
-          popper-class="marker-popper"
-          placement="bottom"
-          trigger="hover"
-          transfer
-        >
-          <div class="page-item page-cpage">
-            <span>{{ page.current }}</span>
-            <span>/</span><span>{{ page.totalPage }}</span>
-          </div>
-          <div class="marker-page" slot="content">
-            <div class="marker-page-set">
-              <span>页面跳转:</span>
-              <InputNumber
-                size="small"
-                :min="1"
-                :max="page.totalPage"
-                :step="1"
-                :precision="0"
-                v-model="pageNo"
-              ></InputNumber>
-              <div class="marker-page-btn" @click="pageNoSet">跳转</div>
-            </div>
-          </div>
-        </Poptip>
-        <div class="page-item" @click="toNextPage" title="下一页">
-          <Icon type="md-arrow-dropright" />
-        </div>
-        <div class="page-item" @click="toLastPage" title="尾页">
-          <Icon type="ios-skip-forward" />
-        </div>
-        <div class="page-item page-size">
-          <Dropdown
-            placement="bottom"
-            transfer
-            trigger="click"
-            transfer-class-name="marker-dropdown"
-            @on-click="pageSizeChange"
-          >
-            <span class="el-dropdown-link">
-              {{ page.size }}张/页 <Icon type="ios-arrow-down"></Icon>
-            </span>
-            <DropdownMenu slot="list">
-              <DropdownItem
-                v-for="item in pageSizeList"
-                :key="item"
-                :name="item"
-                >{{ item }}</DropdownItem
-              >
-            </DropdownMenu>
-          </Dropdown>
-        </div>
-      </div>
-      <!-- right action -->
-      <div class="header-group">
-        <div
-          v-if="showSelectAll"
-          class="header-part header-selection"
-          @click="toSelectAll"
-        >
-          <div
-            :class="[
-              'image-checkbox',
-              {
-                'image-selected': allSelected
-              }
-            ]"
-          >
-            <Icon v-if="allSelected" type="md-checkmark" />
-          </div>
-          全选
-        </div>
-        <Poptip
-          v-if="IS_MARK_LEADER"
-          popper-class="marker-popper"
-          placement="bottom"
-          trigger="click"
-          transfer
-        >
-          <div class="header-part header-filter">
-            筛选 <Icon type="ios-arrow-down"></Icon>
-          </div>
-          <div
-            class="header-filter-body dark-mark"
-            slot="content"
-            @keydown.stop
-          >
-            <!-- 查询标记 -->
-            <div class="filter-part">
-              <h4 class="filter-part-title">查询标记试卷</h4>
-              <div class="filter-part-body">
-                <Select
-                  class="filter-select"
-                  v-model="markFilter.markerId"
-                  placeholder="评卷员"
-                >
-                  <Option
-                    v-for="item in markers"
-                    :key="item.id"
-                    :value="item.id"
-                    :label="item.name"
-                  ></Option>
-                </Select>
-                <Button
-                  type="primary"
-                  size="small"
-                  class="filter-btn"
-                  @click="searchMarkFilter"
-                  >查询</Button
-                >
-              </div>
-            </div>
-            <!-- 查询密号 -->
-            <div class="filter-part">
-              <h4 class="filter-part-title">密号查询试卷</h4>
-              <div class="filter-part-body">
-                <Select
-                  class="filter-select"
-                  v-model="codeFilter.codeType"
-                  placeholder="密号类型"
-                >
-                  <Option
-                    v-for="item in codeTypes"
-                    :key="item.key"
-                    :value="item.key"
-                    :label="item.val"
-                  ></Option>
-                </Select>
-                <Input
-                  class="filter-input"
-                  v-model.trim="codeFilter.code"
-                  placeholder="输入密号"
-                  clearable
-                >
-                </Input>
-                <Button
-                  type="primary"
-                  size="small"
-                  class="filter-btn"
-                  @click="searchCodeFilter"
-                  >查询</Button
-                >
-              </div>
-            </div>
-          </div>
-        </Poptip>
-        <div class="header-part header-step">
-          <Dropdown
-            placement="bottom"
-            transfer
-            trigger="click"
-            transfer-class-name="marker-dropdown header-step-dropdown"
-            @on-click="stepClick"
-          >
-            <span class="el-dropdown-link">
-              <i>{{ curStep.name }}</i>
-              <i v-if="showPaperRelateCount">:{{ curStep.count }} </i>
-              <Icon type="ios-arrow-down"></Icon>
-            </span>
-            <DropdownMenu slot="list">
-              <DropdownItem
-                class="header-step-item"
-                v-for="step in steps.otherStep"
-                :key="step.type"
-                :name="step.name"
-              >
-                <i>{{ step.name }}</i>
-                <i v-if="showPaperRelateCount">({{ step.count }})</i>
-              </DropdownItem>
-              <DropdownItem
-                class="header-step-item"
-                v-for="step in steps.levelStep"
-                :key="step.name"
-                :name="step.name"
-              >
-                <i>{{ step.name }}</i>
-                <i v-if="showPaperRelateCount && IS_MARK_LEADER__SCORE">
-                  ({{ step.count }})
-                </i>
-                <i v-if="showPaperRelateCount && !IS_MARK_LEADER__SCORE">
-                  ({{ step.count }} / {{ step.gcount }})
-                </i>
-              </DropdownItem>
-            </DropdownMenu>
-          </Dropdown>
-        </div>
-        <div v-if="IS_MARK_LEADER" class="header-part" @click="toProgress">
-          <p>{{ stageName }}进度 <Icon type="ios-arrow-down"></Icon></p>
-        </div>
-        <div
-          v-if="showStandard && paramsSet.showSample"
-          class="header-part"
-          @click="toStandard"
-        >
-          <p>标准卷 <Icon type="ios-arrow-down"></Icon></p>
-        </div>
-        <div
-          class="header-part header-history"
-          id="header-history"
-          @click="toHistory"
-        >
-          <p>操作记录 <Icon type="ios-arrow-down"></Icon></p>
-        </div>
-        <div class="header-user" id="header-user">
-          <Dropdown
-            placement="bottom"
-            transfer
-            trigger="click"
-            transfer-class-name="marker-dropdown"
-            @on-click="userClick"
-          >
-            <div class="user-name">
-              <Icon type="md-person" size="16" /> {{ username }}
-              <Icon type="ios-arrow-down"></Icon>
-            </div>
-            <DropdownMenu slot="list">
-              <DropdownItem class="color-default-hover" name="toResetPwd"
-                >修改密码</DropdownItem
-              >
-              <DropdownItem class="color-error-hover" name="logout">
-                退出登录
-              </DropdownItem>
-            </DropdownMenu>
-          </Dropdown>
-        </div>
-      </div>
-    </div>
-
-    <!-- fast-level-nav -->
-    <div v-if="ribbonSet.fastLevelNav" class="header-group fast-nav">
-      <div class="fast-nav-list">
-        <div
-          v-for="step in steps.levelStep"
-          :key="step.name"
-          :class="[
-            'fast-nav-item',
-            { 'is-active': curStep.name === step.name }
-          ]"
-          @click="stepClick(step.name)"
-        >
-          {{ step.name
-          }}<span v-if="showPaperRelateCount">({{ step.count }})</span>
-        </div>
-        <div
-          v-for="step in steps.otherStep"
-          :key="step.name"
-          :class="[
-            'fast-nav-item',
-            { 'is-active': curStep.name === step.name }
-          ]"
-          @click="stepClick(step.name)"
-        >
-          {{ step.name }}
-          <span v-if="showPaperRelateCount">({{ step.count }})</span>
-        </div>
-        <div
-          class="fast-nav-item fast-nav-close is-danger"
-          title="关闭快捷档位导航"
-          @click="closeFastNav"
-        >
-          <Icon type="md-close" :size="18" />
-        </div>
-      </div>
-    </div>
-
-    <!-- ResetPwd -->
-    <reset-pwd ref="ResetPwd"></reset-pwd>
-  </div>
-</template>
-
-<script>
-import { mapState, mapMutations } from "vuex";
-import { areaList, gradingUserList, logout } from "@/api";
-import ResetPwd from "@/modules/login/ResetPwd";
-import { CODE_TYPE } from "@/constants/enumerate";
-
-export default {
-  name: "marker-header",
-  components: { ResetPwd },
-  props: {
-    showStandard: {
-      type: Boolean,
-      default: true
-    },
-    showStatistics: {
-      type: Boolean,
-      default: true
-    },
-    showSelectAll: {
-      type: Boolean,
-      default: false
-    }
-  },
-  data() {
-    return {
-      filter: {
-        workId: "",
-        subject: ""
-      },
-      username: this.$ls.get("user", { loginName: "" }).loginName,
-      pageVisible: false,
-      pageSizeList: [2, 3, 4, 6, 8, 9, 10, 12, 15, 16, 20, 24],
-      pageNo: 1,
-      allSelected: false,
-      codeTypes: [],
-      codeFilter: {
-        codeType: "examNumber",
-        code: ""
-      },
-      markers: [],
-      markFilter: {
-        markerId: ""
-      }
-    };
-  },
-  computed: {
-    ...mapState("marker", [
-      "paramsSet",
-      "page",
-      "curStep",
-      "steps",
-      "curArea",
-      "curSubject",
-      "areas",
-      "IS_MARK_LEADER",
-      "ribbonSet"
-    ]),
-    stageName() {
-      return this.curSubject.stage === "LEVEL" ? "分档" : "打分";
-    },
-    IS_MARK_LEADER__SCORE() {
-      return this.IS_MARK_LEADER && this.curSubject.stage === "SCORE";
-    },
-    showPaperRelateCount() {
-      return !!this.paramsSet["showPaperCount"];
-    }
-  },
-  mounted() {
-    const subjectId = this.$route.params.subjectId.split("-");
-    this.filter.workId = subjectId[0];
-    this.filter.subject = subjectId[1];
-    this.getAreaList();
-    if (this.IS_MARK_LEADER) this.getLeaderMarkerList();
-    document.addEventListener("keydown", this.keyEvent);
-
-    this.codeTypes = Object.entries(CODE_TYPE)
-      .map(([key, val]) => {
-        return {
-          key,
-          val
-        };
-      })
-      .filter(item => item.key !== "examNumber");
-  },
-  methods: {
-    ...mapMutations("marker", ["setPage", "setAreas", "setRibbonSet"]),
-    async getAreaList() {
-      const data = await areaList(this.filter);
-      const areas = data.map(item => {
-        return {
-          id: item.id,
-          areaName: item.areaName,
-          areaCode: item.areaCode
-        };
-      });
-      this.setAreas(areas);
-
-      if (!this.curArea.id) {
-        this.$emit("area-change", areas[0]);
-      }
-    },
-    async getLeaderMarkerList() {
-      const data = await gradingUserList({
-        ...this.filter,
-        role: "MARKER"
-      });
-      this.markers = data || [];
-      const user = this.$ls.get("user", { id: "", name: "" });
-      this.markers.push({
-        id: user.id,
-        name: "我自己"
-      });
-    },
-    keyEvent(e) {
-      if (!e.altKey && !e.shiftKey && !e.repeat) {
-        // 左右键切换分页
-        if (e.code === "ArrowLeft") {
-          e.preventDefault();
-          if (e.ctrlKey) {
-            this.toFirstPage();
-          } else {
-            this.toPrevPage();
-          }
-          return;
-        }
-
-        if (e.code === "ArrowRight") {
-          e.preventDefault();
-          if (e.ctrlKey) {
-            this.toLastPage();
-          } else {
-            this.toNextPage();
-          }
-          return;
-        }
-      }
-    },
-    areaClick(val) {
-      if (this.curArea.id === val) return;
-      const curArea = this.areas.find(item => item.id === val);
-      this.$emit("area-change", curArea);
-    },
-    stepClick(val) {
-      const curStep = [...this.steps.levelStep, ...this.steps.otherStep].find(
-        item => item.name === val
-      );
-      this.$emit("step-change", curStep);
-    },
-    changeAllSelect(selected) {
-      this.allSelected = selected;
-    },
-    toSelectAll() {
-      this.allSelected = !this.allSelected;
-      this.$emit("to-select-all", this.allSelected);
-    },
-    toProgress() {
-      this.$emit("to-progress");
-    },
-    toHistory() {
-      this.$emit("to-history");
-    },
-    toStandard() {
-      this.$emit("to-standard");
-    },
-    toStatistics() {
-      this.$emit("to-statistics");
-    },
-    pageNoSet() {
-      this.pageNo = this.pageNo || 1;
-      this.setPage({ current: this.pageNo });
-      this.pageSetChange();
-    },
-    toFirstPage() {
-      this.setPage({ current: 1 });
-      this.pageSetChange();
-    },
-    toLastPage() {
-      this.setPage({ current: this.page.totalPage });
-      this.pageSetChange();
-    },
-    toPrevPage() {
-      if (this.page.current === 1) return;
-      this.setPage({ current: this.page.current - 1 });
-      this.pageSetChange();
-    },
-    toNextPage() {
-      if (this.page.current === this.page.totalPage) return;
-      this.setPage({ current: this.page.current + 1 });
-      this.pageSetChange();
-    },
-    pageSizeChange(size) {
-      let current = this.page.current;
-      const newTotalPage = Math.ceil(this.page.total / size);
-      if (newTotalPage < current) {
-        current = newTotalPage;
-      }
-
-      this.setPage({ size, current });
-      this.pageSetChange();
-    },
-    pageSetChange() {
-      this.pageVisible = false;
-      this.$emit("page-set-change", this.page);
-    },
-    searchCodeFilter() {
-      if (!this.codeFilter.code || !this.codeFilter.codeType) {
-        this.$Message.error("请设置密号类型和密号!");
-        return;
-      }
-      this.$emit("on-code-search", this.codeFilter);
-    },
-    searchMarkFilter() {
-      if (!this.markFilter.markerId) {
-        this.$Message.error("请选择评卷员!");
-        return;
-      }
-      this.$emit("on-mark-search", {
-        type: "mark",
-        params: this.markFilter
-      });
-    },
-    closeFastNav() {
-      const userId = this.$ls.get("user", { id: "" }).id;
-      const cacheRibbonSet = window.localStorage.getItem("ribbonSet");
-      const ribbonSet = cacheRibbonSet ? JSON.parse(cacheRibbonSet) : {};
-      ribbonSet[userId] = { fastLevelNav: false };
-      this.setRibbonSet(ribbonSet[userId]);
-      window.localStorage.setItem("ribbonSet", JSON.stringify(ribbonSet));
-    },
-    userClick(name) {
-      if (!name) return;
-      this[name]();
-    },
-    toResetPwd() {
-      this.$refs.ResetPwd.open();
-    },
-    async logout() {
-      await logout();
-      this.$ls.clear();
-      this.$router.push({ name: "Login" });
-    }
-  },
-  beforeDestroy() {
-    document.removeEventListener("keydown", this.keyEvent);
-  }
-};
-</script>
+<template>
+  <div class="marker-header">
+    <div class="header-main">
+      <!-- left action -->
+      <div class="header-group">
+        <div class="header-part">
+          <Dropdown
+            v-if="areas.length > 1"
+            placement="bottom"
+            transfer
+            trigger="click"
+            transfer-class-name="marker-dropdown"
+            @on-click="areaClick"
+          >
+            <span class="el-dropdown-link">
+              {{ curArea.areaName }} <Icon type="ios-arrow-down"></Icon>
+            </span>
+            <DropdownMenu slot="list">
+              <DropdownItem
+                v-for="area in areas"
+                :key="area.id"
+                :name="area.id"
+                >{{ area.areaName }}</DropdownItem
+              >
+            </DropdownMenu>
+          </Dropdown>
+          <p v-else>{{ curArea.areaName }}</p>
+        </div>
+        <div v-if="showStatistics" class="header-part" @click="toStatistics">
+          <p>统计分析 <Icon type="ios-arrow-down"></Icon></p>
+        </div>
+      </div>
+      <!-- header-page -->
+      <div class="header-group header-page">
+        <div v-if="showPaperRelateCount" class="page-total">
+          共{{ page.total }}张
+        </div>
+        <div class="page-item" @click="toFirstPage" title="首页">
+          <Icon type="ios-skip-backward" />
+        </div>
+        <div class="page-item" @click="toPrevPage" title="上一页">
+          <Icon type="md-arrow-dropleft" />
+        </div>
+        <Poptip
+          v-if="showPaperRelateCount"
+          popper-class="marker-popper"
+          placement="bottom"
+          trigger="hover"
+          transfer
+        >
+          <div class="page-item page-cpage">
+            <span>{{ page.current }}</span>
+            <span>/</span><span>{{ page.totalPage }}</span>
+          </div>
+          <div class="marker-page" slot="content">
+            <div class="marker-page-set">
+              <span>页面跳转:</span>
+              <InputNumber
+                size="small"
+                :min="1"
+                :max="page.totalPage"
+                :step="1"
+                :precision="0"
+                v-model="pageNo"
+              ></InputNumber>
+              <div class="marker-page-btn" @click="pageNoSet">跳转</div>
+            </div>
+          </div>
+        </Poptip>
+        <div class="page-item" @click="toNextPage" title="下一页">
+          <Icon type="md-arrow-dropright" />
+        </div>
+        <div class="page-item" @click="toLastPage" title="尾页">
+          <Icon type="ios-skip-forward" />
+        </div>
+        <div class="page-item page-size">
+          <Dropdown
+            placement="bottom"
+            transfer
+            trigger="click"
+            transfer-class-name="marker-dropdown"
+            @on-click="pageSizeChange"
+          >
+            <span class="el-dropdown-link">
+              {{ page.size }}张/页 <Icon type="ios-arrow-down"></Icon>
+            </span>
+            <DropdownMenu slot="list">
+              <DropdownItem
+                v-for="item in pageSizeList"
+                :key="item"
+                :name="item"
+                >{{ item }}</DropdownItem
+              >
+            </DropdownMenu>
+          </Dropdown>
+        </div>
+      </div>
+      <!-- right action -->
+      <div class="header-group">
+        <div
+          v-if="showSelectAll"
+          class="header-part header-selection"
+          @click="toSelectAll"
+        >
+          <div
+            :class="[
+              'image-checkbox',
+              {
+                'image-selected': allSelected,
+              },
+            ]"
+          >
+            <Icon v-if="allSelected" type="md-checkmark" />
+          </div>
+          全选
+        </div>
+        <Poptip
+          v-if="IS_MARK_LEADER"
+          popper-class="marker-popper"
+          placement="bottom"
+          trigger="click"
+          transfer
+        >
+          <div class="header-part header-filter">
+            筛选 <Icon type="ios-arrow-down"></Icon>
+          </div>
+          <div
+            class="header-filter-body dark-mark"
+            slot="content"
+            @keydown.stop
+          >
+            <!-- 查询标记 -->
+            <div class="filter-part">
+              <h4 class="filter-part-title">查询标记试卷</h4>
+              <div class="filter-part-body">
+                <Select
+                  class="filter-select"
+                  v-model="markFilter.markerId"
+                  placeholder="评卷员"
+                >
+                  <Option
+                    v-for="item in markers"
+                    :key="item.id"
+                    :value="item.id"
+                    :label="item.name"
+                  ></Option>
+                </Select>
+                <Button
+                  type="primary"
+                  size="small"
+                  class="filter-btn"
+                  @click="searchMarkFilter"
+                  >查询</Button
+                >
+              </div>
+            </div>
+            <!-- 查询密号 -->
+            <div class="filter-part">
+              <h4 class="filter-part-title">密号查询试卷</h4>
+              <div class="filter-part-body">
+                <Select
+                  class="filter-select"
+                  v-model="codeFilter.codeType"
+                  placeholder="密号类型"
+                >
+                  <Option
+                    v-for="item in codeTypes"
+                    :key="item.key"
+                    :value="item.key"
+                    :label="item.val"
+                  ></Option>
+                </Select>
+                <Input
+                  class="filter-input"
+                  v-model.trim="codeFilter.code"
+                  placeholder="输入密号"
+                  clearable
+                >
+                </Input>
+                <Button
+                  type="primary"
+                  size="small"
+                  class="filter-btn"
+                  @click="searchCodeFilter"
+                  >查询</Button
+                >
+              </div>
+            </div>
+          </div>
+        </Poptip>
+        <div class="header-part header-step">
+          <Dropdown
+            placement="bottom"
+            transfer
+            trigger="click"
+            transfer-class-name="marker-dropdown header-step-dropdown"
+            @on-click="stepClick"
+          >
+            <span class="el-dropdown-link">
+              <i>{{ curStep.name }}</i>
+              <i v-if="showPaperRelateCount">:{{ curStep.count }} </i>
+              <Icon type="ios-arrow-down"></Icon>
+            </span>
+            <DropdownMenu slot="list">
+              <DropdownItem
+                class="header-step-item"
+                v-for="step in steps.otherStep"
+                :key="step.type"
+                :name="step.name"
+              >
+                <i>{{ step.name }}</i>
+                <i v-if="showPaperRelateCount">({{ step.count }})</i>
+              </DropdownItem>
+              <DropdownItem
+                class="header-step-item"
+                v-for="step in steps.levelStep"
+                :key="step.name"
+                :name="step.name"
+              >
+                <i>{{ step.name }}</i>
+                <i v-if="showPaperRelateCount && IS_MARK_LEADER__SCORE">
+                  ({{ step.count }})
+                </i>
+                <i v-if="showPaperRelateCount && !IS_MARK_LEADER__SCORE">
+                  ({{ step.count }} / {{ step.gcount }})
+                </i>
+              </DropdownItem>
+            </DropdownMenu>
+          </Dropdown>
+        </div>
+        <div v-if="IS_MARK_LEADER" class="header-part" @click="toProgress">
+          <p>{{ stageName }}进度 <Icon type="ios-arrow-down"></Icon></p>
+        </div>
+        <div
+          v-if="showStandard && paramsSet.showSample"
+          class="header-part"
+          @click="toStandard"
+        >
+          <p>标准卷 <Icon type="ios-arrow-down"></Icon></p>
+        </div>
+        <div
+          class="header-part header-history"
+          id="header-history"
+          @click="toHistory"
+        >
+          <p>操作记录 <Icon type="ios-arrow-down"></Icon></p>
+        </div>
+        <div class="header-user" id="header-user">
+          <Dropdown
+            placement="bottom"
+            transfer
+            trigger="click"
+            transfer-class-name="marker-dropdown"
+            @on-click="userClick"
+          >
+            <div class="user-name">
+              <Icon type="md-person" size="16" /> {{ username }}
+              <Icon type="ios-arrow-down"></Icon>
+            </div>
+            <DropdownMenu slot="list">
+              <DropdownItem class="color-default-hover" name="toResetPwd"
+                >修改密码</DropdownItem
+              >
+              <DropdownItem class="color-error-hover" name="logout">
+                退出登录
+              </DropdownItem>
+            </DropdownMenu>
+          </Dropdown>
+        </div>
+      </div>
+    </div>
+
+    <!-- fast-level-nav -->
+    <div v-if="ribbonSet.fastLevelNav" class="header-group fast-nav">
+      <div class="fast-nav-list">
+        <div
+          v-for="step in steps.levelStep"
+          :key="step.name"
+          :class="[
+            'fast-nav-item',
+            { 'is-active': curStep.name === step.name },
+          ]"
+          @click="stepClick(step.name)"
+        >
+          {{ step.name
+          }}<span v-if="showPaperRelateCount">({{ step.count }})</span>
+        </div>
+        <div
+          v-for="step in steps.otherStep"
+          :key="step.name"
+          :class="[
+            'fast-nav-item',
+            { 'is-active': curStep.name === step.name },
+          ]"
+          @click="stepClick(step.name)"
+        >
+          {{ step.name }}
+          <span v-if="showPaperRelateCount">({{ step.count }})</span>
+        </div>
+        <div
+          class="fast-nav-item fast-nav-close is-danger"
+          title="关闭快捷档位导航"
+          @click="closeFastNav"
+        >
+          <Icon type="md-close" :size="18" />
+        </div>
+      </div>
+    </div>
+
+    <!-- ResetPwd -->
+    <reset-pwd ref="ResetPwd"></reset-pwd>
+  </div>
+</template>
+
+<script>
+import { mapState, mapMutations } from "vuex";
+import { areaList, gradingUserList, logout } from "@/api";
+import ResetPwd from "@/modules/login/ResetPwd";
+import { CODE_TYPE } from "@/constants/enumerate";
+
+export default {
+  name: "marker-header",
+  components: { ResetPwd },
+  props: {
+    showStandard: {
+      type: Boolean,
+      default: true,
+    },
+    showStatistics: {
+      type: Boolean,
+      default: true,
+    },
+    showSelectAll: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      filter: {
+        workId: "",
+        subject: "",
+      },
+      username: this.$ls.get("user", { loginName: "" }).loginName,
+      pageVisible: false,
+      pageSizeList: [2, 3, 4, 6, 8, 9, 10, 12, 15, 16, 20, 24],
+      pageNo: 1,
+      allSelected: false,
+      codeTypes: [],
+      codeFilter: {
+        codeType: "examNumber",
+        code: "",
+      },
+      markers: [],
+      markFilter: {
+        markerId: "",
+      },
+    };
+  },
+  computed: {
+    ...mapState("marker", [
+      "paramsSet",
+      "page",
+      "curStep",
+      "steps",
+      "curArea",
+      "curSubject",
+      "areas",
+      "IS_MARK_LEADER",
+      "ribbonSet",
+    ]),
+    stageName() {
+      return this.curSubject.stage === "LEVEL" ? "分档" : "打分";
+    },
+    IS_MARK_LEADER__SCORE() {
+      return this.IS_MARK_LEADER && this.curSubject.stage === "SCORE";
+    },
+    showPaperRelateCount() {
+      return !!this.paramsSet["showPaperCount"];
+    },
+  },
+  mounted() {
+    const subjectId = this.$route.params.subjectId.split("-");
+    this.filter.workId = subjectId[0];
+    this.filter.subject = subjectId[1];
+    this.getAreaList();
+    if (this.IS_MARK_LEADER) this.getLeaderMarkerList();
+    document.addEventListener("keydown", this.keyEvent);
+
+    this.codeTypes = Object.entries(CODE_TYPE)
+      .map(([key, val]) => {
+        return {
+          key,
+          val,
+        };
+      })
+      .filter((item) => item.key !== "examNumber");
+  },
+  methods: {
+    ...mapMutations("marker", ["setPage", "setAreas", "setRibbonSet"]),
+    async getAreaList() {
+      const data = await areaList(this.filter);
+      const areas = data.map((item) => {
+        return {
+          id: item.id,
+          areaName: item.areaName,
+          areaCode: item.areaCode,
+        };
+      });
+      this.setAreas(areas);
+
+      if (!this.curArea.id) {
+        this.$emit("area-change", areas[0]);
+      }
+    },
+    async getLeaderMarkerList() {
+      const data = await gradingUserList({
+        ...this.filter,
+        role: "MARKER",
+      });
+      this.markers = data || [];
+      const user = this.$ls.get("user", { id: "", name: "" });
+      this.markers.push({
+        id: user.id,
+        name: "我自己",
+      });
+    },
+    keyEvent(e) {
+      if (!e.altKey && !e.shiftKey && !e.repeat) {
+        // 左右键切换分页
+        if (e.code === "ArrowLeft") {
+          e.preventDefault();
+          if (e.ctrlKey) {
+            this.toFirstPage();
+          } else {
+            this.toPrevPage();
+          }
+          return;
+        }
+
+        if (e.code === "ArrowRight") {
+          e.preventDefault();
+          if (e.ctrlKey) {
+            this.toLastPage();
+          } else {
+            this.toNextPage();
+          }
+          return;
+        }
+      }
+    },
+    areaClick(val) {
+      if (this.curArea.id === val) return;
+      const curArea = this.areas.find((item) => item.id === val);
+      this.$emit("area-change", curArea);
+    },
+    stepClick(val) {
+      const curStep = [...this.steps.levelStep, ...this.steps.otherStep].find(
+        (item) => item.name === val
+      );
+      this.$emit("step-change", curStep);
+    },
+    changeAllSelect(selected) {
+      this.allSelected = selected;
+    },
+    toSelectAll() {
+      this.allSelected = !this.allSelected;
+      this.$emit("to-select-all", this.allSelected);
+    },
+    toProgress() {
+      this.$emit("to-progress");
+    },
+    toHistory() {
+      this.$emit("to-history");
+    },
+    toStandard() {
+      this.$emit("to-standard");
+    },
+    toStatistics() {
+      this.$emit("to-statistics");
+    },
+    pageNoSet() {
+      this.pageNo = this.pageNo || 1;
+      this.setPage({ current: this.pageNo });
+      this.pageSetChange();
+    },
+    toFirstPage() {
+      this.setPage({ current: 1 });
+      this.pageSetChange();
+    },
+    toLastPage() {
+      this.setPage({ current: this.page.totalPage });
+      this.pageSetChange();
+    },
+    toPrevPage() {
+      if (this.page.current === 1) return;
+      this.setPage({ current: this.page.current - 1 });
+      this.pageSetChange();
+    },
+    toNextPage() {
+      if (this.page.current === this.page.totalPage) return;
+      this.setPage({ current: this.page.current + 1 });
+      this.pageSetChange();
+    },
+    pageSizeChange(size) {
+      let current = this.page.current;
+      const newTotalPage = Math.ceil(this.page.total / size);
+      if (newTotalPage < current) {
+        current = newTotalPage;
+      }
+
+      this.setPage({ size, current });
+      this.pageSetChange();
+    },
+    pageSetChange() {
+      this.pageVisible = false;
+      this.$emit("page-set-change", this.page);
+    },
+    searchCodeFilter() {
+      if (!this.codeFilter.code || !this.codeFilter.codeType) {
+        this.$Message.error("请设置密号类型和密号!");
+        return;
+      }
+      this.$emit("on-code-search", this.codeFilter);
+    },
+    searchMarkFilter() {
+      if (!this.markFilter.markerId) {
+        this.$Message.error("请选择评卷员!");
+        return;
+      }
+      this.$emit("on-mark-search", {
+        type: "mark",
+        params: this.markFilter,
+      });
+    },
+    closeFastNav() {
+      const userId = this.$ls.get("user", { id: "" }).id;
+      const cacheRibbonSet = window.localStorage.getItem("ribbonSet");
+      const ribbonSet = cacheRibbonSet ? JSON.parse(cacheRibbonSet) : {};
+      ribbonSet[userId] = { fastLevelNav: false };
+      this.setRibbonSet(ribbonSet[userId]);
+      window.localStorage.setItem("ribbonSet", JSON.stringify(ribbonSet));
+    },
+    userClick(name) {
+      if (!name) return;
+      this[name]();
+    },
+    toResetPwd() {
+      this.$refs.ResetPwd.open();
+    },
+    async logout() {
+      await logout();
+      this.$ls.clear();
+      this.$router.push({ name: "Login" });
+    },
+  },
+  beforeDestroy() {
+    document.removeEventListener("keydown", this.keyEvent);
+  },
+};
+</script>

+ 138 - 138
src/modules/grading/marker/MarkerHistory.vue

@@ -1,138 +1,138 @@
-<template>
-  <Modal
-    v-model="modalIsShow"
-    class="marker-history marker-modal"
-    title="操作记录"
-    footer-hide
-    :transition-names="['slide-up', 'fade']"
-    @on-visible-change="visibleChange"
-  >
-    <div class="history-image-list marker-image-list" v-if="papers.length">
-      <div
-        v-for="(paper, index) in papers"
-        :key="paper.id"
-        class="marker-image-item"
-      >
-        <div class="marker-image-content">
-          <marker-image-view :data="paper" @to-review="toReview(index)">
-            <div class="image-info">
-              <div class="image-level">
-                {{ paper.actionResult }}
-              </div>
-              <div class="image-action-name">{{ paper.actionName }}</div>
-            </div>
-            <div class="image-sn" :title="'NO.' + paper.sn">
-              NO.{{ paper.sn }}
-            </div>
-          </marker-image-view>
-        </div>
-      </div>
-    </div>
-    <div v-else class="history-image-list marker-image-none">暂无数据</div>
-  </Modal>
-</template>
-
-<script>
-import { mapState } from "vuex";
-
-import { actionHistory, actionLeaderHistory } from "@/api";
-import MarkerImageView from "./MarkerImageView";
-
-export default {
-  name: "marker-history",
-  props: {
-    questionId: {
-      type: [Number, String]
-    },
-    stage: {
-      type: String,
-      default: "LEVEL"
-    }
-  },
-  components: { MarkerImageView },
-  data() {
-    return {
-      modalIsShow: false,
-      workId: "",
-      subject: "",
-      subjectId: this.$route.params.subjectId,
-      userId: "",
-      curPaper: {},
-      papers: []
-    };
-  },
-  computed: {
-    ...mapState("marker", ["IS_MARK_LEADER"])
-  },
-  mounted() {
-    this.userId = this.$ls.get("user", { id: "" }).id;
-    const subjectId = this.subjectId.split("-");
-    this.workId = subjectId[0];
-    this.subject = subjectId[1];
-  },
-  methods: {
-    visibleChange(visible) {
-      if (visible) {
-        this.updatePapers();
-      }
-    },
-    async updatePapers() {
-      let data = [];
-      if (this.IS_MARK_LEADER) {
-        const datas = {
-          workId: this.workId,
-          subject: this.subject,
-          questionId: this.questionId
-        };
-
-        data = await actionLeaderHistory(datas);
-      } else {
-        const datas = {
-          markerId: this.userId,
-          stage: this.stage,
-          questionId: this.questionId
-        };
-
-        data = await actionHistory(datas);
-      }
-
-      this.papers = data;
-      this.papers.forEach(paper => {
-        paper.actionResult = this.IS_MARK_LEADER ? paper.level : paper.result;
-        paper.actionName = this.IS_MARK_LEADER
-          ? this.getLeaderActionName(paper)
-          : "已评";
-      });
-    },
-    getLeaderActionName(paper) {
-      const names = {
-        oneClick: "一键定档",
-        sample: "设立标准卷",
-        isRejectedByLeader: "打回"
-      };
-      const typeKey = Object.keys(names).find(key => paper[key]);
-      return typeKey && names[typeKey];
-    },
-    updateCachePapers(papers) {
-      papers.forEach(paper => {
-        const paperIndex = this.papers.findIndex(
-          item => item.paperId === paper.paperId
-        );
-        if (paperIndex !== -1) {
-          this.papers.splice(paperIndex, 1);
-        }
-      });
-      this.papers = [...this.papers, ...papers].slice(-5);
-    },
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    },
-    toReview(index) {
-      this.$emit("on-paper-click", index, this.papers);
-    }
-  }
-};
-</script>
+<template>
+  <Modal
+    v-model="modalIsShow"
+    class="marker-history marker-modal"
+    title="操作记录"
+    footer-hide
+    :transition-names="['slide-up', 'fade']"
+    @on-visible-change="visibleChange"
+  >
+    <div class="history-image-list marker-image-list" v-if="papers.length">
+      <div
+        v-for="(paper, index) in papers"
+        :key="paper.id"
+        class="marker-image-item"
+      >
+        <div class="marker-image-content">
+          <marker-image-view :data="paper" @to-review="toReview(index)">
+            <div class="image-info">
+              <div class="image-level">
+                {{ paper.actionResult }}
+              </div>
+              <div class="image-action-name">{{ paper.actionName }}</div>
+            </div>
+            <div class="image-sn" :title="'NO.' + paper.sn">
+              NO.{{ paper.sn }}
+            </div>
+          </marker-image-view>
+        </div>
+      </div>
+    </div>
+    <div v-else class="history-image-list marker-image-none">暂无数据</div>
+  </Modal>
+</template>
+
+<script>
+import { mapState } from "vuex";
+
+import { actionHistory, actionLeaderHistory } from "@/api";
+import MarkerImageView from "./MarkerImageView";
+
+export default {
+  name: "marker-history",
+  props: {
+    questionId: {
+      type: [Number, String],
+    },
+    stage: {
+      type: String,
+      default: "LEVEL",
+    },
+  },
+  components: { MarkerImageView },
+  data() {
+    return {
+      modalIsShow: false,
+      workId: "",
+      subject: "",
+      subjectId: this.$route.params.subjectId,
+      userId: "",
+      curPaper: {},
+      papers: [],
+    };
+  },
+  computed: {
+    ...mapState("marker", ["IS_MARK_LEADER"]),
+  },
+  mounted() {
+    this.userId = this.$ls.get("user", { id: "" }).id;
+    const subjectId = this.subjectId.split("-");
+    this.workId = subjectId[0];
+    this.subject = subjectId[1];
+  },
+  methods: {
+    visibleChange(visible) {
+      if (visible) {
+        this.updatePapers();
+      }
+    },
+    async updatePapers() {
+      let data = [];
+      if (this.IS_MARK_LEADER) {
+        const datas = {
+          workId: this.workId,
+          subject: this.subject,
+          questionId: this.questionId,
+        };
+
+        data = await actionLeaderHistory(datas);
+      } else {
+        const datas = {
+          markerId: this.userId,
+          stage: this.stage,
+          questionId: this.questionId,
+        };
+
+        data = await actionHistory(datas);
+      }
+
+      this.papers = data;
+      this.papers.forEach((paper) => {
+        paper.actionResult = this.IS_MARK_LEADER ? paper.level : paper.result;
+        paper.actionName = this.IS_MARK_LEADER
+          ? this.getLeaderActionName(paper)
+          : "已评";
+      });
+    },
+    getLeaderActionName(paper) {
+      const names = {
+        oneClick: "一键定档",
+        sample: "设立标准卷",
+        isRejectedByLeader: "打回",
+      };
+      const typeKey = Object.keys(names).find((key) => paper[key]);
+      return typeKey && names[typeKey];
+    },
+    updateCachePapers(papers) {
+      papers.forEach((paper) => {
+        const paperIndex = this.papers.findIndex(
+          (item) => item.paperId === paper.paperId
+        );
+        if (paperIndex !== -1) {
+          this.papers.splice(paperIndex, 1);
+        }
+      });
+      this.papers = [...this.papers, ...papers].slice(-5);
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    toReview(index) {
+      this.$emit("on-paper-click", index, this.papers);
+    },
+  },
+};
+</script>

+ 158 - 158
src/modules/grading/marker/MarkerImageView.vue

@@ -1,158 +1,158 @@
-<template>
-  <div class="marker-image-view">
-    <image-view-contain
-      ref="ImageViewContain"
-      :image="image"
-      @to-review="toReview"
-    ></image-view-contain>
-    <div class="image-view-footer">
-      <slot>
-        <div v-if="IS_LEVEL" class="image-info">
-          <div v-if="image.level" class="image-level">{{ image.level }}</div>
-          <div v-if="image.sample" class="image-sample">标</div>
-          <div
-            v-else
-            :class="[
-              'image-checkbox',
-              {
-                'image-selected': image.selected
-              }
-            ]"
-            @click="toSelect"
-          >
-            <Icon v-if="image.selected" type="md-checkmark" />
-          </div>
-        </div>
-        <div v-else class="image-info">
-          <div v-if="image.level" class="image-level">{{ image.level }}</div>
-          <div v-if="image.score" class="image-level">{{ image.score }}</div>
-        </div>
-        <div
-          v-if="IS_LEVEL"
-          class="image-title"
-          :title="image.title"
-          @click="toSelect"
-        >
-          {{ image.title }}
-        </div>
-        <div class="image-action">
-          <div
-            :class="['image-action-li', { 'is-disabled': image.markDisabled }]"
-            @click="toMark"
-          >
-            <Icon :class="{ 'mark-act': image.mark }" type="md-bookmark" />
-          </div>
-          <div class="image-action-li" @click="toRotate">
-            <Icon type="md-refresh-circle" />
-          </div>
-        </div>
-      </slot>
-    </div>
-  </div>
-</template>
-
-<script>
-import ImageViewContain from "@/components/ImageViewContain";
-import { markTask, markPaper } from "@/api";
-
-export default {
-  name: "marker-image-view",
-  components: { ImageViewContain },
-  props: {
-    data: {
-      type: Object,
-      default() {
-        return {};
-      }
-    },
-    stage: {
-      type: String,
-      default: "LEVEL"
-    },
-    canSelect: {
-      type: Boolean,
-      default: true
-    }
-  },
-  computed: {
-    IS_LEVEL() {
-      return this.stage === "LEVEL";
-    }
-  },
-  created() {
-    this.initData();
-  },
-  watch: {
-    "data.selected": {
-      handler() {
-        this.initData();
-      }
-    }
-  },
-  data() {
-    return {
-      curUserRoleType: this.$ls.get("user", { role: "" }).role,
-      initImage: {
-        id: "",
-        thumbSrc: "",
-        title: "",
-        level: "",
-        score: "",
-        deg: 0,
-        mark: false,
-        markDisabled: false,
-        sample: false,
-        selected: false
-      },
-      loading: false,
-      image: {}
-    };
-  },
-  methods: {
-    initData() {
-      this.image = this.$objAssign(this.initImage, this.data);
-    },
-    toReview() {
-      this.$emit("to-review", this.data);
-    },
-    toRotate() {
-      const image = this.image;
-      image.deg += 90;
-      if (image.deg === 360) image.deg = 0;
-
-      this.$refs.ImageViewContain.resizeImage(image.deg);
-    },
-    async toMark() {
-      if (this.image.markDisabled) return;
-      if (this.loading) return;
-      this.loading = true;
-      let res = null;
-      if (this.curUserRoleType === "MARK_LEADER") {
-        res = await markPaper({
-          paperId: this.image.id,
-          isMark: !this.image.mark,
-          role: this.curUserRoleType
-        }).catch(() => {});
-      } else {
-        res = await markTask({
-          markTaskId: this.image.id,
-          isMark: !this.image.mark
-        }).catch(() => {});
-      }
-      this.loading = false;
-      if (!res) return;
-      this.image.mark = !this.image.mark;
-    },
-    toSelect() {
-      if (this.image.sample || !this.IS_LEVEL) return;
-      this.image.selected = !this.image.selected;
-      this.$emit("to-select", this.image);
-    },
-    changeSelect(selected) {
-      if (this.image.sample) return;
-      this.image.selected = selected;
-      this.$emit("to-select", this.image);
-    }
-  }
-};
-</script>
+<template>
+  <div class="marker-image-view">
+    <image-view-contain
+      ref="ImageViewContain"
+      :image="image"
+      @to-review="toReview"
+    ></image-view-contain>
+    <div class="image-view-footer">
+      <slot>
+        <div v-if="IS_LEVEL" class="image-info">
+          <div v-if="image.level" class="image-level">{{ image.level }}</div>
+          <div v-if="image.sample" class="image-sample">标</div>
+          <div
+            v-else
+            :class="[
+              'image-checkbox',
+              {
+                'image-selected': image.selected,
+              },
+            ]"
+            @click="toSelect"
+          >
+            <Icon v-if="image.selected" type="md-checkmark" />
+          </div>
+        </div>
+        <div v-else class="image-info">
+          <div v-if="image.level" class="image-level">{{ image.level }}</div>
+          <div v-if="image.score" class="image-level">{{ image.score }}</div>
+        </div>
+        <div
+          v-if="IS_LEVEL"
+          class="image-title"
+          :title="image.title"
+          @click="toSelect"
+        >
+          {{ image.title }}
+        </div>
+        <div class="image-action">
+          <div
+            :class="['image-action-li', { 'is-disabled': image.markDisabled }]"
+            @click="toMark"
+          >
+            <Icon :class="{ 'mark-act': image.mark }" type="md-bookmark" />
+          </div>
+          <div class="image-action-li" @click="toRotate">
+            <Icon type="md-refresh-circle" />
+          </div>
+        </div>
+      </slot>
+    </div>
+  </div>
+</template>
+
+<script>
+import ImageViewContain from "@/components/ImageViewContain";
+import { markTask, markPaper } from "@/api";
+
+export default {
+  name: "marker-image-view",
+  components: { ImageViewContain },
+  props: {
+    data: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    stage: {
+      type: String,
+      default: "LEVEL",
+    },
+    canSelect: {
+      type: Boolean,
+      default: true,
+    },
+  },
+  computed: {
+    IS_LEVEL() {
+      return this.stage === "LEVEL";
+    },
+  },
+  created() {
+    this.initData();
+  },
+  watch: {
+    "data.selected": {
+      handler() {
+        this.initData();
+      },
+    },
+  },
+  data() {
+    return {
+      curUserRoleType: this.$ls.get("user", { role: "" }).role,
+      initImage: {
+        id: "",
+        thumbSrc: "",
+        title: "",
+        level: "",
+        score: "",
+        deg: 0,
+        mark: false,
+        markDisabled: false,
+        sample: false,
+        selected: false,
+      },
+      loading: false,
+      image: {},
+    };
+  },
+  methods: {
+    initData() {
+      this.image = this.$objAssign(this.initImage, this.data);
+    },
+    toReview() {
+      this.$emit("to-review", this.data);
+    },
+    toRotate() {
+      const image = this.image;
+      image.deg += 90;
+      if (image.deg === 360) image.deg = 0;
+
+      this.$refs.ImageViewContain.resizeImage(image.deg);
+    },
+    async toMark() {
+      if (this.image.markDisabled) return;
+      if (this.loading) return;
+      this.loading = true;
+      let res = null;
+      if (this.curUserRoleType === "MARK_LEADER") {
+        res = await markPaper({
+          paperId: this.image.id,
+          isMark: !this.image.mark,
+          role: this.curUserRoleType,
+        }).catch(() => {});
+      } else {
+        res = await markTask({
+          markTaskId: this.image.id,
+          isMark: !this.image.mark,
+        }).catch(() => {});
+      }
+      this.loading = false;
+      if (!res) return;
+      this.image.mark = !this.image.mark;
+    },
+    toSelect() {
+      if (this.image.sample || !this.IS_LEVEL) return;
+      this.image.selected = !this.image.selected;
+      this.$emit("to-select", this.image);
+    },
+    changeSelect(selected) {
+      if (this.image.sample) return;
+      this.image.selected = selected;
+      this.$emit("to-select", this.image);
+    },
+  },
+};
+</script>

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

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

+ 11 - 11
src/modules/grading/marker/MarkerStatistics.vue

@@ -52,14 +52,14 @@ export default {
   data() {
     return {
       modalIsShow: false,
-      lineChartData: null
+      lineChartData: null,
     };
   },
   computed: {
     ...mapState("marker", ["paramsSet", "steps"]),
     showPaperRelateCount() {
       return !!this.paramsSet["showPaperCount"];
-    }
+    },
   },
   methods: {
     visibleChange(visible) {
@@ -73,23 +73,23 @@ export default {
       const groups = [
         {
           key: "percent",
-          label: "当前批次评卷员"
+          label: "当前批次评卷员",
         },
         {
           key: "gpercent",
-          label: "考区定档"
-        }
+          label: "考区定档",
+        },
       ];
-      this.lineChartData = groups.map(group => {
-        const data = this.steps.levelStep.map(item => {
+      this.lineChartData = groups.map((group) => {
+        const data = this.steps.levelStep.map((item) => {
           return {
             name: item.name,
-            value: item[group.key]
+            value: item[group.key],
           };
         });
         return {
           name: group.label,
-          data
+          data,
         };
       });
     },
@@ -102,7 +102,7 @@ export default {
     stepClick(step) {
       this.cancel();
       this.$emit("step-change", step.name);
-    }
-  }
+    },
+  },
 };
 </script>

+ 77 - 77
src/modules/grading/marker/store.js

@@ -1,77 +1,77 @@
-const state = {
-  paramsSet: {},
-  page: {
-    current: 1,
-    size: 12,
-    total: 0,
-    totalPage: 1
-  },
-  steps: {},
-  curStep: { name: "", count: 0 },
-  areas: [],
-  curArea: {},
-  curSubject: {},
-  curUserRoleType: "",
-  IS_MARKER: false,
-  IS_MARK_LEADER: false,
-  ribbonSet: { fastLevelNav: false }
-};
-const mutations = {
-  setParamSet(state, paramsSet) {
-    state.paramsSet = paramsSet;
-  },
-  setPage(state, page) {
-    if (
-      Object.prototype.hasOwnProperty.call(page, "totalPage") &&
-      !page.totalPage
-    )
-      page.totalPage = 1;
-
-    state.page = Object.assign({}, state.page, page);
-  },
-  setSteps(state, steps) {
-    state.steps = steps;
-  },
-  setCurStep(state, curStep) {
-    state.curStep = curStep;
-  },
-  setAreas(state, areas) {
-    state.areas = areas;
-  },
-  setCurArea(state, curArea) {
-    state.curArea = curArea;
-  },
-  setCurSubject(state, curSubject) {
-    state.curSubject = curSubject;
-  },
-  setCurUserRoleType(state, curUserRoleType) {
-    state.curUserRoleType = curUserRoleType;
-    state.IS_MARKER = curUserRoleType === "MARKER";
-    state.IS_MARK_LEADER = curUserRoleType === "MARK_LEADER";
-  },
-  setRibbonSet(state, ribbonSet) {
-    state.ribbonSet = ribbonSet;
-  },
-  clearState(state) {
-    state.paramsSet = {};
-    state.page = {
-      current: 1,
-      size: 12,
-      total: 0,
-      totalPage: 1
-    };
-    state.steps = {};
-    state.curStep = { name: "", count: 0 };
-    state.curArea = {};
-    state.curSubject = {};
-    state.curUserRoleType = "";
-    state.IS_MARKER = false;
-    state.IS_MARK_LEADER = false;
-  }
-};
-
-export default {
-  namespaced: true,
-  state,
-  mutations
-};
+const state = {
+  paramsSet: {},
+  page: {
+    current: 1,
+    size: 12,
+    total: 0,
+    totalPage: 1,
+  },
+  steps: {},
+  curStep: { name: "", count: 0 },
+  areas: [],
+  curArea: {},
+  curSubject: {},
+  curUserRoleType: "",
+  IS_MARKER: false,
+  IS_MARK_LEADER: false,
+  ribbonSet: { fastLevelNav: false },
+};
+const mutations = {
+  setParamSet(state, paramsSet) {
+    state.paramsSet = paramsSet;
+  },
+  setPage(state, page) {
+    if (
+      Object.prototype.hasOwnProperty.call(page, "totalPage") &&
+      !page.totalPage
+    )
+      page.totalPage = 1;
+
+    state.page = Object.assign({}, state.page, page);
+  },
+  setSteps(state, steps) {
+    state.steps = steps;
+  },
+  setCurStep(state, curStep) {
+    state.curStep = curStep;
+  },
+  setAreas(state, areas) {
+    state.areas = areas;
+  },
+  setCurArea(state, curArea) {
+    state.curArea = curArea;
+  },
+  setCurSubject(state, curSubject) {
+    state.curSubject = curSubject;
+  },
+  setCurUserRoleType(state, curUserRoleType) {
+    state.curUserRoleType = curUserRoleType;
+    state.IS_MARKER = curUserRoleType === "MARKER";
+    state.IS_MARK_LEADER = curUserRoleType === "MARK_LEADER";
+  },
+  setRibbonSet(state, ribbonSet) {
+    state.ribbonSet = ribbonSet;
+  },
+  clearState(state) {
+    state.paramsSet = {};
+    state.page = {
+      current: 1,
+      size: 12,
+      total: 0,
+      totalPage: 1,
+    };
+    state.steps = {};
+    state.curStep = { name: "", count: 0 };
+    state.curArea = {};
+    state.curSubject = {};
+    state.curUserRoleType = "";
+    state.IS_MARKER = false;
+    state.IS_MARK_LEADER = false;
+  },
+};
+
+export default {
+  namespaced: true,
+  state,
+  mutations,
+};

+ 4 - 4
src/modules/inspection/Inspection.vue

@@ -12,7 +12,7 @@
             <i
               :class="[
                 'icon',
-                curNav.name === nav.name ? `${nav.icon}-act` : nav.icon
+                curNav.name === nav.name ? `${nav.icon}-act` : nav.icon,
               ]"
               v-if="nav.icon"
             ></i>
@@ -44,11 +44,11 @@ export default {
     $route: {
       handler(val) {
         this.actCurNav(val);
-      }
-    }
+      },
+    },
   },
   mounted() {
     this.actCurNav(this.$route);
-  }
+  },
 };
 </script>

+ 19 - 19
src/modules/inspection/InspectionActionLogs.vue

@@ -118,7 +118,7 @@ export default {
         studentName: "",
         operType: null,
         startTime: null,
-        endTime: null
+        endTime: null,
       },
       actionTypes: [],
       ACTION_TYPE: {},
@@ -133,53 +133,53 @@ export default {
       columns: [
         {
           title: "工作",
-          key: "workName"
+          key: "workName",
         },
         {
           title: "操作人",
-          key: "createUserName"
+          key: "createUserName",
         },
         {
           title: "角色",
-          key: "createRole"
+          key: "createRole",
         },
         {
           title: "科目",
           key: "subject",
           render: (h, param) => {
             return h("div", this.SUBJECT_TYPE[param.row.subject]);
-          }
+          },
         },
         {
           title: "准考证号",
           key: "examNumber",
-          width: 130
+          width: 130,
         },
         {
           title: "学生姓名",
-          key: "studentName"
+          key: "studentName",
         },
         {
           title: "操作类型",
           key: "operType",
           render: (h, param) => {
             return h("div", this.ACTION_TYPE[param.row.operType]);
-          }
+          },
         },
         {
           title: "操作前数据",
-          key: "operDataBefore"
+          key: "operDataBefore",
         },
         {
           title: "操作后数据",
-          key: "operDataAfter"
+          key: "operDataAfter",
         },
         {
           title: "操作时间",
           key: "createTime",
-          width: 200
-        }
-      ]
+          width: 200,
+        },
+      ],
     };
   },
   mounted() {
@@ -196,7 +196,7 @@ export default {
     },
     async getActionTypeList() {
       this.actionTypes = await logTypeList();
-      this.actionTypes.map(item => {
+      this.actionTypes.map((item) => {
         this.ACTION_TYPE[item.id] = item.name;
       });
     },
@@ -207,7 +207,7 @@ export default {
       const datas = {
         ...this.filter,
         curPage: this.current - 1,
-        pageSize: this.size
+        pageSize: this.size,
       };
 
       const data = await inspectionActionLogPageList(filterObjNull(datas));
@@ -219,14 +219,14 @@ export default {
       this.getList();
     },
     toSearch() {
-      this.subjects.map(item => {
+      this.subjects.map((item) => {
         this.SUBJECT_TYPE[item.subject] = item.name;
       });
       this.toPage(1);
     },
     workChange() {
       this.filter.subject = null;
-      const curWork = this.works.find(item => item.id === this.filter.workId);
+      const curWork = this.works.find((item) => item.id === this.filter.workId);
       this.subjects = curWork.subjects;
       this.filter.subject = this.subjects[0].subject;
     },
@@ -244,7 +244,7 @@ export default {
           `${this.GLOBAL.domain}/api/export/log/oper?${qsParams(this.filter)}`
         )
       );
-    }
-  }
+    },
+  },
 };
 </script>

+ 18 - 18
src/modules/inspection/InspectionCollectLogs.vue

@@ -107,7 +107,7 @@
 import {
   inspectionCollectLogPageList,
   workList,
-  clientUserPageList
+  clientUserPageList,
 } from "@/api";
 import { filterObjNull, qsParams } from "@/plugins/utils";
 
@@ -122,7 +122,7 @@ export default {
         studentName: "",
         createUserId: null,
         startTime: null,
-        endTime: null
+        endTime: null,
       },
       current: 1,
       size: this.GLOBAL.pageSize,
@@ -135,41 +135,41 @@ export default {
       columns: [
         {
           title: "工作",
-          key: "workName"
+          key: "workName",
         },
         {
           title: "科目",
-          key: "subject"
+          key: "subject",
         },
         {
           title: "学生姓名",
-          key: "studentName"
+          key: "studentName",
         },
         {
           title: "准考证号",
           key: "examNumber",
-          width: 130
+          width: 130,
         },
         {
           title: "采集账号",
-          key: "createUserName"
+          key: "createUserName",
         },
         {
           title: "上传时间",
           key: "createTime",
-          width: 200
+          width: 200,
         },
 
         {
           title: "识别方式",
-          key: "remark"
+          key: "remark",
         },
         {
           title: "登录时间",
           key: "loginTime",
-          width: 200
-        }
-      ]
+          width: 200,
+        },
+      ],
     };
   },
   mounted() {
@@ -186,9 +186,9 @@ export default {
       const data = await clientUserPageList({
         workId,
         curPage: 0,
-        pageSize: 100
+        pageSize: 100,
       });
-      this.collectionUsers = data.data.filter(item => item.enabled);
+      this.collectionUsers = data.data.filter((item) => item.enabled);
     },
     async getWorkList() {
       this.works = await workList();
@@ -197,7 +197,7 @@ export default {
       const datas = {
         ...this.filter,
         curPage: this.current - 1,
-        pageSize: this.size
+        pageSize: this.size,
       };
       const data = await inspectionCollectLogPageList(filterObjNull(datas));
       this.dataList = data.data;
@@ -210,7 +210,7 @@ export default {
     workChange() {
       this.filter.subject = null;
       this.filter.createUserId = null;
-      const curWork = this.works.find(item => item.id === this.filter.workId);
+      const curWork = this.works.find((item) => item.id === this.filter.workId);
       this.subjects = curWork.subjects;
       this.filter.subject = this.subjects[0].subject;
       this.getCollectionUsers(this.filter.workId);
@@ -231,7 +231,7 @@ export default {
           )}`
         )
       );
-    }
-  }
+    },
+  },
 };
 </script>

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

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

+ 2 - 4
src/modules/inspection/InspectionScore.vue

@@ -1,7 +1,5 @@
 <template>
-  <div class="inspection-score">
-    直接使用-main-StudentScore
-  </div>
+  <div class="inspection-score">直接使用-main-StudentScore</div>
 </template>
 
 <script>
@@ -10,6 +8,6 @@ export default {
   data() {
     return {};
   },
-  methods: {}
+  methods: {},
 };
 </script>

+ 21 - 21
src/modules/login/LoginHome.vue

@@ -27,7 +27,7 @@
               clearable
             ></Input>
           </FormItem>
-          <FormItem style="margin-top:70px;">
+          <FormItem style="margin-top: 70px">
             <Button
               class="login-submit"
               long
@@ -67,7 +67,7 @@ export default {
     return {
       loginModel: {
         loginName: "",
-        password: ""
+        password: "",
       },
       loginRules: {
         loginName: [
@@ -75,44 +75,44 @@ export default {
             required: true,
             pattern: /^[a-zA-Z0-9_-]{2,40}$/,
             message: "用户名只能包含字母、数字、下划线以及短横线",
-            trigger: "change"
-          }
+            trigger: "change",
+          },
         ],
-        password
+        password,
       },
       rightRoutes: {
         SUPER_ADMIN: {
-          router: "OrgManage"
+          router: "OrgManage",
         },
         ADMIN: {
-          router: "WorkManage"
+          router: "WorkManage",
         },
         MARKER_LEVEL: {
-          router: "MarkerGrading"
+          router: "MarkerGrading",
         },
         MARKER_SCORE: {
-          router: "MarkerMarking"
+          router: "MarkerMarking",
         },
         MARK_LEADER_LEVEL: {
-          router: "LeaderGrading"
+          router: "LeaderGrading",
         },
         MARK_LEADER_SCORE: {
-          router: "LeaderMarking"
+          router: "LeaderMarking",
         },
         INSPECTION: {
-          router: "Inspection"
+          router: "Inspection",
         },
         QC: {
-          router: "Quality"
-        }
+          router: "Quality",
+        },
       },
-      isSubmit: false
+      isSubmit: false,
     };
   },
   computed: {
     isDark() {
       return !this.$route.name.includes("Admin");
-    }
+    },
   },
   mounted() {
     this.$ls.clear();
@@ -135,7 +135,7 @@ export default {
       if (rights.length === 1 && !data.leaderConfirm) {
         data.markLeaderOnlyRight = {
           code: rights[0][0],
-          ...rights[0][1]
+          ...rights[0][1],
         };
       } else {
         data.markLeaderOnlyRight = null;
@@ -158,7 +158,7 @@ export default {
 
       const params = {
         workId: data.workId,
-        subjectId: `${data.workId}-${data.subject}`
+        subjectId: `${data.workId}-${data.subject}`,
       };
       // 根据角色跳转不同的路由
       const { role, markRight } = data;
@@ -186,12 +186,12 @@ export default {
       const routerName = this.rightRoutes[routerType].router;
       this.$router.push({
         name: routerName,
-        params
+        params,
       });
     },
     resetSuccess(newpassword) {
       this.loginModel.password = newpassword;
-    }
-  }
+    },
+  },
 };
 </script>

+ 11 - 11
src/modules/login/ResetPwd.vue

@@ -55,13 +55,13 @@
               type="primary"
               :disabled="isSubmit"
               @click="submit"
-              style="width: 130px;margin-right:10px;"
+              style="width: 130px; margin-right: 10px"
               >确定</Button
             >
             <Button
               size="large"
               shape="circle"
-              style="width: 130px;"
+              style="width: 130px"
               @click="cancel"
               >取消</Button
             >
@@ -87,7 +87,7 @@ import { password } from "@/plugins/formRules";
 const initModalForm = {
   // password: "",
   newpswd: "",
-  renewpswd: ""
+  renewpswd: "",
 };
 export default {
   name: "reset-pswd",
@@ -105,7 +105,7 @@ export default {
       isSubmit: false,
       userId: "",
       reset: {
-        ...initModalForm
+        ...initModalForm,
       },
       resetRules: {
         // password,
@@ -114,10 +114,10 @@ export default {
           ...password,
           {
             validator: equalToPswd,
-            trigger: "blur"
-          }
-        ]
-      }
+            trigger: "blur",
+          },
+        ],
+      },
     };
   },
   methods: {
@@ -143,7 +143,7 @@ export default {
       let result = true;
       await resetPwd({
         userId: this.userId,
-        password: this.reset.newpswd
+        password: this.reset.newpswd,
       }).catch(() => {
         result = false;
       });
@@ -151,7 +151,7 @@ export default {
       if (!result) return;
       this.cancel();
       this.$emit("confirm", this.reset.newpswd);
-    }
-  }
+    },
+  },
 };
 </script>

+ 7 - 7
src/modules/login/fetchSmsMixins.js

@@ -12,7 +12,7 @@ const wstorage = {
   },
   remove(key) {
     window.localStorage.removeItem(key);
-  }
+  },
 };
 
 const codeWaitingTime = 60;
@@ -23,7 +23,7 @@ export default {
       isFetchingCode: false,
       codeContent: "获取验证码",
       codeWaitingTime,
-      time: codeWaitingTime
+      time: codeWaitingTime,
     };
   },
   methods: {
@@ -39,7 +39,7 @@ export default {
       }
     },
     fetchSmsCode() {
-      this.$refs.modalFormComp.validateField("phone", async valid => {
+      this.$refs.modalFormComp.validateField("phone", async (valid) => {
         if (valid) return;
         this.isFetchingCode = true;
         const data = await getSmsCode(this.modalForm.phone).catch(() => {
@@ -52,7 +52,7 @@ export default {
     changeContent() {
       if (!this.isFetchingCode) return;
       this.codeContent = "倒计时" + this.time + "s";
-      const circleTime = time => {
+      const circleTime = (time) => {
         let t = setInterval(() => {
           if (time > 1) {
             time--;
@@ -61,7 +61,7 @@ export default {
               this.nameWaitTime,
               {
                 time,
-                expire
+                expire,
               },
               expire
             );
@@ -76,6 +76,6 @@ export default {
         }, 1e3);
       };
       circleTime(this.time);
-    }
-  }
+    },
+  },
 };

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

@@ -1,179 +1,179 @@
-<template>
-  <div class="client-monitor page-container-flex">
-    <div class="page-action">
-      <div class="set-navs">
-        <div
-          :class="[
-            'set-navs-item',
-            { 'set-navs-item-act': curNav === nav.name }
-          ]"
-          v-for="nav in navs"
-          :key="nav.name"
-          @click="switchNav(nav.name)"
-        >
-          {{ nav.title }}
-        </div>
-      </div>
-      <Button type="success" icon="md-refresh" @click="getList">查询</Button>
-    </div>
-
-    <div class="image-view-list image-view-list-5">
-      <div class="image-view" v-for="(image, index) in papers" :key="image.key">
-        <div class="image-view-container">
-          <h5 class="image-view-title">{{ image.title }}</h5>
-          <div
-            :class="[
-              'image-view-contain',
-              { 'image-view-none': !image.thumbSrc }
-            ]"
-            :style="image.styles"
-          >
-            <img
-              v-if="image.thumbSrc"
-              :src="image.thumbSrc"
-              :alt="image.title"
-              @click="toReview(index)"
-            />
-          </div>
-        </div>
-      </div>
-    </div>
-
-    <div class="part-page" v-if="total > size">
-      <Page
-        :current="current"
-        :total="total"
-        :page-size="size"
-        show-total
-        show-elevator
-        @on-change="toPage"
-      ></Page>
-    </div>
-
-    <!-- image-preview -->
-    <simple-image-preview
-      :cur-image="curPaper"
-      @on-prev="toPrevPaper"
-      @on-next="toNextPaper"
-      ref="SimpleImagePreview"
-    ></simple-image-preview>
-  </div>
-</template>
-
-<script>
-import { clientMonitorList } from "@/api";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-
-export default {
-  name: "client-monitor",
-  components: { SimpleImagePreview },
-  data() {
-    return {
-      workId: this.$route.params.workId,
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      totalPage: 0,
-      dataList: [],
-      papers: [],
-      curPaper: {},
-      curPaperIndex: 0,
-      navs: [
-        {
-          name: "tailor",
-          title: "阅卷图"
-        },
-        {
-          name: "origin",
-          title: "原图"
-        }
-      ],
-      curNav: "tailor"
-    };
-  },
-  mounted() {
-    this.getList();
-  },
-  methods: {
-    async getList() {
-      const data = await clientMonitorList({
-        workId: this.workId,
-        page: this.current - 1,
-        size: this.size
-      });
-      this.dataList = data.data;
-      this.total = data.totalCount;
-      this.totalPage = data.pageCount;
-      this.switchNav(this.curNav);
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    toReview(index) {
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    switchNav(navName) {
-      this.curNav = navName;
-      this.papers = this.dataList.map(item => {
-        let nitem = { ...item };
-        nitem.title = item.createUserName;
-        nitem.key = this.$randomCode();
-        if (this.curNav === "origin") {
-          nitem.imgSrc = item.sheetSrc;
-          nitem.thumbSrc = item.sheetSrc;
-        } else {
-          nitem.imgSrc = item.imgSrc;
-          nitem.thumbSrc = item.thumbSrc;
-        }
-        return nitem;
-      });
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        if (this.current > 1) {
-          this.current--;
-          this.curPaperIndex = this.size - 1;
-          await this.getList();
-        } else {
-          this.$Message.warning("当前已经是第一条数据了");
-          return;
-        }
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        if (this.current === this.totalPage) {
-          this.$Message.warning("当前已经是最后一条数据了");
-          return;
-        } else {
-          this.current++;
-          this.curPaperIndex = 0;
-          await this.getList();
-        }
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    }
-  }
-};
-</script>
+<template>
+  <div class="client-monitor page-container-flex">
+    <div class="page-action">
+      <div class="set-navs">
+        <div
+          :class="[
+            'set-navs-item',
+            { 'set-navs-item-act': curNav === nav.name },
+          ]"
+          v-for="nav in navs"
+          :key="nav.name"
+          @click="switchNav(nav.name)"
+        >
+          {{ nav.title }}
+        </div>
+      </div>
+      <Button type="success" icon="md-refresh" @click="getList">查询</Button>
+    </div>
+
+    <div class="image-view-list image-view-list-5">
+      <div class="image-view" v-for="(image, index) in papers" :key="image.key">
+        <div class="image-view-container">
+          <h5 class="image-view-title">{{ image.title }}</h5>
+          <div
+            :class="[
+              'image-view-contain',
+              { 'image-view-none': !image.thumbSrc },
+            ]"
+            :style="image.styles"
+          >
+            <img
+              v-if="image.thumbSrc"
+              :src="image.thumbSrc"
+              :alt="image.title"
+              @click="toReview(index)"
+            />
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="part-page" v-if="total > size">
+      <Page
+        :current="current"
+        :total="total"
+        :page-size="size"
+        show-total
+        show-elevator
+        @on-change="toPage"
+      ></Page>
+    </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
+  </div>
+</template>
+
+<script>
+import { clientMonitorList } from "@/api";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+
+export default {
+  name: "client-monitor",
+  components: { SimpleImagePreview },
+  data() {
+    return {
+      workId: this.$route.params.workId,
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      totalPage: 0,
+      dataList: [],
+      papers: [],
+      curPaper: {},
+      curPaperIndex: 0,
+      navs: [
+        {
+          name: "tailor",
+          title: "阅卷图",
+        },
+        {
+          name: "origin",
+          title: "原图",
+        },
+      ],
+      curNav: "tailor",
+    };
+  },
+  mounted() {
+    this.getList();
+  },
+  methods: {
+    async getList() {
+      const data = await clientMonitorList({
+        workId: this.workId,
+        page: this.current - 1,
+        size: this.size,
+      });
+      this.dataList = data.data;
+      this.total = data.totalCount;
+      this.totalPage = data.pageCount;
+      this.switchNav(this.curNav);
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    toReview(index) {
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    switchNav(navName) {
+      this.curNav = navName;
+      this.papers = this.dataList.map((item) => {
+        let nitem = { ...item };
+        nitem.title = item.createUserName;
+        nitem.key = this.$randomCode();
+        if (this.curNav === "origin") {
+          nitem.imgSrc = item.sheetSrc;
+          nitem.thumbSrc = item.sheetSrc;
+        } else {
+          nitem.imgSrc = item.imgSrc;
+          nitem.thumbSrc = item.thumbSrc;
+        }
+        return nitem;
+      });
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        if (this.current > 1) {
+          this.current--;
+          this.curPaperIndex = this.size - 1;
+          await this.getList();
+        } else {
+          this.$Message.warning("当前已经是第一条数据了");
+          return;
+        }
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        if (this.current === this.totalPage) {
+          this.$Message.warning("当前已经是最后一条数据了");
+          return;
+        } else {
+          this.current++;
+          this.curPaperIndex = 0;
+          await this.getList();
+        }
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+  },
+};
+</script>

+ 5 - 5
src/modules/main/ExamPaperView.vue

@@ -31,7 +31,7 @@ export default {
       workId: this.$route.params.workId,
       subjectId: this.$route.params.subjectId,
       subject: "",
-      dataList: []
+      dataList: [],
     };
   },
   mounted() {
@@ -41,16 +41,16 @@ export default {
   methods: {
     async getData() {
       const data = await uploadPaperList(this.workId);
-      this.dataList = data.map(area => {
+      this.dataList = data.map((area) => {
         area.subjects = area.subjects.filter(
-          subject => subject.subject === this.subject
+          (subject) => subject.subject === this.subject
         );
         return area;
       });
     },
     downloadPaper(subject) {
       if (subject.url) window.open(this.urlAddAuthor(subject.url));
-    }
-  }
+    },
+  },
 };
 </script>

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

@@ -12,7 +12,7 @@
             <i
               :class="[
                 'icon',
-                curNav.name === nav.name ? `${nav.icon}-act` : nav.icon
+                curNav.name === nav.name ? `${nav.icon}-act` : nav.icon,
               ]"
               v-if="nav.icon"
             ></i>
@@ -43,15 +43,15 @@ export default {
     return {
       navs: [],
       IS_ADMIN: false,
-      curNav: {}
+      curNav: {},
     };
   },
   watch: {
     $route: {
       handler(val) {
         this.actMainNav();
-      }
-    }
+      },
+    },
   },
   mounted() {
     this.IS_ADMIN = this.$ls.get("user", { role: "" }).role === "ADMIN";
@@ -64,10 +64,10 @@ export default {
   methods: {
     actMainNav() {
       const router = this.$route.matched.filter(
-        item => item.name !== "Main"
+        (item) => item.name !== "Main"
       )[0];
       this.actCurNav(router);
-    }
-  }
+    },
+  },
 };
 </script>

+ 9 - 9
src/modules/main/OrgManage.vue

@@ -43,7 +43,7 @@
                         'ivu-icon',
                         org.markUsers[0].enabled
                           ? 'ivu-icon-enable'
-                          : 'ivu-icon-disable'
+                          : 'ivu-icon-disable',
                       ]"
                       :title="org.markUsers[0].enabled ? '禁用' : '启用'"
                       @click="toAble(org.markUsers[0])"
@@ -54,7 +54,7 @@
                       :class="[
                         'ivu-icon',
                         'ivu-icon-md-create',
-                        { 'btn-disabled': !org.markUsers[0].enabled }
+                        { 'btn-disabled': !org.markUsers[0].enabled },
                       ]"
                       title="编辑"
                       @click="toEdit(org.markUsers[0])"
@@ -84,7 +84,7 @@
                         'ivu-icon',
                         org.markUsers[1].enabled
                           ? 'ivu-icon-enable'
-                          : 'ivu-icon-disable'
+                          : 'ivu-icon-disable',
                       ]"
                       :title="org.markUsers[1].enabled ? '禁用' : '启用'"
                       @click="toAble(org.markUsers[1])"
@@ -95,7 +95,7 @@
                       :class="[
                         'ivu-icon',
                         'ivu-icon-md-create',
-                        { 'btn-disabled': !org.markUsers[1].enabled }
+                        { 'btn-disabled': !org.markUsers[1].enabled },
                       ]"
                       title="编辑"
                       @click="toEdit(org.markUsers[1])"
@@ -144,7 +144,7 @@ export default {
       total: 0,
       totalPage: 0,
       orgs: [],
-      curUsers: []
+      curUsers: [],
     };
   },
   mounted() {
@@ -154,7 +154,7 @@ export default {
     async getList() {
       const datas = {
         curPage: this.current - 1,
-        pageSize: this.size
+        pageSize: this.size,
       };
       const data = await orgList(datas);
       this.orgs = data.data;
@@ -186,14 +186,14 @@ export default {
         content: "确定要删除当前机构吗?",
         onOk: () => {
           this.toDel(row.id);
-        }
+        },
       });
     },
     async toDel(id) {
       await deleteOrg(id);
       this.$Message.success("删除成功!");
       this.getList();
-    }
-  }
+    },
+  },
 };
 </script>

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

@@ -1,373 +1,373 @@
-<template>
-  <div class="paper-manage page-container-flex ">
-    <div class="part-box">
-      <Form ref="FilterForm" label-position="left" inline>
-        <FormItem>
-          <Select
-            v-model="filter.subject"
-            @on-change="subjectChange"
-            placeholder="科目"
-          >
-            <Option
-              v-for="(item, index) in subjects"
-              :key="index"
-              :value="item.subject"
-              :label="item.name"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.areaCode" placeholder="选择考区" clearable>
-            <Option
-              v-for="area in areas"
-              :key="area.id"
-              :value="area.areaCode"
-              :label="area.areaName"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Input
-            v-model="filter.startNumber"
-            type="text"
-            placeholder="输入开始编号"
-            clearable
-          />
-        </FormItem>
-        <FormItem>
-          <Input
-            v-model="filter.endNumber"
-            type="text"
-            placeholder="输入结束编号"
-            clearable
-          />
-        </FormItem>
-        <FormItem>
-          <Select
-            v-model="paperType"
-            @on-change="typeChange"
-            placeholder="类型"
-          >
-            <Option
-              v-for="(val, key) in CAFA_EXCEPTION_TYPE"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select
-            v-model="filter.scanUserId"
-            placeholder="选择采集账号"
-            clearable
-          >
-            <Option
-              v-for="user in scanUsers"
-              :key="user.id"
-              :value="user.id"
-              :label="user.loginName"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Input
-            v-model.trim="filter.studentName"
-            placeholder="输入姓名"
-            clearable
-          ></Input>
-        </FormItem>
-        <FormItem>
-          <Select v-model="filter.sortBy" placeholder="排序方式" clearable>
-            <Option
-              v-for="(val, key) in SORT_RULE_TYPE"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></Option>
-          </Select>
-        </FormItem>
-      </Form>
-      <div class="box-justify">
-        <Button
-          type="success"
-          shape="circle"
-          icon="upload-white icon"
-          @click="toExportMark"
-          >导出标记试卷</Button
-        >
-        <Button
-          size="small"
-          class="btn-form-search"
-          type="primary"
-          @click="toPage(1)"
-          >查询</Button
-        >
-      </div>
-    </div>
-
-    <image-action-list
-      v-if="papers.length"
-      :data="papers"
-      :actions="actions"
-      @on-review="toReview"
-      ref="ImageActionList"
-    ></image-action-list>
-
-    <div class="part-page">
-      <Page
-        :current="current"
-        :total="total"
-        :page-size="size"
-        show-total
-        show-elevator
-        @on-change="toPage"
-      ></Page>
-    </div>
-
-    <!-- image-preview -->
-    <simple-image-preview
-      :cur-image="curPaper"
-      @on-prev="toPrevPaper"
-      @on-next="toNextPaper"
-      ref="SimpleImagePreview"
-    ></simple-image-preview>
-  </div>
-</template>
-
-<script>
-import { paperPageList, subjectList, areaList, clientUserQuery } from "@/api";
-import { SORT_RULE_TYPE, CAFA_EXCEPTION_TYPE } from "@/constants/enumerate";
-import ImageActionList from "./components/ImageActionList";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-
-export default {
-  name: "paper-manage",
-  components: { ImageActionList, SimpleImagePreview },
-  data() {
-    return {
-      filter: {
-        workId: this.$route.params.workId,
-        studentName: "",
-        areaCode: "",
-        startNumber: null,
-        endNumber: null,
-        subject: "",
-        sortBy: "",
-        scanUserId: "",
-        isManual: null,
-        missing: null,
-        isRelate: null,
-        isMark: null
-      },
-      SORT_RULE_TYPE,
-      CAFA_EXCEPTION_TYPE: {},
-      paperType: "9",
-      confirmPaperType: "9",
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      totalPage: 0,
-      papers: [],
-      subjects: [],
-      scanUsers: [],
-      areas: [],
-      curPaper: {},
-      curPaperIndex: 0
-    };
-  },
-  computed: {
-    actions() {
-      return this.confirmPaperType === "1"
-        ? ["mark"]
-        : ["rotate", "absent", "mark"];
-    }
-  },
-  mounted() {
-    this.CAFA_EXCEPTION_TYPE = {
-      ...CAFA_EXCEPTION_TYPE,
-      8: "已标记",
-      9: "全部"
-    };
-    this.initData();
-    document.addEventListener("keydown", this.keyEvent);
-  },
-  beforeDestroy() {
-    document.removeEventListener("keydown", this.keyEvent);
-  },
-  methods: {
-    async initData() {
-      await this.getSubjects();
-      this.filter.subject = this.subjects[0].subject;
-      this.filter.areaCode = "";
-      this.areas = [];
-      await this.getAreaList();
-      if (!this.filter.areaCode) {
-        this.filter.areaCode = this.areas[0].areaCode;
-      }
-      this.getScanUsers();
-      this.toPage(1);
-    },
-    keyEvent(e) {
-      if (!e.altKey && !e.shiftKey && !e.repeat) {
-        // 左右键切换分页
-        if (e.code === "ArrowLeft") {
-          e.preventDefault();
-          if (e.ctrlKey) {
-            this.toPage(1);
-          } else {
-            if (this.current === 1) return;
-            this.toPage(this.current - 1);
-          }
-          return;
-        }
-
-        if (e.code === "ArrowRight") {
-          e.preventDefault();
-          if (e.ctrlKey) {
-            this.toPage(this.totalPage);
-          } else {
-            if (this.current === this.totalPage) return;
-            this.toPage(this.current + 1);
-          }
-          return;
-        }
-      }
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        page: this.current - 1,
-        size: this.size
-      };
-      this.papers = [];
-      const data = await paperPageList(datas);
-      this.papers = data.data.map(paper => {
-        const title = paper.manual
-          ? `${paper.examNumber} ${paper.studentName}`
-          : paper.examNumber;
-        return {
-          id: paper.id,
-          key: this.$randomCode(),
-          title,
-          imgSrc: paper.imgSrc,
-          thumbSrc: paper.thumbSrc,
-          missing: paper.missing,
-          mark: paper.adminMark,
-          stage: paper.stage,
-          styles: {},
-          deg: 0
-        };
-      });
-      this.total = data.totalCount;
-      this.totalPage = data.pageCount;
-    },
-    toPage(page) {
-      if (!this.filter.subject || !this.filter.areaCode) {
-        this.$Message.error("请选择科目和考区!");
-        return;
-      }
-      this.confirmPaperType = this.paperType;
-      this.current = page;
-      this.getList();
-    },
-    subjectChange() {
-      this.filter.areaCode = "";
-      this.areas = [];
-      if (!this.filter.subject) return;
-      this.getAreaList();
-    },
-    async getAreaList() {
-      const data = await areaList({
-        workId: this.filter.workId,
-        subject: this.filter.subject
-      });
-      this.areas = data.map(item => {
-        return {
-          id: item.id,
-          areaName: item.areaName,
-          areaCode: item.areaCode
-        };
-      });
-      if (this.areas.length === 1) {
-        this.filter.areaCode = this.areas[0].areaCode;
-      }
-    },
-    async getSubjects() {
-      const data = await subjectList(this.filter.workId);
-      this.subjects = data.filter(item => item.enable);
-    },
-    async getScanUsers() {
-      const data = await clientUserQuery(this.filter.workId);
-      this.scanUsers = data;
-    },
-    typeChange() {
-      const typeToField = {
-        0: "missing",
-        1: "isManual",
-        2: "isRelate",
-        8: "isMark"
-      };
-      Object.values(typeToField).forEach(val => {
-        this.filter[val] = typeToField[this.paperType] === val ? true : null;
-      });
-    },
-    toExportMark() {
-      window.open(
-        this.urlAddAuthor(
-          `${this.GLOBAL.domain}/api/export/paper/${this.filter.workId}/mark`
-        )
-      );
-    },
-    // paper view
-    toReview(index) {
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        if (this.current > 1) {
-          this.current--;
-          this.curPaperIndex = this.size - 1;
-          await this.getList();
-        } else {
-          this.$Message.warning("当前已经是第一条数据了");
-          return;
-        }
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        if (this.current === this.totalPage) {
-          this.$Message.warning("当前已经是最后一条数据了");
-          return;
-        } else {
-          this.current++;
-          this.curPaperIndex = 0;
-          await this.getList();
-        }
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    }
-  }
-};
-</script>
+<template>
+  <div class="paper-manage page-container-flex">
+    <div class="part-box">
+      <Form ref="FilterForm" label-position="left" inline>
+        <FormItem>
+          <Select
+            v-model="filter.subject"
+            @on-change="subjectChange"
+            placeholder="科目"
+          >
+            <Option
+              v-for="(item, index) in subjects"
+              :key="index"
+              :value="item.subject"
+              :label="item.name"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select v-model="filter.areaCode" placeholder="选择考区" clearable>
+            <Option
+              v-for="area in areas"
+              :key="area.id"
+              :value="area.areaCode"
+              :label="area.areaName"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Input
+            v-model="filter.startNumber"
+            type="text"
+            placeholder="输入开始编号"
+            clearable
+          />
+        </FormItem>
+        <FormItem>
+          <Input
+            v-model="filter.endNumber"
+            type="text"
+            placeholder="输入结束编号"
+            clearable
+          />
+        </FormItem>
+        <FormItem>
+          <Select
+            v-model="paperType"
+            @on-change="typeChange"
+            placeholder="类型"
+          >
+            <Option
+              v-for="(val, key) in CAFA_EXCEPTION_TYPE"
+              :key="key"
+              :value="key"
+              :label="val"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select
+            v-model="filter.scanUserId"
+            placeholder="选择采集账号"
+            clearable
+          >
+            <Option
+              v-for="user in scanUsers"
+              :key="user.id"
+              :value="user.id"
+              :label="user.loginName"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Input
+            v-model.trim="filter.studentName"
+            placeholder="输入姓名"
+            clearable
+          ></Input>
+        </FormItem>
+        <FormItem>
+          <Select v-model="filter.sortBy" placeholder="排序方式" clearable>
+            <Option
+              v-for="(val, key) in SORT_RULE_TYPE"
+              :key="key"
+              :value="key"
+              :label="val"
+            ></Option>
+          </Select>
+        </FormItem>
+      </Form>
+      <div class="box-justify">
+        <Button
+          type="success"
+          shape="circle"
+          icon="upload-white icon"
+          @click="toExportMark"
+          >导出标记试卷</Button
+        >
+        <Button
+          size="small"
+          class="btn-form-search"
+          type="primary"
+          @click="toPage(1)"
+          >查询</Button
+        >
+      </div>
+    </div>
+
+    <image-action-list
+      v-if="papers.length"
+      :data="papers"
+      :actions="actions"
+      @on-review="toReview"
+      ref="ImageActionList"
+    ></image-action-list>
+
+    <div class="part-page">
+      <Page
+        :current="current"
+        :total="total"
+        :page-size="size"
+        show-total
+        show-elevator
+        @on-change="toPage"
+      ></Page>
+    </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
+  </div>
+</template>
+
+<script>
+import { paperPageList, subjectList, areaList, clientUserQuery } from "@/api";
+import { SORT_RULE_TYPE, CAFA_EXCEPTION_TYPE } from "@/constants/enumerate";
+import ImageActionList from "./components/ImageActionList";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+
+export default {
+  name: "paper-manage",
+  components: { ImageActionList, SimpleImagePreview },
+  data() {
+    return {
+      filter: {
+        workId: this.$route.params.workId,
+        studentName: "",
+        areaCode: "",
+        startNumber: null,
+        endNumber: null,
+        subject: "",
+        sortBy: "",
+        scanUserId: "",
+        isManual: null,
+        missing: null,
+        isRelate: null,
+        isMark: null,
+      },
+      SORT_RULE_TYPE,
+      CAFA_EXCEPTION_TYPE: {},
+      paperType: "9",
+      confirmPaperType: "9",
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      totalPage: 0,
+      papers: [],
+      subjects: [],
+      scanUsers: [],
+      areas: [],
+      curPaper: {},
+      curPaperIndex: 0,
+    };
+  },
+  computed: {
+    actions() {
+      return this.confirmPaperType === "1"
+        ? ["mark"]
+        : ["rotate", "absent", "mark"];
+    },
+  },
+  mounted() {
+    this.CAFA_EXCEPTION_TYPE = {
+      ...CAFA_EXCEPTION_TYPE,
+      8: "已标记",
+      9: "全部",
+    };
+    this.initData();
+    document.addEventListener("keydown", this.keyEvent);
+  },
+  beforeDestroy() {
+    document.removeEventListener("keydown", this.keyEvent);
+  },
+  methods: {
+    async initData() {
+      await this.getSubjects();
+      this.filter.subject = this.subjects[0].subject;
+      this.filter.areaCode = "";
+      this.areas = [];
+      await this.getAreaList();
+      if (!this.filter.areaCode) {
+        this.filter.areaCode = this.areas[0].areaCode;
+      }
+      this.getScanUsers();
+      this.toPage(1);
+    },
+    keyEvent(e) {
+      if (!e.altKey && !e.shiftKey && !e.repeat) {
+        // 左右键切换分页
+        if (e.code === "ArrowLeft") {
+          e.preventDefault();
+          if (e.ctrlKey) {
+            this.toPage(1);
+          } else {
+            if (this.current === 1) return;
+            this.toPage(this.current - 1);
+          }
+          return;
+        }
+
+        if (e.code === "ArrowRight") {
+          e.preventDefault();
+          if (e.ctrlKey) {
+            this.toPage(this.totalPage);
+          } else {
+            if (this.current === this.totalPage) return;
+            this.toPage(this.current + 1);
+          }
+          return;
+        }
+      }
+    },
+    async getList() {
+      const datas = {
+        ...this.filter,
+        page: this.current - 1,
+        size: this.size,
+      };
+      this.papers = [];
+      const data = await paperPageList(datas);
+      this.papers = data.data.map((paper) => {
+        const title = paper.manual
+          ? `${paper.examNumber} ${paper.studentName}`
+          : paper.examNumber;
+        return {
+          id: paper.id,
+          key: this.$randomCode(),
+          title,
+          imgSrc: paper.imgSrc,
+          thumbSrc: paper.thumbSrc,
+          missing: paper.missing,
+          mark: paper.adminMark,
+          stage: paper.stage,
+          styles: {},
+          deg: 0,
+        };
+      });
+      this.total = data.totalCount;
+      this.totalPage = data.pageCount;
+    },
+    toPage(page) {
+      if (!this.filter.subject || !this.filter.areaCode) {
+        this.$Message.error("请选择科目和考区!");
+        return;
+      }
+      this.confirmPaperType = this.paperType;
+      this.current = page;
+      this.getList();
+    },
+    subjectChange() {
+      this.filter.areaCode = "";
+      this.areas = [];
+      if (!this.filter.subject) return;
+      this.getAreaList();
+    },
+    async getAreaList() {
+      const data = await areaList({
+        workId: this.filter.workId,
+        subject: this.filter.subject,
+      });
+      this.areas = data.map((item) => {
+        return {
+          id: item.id,
+          areaName: item.areaName,
+          areaCode: item.areaCode,
+        };
+      });
+      if (this.areas.length === 1) {
+        this.filter.areaCode = this.areas[0].areaCode;
+      }
+    },
+    async getSubjects() {
+      const data = await subjectList(this.filter.workId);
+      this.subjects = data.filter((item) => item.enable);
+    },
+    async getScanUsers() {
+      const data = await clientUserQuery(this.filter.workId);
+      this.scanUsers = data;
+    },
+    typeChange() {
+      const typeToField = {
+        0: "missing",
+        1: "isManual",
+        2: "isRelate",
+        8: "isMark",
+      };
+      Object.values(typeToField).forEach((val) => {
+        this.filter[val] = typeToField[this.paperType] === val ? true : null;
+      });
+    },
+    toExportMark() {
+      window.open(
+        this.urlAddAuthor(
+          `${this.GLOBAL.domain}/api/export/paper/${this.filter.workId}/mark`
+        )
+      );
+    },
+    // paper view
+    toReview(index) {
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        if (this.current > 1) {
+          this.current--;
+          this.curPaperIndex = this.size - 1;
+          await this.getList();
+        } else {
+          this.$Message.warning("当前已经是第一条数据了");
+          return;
+        }
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        if (this.current === this.totalPage) {
+          this.$Message.warning("当前已经是最后一条数据了");
+          return;
+        } else {
+          this.current++;
+          this.curPaperIndex = 0;
+          await this.getList();
+        }
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+  },
+};
+</script>

+ 22 - 22
src/modules/main/QualityAnalysis.vue

@@ -124,7 +124,7 @@ import {
   distanceReport,
   callbackReport,
   subjectList,
-  areaList
+  areaList,
 } from "@/api";
 import EchartRender from "@/components/EchartRender";
 import QualityAnalysisExport from "./components/QualityAnalysisExport";
@@ -140,7 +140,7 @@ export default {
         subject: "",
         areaCode: "",
         startTime: null,
-        endTime: null
+        endTime: null,
       },
       searchTime: [],
       levelsPropReportData: null,
@@ -154,7 +154,7 @@ export default {
       renderExportPage: false,
       renderChartData: {},
       renderPageInfo: {},
-      isDownload: false
+      isDownload: false,
     };
   },
   mounted() {
@@ -172,18 +172,18 @@ export default {
     },
     async getSubjects() {
       const data = await subjectList(this.filter.workId);
-      this.subjects = data.filter(item => item.enable);
+      this.subjects = data.filter((item) => item.enable);
     },
     async getAreaList() {
       const data = await areaList({
         workId: this.filter.workId,
-        subject: this.filter.subject
+        subject: this.filter.subject,
       });
-      this.areas = data.map(item => {
+      this.areas = data.map((item) => {
         return {
           id: item.id,
           areaName: item.areaName,
-          areaCode: item.areaCode
+          areaCode: item.areaCode,
         };
       });
     },
@@ -195,32 +195,32 @@ export default {
       if (!datas.length) {
         return { names: [], dataList: [] };
       }
-      var names = datas[0].data.map(function(item) {
+      var names = datas[0].data.map(function (item) {
         return item.markerName;
       });
-      var dataList = datas.map(function(item) {
+      var dataList = datas.map(function (item) {
         return {
           name: item.name,
-          data: item.data.map(function(elem) {
+          data: item.data.map(function (elem) {
             return elem.prop;
-          })
+          }),
         };
       });
       return {
         names: names,
-        dataList: dataList
+        dataList: dataList,
       };
     },
     parseBarData(datas) {
       var names = [];
       var dataList = [];
-      datas.map(function(item, index) {
+      datas.map(function (item, index) {
         names[index] = item.userName;
         dataList[index] = item.sumCount;
       });
       return {
         names: names,
-        dataList: dataList
+        dataList: dataList,
       };
     },
     async toSearch() {
@@ -230,13 +230,13 @@ export default {
       this.callbackReportData = null;
 
       const datas = filterObjNull({
-        ...this.filter
+        ...this.filter,
       });
       const requests = [
         levelsPropReport(datas),
         deviationReport(datas),
         distanceReport(datas),
-        callbackReport(datas)
+        callbackReport(datas),
       ];
       const data = await Promise.all(requests);
 
@@ -257,22 +257,22 @@ export default {
     toExport() {
       if (!this.dataReady) return;
       const curSubject = this.subjects.find(
-        item => item.subject === this.filter.subject
+        (item) => item.subject === this.filter.subject
       );
       const curArea = this.areas.find(
-        item => item.areaCode === this.filter.areaCode
+        (item) => item.areaCode === this.filter.areaCode
       );
       this.renderPageInfo = {
         subjectName: curSubject.name,
         areaName: curArea.areaName,
         startTime: this.filter.startTime || "无",
-        endTime: this.filter.endTime || "无"
+        endTime: this.filter.endTime || "无",
       };
       this.renderChartData = {
         levelsPropReportData: this.levelsPropReportData,
         deviationReportData: this.deviationReportData,
         distanceReportData: this.distanceReportData,
-        callbackReportData: this.callbackReportData
+        callbackReportData: this.callbackReportData,
       };
       this.renderExportPage = true;
     },
@@ -282,7 +282,7 @@ export default {
       }
       this.renderExportPage = false;
       this.isDownload = false;
-    }
-  }
+    },
+  },
 };
 </script>

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

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

+ 327 - 327
src/modules/main/StudentScore.vue

@@ -1,327 +1,327 @@
-<template>
-  <div class="student-score">
-    <div class="part-box part-box-filter">
-      <Form ref="FilterForm" label-position="left" inline>
-        <FormItem v-if="IS_INSPECTION">
-          <Select
-            v-model="filter.workId"
-            @on-change="workChange"
-            placeholder="工作文件夹"
-            style="width: 150px"
-          >
-            <Option
-              v-for="(work, windex) in works"
-              :key="windex"
-              :value="work.id"
-              :label="work.name"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Select
-            v-model="filter.subject"
-            @on-change="subjecChange"
-            placeholder="科目"
-            style="width: 100px;"
-            clearable
-          >
-            <Option
-              v-for="(item, index) in subjects"
-              :key="index"
-              :value="item.subject"
-              :label="item.name"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem v-if="IS_INSPECTION">
-          <Select v-model="filter.questionId" placeholder="考区">
-            <Option
-              v-for="area in areas"
-              :key="area.id"
-              :value="area.id"
-              :label="area.areaName"
-            ></Option>
-          </Select>
-        </FormItem>
-
-        <FormItem>
-          <Select
-            v-model="filter.type"
-            placeholder="号码类型"
-            style="width: 100px"
-          >
-            <Option
-              v-for="(val, key) in CODE_TYPE"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></Option>
-          </Select>
-        </FormItem>
-        <FormItem>
-          <Input
-            v-model.trim="filter.number"
-            placeholder="输入号码"
-            clearable
-          ></Input>
-        </FormItem>
-        <FormItem>
-          <Input
-            v-model.trim="filter.studentName"
-            placeholder="输入姓名"
-            clearable
-          ></Input>
-        </FormItem>
-        <FormItem>
-          <Button
-            class="btn-form-search"
-            size="small"
-            type="primary"
-            @click="toSearch"
-            >查询</Button
-          >
-        </FormItem>
-      </Form>
-    </div>
-
-    <div class="student-score-content" v-if="curStudent.name">
-      <div class="score-content-head">
-        <h1 class="score-content-title">{{ curStudent.name }}</h1>
-        <p class="score-content-info">
-          <span>考号:</span><span>{{ curStudent.examNumber }}</span>
-        </p>
-        <p class="score-content-tscore">
-          <span>总分:</span><span>{{ curStudent.sumScore }}</span>
-        </p>
-      </div>
-      <div class="score-content-body">
-        <image-action-list
-          :data="papers"
-          :column-number="papers.length"
-          @on-review="toReview"
-          ref="ImageActionList"
-        ></image-action-list>
-
-        <table :class="['table', `table-column-${papers.length}`]">
-          <tr>
-            <td v-for="(paper, sindex) in papers" :key="sindex">
-              <div class="score-content-task">
-                <div class="task-list">
-                  <div class="task-item">
-                    <div class="task-item-label">试卷密号:</div>
-                    <div class="task-item-content">
-                      {{ paper.secretNumber }}
-                    </div>
-                  </div>
-                  <div class="task-item">
-                    <div class="task-item-label">任务密号:</div>
-                    <div class="task-item-content">
-                      <p v-for="task in paper.taskList" :key="task.id">
-                        {{ task.secretNumber }}({{ task.markerName }})
-                      </p>
-                    </div>
-                  </div>
-                </div>
-              </div>
-            </td>
-          </tr>
-          <tr>
-            <td
-              class="color-dark"
-              v-for="(paper, sindex) in papers"
-              :key="sindex"
-            >
-              {{ paper.level || "空" }}
-            </td>
-          </tr>
-          <tr>
-            <td
-              class="color-error"
-              v-for="(paper, sindex) in papers"
-              :key="sindex"
-            >
-              {{ paper.score ? paper.score + "分" : "空" }}
-            </td>
-          </tr>
-        </table>
-      </div>
-    </div>
-
-    <div class="part-page" v-if="total > size">
-      <Page
-        :current="current"
-        :total="total"
-        :page-size="size"
-        show-total
-        show-elevator
-        @on-change="toPage"
-      ></Page>
-    </div>
-
-    <!-- image-preview -->
-    <simple-image-preview
-      :cur-image="curPaper"
-      @on-prev="toPrevPaper"
-      @on-next="toNextPaper"
-      ref="SimpleImagePreview"
-    ></simple-image-preview>
-  </div>
-</template>
-
-<script>
-import { studentScoreList, workList, subjectList, areaList } from "@/api";
-import { CODE_TYPE } from "@/constants/enumerate";
-import ImageActionList from "./components/ImageActionList";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-
-export default {
-  name: "student-score",
-  components: { ImageActionList, SimpleImagePreview },
-  data() {
-    return {
-      filter: {
-        workId: this.$route.params && this.$route.params.workId,
-        subject: "",
-        questionId: "",
-        type: "examNumber",
-        number: "",
-        studentName: ""
-      },
-      CODE_TYPE,
-      IS_INSPECTION: false,
-      works: [],
-      subjects: [],
-      areas: [],
-      current: 1,
-      total: 0,
-      size: 1,
-      curStudent: { name: "" },
-      students: [],
-      // image preview
-      papers: [],
-      curPaper: {},
-      curPaperIndex: 0
-    };
-  },
-  mounted() {
-    this.initData();
-  },
-  methods: {
-    async initData() {
-      this.IS_INSPECTION =
-        this.$ls.get("user", { role: "" }).role === "INSPECTION";
-      if (this.IS_INSPECTION) {
-        await this.getWorkList();
-        this.filter.workId = this.works[0].id;
-        this.workChange();
-        this.getAreaList();
-      } else {
-        await this.getSubjects();
-        // this.filter.subject = this.subjects[0].subject;
-      }
-    },
-    async getWorkList() {
-      this.works = await workList();
-    },
-    async getSubjects() {
-      const data = await subjectList(this.filter.workId);
-      this.subjects = data.filter(item => item.enable);
-    },
-    async getAreaList() {
-      const data = await areaList({
-        workId: this.filter.workId,
-        subject: this.filter.subject
-      });
-      this.areas = data.map(item => {
-        return {
-          id: item.id,
-          areaName: item.areaName,
-          areaCode: item.areaCode
-        };
-      });
-    },
-    async toSearch() {
-      this.students = [];
-      if (!this.filter.number && !this.filter.studentName) {
-        this.$Message.error("号码和姓名必须填写一个");
-        return;
-      }
-      const data = await studentScoreList(this.filter);
-      if (!data.length) {
-        this.$Message.error("无此考生");
-        return;
-      }
-      this.students = data;
-      this.total = this.students.length;
-      this.toPage(1);
-    },
-    toPage(page) {
-      if (!this.students[page - 1]) return;
-      this.current = page;
-      this.curStudent = this.students[page - 1];
-      this.papers = this.curStudent.papers.map(item => {
-        let nitem = { ...item };
-        nitem.key = this.$randomCode();
-        nitem.imgSrc = item.sheetSrc;
-        nitem.thumbSrc = item.sheetSrc;
-        const fields = ["taskScores", "taskLevels"];
-        const validField = fields.find(
-          field => item[field] && item[field].length
-        );
-        nitem.taskList = validField ? item[validField] : [];
-        return nitem;
-      });
-    },
-    workChange() {
-      this.filter.subject = null;
-      this.filter.questionId = null;
-      const curWork = this.works.find(item => item.id === this.filter.workId);
-      this.subjects = curWork.subjects;
-      this.filter.subject = this.subjects[0].subject;
-    },
-    subjecChange() {
-      if (this.IS_INSPECTION) {
-        this.filter.questionId = null;
-        this.getAreaList();
-      }
-    },
-    // paper view
-    toReview(index) {
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        this.$Message.warning("当前已经是第一条数据了");
-        return;
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        this.$Message.warning("当前已经是最后一条数据了");
-        return;
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    }
-  }
-};
-</script>
+<template>
+  <div class="student-score">
+    <div class="part-box part-box-filter">
+      <Form ref="FilterForm" label-position="left" inline>
+        <FormItem v-if="IS_INSPECTION">
+          <Select
+            v-model="filter.workId"
+            @on-change="workChange"
+            placeholder="工作文件夹"
+            style="width: 150px"
+          >
+            <Option
+              v-for="(work, windex) in works"
+              :key="windex"
+              :value="work.id"
+              :label="work.name"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Select
+            v-model="filter.subject"
+            @on-change="subjecChange"
+            placeholder="科目"
+            style="width: 100px"
+            clearable
+          >
+            <Option
+              v-for="(item, index) in subjects"
+              :key="index"
+              :value="item.subject"
+              :label="item.name"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem v-if="IS_INSPECTION">
+          <Select v-model="filter.questionId" placeholder="考区">
+            <Option
+              v-for="area in areas"
+              :key="area.id"
+              :value="area.id"
+              :label="area.areaName"
+            ></Option>
+          </Select>
+        </FormItem>
+
+        <FormItem>
+          <Select
+            v-model="filter.type"
+            placeholder="号码类型"
+            style="width: 100px"
+          >
+            <Option
+              v-for="(val, key) in CODE_TYPE"
+              :key="key"
+              :value="key"
+              :label="val"
+            ></Option>
+          </Select>
+        </FormItem>
+        <FormItem>
+          <Input
+            v-model.trim="filter.number"
+            placeholder="输入号码"
+            clearable
+          ></Input>
+        </FormItem>
+        <FormItem>
+          <Input
+            v-model.trim="filter.studentName"
+            placeholder="输入姓名"
+            clearable
+          ></Input>
+        </FormItem>
+        <FormItem>
+          <Button
+            class="btn-form-search"
+            size="small"
+            type="primary"
+            @click="toSearch"
+            >查询</Button
+          >
+        </FormItem>
+      </Form>
+    </div>
+
+    <div class="student-score-content" v-if="curStudent.name">
+      <div class="score-content-head">
+        <h1 class="score-content-title">{{ curStudent.name }}</h1>
+        <p class="score-content-info">
+          <span>考号:</span><span>{{ curStudent.examNumber }}</span>
+        </p>
+        <p class="score-content-tscore">
+          <span>总分:</span><span>{{ curStudent.sumScore }}</span>
+        </p>
+      </div>
+      <div class="score-content-body">
+        <image-action-list
+          :data="papers"
+          :column-number="papers.length"
+          @on-review="toReview"
+          ref="ImageActionList"
+        ></image-action-list>
+
+        <table :class="['table', `table-column-${papers.length}`]">
+          <tr>
+            <td v-for="(paper, sindex) in papers" :key="sindex">
+              <div class="score-content-task">
+                <div class="task-list">
+                  <div class="task-item">
+                    <div class="task-item-label">试卷密号:</div>
+                    <div class="task-item-content">
+                      {{ paper.secretNumber }}
+                    </div>
+                  </div>
+                  <div class="task-item">
+                    <div class="task-item-label">任务密号:</div>
+                    <div class="task-item-content">
+                      <p v-for="task in paper.taskList" :key="task.id">
+                        {{ task.secretNumber }}({{ task.markerName }})
+                      </p>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </td>
+          </tr>
+          <tr>
+            <td
+              class="color-dark"
+              v-for="(paper, sindex) in papers"
+              :key="sindex"
+            >
+              {{ paper.level || "空" }}
+            </td>
+          </tr>
+          <tr>
+            <td
+              class="color-error"
+              v-for="(paper, sindex) in papers"
+              :key="sindex"
+            >
+              {{ paper.score ? paper.score + "分" : "空" }}
+            </td>
+          </tr>
+        </table>
+      </div>
+    </div>
+
+    <div class="part-page" v-if="total > size">
+      <Page
+        :current="current"
+        :total="total"
+        :page-size="size"
+        show-total
+        show-elevator
+        @on-change="toPage"
+      ></Page>
+    </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
+  </div>
+</template>
+
+<script>
+import { studentScoreList, workList, subjectList, areaList } from "@/api";
+import { CODE_TYPE } from "@/constants/enumerate";
+import ImageActionList from "./components/ImageActionList";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+
+export default {
+  name: "student-score",
+  components: { ImageActionList, SimpleImagePreview },
+  data() {
+    return {
+      filter: {
+        workId: this.$route.params && this.$route.params.workId,
+        subject: "",
+        questionId: "",
+        type: "examNumber",
+        number: "",
+        studentName: "",
+      },
+      CODE_TYPE,
+      IS_INSPECTION: false,
+      works: [],
+      subjects: [],
+      areas: [],
+      current: 1,
+      total: 0,
+      size: 1,
+      curStudent: { name: "" },
+      students: [],
+      // image preview
+      papers: [],
+      curPaper: {},
+      curPaperIndex: 0,
+    };
+  },
+  mounted() {
+    this.initData();
+  },
+  methods: {
+    async initData() {
+      this.IS_INSPECTION =
+        this.$ls.get("user", { role: "" }).role === "INSPECTION";
+      if (this.IS_INSPECTION) {
+        await this.getWorkList();
+        this.filter.workId = this.works[0].id;
+        this.workChange();
+        this.getAreaList();
+      } else {
+        await this.getSubjects();
+        // this.filter.subject = this.subjects[0].subject;
+      }
+    },
+    async getWorkList() {
+      this.works = await workList();
+    },
+    async getSubjects() {
+      const data = await subjectList(this.filter.workId);
+      this.subjects = data.filter((item) => item.enable);
+    },
+    async getAreaList() {
+      const data = await areaList({
+        workId: this.filter.workId,
+        subject: this.filter.subject,
+      });
+      this.areas = data.map((item) => {
+        return {
+          id: item.id,
+          areaName: item.areaName,
+          areaCode: item.areaCode,
+        };
+      });
+    },
+    async toSearch() {
+      this.students = [];
+      if (!this.filter.number && !this.filter.studentName) {
+        this.$Message.error("号码和姓名必须填写一个");
+        return;
+      }
+      const data = await studentScoreList(this.filter);
+      if (!data.length) {
+        this.$Message.error("无此考生");
+        return;
+      }
+      this.students = data;
+      this.total = this.students.length;
+      this.toPage(1);
+    },
+    toPage(page) {
+      if (!this.students[page - 1]) return;
+      this.current = page;
+      this.curStudent = this.students[page - 1];
+      this.papers = this.curStudent.papers.map((item) => {
+        let nitem = { ...item };
+        nitem.key = this.$randomCode();
+        nitem.imgSrc = item.sheetSrc;
+        nitem.thumbSrc = item.sheetSrc;
+        const fields = ["taskScores", "taskLevels"];
+        const validField = fields.find(
+          (field) => item[field] && item[field].length
+        );
+        nitem.taskList = validField ? item[validField] : [];
+        return nitem;
+      });
+    },
+    workChange() {
+      this.filter.subject = null;
+      this.filter.questionId = null;
+      const curWork = this.works.find((item) => item.id === this.filter.workId);
+      this.subjects = curWork.subjects;
+      this.filter.subject = this.subjects[0].subject;
+    },
+    subjecChange() {
+      if (this.IS_INSPECTION) {
+        this.filter.questionId = null;
+        this.getAreaList();
+      }
+    },
+    // paper view
+    toReview(index) {
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        this.$Message.warning("当前已经是第一条数据了");
+        return;
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        this.$Message.warning("当前已经是最后一条数据了");
+        return;
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+  },
+};
+</script>

+ 182 - 182
src/modules/main/WorkManage.vue

@@ -1,182 +1,182 @@
-<template>
-  <div class="home">
-    <view-header class="home-header" :show-reset-pwd="false"></view-header>
-
-    <div class="home-body">
-      <div class="home-main">
-        <div class="work-manage">
-          <div class="part-box-head">
-            <div class="part-box-head-left">
-              <Form label-position="left" inline>
-                <FormItem>
-                  <Input
-                    v-model.trim="modalForm.name"
-                    placeholder="工作名称"
-                    clearable
-                  ></Input>
-                </FormItem>
-                <FormItem :label-width="0">
-                  <Button
-                    size="small"
-                    type="success"
-                    icon="recode-white icon"
-                    shape="circle"
-                    @click="toAdd"
-                    >新增工作文件</Button
-                  >
-                </FormItem>
-              </Form>
-            </div>
-            <div class="part-box-head-right" v-if="IS_SUPER_ADMIN">
-              <Button
-                size="small"
-                icon="md-arrow-back"
-                shape="circle"
-                @click="$router.push({ name: 'OrgManage' })"
-                >返回</Button
-              >
-            </div>
-          </div>
-          <Table
-            ref="TableList"
-            :columns="columns"
-            :data="works"
-            :row-class-name="rowClassName"
-            disabled-hover
-            border
-          ></Table>
-        </div>
-
-        <!-- <view-footer></view-footer> -->
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { workList, createWork, deleteWork } from "@/api";
-export default {
-  name: "work",
-  data() {
-    return {
-      modalForm: {
-        name: ""
-      },
-      IS_SUPER_ADMIN: false,
-      works: [],
-      columns: [
-        {
-          title: "序号",
-          width: 80,
-          render: (h, param) => {
-            return h("div", param.index + 1 + "");
-          }
-        },
-        {
-          title: "ID",
-          key: "id",
-          minWidth: 100
-        },
-        {
-          title: "名称",
-          key: "name",
-          minWidth: 200
-        },
-        {
-          title: "创建时间",
-          key: "createdOn",
-          minWidth: 160
-        },
-        {
-          title: "操作",
-          key: "action",
-          width: 140,
-          align: "center",
-          className: "table-action",
-          render: (h, param) => {
-            const actions = [
-              {
-                icon: "md-trash",
-                classes: ["icon-danger"],
-                attrs: {
-                  title: "删除"
-                },
-                action: () => {
-                  this.toDelete(param.row);
-                }
-              },
-              {
-                icon: "md-arrow-round-forward",
-                attrs: {
-                  title: "进入"
-                },
-                action: () => {
-                  this.toDetail(param.row);
-                }
-              }
-            ];
-
-            return h("div", this.$tableIconAction(h, actions));
-          }
-        }
-      ]
-    };
-  },
-  mounted() {
-    this.IS_SUPER_ADMIN =
-      this.$ls.get("user", { role: "" }).role === "SUPER_ADMIN";
-    this.getList();
-  },
-  methods: {
-    async getList() {
-      const data = await workList();
-      this.works = data.map(item => {
-        return {
-          id: item.id,
-          name: item.name,
-          active: item.active,
-          createdOn: item.createdOn
-        };
-      });
-    },
-    rowClassName(row) {
-      return row.active ? "row-active" : "";
-    },
-    async toAdd() {
-      if (!this.modalForm.name) {
-        this.$Message.error("请输入工作名称!");
-        return;
-      }
-      if (this.modalForm.name.length > 100) {
-        this.$Message.error("工作名称长度不能超过100个字符!");
-        return;
-      }
-
-      await createWork(this.modalForm);
-      this.$Message.success("创建工作成功!");
-      this.getList();
-    },
-    toDetail(row) {
-      this.$router.push({
-        name: "WorkOverview",
-        params: {
-          workId: row.id
-        }
-      });
-    },
-    toDelete(row) {
-      this.$Modal.confirm({
-        content: "确定要删除当前工作吗?",
-        onOk: () => {
-          this.toDel(row.id);
-        }
-      });
-    },
-    async toDel(id) {
-      await deleteWork(id);
-      this.$Message.success("删除成功!");
-      this.getList();
-    }
-  }
-};
-</script>
+<template>
+  <div class="home">
+    <view-header class="home-header" :show-reset-pwd="false"></view-header>
+
+    <div class="home-body">
+      <div class="home-main">
+        <div class="work-manage">
+          <div class="part-box-head">
+            <div class="part-box-head-left">
+              <Form label-position="left" inline>
+                <FormItem>
+                  <Input
+                    v-model.trim="modalForm.name"
+                    placeholder="工作名称"
+                    clearable
+                  ></Input>
+                </FormItem>
+                <FormItem :label-width="0">
+                  <Button
+                    size="small"
+                    type="success"
+                    icon="recode-white icon"
+                    shape="circle"
+                    @click="toAdd"
+                    >新增工作文件</Button
+                  >
+                </FormItem>
+              </Form>
+            </div>
+            <div class="part-box-head-right" v-if="IS_SUPER_ADMIN">
+              <Button
+                size="small"
+                icon="md-arrow-back"
+                shape="circle"
+                @click="$router.push({ name: 'OrgManage' })"
+                >返回</Button
+              >
+            </div>
+          </div>
+          <Table
+            ref="TableList"
+            :columns="columns"
+            :data="works"
+            :row-class-name="rowClassName"
+            disabled-hover
+            border
+          ></Table>
+        </div>
+
+        <!-- <view-footer></view-footer> -->
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { workList, createWork, deleteWork } from "@/api";
+export default {
+  name: "work",
+  data() {
+    return {
+      modalForm: {
+        name: "",
+      },
+      IS_SUPER_ADMIN: false,
+      works: [],
+      columns: [
+        {
+          title: "序号",
+          width: 80,
+          render: (h, param) => {
+            return h("div", param.index + 1 + "");
+          },
+        },
+        {
+          title: "ID",
+          key: "id",
+          minWidth: 100,
+        },
+        {
+          title: "名称",
+          key: "name",
+          minWidth: 200,
+        },
+        {
+          title: "创建时间",
+          key: "createdOn",
+          minWidth: 160,
+        },
+        {
+          title: "操作",
+          key: "action",
+          width: 140,
+          align: "center",
+          className: "table-action",
+          render: (h, param) => {
+            const actions = [
+              {
+                icon: "md-trash",
+                classes: ["icon-danger"],
+                attrs: {
+                  title: "删除",
+                },
+                action: () => {
+                  this.toDelete(param.row);
+                },
+              },
+              {
+                icon: "md-arrow-round-forward",
+                attrs: {
+                  title: "进入",
+                },
+                action: () => {
+                  this.toDetail(param.row);
+                },
+              },
+            ];
+
+            return h("div", this.$tableIconAction(h, actions));
+          },
+        },
+      ],
+    };
+  },
+  mounted() {
+    this.IS_SUPER_ADMIN =
+      this.$ls.get("user", { role: "" }).role === "SUPER_ADMIN";
+    this.getList();
+  },
+  methods: {
+    async getList() {
+      const data = await workList();
+      this.works = data.map((item) => {
+        return {
+          id: item.id,
+          name: item.name,
+          active: item.active,
+          createdOn: item.createdOn,
+        };
+      });
+    },
+    rowClassName(row) {
+      return row.active ? "row-active" : "";
+    },
+    async toAdd() {
+      if (!this.modalForm.name) {
+        this.$Message.error("请输入工作名称!");
+        return;
+      }
+      if (this.modalForm.name.length > 100) {
+        this.$Message.error("工作名称长度不能超过100个字符!");
+        return;
+      }
+
+      await createWork(this.modalForm);
+      this.$Message.success("创建工作成功!");
+      this.getList();
+    },
+    toDetail(row) {
+      this.$router.push({
+        name: "WorkOverview",
+        params: {
+          workId: row.id,
+        },
+      });
+    },
+    toDelete(row) {
+      this.$Modal.confirm({
+        content: "确定要删除当前工作吗?",
+        onOk: () => {
+          this.toDel(row.id);
+        },
+      });
+    },
+    async toDel(id) {
+      await deleteWork(id);
+      this.$Message.success("删除成功!");
+      this.getList();
+    },
+  },
+};
+</script>

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

@@ -75,7 +75,7 @@
             type="primary"
             shape="circle"
             @click="toCommit(subject)"
-            style="width: 120px;"
+            style="width: 120px"
             >评卷管理</Button
           >
         </div>
@@ -112,21 +112,21 @@ export default {
       exportGradeScoreUrl: "",
       exportScoreUrl: "",
       overviewInfo: {
-        subjectOverviews: []
+        subjectOverviews: [],
       },
       // upload
       headers: {
         Authorization: this.$ls.get("user", { token: "" }).token,
         workId: this.$route.params.workId,
-        userId: this.$ls.get("user", { id: "" }).id
+        userId: this.$ls.get("user", { id: "" }).id,
       },
       uploadData: {
         workId: this.$route.params.workId,
-        subject: ""
+        subject: "",
       },
       uploadUrl: "/api/import/students/missingStudent",
       downloadManualTemplateUrl: "/templates/导入缺考名单-模板.xlsx",
-      downloadManualTemplateFilename: "导入缺考名单-模板.xlsx"
+      downloadManualTemplateFilename: "导入缺考名单-模板.xlsx",
     };
   },
   mounted() {
@@ -137,7 +137,7 @@ export default {
   methods: {
     async getDetail() {
       const data = await workOverviewDetail(this.workId);
-      data.subjectOverviews.map(item => {
+      data.subjectOverviews.map((item) => {
         item.markStageName = SUBJECT_STAGE[item.markStage];
         item.exportAbsentDataUrl = `${this.GLOBAL.domain}/api/export/users/${this.workId}/${item.subject}/export`;
         item.progress =
@@ -164,9 +164,9 @@ export default {
       const routerName = subject.markStage === "SCORE" ? "Mark" : "Grading";
       this.$router.push({
         name: routerName,
-        params: { workId: this.workId, subjectId: subject.subjectId }
+        params: { workId: this.workId, subjectId: subject.subjectId },
       });
-    }
-  }
+    },
+  },
 };
 </script>

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

@@ -1,164 +1,164 @@
-<template>
-  <div :class="classes">
-    <div class="image-view" v-for="(image, index) in data" :key="image.key">
-      <div class="image-view-container">
-        <h5 class="image-view-title">{{ image.title }}</h5>
-        <image-view-contain
-          v-if="canRotate"
-          :ref="`image${image.id}`"
-          :image="image"
-          @to-review="toReview(index)"
-        ></image-view-contain>
-        <div
-          v-else
-          :class="[
-            'image-view-contain',
-            { 'image-view-none': !image.thumbSrc }
-          ]"
-        >
-          <img
-            v-if="image.thumbSrc"
-            :src="image.thumbSrc"
-            :alt="image.title"
-            :style="image.styles"
-            @click="toReview(index)"
-          />
-        </div>
-        <div class="image-view-actions" v-if="actions.length">
-          <div>
-            <Button
-              class="view-action-rotate"
-              size="small"
-              icon="md-refresh"
-              @click="toRotate(image)"
-              v-if="canRotate"
-            ></Button>
-            <Button
-              class="view-action-save"
-              size="small"
-              type="primary"
-              @click="toSaveRotate(image)"
-              :disabled="saving"
-              v-if="canRotate && image['stepDeg']"
-              >保存</Button
-            >
-          </div>
-          <div>
-            <Button
-              class="view-action-absent"
-              :type="image.missing ? 'error' : 'default'"
-              size="small"
-              @click="toSignAbsent(image)"
-              v-if="canAbsent"
-              >缺考</Button
-            >
-            <Button
-              v-if="canMark"
-              :class="['view-action-mark', { 'mark-act': image.mark }]"
-              size="small"
-              icon="md-bookmark"
-              @click="toMark(image)"
-            ></Button>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { rotatePaper, absentPaper, markPaper } from "@/api";
-import ImageViewContain from "../../../components/ImageViewContain";
-
-export default {
-  name: "image-action-list",
-  components: { ImageViewContain },
-  props: {
-    data: {
-      type: Array,
-      default() {
-        return [];
-      }
-    },
-    actions: {
-      type: Array,
-      default() {
-        return [];
-      }
-    },
-    columnNumber: {
-      type: Number,
-      default: 5
-    }
-  },
-  data() {
-    return {
-      curImageIndex: 0,
-      stepDeg: 0,
-      saving: false,
-      curUserRoleType: this.$ls.get("user", { role: "" }).role
-    };
-  },
-  computed: {
-    classes() {
-      return [
-        "image-action-list",
-        "image-view-list",
-        `image-view-list-${this.columnNumber}`
-      ];
-    },
-    canRotate() {
-      return this.actions.includes("rotate");
-    },
-    canAbsent() {
-      return this.actions.includes("absent");
-    },
-    canMark() {
-      return this.actions.includes("mark");
-    }
-  },
-  methods: {
-    toRotate(image) {
-      if (!image["stepDeg"]) this.$set(image, "stepDeg", 0);
-      image.deg += 90;
-      if (image.deg === 360) image.deg = 0;
-      image.stepDeg += 90;
-      if (image.stepDeg === 360) image.stepDeg = 0;
-      image.styles = {
-        transform: `rotate(${image.deg}deg)`
-      };
-
-      this.$refs[`image${image.id}`][0].resizeImage(image.deg);
-    },
-    async toSaveRotate(image) {
-      if (this.saving) return;
-      if (!image.stepDeg) return;
-      this.saving = true;
-
-      let result = true;
-      await rotatePaper(image.id, image.stepDeg).catch(() => {
-        result = false;
-      });
-      this.saving = false;
-      if (!result) return;
-      image.stepDeg = 0;
-      this.$Message.success("保存成功!");
-    },
-    async toSignAbsent(image) {
-      await absentPaper(image.id);
-      image.missing = !image.missing;
-    },
-    async toMark(image) {
-      await markPaper({
-        paperId: image.id,
-        isMark: !image.mark,
-        role: this.curUserRoleType
-      });
-      image.mark = !image.mark;
-    },
-    toReview(index) {
-      this.$emit("on-review", index);
-    }
-  }
-};
-</script>
+<template>
+  <div :class="classes">
+    <div class="image-view" v-for="(image, index) in data" :key="image.key">
+      <div class="image-view-container">
+        <h5 class="image-view-title">{{ image.title }}</h5>
+        <image-view-contain
+          v-if="canRotate"
+          :ref="`image${image.id}`"
+          :image="image"
+          @to-review="toReview(index)"
+        ></image-view-contain>
+        <div
+          v-else
+          :class="[
+            'image-view-contain',
+            { 'image-view-none': !image.thumbSrc },
+          ]"
+        >
+          <img
+            v-if="image.thumbSrc"
+            :src="image.thumbSrc"
+            :alt="image.title"
+            :style="image.styles"
+            @click="toReview(index)"
+          />
+        </div>
+        <div class="image-view-actions" v-if="actions.length">
+          <div>
+            <Button
+              class="view-action-rotate"
+              size="small"
+              icon="md-refresh"
+              @click="toRotate(image)"
+              v-if="canRotate"
+            ></Button>
+            <Button
+              class="view-action-save"
+              size="small"
+              type="primary"
+              @click="toSaveRotate(image)"
+              :disabled="saving"
+              v-if="canRotate && image['stepDeg']"
+              >保存</Button
+            >
+          </div>
+          <div>
+            <Button
+              class="view-action-absent"
+              :type="image.missing ? 'error' : 'default'"
+              size="small"
+              @click="toSignAbsent(image)"
+              v-if="canAbsent"
+              >缺考</Button
+            >
+            <Button
+              v-if="canMark"
+              :class="['view-action-mark', { 'mark-act': image.mark }]"
+              size="small"
+              icon="md-bookmark"
+              @click="toMark(image)"
+            ></Button>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { rotatePaper, absentPaper, markPaper } from "@/api";
+import ImageViewContain from "../../../components/ImageViewContain";
+
+export default {
+  name: "image-action-list",
+  components: { ImageViewContain },
+  props: {
+    data: {
+      type: Array,
+      default() {
+        return [];
+      },
+    },
+    actions: {
+      type: Array,
+      default() {
+        return [];
+      },
+    },
+    columnNumber: {
+      type: Number,
+      default: 5,
+    },
+  },
+  data() {
+    return {
+      curImageIndex: 0,
+      stepDeg: 0,
+      saving: false,
+      curUserRoleType: this.$ls.get("user", { role: "" }).role,
+    };
+  },
+  computed: {
+    classes() {
+      return [
+        "image-action-list",
+        "image-view-list",
+        `image-view-list-${this.columnNumber}`,
+      ];
+    },
+    canRotate() {
+      return this.actions.includes("rotate");
+    },
+    canAbsent() {
+      return this.actions.includes("absent");
+    },
+    canMark() {
+      return this.actions.includes("mark");
+    },
+  },
+  methods: {
+    toRotate(image) {
+      if (!image["stepDeg"]) this.$set(image, "stepDeg", 0);
+      image.deg += 90;
+      if (image.deg === 360) image.deg = 0;
+      image.stepDeg += 90;
+      if (image.stepDeg === 360) image.stepDeg = 0;
+      image.styles = {
+        transform: `rotate(${image.deg}deg)`,
+      };
+
+      this.$refs[`image${image.id}`][0].resizeImage(image.deg);
+    },
+    async toSaveRotate(image) {
+      if (this.saving) return;
+      if (!image.stepDeg) return;
+      this.saving = true;
+
+      let result = true;
+      await rotatePaper(image.id, image.stepDeg).catch(() => {
+        result = false;
+      });
+      this.saving = false;
+      if (!result) return;
+      image.stepDeg = 0;
+      this.$Message.success("保存成功!");
+    },
+    async toSignAbsent(image) {
+      await absentPaper(image.id);
+      image.missing = !image.missing;
+    },
+    async toMark(image) {
+      await markPaper({
+        paperId: image.id,
+        isMark: !image.mark,
+        role: this.curUserRoleType,
+      });
+      image.mark = !image.mark;
+    },
+    toReview(index) {
+      this.$emit("on-review", index);
+    },
+  },
+};
+</script>

+ 19 - 19
src/modules/main/components/ModifyOrg.vue

@@ -65,13 +65,13 @@ const initModalForms = [
   {
     name: "",
     loginName: "",
-    userType: "1"
+    userType: "1",
   },
   {
     name: "",
     loginName: "",
-    userType: "2"
-  }
+    userType: "2",
+  },
 ];
 
 export default {
@@ -81,8 +81,8 @@ export default {
       type: Array,
       default() {
         return [];
-      }
-    }
+      },
+    },
   },
   computed: {
     isEdit() {
@@ -93,7 +93,7 @@ export default {
     },
     modalWidth() {
       return this.isEdit ? 600 : 900;
-    }
+    },
   },
   data() {
     return {
@@ -105,34 +105,34 @@ export default {
           {
             required: true,
             message: "请输入名称",
-            trigger: "change"
+            trigger: "change",
           },
           {
             min: 2,
             max: 20,
-            message: "长度只能介于2到20之间"
-          }
+            message: "长度只能介于2到20之间",
+          },
         ],
         loginName: [
           {
             required: true,
             pattern: /^[a-zA-Z0-9_-]{3,20}$/,
             message: "只能包含字母、数字、下划线以及短横线,长度3-20位",
-            trigger: "change"
-          }
+            trigger: "change",
+          },
         ],
-        password
-      }
+        password,
+      },
     };
   },
   methods: {
     initData(val) {
       if (this.instance.length) {
-        this.modalForms = this.instance.map(item => {
+        this.modalForms = this.instance.map((item) => {
           return { ...item };
         });
       } else {
-        this.modalForms = initModalForms.map(item => {
+        this.modalForms = initModalForms.map((item) => {
           return { ...item };
         });
       }
@@ -170,7 +170,7 @@ export default {
       });
       const res = await Promise.all(validAll).catch(() => {});
       console.log(res);
-      if (res.some(item => !item)) return;
+      if (res.some((item) => !item)) return;
 
       if (this.isSubmit) return;
       this.isSubmit = true;
@@ -179,7 +179,7 @@ export default {
         data = await updateOrgUser(this.modalForms[0]).catch(() => {});
       } else {
         data = await createOrg({
-          markUsers: this.modalForms
+          markUsers: this.modalForms,
         }).catch(() => {});
       }
       this.isSubmit = false;
@@ -189,7 +189,7 @@ export default {
       this.$Message.success(this.title + "成功!");
       this.$emit("modified");
       this.cancel();
-    }
-  }
+    },
+  },
 };
 </script>

+ 26 - 26
src/modules/main/components/ModifyStudent.vue

@@ -14,7 +14,7 @@
       :rules="rules"
       :key="modalForm.id"
       :label-width="100"
-      style="width: 340px;"
+      style="width: 340px"
     >
       <FormItem prop="name" label="姓名">
         <Input
@@ -104,7 +104,7 @@ const initModalForm = {
   areaName: "",
   areaCode: "",
   school: "",
-  examRoom: ""
+  examRoom: "",
 };
 
 export default {
@@ -114,14 +114,14 @@ export default {
       type: Object,
       default() {
         return {};
-      }
+      },
     },
     cascadeList: {
       type: Array,
       default() {
         return [];
-      }
-    }
+      },
+    },
   },
   computed: {
     isEdit() {
@@ -129,7 +129,7 @@ export default {
     },
     title() {
       return (this.isEdit ? "编辑" : "新增") + "考生信息";
-    }
+    },
   },
   data() {
     return {
@@ -143,48 +143,48 @@ export default {
           {
             required: true,
             message: "请输入姓名",
-            trigger: "change"
+            trigger: "change",
           },
           {
             min: 2,
             max: 20,
-            message: "姓名长度只能介于2到20之间"
-          }
+            message: "姓名长度只能介于2到20之间",
+          },
         ],
         examNumber: [
           {
             required: true,
             message: "请输入考号",
-            trigger: "change"
+            trigger: "change",
           },
           {
             min: 2,
             max: 20,
-            message: "考号长度只能介于2到20之间"
-          }
+            message: "考号长度只能介于2到20之间",
+          },
         ],
         areaCode: [
           {
             required: true,
             message: "请选择考区",
-            trigger: "change"
-          }
+            trigger: "change",
+          },
         ],
         school: [
           {
             required: true,
             message: "请选择学校",
-            trigger: "change"
-          }
+            trigger: "change",
+          },
         ],
         examRoom: [
           {
             required: true,
             message: "请选择考场",
-            trigger: "change"
-          }
-        ]
-      }
+            trigger: "change",
+          },
+        ],
+      },
     };
   },
   methods: {
@@ -204,17 +204,17 @@ export default {
     },
     reviewInfo() {
       const curArea = this.cascadeList.find(
-        item => item.areaCode === this.modalForm.areaCode
+        (item) => item.areaCode === this.modalForm.areaCode
       );
       this.schools = curArea.schools;
       const curSchool = this.schools.find(
-        item => item.school === this.modalForm.school
+        (item) => item.school === this.modalForm.school
       );
       this.rooms = curSchool.rooms;
     },
     areaChange() {
       const curArea = this.cascadeList.find(
-        item => item.areaCode === this.modalForm.areaCode
+        (item) => item.areaCode === this.modalForm.areaCode
       );
       this.schools = curArea ? curArea.schools : [];
       this.modalForm.areaName = curArea.areaName;
@@ -227,7 +227,7 @@ export default {
     },
     schoolChange() {
       const curSchool = this.schools.find(
-        item => item.school === this.modalForm.school
+        (item) => item.school === this.modalForm.school
       );
       this.rooms = curSchool ? curSchool.rooms : [];
       this.modalForm.examRoom = null;
@@ -262,7 +262,7 @@ export default {
       this.$Message.success(this.title + "成功!");
       this.$emit("modified");
       this.cancel();
-    }
-  }
+    },
+  },
 };
 </script>

+ 17 - 19
src/modules/main/components/QualityAnalysisExport.vue

@@ -1,9 +1,7 @@
 <template>
   <div class="quality-analysis-export analysis-export-modal">
     <div class="print-box">
-      <h1>
-        阅卷质量分析
-      </h1>
+      <h1>阅卷质量分析</h1>
       <div class="quality-info">
         <p>科目:{{ pageInfo.subjectName }}</p>
         <p>考区:{{ pageInfo.areaName }}</p>
@@ -104,37 +102,37 @@ export default {
       type: Object,
       default() {
         return {};
-      }
+      },
     },
     pageInfo: {
       type: Object,
       default() {
         return {};
-      }
-    }
+      },
+    },
   },
   data() {
     return {
-      showImg: false
+      showImg: false,
     };
   },
   mounted() {
     this.$nextTick(() => {
       this.$refs.levelsPropImg.src = this.$refs.levelsPropChart.getDataURL({
         backgroundColor: "#fff",
-        excludeComponents: ["toolbox "]
+        excludeComponents: ["toolbox "],
       });
       this.$refs.deviationImg.src = this.$refs.deviationChart.getDataURL({
         backgroundColor: "#fff",
-        excludeComponents: ["toolbox "]
+        excludeComponents: ["toolbox "],
       });
       this.$refs.distanceImg.src = this.$refs.distanceChart.getDataURL({
         backgroundColor: "#fff",
-        excludeComponents: ["toolbox "]
+        excludeComponents: ["toolbox "],
       });
       this.$refs.callbackImg.src = this.$refs.callbackChart.getDataURL({
         backgroundColor: "#fff",
-        excludeComponents: ["toolbox "]
+        excludeComponents: ["toolbox "],
       });
 
       this.showImg = true;
@@ -146,17 +144,17 @@ export default {
   methods: {
     async toExport() {
       let fetchAll = [];
-      this.$el.childNodes.forEach(item => {
+      this.$el.childNodes.forEach((item) => {
         fetchAll.push(
           html2canvas(item, {
-            allowTaint: true
+            allowTaint: true,
           })
         );
       });
       const canvasList = await Promise.all(fetchAll).catch(() => {});
       const contents = canvasList
-        .filter(canvas => canvas)
-        .map(canvas => canvas.toDataURL().split(",")[1]);
+        .filter((canvas) => canvas)
+        .map((canvas) => canvas.toDataURL().split(",")[1]);
 
       if (!contents.length) {
         this.$emit("on-exported", false);
@@ -170,15 +168,15 @@ export default {
         url: `${this.GLOBAL.domain}/api/exportPdf`,
         header: { Authorization: user.token, userId: user.id },
         data: {
-          content: contents
+          content: contents,
         },
-        fileName: `${this.pageInfo.subjectName}-${this.pageInfo.areaName}-阅卷质量分析.pdf`
+        fileName: `${this.pageInfo.subjectName}-${this.pageInfo.areaName}-阅卷质量分析.pdf`,
       }).catch(() => {
         result = false;
       });
 
       this.$emit("on-exported", result);
-    }
-  }
+    },
+  },
 };
 </script>

+ 1 - 1
src/modules/main/components/UploadStudentPaper.vue

@@ -36,6 +36,6 @@ export default {
   data() {
     return {};
   },
-  methods: {}
+  methods: {},
 };
 </script>

+ 8 - 8
src/modules/mark-set/ExportPaper.vue

@@ -58,7 +58,7 @@
 import {
   subjectList,
   areaSchoolRoomCascadeList,
-  exportDecryptPictures
+  exportDecryptPictures,
 } from "@/api";
 import { IMAGE_TYPE } from "@/constants/enumerate";
 import { requiredValid } from "@/plugins/formRules";
@@ -71,18 +71,18 @@ export default {
       decryptFilter: {
         imageType: "",
         areaId: "",
-        subject: ""
+        subject: "",
       },
       decryptRules: {
         imageType: requiredValid("请选择图片类型"),
         areaId: requiredValid("请选择考区"),
-        subject: requiredValid("请选择科目")
+        subject: requiredValid("请选择科目"),
       },
       IMAGE_TYPE,
       subjects: [],
       cascadeList: [],
       schools: [],
-      rooms: []
+      rooms: [],
     };
   },
   mounted() {
@@ -95,7 +95,7 @@ export default {
     },
     async getSubjects() {
       const data = await subjectList(this.workId);
-      this.subjects = data.filter(item => item.enable);
+      this.subjects = data.filter((item) => item.enable);
     },
     async toExportDecrypt() {
       const valid = await this.$refs.decryptForm.validate();
@@ -103,10 +103,10 @@ export default {
 
       await exportDecryptPictures({
         ...this.decryptFilter,
-        workId: this.workId
+        workId: this.workId,
       });
       this.$Message.success("操作成功,后台正在导出!");
-    }
-  }
+    },
+  },
 };
 </script>

+ 6 - 6
src/modules/mark-set/MarkRuleSet.vue

@@ -79,14 +79,14 @@
       <FormItem>
         <Button
           shape="circle"
-          style="width: 80px;"
+          style="width: 80px"
           @click="modalFormCanEdit = true"
           >编辑</Button
         >
         <Button
           type="primary"
           shape="circle"
-          style="width: 80px;"
+          style="width: 80px"
           :disabled="isSubmit"
           @click="submit"
           >保存</Button
@@ -114,10 +114,10 @@ export default {
         changeStage: 0,
         scoreShowAllPaper: 0,
         isLevelToScore: 0,
-        directScore: 0
+        directScore: 0,
       },
       modalFormCanEdit: false,
-      modalForm: {}
+      modalForm: {},
     };
   },
   mounted() {
@@ -141,7 +141,7 @@ export default {
       if (!result) return;
       this.modalFormCanEdit = false;
       this.$Message.success("保存成功!");
-    }
-  }
+    },
+  },
 };
 </script>

+ 5 - 5
src/modules/mark-set/MarkSet.vue

@@ -4,7 +4,7 @@
       <div
         :class="[
           'set-navs-item',
-          { 'set-navs-item-act': curNav.name === nav.name }
+          { 'set-navs-item-act': curNav.name === nav.name },
         ]"
         v-for="(nav, index) in navs"
         :key="index"
@@ -28,18 +28,18 @@ export default {
   data() {
     return {
       navs: markSet,
-      curNav: {}
+      curNav: {},
     };
   },
   watch: {
     $route: {
       handler(val) {
         this.actCurNav(val);
-      }
-    }
+      },
+    },
   },
   mounted() {
     this.actCurNav(this.$route);
-  }
+  },
 };
 </script>

+ 487 - 487
src/modules/mark/MarkDetail.vue

@@ -1,487 +1,487 @@
-<template>
-  <div :class="compClasses">
-    <grade-filter
-      ref="GradeFilter"
-      :data="workSubject"
-      @change="areaChange"
-    ></grade-filter>
-    <mark-step
-      :steps="steps"
-      :init-step="curStep"
-      :show-count="showPaperRelateCount"
-      :show-top-number="false"
-      @on-change="stepChange"
-      ref="MarkStep"
-      v-if="steps.levelStep"
-    ></mark-step>
-    <div class="detail-body">
-      <!-- detail-papers -->
-      <div :class="detailPapersClasses">
-        <div class="detail-papers-carousel" v-if="!IS_ADMIN">
-          <grade-history-paper
-            :question-id="filter.questionId"
-            stage="SCORE"
-            @on-paper-click="toViewCarouselPaper"
-            v-if="filter.questionId"
-            ref="GradeHistoryPaper"
-          ></grade-history-paper>
-        </div>
-        <div class="detail-papers-list" v-if="papers.length">
-          <div :class="imageViewClasses">
-            <div
-              :class="[
-                'image-view',
-                { 'image-view-act': curPaperIndex === index }
-              ]"
-              v-for="(image, index) in papers"
-              :key="index"
-            >
-              <div class="image-view-container">
-                <h5 class="image-view-title">{{ image.title }}</h5>
-                <div class="image-view-contain">
-                  <img
-                    :src="image.thumbSrc"
-                    :alt="image.title"
-                    @click="toReview(index)"
-                  />
-                </div>
-                <div class="image-view-actions">
-                  <span
-                    v-if="image.score || image.score === 0"
-                    class="color-error"
-                    >{{ image.score }}分</span
-                  >
-                </div>
-              </div>
-            </div>
-          </div>
-          <div
-            :class="[
-              'part-page',
-              { 'part-page-simple': !showPaperRelateCount }
-            ]"
-          >
-            <Page
-              :current="current"
-              :total="total"
-              :page-size="size"
-              :show-total="showPaperRelateCount"
-              show-elevator
-              @on-change="toPage"
-            ></Page>
-          </div>
-        </div>
-        <div class="detail-papers-list" v-else>
-          <p class="detail-papers-none">暂无数据</p>
-        </div>
-      </div>
-      <!-- detail-aciton -->
-      <div
-        :class="[
-          'detail-action',
-          { 'detail-action-fullscreen': isFullscreenMarking }
-        ]"
-      >
-        <mark-action
-          :cur-paper-or-task="curPaper"
-          :levels="levels"
-          @on-leader-level="leaderSelectLevel"
-          @on-code-search="serachPaperByCode"
-          @on-grade-change-search="searchGradeChangeList"
-          v-if="curPaper.id"
-          ref="GradeAction"
-        ></mark-action>
-      </div>
-      <!-- 占位 -->
-      <div class="detail-action" v-if="isFullscreenMarking"></div>
-    </div>
-
-    <!-- image-preview -->
-    <simple-image-preview
-      :class="imagePreviewClasses"
-      :cur-image="curPaper"
-      @on-prev="toPrevPaper"
-      @on-next="toNextPaper"
-      @on-close="isFullscreenMarking = false"
-      ref="SimpleImagePreview"
-    ></simple-image-preview>
-    <!-- carousel paper review -->
-    <simple-image-preview
-      :class="imagePreviewClasses"
-      :cur-image="curPaper"
-      @on-prev="toCarousePaper('prev')"
-      @on-next="toCarousePaper('next')"
-      @on-close="carouseImagePreviewClose"
-      ref="CarouselPapersPreview"
-    ></simple-image-preview>
-  </div>
-</template>
-
-<script>
-import {
-  paperList,
-  changeLevelPaperList,
-  paperManualScoreList,
-  scoreStatData,
-  workLevelList,
-  taskSnSearch,
-  markStepChangeLevel,
-  getParamsSet
-} from "@/api";
-import SimpleImagePreview from "@/components/SimpleImagePreview";
-import MarkStep from "./components/MarkStep";
-import GradeFilter from "../grading/components/GradeFilter";
-import GradeHistoryPaper from "../grading/components/GradeHistoryPaper";
-import MarkAction from "./components/MarkAction";
-// 三种情况:
-// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
-// 管理员:试卷列表,操作盘
-// 科组长:操作记录,试卷列表,操作盘(改档)
-
-// TIP:不考虑评卷员的情况
-// 评卷员:操作记录,试卷列表,操作盘(打分)
-
-export default {
-  name: "mark-detail",
-  components: {
-    SimpleImagePreview,
-    MarkStep,
-    GradeFilter,
-    GradeHistoryPaper,
-    MarkAction
-  },
-  data() {
-    return {
-      filter: {
-        questionId: "",
-        sort: "score,desc"
-      },
-      workId: this.$route.params.workId,
-      subjectId: this.$route.params.subjectId,
-      subject: "",
-      workSubject: {},
-      curUserRoleType: "",
-      applyChangeLevelStatus: 1, // 改档申请处理状态
-      current: 1,
-      size: 6,
-      total: 0,
-      totalPage: 1,
-      curStep: { type: "", name: "" },
-      steps: [],
-      levels: [],
-      curArea: [],
-      papers: [],
-      curPaper: {},
-      curPaperIndex: 0,
-      paramsSet: {},
-      // carousel paper review,
-      carouselPapers: [],
-      curCarouselPaperIndex: 0,
-      isFullscreenMarking: false
-    };
-  },
-  computed: {
-    compClasses() {
-      return [
-        "page-container-flex",
-        "mark-detail",
-        "grading-detail",
-        { "grading-operation": this.IS_MARK_LEADER }
-      ];
-    },
-    bodyClasses() {
-      return ["detail-body", { "detail-body-2": this.IS_ADMIN }];
-    },
-    detailPapersClasses() {
-      return [
-        "detail-papers",
-        {
-          [`detail-papers-col-${1 + this.size / 2}`]: !this.IS_ADMIN
-        }
-      ];
-    },
-    imageViewClasses() {
-      return ["image-view-list", `image-view-list-${this.size / 2}`];
-    },
-    showPaperRelateCount() {
-      return this.IS_ADMIN || !!this.paramsSet["showPaperCount"];
-    },
-    IS_ADMIN() {
-      return (
-        this.curUserRoleType === "ADMIN" ||
-        this.curUserRoleType === "SUPER_ADMIN"
-      );
-    },
-    IS_MARK_LEADER() {
-      return this.curUserRoleType === "MARK_LEADER";
-    },
-    imagePreviewClasses() {
-      return this.IS_ADMIN
-        ? "grading-detail-image-preview"
-        : "grading-operation-image-preview";
-    }
-  },
-  created() {
-    this.subject = this.subjectId.split("-")[1];
-    this.workSubject = {
-      workId: this.workId,
-      subject: this.subject
-    };
-    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
-    if (this.IS_ADMIN) this.size = 8;
-    this.initData();
-  },
-  methods: {
-    async initData() {
-      this.getWorkLevels();
-      this.getParamsSetInfo();
-    },
-    async getParamsSetInfo() {
-      this.paramsSet = await getParamsSet(this.workId);
-    },
-    async getList() {
-      let data = [];
-      if (this.curStep.type === "shift") {
-        const datas = {
-          workId: this.workId,
-          subject: this.subject,
-          questionId: this.filter.questionId,
-          status: this.applyChangeLevelStatus,
-          page: this.current - 1,
-          size: this.size
-        };
-        data = await changeLevelPaperList(datas);
-      } else if (this.curStep.type === "manualScore") {
-        const datas = {
-          workId: this.workId,
-          questionId: this.filter.questionId,
-          page: this.current - 1,
-          size: this.size
-        };
-        data = await paperManualScoreList(datas);
-      } else {
-        const datas = {
-          ...this.filter,
-          isScore: true,
-          page: this.current - 1,
-          size: this.size
-        };
-        if (this.curStep.type === "done") datas.level = this.curStep.name;
-
-        data = await paperList(datas);
-      }
-      this.papers = data.data.map(paper => {
-        paper.title = this.IS_ADMIN ? paper.examNumber : `NO.${paper.sn}`;
-        return paper;
-      });
-      this.total = data.totalCount;
-      this.totalPage = data.pageCount;
-    },
-    async toPage(page) {
-      this.current = page;
-      await this.getList();
-      this.selectPaper(this.curPaperIndex);
-    },
-    async getStepLevels() {
-      const data = await scoreStatData(this.subjectId, this.filter.questionId);
-      const undoIndex = data.findIndex(item => item.id === null);
-      let otherStep = [];
-      let undo = {
-        count: 0,
-        shift: 0
-      };
-      if (undoIndex !== -1) {
-        undo = { ...data[undoIndex] };
-        data.splice(undoIndex, 1);
-      }
-      otherStep.push({
-        name: "待评",
-        count: undo.count,
-        type: "undo"
-      });
-      otherStep.push({
-        name: "改档",
-        count: undo.shift,
-        type: "shift"
-      });
-      let levelStep = data
-        .filter(item => item.id !== "manualScore")
-        .map(item => {
-          return {
-            ...item,
-            name: item.id,
-            type: "done"
-          };
-        });
-      const msInfo = data.find(item => item.id === "manualScore");
-      if (msInfo) {
-        levelStep.push({
-          count: msInfo.count,
-          name: "输分试卷",
-          type: "manualScore"
-        });
-      }
-
-      this.steps = { levelStep, otherStep };
-      if (!this.curStep.type) {
-        this.curStep = levelStep[0];
-      }
-    },
-    async getWorkLevels() {
-      const data = await workLevelList(this.workId);
-      this.levels = data.map(item => {
-        return {
-          ...item,
-          name: item.code
-        };
-      });
-    },
-    async stepChange(step) {
-      this.applyChangeLevelStatus = 1;
-      this.curStep = step;
-      // this.toPage(1);
-      this.current = 1;
-      await this.getList();
-      if (this.papers.length) {
-        this.selectPaper(0);
-      } else {
-        this.curPaper = {};
-      }
-    },
-    async areaChange(curArea) {
-      this.curArea = curArea;
-      this.filter.questionId = curArea.id;
-      await this.getStepLevels();
-      this.toPage(1);
-    },
-    toReview(index) {
-      this.isFullscreenMarking = true;
-      this.selectPaper(index);
-      this.$refs.SimpleImagePreview.open();
-    },
-    selectPaper(index) {
-      let nindex = index;
-      if (!this.papers.length) {
-        nindex = 0;
-      } else if (index > this.papers.length - 1) {
-        nindex = this.papers.length - 1;
-      } else if (index < 0) {
-        nindex = 0;
-      }
-      this.curPaperIndex = nindex;
-      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
-    },
-    async toPrevPaper() {
-      if (this.curPaperIndex === 0) {
-        if (this.current > 1) {
-          this.current--;
-          this.curPaperIndex = this.size - 1;
-          await this.getList();
-        } else {
-          this.$Message.warning("当前已经是第一条数据了");
-          return;
-        }
-      } else {
-        this.curPaperIndex--;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toNextPaper() {
-      if (this.curPaperIndex === this.papers.length - 1) {
-        if (this.current === this.totalPage) {
-          this.$Message.warning("当前已经是最后一条数据了");
-          return;
-        } else {
-          this.current++;
-          this.curPaperIndex = 0;
-          await this.getList();
-        }
-      } else {
-        this.curPaperIndex++;
-      }
-
-      this.selectPaper(this.curPaperIndex);
-    },
-    async toActionNextPaper() {
-      if (this.current > 1 && this.papers.length === 1) {
-        this.current--;
-        this.curPaperIndex = this.size;
-      }
-
-      await this.getList();
-      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
-      this.selectPaper(this.curPaperIndex);
-    },
-    updateHistory() {
-      this.$refs.GradeHistoryPaper.updatePapers();
-    },
-    async serachPaperByCode(params) {
-      const data = await taskSnSearch(
-        params.codeType,
-        params.code,
-        this.filter.questionId
-      );
-      if (!data) {
-        this.$Message.error("没有查找到结果!");
-        return;
-      }
-      data.title = this.IS_ADMIN ? data.examNumber : `NO.${data.sn}`;
-      data.key = this.$randomCode();
-      this.papers = [data];
-      this.total = 1;
-      this.selectPaper(0);
-    },
-    searchGradeChangeList(applyChangeLevelStatus) {
-      this.applyChangeLevelStatus = applyChangeLevelStatus;
-      this.toPage(1);
-    },
-    leaderSelectLevel(levelInfo) {
-      const content = `确定申请由${levelInfo.curLevel}档改为${levelInfo.selectedLevel}并打回给所有老师吗?`;
-      this.$Modal.confirm({
-        content,
-        onOk: async () => {
-          await markStepChangeLevel({
-            subjectId: this.subjectId,
-            paperId: levelInfo.paperId,
-            level: levelInfo.selectedLevel,
-            userId: this.$ls.get("user", { id: "" }).id
-          });
-          this.$Message.success("申请改档成功!");
-          this.getStepLevels();
-          this.updateHistory();
-          this.toActionNextPaper();
-        }
-      });
-    },
-    // paper carousel
-    toViewCarouselPaper(paperIndex, papers) {
-      this.isFullscreenMarking = true;
-      this.carouselPapers = papers;
-      this.selectCarouselPaper(paperIndex);
-      this.$nextTick(() => {
-        this.$refs.CarouselPapersPreview.open();
-      });
-    },
-    selectCarouselPaper(index) {
-      this.curCarouselPaperIndex = index;
-      this.curPaper = { ...this.carouselPapers[index] };
-    },
-    toCarousePaper(type) {
-      if (type === "prev" && this.curCarouselPaperIndex > 0) {
-        this.curCarouselPaperIndex--;
-      } else if (
-        type === "next" &&
-        this.curCarouselPaperIndex < this.carouselPapers.length - 1
-      ) {
-        this.curCarouselPaperIndex++;
-      }
-      this.selectCarouselPaper(this.curCarouselPaperIndex);
-    },
-    carouseImagePreviewClose() {
-      this.isFullscreenMarking = false;
-      this.selectPaper(this.curPaperIndex);
-    }
-  }
-};
-</script>
+<template>
+  <div :class="compClasses">
+    <grade-filter
+      ref="GradeFilter"
+      :data="workSubject"
+      @change="areaChange"
+    ></grade-filter>
+    <mark-step
+      :steps="steps"
+      :init-step="curStep"
+      :show-count="showPaperRelateCount"
+      :show-top-number="false"
+      @on-change="stepChange"
+      ref="MarkStep"
+      v-if="steps.levelStep"
+    ></mark-step>
+    <div class="detail-body">
+      <!-- detail-papers -->
+      <div :class="detailPapersClasses">
+        <div class="detail-papers-carousel" v-if="!IS_ADMIN">
+          <grade-history-paper
+            :question-id="filter.questionId"
+            stage="SCORE"
+            @on-paper-click="toViewCarouselPaper"
+            v-if="filter.questionId"
+            ref="GradeHistoryPaper"
+          ></grade-history-paper>
+        </div>
+        <div class="detail-papers-list" v-if="papers.length">
+          <div :class="imageViewClasses">
+            <div
+              :class="[
+                'image-view',
+                { 'image-view-act': curPaperIndex === index },
+              ]"
+              v-for="(image, index) in papers"
+              :key="index"
+            >
+              <div class="image-view-container">
+                <h5 class="image-view-title">{{ image.title }}</h5>
+                <div class="image-view-contain">
+                  <img
+                    :src="image.thumbSrc"
+                    :alt="image.title"
+                    @click="toReview(index)"
+                  />
+                </div>
+                <div class="image-view-actions">
+                  <span
+                    v-if="image.score || image.score === 0"
+                    class="color-error"
+                    >{{ image.score }}分</span
+                  >
+                </div>
+              </div>
+            </div>
+          </div>
+          <div
+            :class="[
+              'part-page',
+              { 'part-page-simple': !showPaperRelateCount },
+            ]"
+          >
+            <Page
+              :current="current"
+              :total="total"
+              :page-size="size"
+              :show-total="showPaperRelateCount"
+              show-elevator
+              @on-change="toPage"
+            ></Page>
+          </div>
+        </div>
+        <div class="detail-papers-list" v-else>
+          <p class="detail-papers-none">暂无数据</p>
+        </div>
+      </div>
+      <!-- detail-aciton -->
+      <div
+        :class="[
+          'detail-action',
+          { 'detail-action-fullscreen': isFullscreenMarking },
+        ]"
+      >
+        <mark-action
+          :cur-paper-or-task="curPaper"
+          :levels="levels"
+          @on-leader-level="leaderSelectLevel"
+          @on-code-search="serachPaperByCode"
+          @on-grade-change-search="searchGradeChangeList"
+          v-if="curPaper.id"
+          ref="GradeAction"
+        ></mark-action>
+      </div>
+      <!-- 占位 -->
+      <div class="detail-action" v-if="isFullscreenMarking"></div>
+    </div>
+
+    <!-- image-preview -->
+    <simple-image-preview
+      :class="imagePreviewClasses"
+      :cur-image="curPaper"
+      @on-prev="toPrevPaper"
+      @on-next="toNextPaper"
+      @on-close="isFullscreenMarking = false"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
+    <!-- carousel paper review -->
+    <simple-image-preview
+      :class="imagePreviewClasses"
+      :cur-image="curPaper"
+      @on-prev="toCarousePaper('prev')"
+      @on-next="toCarousePaper('next')"
+      @on-close="carouseImagePreviewClose"
+      ref="CarouselPapersPreview"
+    ></simple-image-preview>
+  </div>
+</template>
+
+<script>
+import {
+  paperList,
+  changeLevelPaperList,
+  paperManualScoreList,
+  scoreStatData,
+  workLevelList,
+  taskSnSearch,
+  markStepChangeLevel,
+  getParamsSet,
+} from "@/api";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+import MarkStep from "./components/MarkStep";
+import GradeFilter from "../grading/components/GradeFilter";
+import GradeHistoryPaper from "../grading/components/GradeHistoryPaper";
+import MarkAction from "./components/MarkAction";
+// 三种情况:
+// 管理员(ADMIN),科组长(MARK_LEADER),评卷员(MARKER)
+// 管理员:试卷列表,操作盘
+// 科组长:操作记录,试卷列表,操作盘(改档)
+
+// TIP:不考虑评卷员的情况
+// 评卷员:操作记录,试卷列表,操作盘(打分)
+
+export default {
+  name: "mark-detail",
+  components: {
+    SimpleImagePreview,
+    MarkStep,
+    GradeFilter,
+    GradeHistoryPaper,
+    MarkAction,
+  },
+  data() {
+    return {
+      filter: {
+        questionId: "",
+        sort: "score,desc",
+      },
+      workId: this.$route.params.workId,
+      subjectId: this.$route.params.subjectId,
+      subject: "",
+      workSubject: {},
+      curUserRoleType: "",
+      applyChangeLevelStatus: 1, // 改档申请处理状态
+      current: 1,
+      size: 6,
+      total: 0,
+      totalPage: 1,
+      curStep: { type: "", name: "" },
+      steps: [],
+      levels: [],
+      curArea: [],
+      papers: [],
+      curPaper: {},
+      curPaperIndex: 0,
+      paramsSet: {},
+      // carousel paper review,
+      carouselPapers: [],
+      curCarouselPaperIndex: 0,
+      isFullscreenMarking: false,
+    };
+  },
+  computed: {
+    compClasses() {
+      return [
+        "page-container-flex",
+        "mark-detail",
+        "grading-detail",
+        { "grading-operation": this.IS_MARK_LEADER },
+      ];
+    },
+    bodyClasses() {
+      return ["detail-body", { "detail-body-2": this.IS_ADMIN }];
+    },
+    detailPapersClasses() {
+      return [
+        "detail-papers",
+        {
+          [`detail-papers-col-${1 + this.size / 2}`]: !this.IS_ADMIN,
+        },
+      ];
+    },
+    imageViewClasses() {
+      return ["image-view-list", `image-view-list-${this.size / 2}`];
+    },
+    showPaperRelateCount() {
+      return this.IS_ADMIN || !!this.paramsSet["showPaperCount"];
+    },
+    IS_ADMIN() {
+      return (
+        this.curUserRoleType === "ADMIN" ||
+        this.curUserRoleType === "SUPER_ADMIN"
+      );
+    },
+    IS_MARK_LEADER() {
+      return this.curUserRoleType === "MARK_LEADER";
+    },
+    imagePreviewClasses() {
+      return this.IS_ADMIN
+        ? "grading-detail-image-preview"
+        : "grading-operation-image-preview";
+    },
+  },
+  created() {
+    this.subject = this.subjectId.split("-")[1];
+    this.workSubject = {
+      workId: this.workId,
+      subject: this.subject,
+    };
+    this.curUserRoleType = this.$ls.get("user", { role: "" }).role;
+    if (this.IS_ADMIN) this.size = 8;
+    this.initData();
+  },
+  methods: {
+    async initData() {
+      this.getWorkLevels();
+      this.getParamsSetInfo();
+    },
+    async getParamsSetInfo() {
+      this.paramsSet = await getParamsSet(this.workId);
+    },
+    async getList() {
+      let data = [];
+      if (this.curStep.type === "shift") {
+        const datas = {
+          workId: this.workId,
+          subject: this.subject,
+          questionId: this.filter.questionId,
+          status: this.applyChangeLevelStatus,
+          page: this.current - 1,
+          size: this.size,
+        };
+        data = await changeLevelPaperList(datas);
+      } else if (this.curStep.type === "manualScore") {
+        const datas = {
+          workId: this.workId,
+          questionId: this.filter.questionId,
+          page: this.current - 1,
+          size: this.size,
+        };
+        data = await paperManualScoreList(datas);
+      } else {
+        const datas = {
+          ...this.filter,
+          isScore: true,
+          page: this.current - 1,
+          size: this.size,
+        };
+        if (this.curStep.type === "done") datas.level = this.curStep.name;
+
+        data = await paperList(datas);
+      }
+      this.papers = data.data.map((paper) => {
+        paper.title = this.IS_ADMIN ? paper.examNumber : `NO.${paper.sn}`;
+        return paper;
+      });
+      this.total = data.totalCount;
+      this.totalPage = data.pageCount;
+    },
+    async toPage(page) {
+      this.current = page;
+      await this.getList();
+      this.selectPaper(this.curPaperIndex);
+    },
+    async getStepLevels() {
+      const data = await scoreStatData(this.subjectId, this.filter.questionId);
+      const undoIndex = data.findIndex((item) => item.id === null);
+      let otherStep = [];
+      let undo = {
+        count: 0,
+        shift: 0,
+      };
+      if (undoIndex !== -1) {
+        undo = { ...data[undoIndex] };
+        data.splice(undoIndex, 1);
+      }
+      otherStep.push({
+        name: "待评",
+        count: undo.count,
+        type: "undo",
+      });
+      otherStep.push({
+        name: "改档",
+        count: undo.shift,
+        type: "shift",
+      });
+      let levelStep = data
+        .filter((item) => item.id !== "manualScore")
+        .map((item) => {
+          return {
+            ...item,
+            name: item.id,
+            type: "done",
+          };
+        });
+      const msInfo = data.find((item) => item.id === "manualScore");
+      if (msInfo) {
+        levelStep.push({
+          count: msInfo.count,
+          name: "输分试卷",
+          type: "manualScore",
+        });
+      }
+
+      this.steps = { levelStep, otherStep };
+      if (!this.curStep.type) {
+        this.curStep = levelStep[0];
+      }
+    },
+    async getWorkLevels() {
+      const data = await workLevelList(this.workId);
+      this.levels = data.map((item) => {
+        return {
+          ...item,
+          name: item.code,
+        };
+      });
+    },
+    async stepChange(step) {
+      this.applyChangeLevelStatus = 1;
+      this.curStep = step;
+      // this.toPage(1);
+      this.current = 1;
+      await this.getList();
+      if (this.papers.length) {
+        this.selectPaper(0);
+      } else {
+        this.curPaper = {};
+      }
+    },
+    async areaChange(curArea) {
+      this.curArea = curArea;
+      this.filter.questionId = curArea.id;
+      await this.getStepLevels();
+      this.toPage(1);
+    },
+    toReview(index) {
+      this.isFullscreenMarking = true;
+      this.selectPaper(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    selectPaper(index) {
+      let nindex = index;
+      if (!this.papers.length) {
+        nindex = 0;
+      } else if (index > this.papers.length - 1) {
+        nindex = this.papers.length - 1;
+      } else if (index < 0) {
+        nindex = 0;
+      }
+      this.curPaperIndex = nindex;
+      this.curPaper = this.papers[nindex] ? { ...this.papers[nindex] } : {};
+    },
+    async toPrevPaper() {
+      if (this.curPaperIndex === 0) {
+        if (this.current > 1) {
+          this.current--;
+          this.curPaperIndex = this.size - 1;
+          await this.getList();
+        } else {
+          this.$Message.warning("当前已经是第一条数据了");
+          return;
+        }
+      } else {
+        this.curPaperIndex--;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toNextPaper() {
+      if (this.curPaperIndex === this.papers.length - 1) {
+        if (this.current === this.totalPage) {
+          this.$Message.warning("当前已经是最后一条数据了");
+          return;
+        } else {
+          this.current++;
+          this.curPaperIndex = 0;
+          await this.getList();
+        }
+      } else {
+        this.curPaperIndex++;
+      }
+
+      this.selectPaper(this.curPaperIndex);
+    },
+    async toActionNextPaper() {
+      if (this.current > 1 && this.papers.length === 1) {
+        this.current--;
+        this.curPaperIndex = this.size;
+      }
+
+      await this.getList();
+      if (!this.papers.length) this.$refs.SimpleImagePreview.cancel();
+      this.selectPaper(this.curPaperIndex);
+    },
+    updateHistory() {
+      this.$refs.GradeHistoryPaper.updatePapers();
+    },
+    async serachPaperByCode(params) {
+      const data = await taskSnSearch(
+        params.codeType,
+        params.code,
+        this.filter.questionId
+      );
+      if (!data) {
+        this.$Message.error("没有查找到结果!");
+        return;
+      }
+      data.title = this.IS_ADMIN ? data.examNumber : `NO.${data.sn}`;
+      data.key = this.$randomCode();
+      this.papers = [data];
+      this.total = 1;
+      this.selectPaper(0);
+    },
+    searchGradeChangeList(applyChangeLevelStatus) {
+      this.applyChangeLevelStatus = applyChangeLevelStatus;
+      this.toPage(1);
+    },
+    leaderSelectLevel(levelInfo) {
+      const content = `确定申请由${levelInfo.curLevel}档改为${levelInfo.selectedLevel}并打回给所有老师吗?`;
+      this.$Modal.confirm({
+        content,
+        onOk: async () => {
+          await markStepChangeLevel({
+            subjectId: this.subjectId,
+            paperId: levelInfo.paperId,
+            level: levelInfo.selectedLevel,
+            userId: this.$ls.get("user", { id: "" }).id,
+          });
+          this.$Message.success("申请改档成功!");
+          this.getStepLevels();
+          this.updateHistory();
+          this.toActionNextPaper();
+        },
+      });
+    },
+    // paper carousel
+    toViewCarouselPaper(paperIndex, papers) {
+      this.isFullscreenMarking = true;
+      this.carouselPapers = papers;
+      this.selectCarouselPaper(paperIndex);
+      this.$nextTick(() => {
+        this.$refs.CarouselPapersPreview.open();
+      });
+    },
+    selectCarouselPaper(index) {
+      this.curCarouselPaperIndex = index;
+      this.curPaper = { ...this.carouselPapers[index] };
+    },
+    toCarousePaper(type) {
+      if (type === "prev" && this.curCarouselPaperIndex > 0) {
+        this.curCarouselPaperIndex--;
+      } else if (
+        type === "next" &&
+        this.curCarouselPaperIndex < this.carouselPapers.length - 1
+      ) {
+        this.curCarouselPaperIndex++;
+      }
+      this.selectCarouselPaper(this.curCarouselPaperIndex);
+    },
+    carouseImagePreviewClose() {
+      this.isFullscreenMarking = false;
+      this.selectPaper(this.curPaperIndex);
+    },
+  },
+};
+</script>

Деякі файли не було показано, через те що забагато файлів було змінено