zhangjie vor 4 Jahren
Ursprung
Commit
e0336bf396
83 geänderte Dateien mit 3455 neuen und 6900 gelöschten Zeilen
  1. 1 1
      .env
  2. 1 0
      .gitignore
  3. 1 1
      card/api.js
  4. 0 0
      card/card.temp.json
  5. 0 0
      src/assets/images/icon-exam-gray.png
  6. 0 0
      src/assets/images/icon-exam.png
  7. 13 7
      src/assets/styles/element-ui-costom.scss
  8. 73 26
      src/assets/styles/home.scss
  9. 12 12
      src/assets/styles/icons.scss
  10. 38 1
      src/assets/styles/pages.scss
  11. 4 5
      src/assets/styles/variables.scss
  12. 26 21
      src/constants/enumerate.js
  13. 126 87
      src/constants/navs.js
  14. 2 1
      src/main.js
  15. 0 19
      src/modules/analyze/api.js
  16. 0 114
      src/modules/analyze/components/ModifyData.vue
  17. 0 9
      src/modules/analyze/router.js
  18. 0 186
      src/modules/analyze/views/ScoreAnalyze.vue
  19. 83 39
      src/modules/base/api.js
  20. 1 15
      src/modules/base/components/BusinessFields.vue
  21. 397 0
      src/modules/base/components/ModifyCardRule.vue
  22. 10 10
      src/modules/base/components/ModifyCourse.vue
  23. 99 0
      src/modules/base/components/ModifyField.vue
  24. 164 0
      src/modules/base/components/ModifyMenu.vue
  25. 157 0
      src/modules/base/components/ModifyOrganization.vue
  26. 177 0
      src/modules/base/components/ModifyRole.vue
  27. 254 0
      src/modules/base/components/ModifyTemplate.vue
  28. 239 0
      src/modules/base/components/ModifyUser.vue
  29. 36 34
      src/modules/base/components/ResetPwd.vue
  30. 210 0
      src/modules/base/components/RuleBusiness.vue
  31. 44 15
      src/modules/base/router.js
  32. 195 0
      src/modules/base/views/CardRule.vue
  33. 17 0
      src/modules/base/views/CommonCardTemplate.vue
  34. 17 0
      src/modules/base/views/CommonPrintTemplate.vue
  35. 5 13
      src/modules/base/views/CommonRule.vue
  36. 11 9
      src/modules/base/views/CourseManage.vue
  37. 159 0
      src/modules/base/views/MenuManage.vue
  38. 140 0
      src/modules/base/views/OrganizationManage.vue
  39. 17 0
      src/modules/base/views/ParamPrintTemplate.vue
  40. 0 15
      src/modules/base/views/PswdManage.vue
  41. 281 0
      src/modules/base/views/RoleManage.vue
  42. 212 0
      src/modules/base/views/TemplateManage.vue
  43. 0 201
      src/modules/base/views/UserEdit.vue
  44. 62 51
      src/modules/base/views/UserManage.vue
  45. 0 174
      src/modules/exam-center/api.js
  46. 0 115
      src/modules/exam-center/components/BusinessData.vue
  47. 0 256
      src/modules/exam-center/components/CardOptionDialog.vue
  48. 0 47
      src/modules/exam-center/components/ExamPlanData.vue
  49. 0 131
      src/modules/exam-center/components/UploadPaperDialog.vue
  50. 0 154
      src/modules/exam-center/components/UploadSamplePaperDialog.vue
  51. 0 145
      src/modules/exam-center/router.js
  52. 0 25
      src/modules/exam-center/store.js
  53. 0 254
      src/modules/exam-center/views/CardAudit.vue
  54. 0 391
      src/modules/exam-center/views/CardManage.vue
  55. 0 134
      src/modules/exam-center/views/DoneTask.vue
  56. 0 157
      src/modules/exam-center/views/DoneTaskDetail.vue
  57. 0 338
      src/modules/exam-center/views/ExamManage.vue
  58. 0 484
      src/modules/exam-center/views/ExamModify.vue
  59. 0 207
      src/modules/exam-center/views/ExamRoomDetail.vue
  60. 0 245
      src/modules/exam-center/views/ExamRoomStudentDetail.vue
  61. 0 173
      src/modules/exam-center/views/ExamTaskAudit.vue
  62. 0 214
      src/modules/exam-center/views/ExamTaskAuditEdit.vue
  63. 0 50
      src/modules/exam-center/views/ExamTaskDetail.vue
  64. 0 184
      src/modules/exam-center/views/PrintManage.vue
  65. 0 140
      src/modules/exam-center/views/TodoExam.vue
  66. 0 331
      src/modules/exam-center/views/TopicTaskManage.vue
  67. 0 227
      src/modules/exam-center/views/TopicTaskModify.vue
  68. 0 152
      src/modules/exam-center/views/WaitTask.vue
  69. 0 401
      src/modules/exam-center/views/WaitTaskDetail.vue
  70. 0 19
      src/modules/example/api.js
  71. 0 114
      src/modules/example/components/ModifyData.vue
  72. 0 9
      src/modules/example/router.js
  73. 0 186
      src/modules/example/views/DataManage.vue
  74. 2 2
      src/modules/login/views/Login.vue
  75. 0 19
      src/modules/score-paper/api.js
  76. 0 114
      src/modules/score-paper/components/ModifyData.vue
  77. 0 9
      src/modules/score-paper/router.js
  78. 0 186
      src/modules/score-paper/views/ClassPaper.vue
  79. 15 0
      src/plugins/filters.js
  80. 5 0
      src/plugins/mixins.js
  81. 4 4
      src/router.js
  82. 3 3
      src/store.js
  83. 142 214
      src/views/Home.vue

+ 1 - 1
.env

@@ -2,4 +2,4 @@ NODE_ENV=development
 VUE_APP_DOMAIN=
 VUE_APP_TIMEOUT=600000
 VUE_APP_PAGE_SIZE=10
-VUE_APP_AUTH_TIMEOUT=7200000
+VUE_APP_AUTH_TIMEOUT=72000000

+ 1 - 0
.gitignore

@@ -2,6 +2,7 @@
 node_modules
 /dist
 dev-proxy.js
+modules-old*
 
 # local env files
 .env.local

+ 1 - 1
card/api.js

@@ -26,7 +26,7 @@ export const cardConfigInfos = () => {
   //       field: "username"
   //     },
   //     {
-  //       name: "科目名称",
+  //       name: "课程名称",
   //       field: "courseName"
   //     },
   //     {

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
card/card.temp.json


+ 0 - 0
src/assets/images/icon-exam-center-gray.png → src/assets/images/icon-exam-gray.png


+ 0 - 0
src/assets/images/icon-exam-center.png → src/assets/images/icon-exam.png


+ 13 - 7
src/assets/styles/element-ui-costom.scss

@@ -1,6 +1,6 @@
 // dialog
 .el-dialog {
-  border-radius: 10px;
+  border-radius: 8px;
   overflow: hidden;
   border: 1px solid #c8c8ca;
   background-color: #f6f6f6;
@@ -18,7 +18,7 @@
   }
 }
 .el-dialog__body {
-  padding: 30px 20px 20px;
+  padding: 20px;
   background-color: #f6f6f6;
   position: relative;
   border-top: 1px solid #e5e5e5;
@@ -39,7 +39,7 @@
   }
   .el-form-item__label {
     font-weight: bold;
-    color: rgba(153, 153, 153, 1);
+    color: #545454;
     padding-right: 2px;
   }
   .el-input-tips {
@@ -53,7 +53,7 @@
   text-align: center;
   .el-button {
     width: 100px;
-    border-radius: 10px;
+    border-radius: 8px;
   }
   .el-button--default {
     background: rgba(245, 245, 245, 1);
@@ -248,7 +248,7 @@
 }
 // table
 .el-table {
-  color: $--color-text-regular;
+  color: $--color-text-primary;
   font-weight: bold;
 
   &--border {
@@ -257,8 +257,8 @@
   }
 
   &__header thead {
-    font-size: 16px;
-    color: $--color-text-primary;
+    // font-size: 16px;
+    color: $--color-text-regular;
     font-weight: bold;
   }
   tr.el-table__row {
@@ -307,6 +307,11 @@
         border-color: $--color-border;
       }
     }
+    &.is-indeterminate {
+      .el-checkbox__inner {
+        background-color: $--color-primary;
+      }
+    }
   }
   .el-checkbox__label {
     color: $--color-text-regular !important;
@@ -376,6 +381,7 @@
       color: $--color-text-regular;
       font-weight: bold;
       margin: 0 5px;
+      padding: 0 8px;
       line-height: 32px;
 
       @extend .el-pagination-li;

+ 73 - 26
src/assets/styles/home.scss

@@ -8,7 +8,7 @@
 .home-body {
   position: absolute;
   left: 0;
-  top: 60px;
+  top: 50px;
   right: 0;
   bottom: 0;
   overflow: auto;
@@ -17,7 +17,7 @@
 }
 .home-main {
   position: relative;
-  padding: 0 0 60px 240px;
+  padding: 0 0 50px 220px;
   min-height: 100%;
   transition: padding-left 0.2s ease;
 }
@@ -25,13 +25,13 @@
 /* navs */
 .home-navs {
   position: absolute;
-  width: 240px;
-  top: 60px;
+  width: 220px;
+  top: 50px;
   left: 0;
   bottom: 0;
   z-index: 99;
   overflow: auto;
-  font-size: 16px;
+  font-size: 14px;
   background: linear-gradient(
     90deg,
     rgba(247, 247, 247, 1) 0%,
@@ -50,15 +50,21 @@
     background: rgba(229, 229, 229, 1);
   }
 
+  .nav-part {
+    margin-bottom: 30px;
+  }
+
   .nav-head {
-    padding: 20px 30px;
+    padding: 15px 10px;
     color: $--color-text-secondary;
-    font-size: 18px;
-    line-height: 40px;
+    font-size: 16px;
+    line-height: 20px;
     font-weight: bold;
     border-bottom: 1px solid #e9e9e9;
     > i {
-      margin-right: 12px;
+      margin-right: 6px;
+      width: 20px;
+      height: 20px;
     }
     > span {
       display: inline-block;
@@ -67,15 +73,15 @@
   }
 
   .nav-list {
-    padding: 0 30px;
+    padding: 0 10px 0 36px;
   }
   .nav-item {
     overflow: hidden;
 
     border-bottom: 1px solid $--color-border;
     &-main {
-      padding: 15px 0;
-      line-height: 30px;
+      padding: 12px 0;
+      line-height: 20px;
       position: relative;
       cursor: pointer;
       font-weight: bold;
@@ -89,12 +95,12 @@
       position: absolute;
       width: 20px;
       height: 20px;
-      top: 20px;
+      top: 10px;
       text-align: center;
       line-height: 20px;
     }
     &-icon-right {
-      right: 10px;
+      right: 5px;
     }
     &-info {
       display: block;
@@ -104,8 +110,8 @@
       height: 20px;
       font-size: 14px;
       line-height: 20px;
-      top: 20px;
-      right: 35px;
+      top: 10px;
+      right: 25px;
       background-color: $--color-danger;
       color: #fff;
       text-align: center;
@@ -118,7 +124,7 @@
 .home-header {
   position: absolute;
   width: 100%;
-  height: 60px;
+  height: 50px;
   top: 0;
   left: 0;
   z-index: 100;
@@ -127,9 +133,9 @@
   overflow: hidden;
 
   .head-logo {
-    width: 240px;
+    width: 220px;
     float: left;
-    padding: 15px 20px;
+    padding: 10px 36px;
     font-size: 20px;
     line-height: 30px;
   }
@@ -149,9 +155,10 @@
       display: inline-block;
       vertical-align: top;
       width: 190px;
-      padding: 15px 0;
+      padding: 10px 0;
+      height: 50px;
       line-height: 30px;
-      opacity: 0.5;
+      opacity: 0.7;
       font-size: 16px;
       position: relative;
       text-align: center;
@@ -247,7 +254,7 @@
 
 // home-breadcrumb
 .home-breadcrumb {
-  padding: 25px 30px;
+  padding: 15px 20px;
   .el-breadcrumb {
     line-height: 30px;
     font-weight: bold;
@@ -259,7 +266,7 @@
 
       &:last-child {
         .el-breadcrumb__inner {
-          color: $--color-text-regular;
+          color: $--color-text-primary;
           font-weight: bold;
         }
       }
@@ -276,7 +283,7 @@
 
 // home-view
 .home-view {
-  padding: 0 30px;
+  padding: 0 20px;
 }
 
 /* view-footer */
@@ -310,12 +317,35 @@
     border: 1px solid $--color-border;
   }
   &-pad {
-    padding: 20px;
+    padding: 15px;
   }
 
   &-filter {
-    padding: 20px 20px 0;
+    padding: 15px 15px 0;
     border: 1px solid $--color-border;
+
+    .el-form-item {
+      margin-bottom: 15px;
+    }
+  }
+
+  &-flex {
+    display: flex;
+    align-items: stretch;
+    justify-content: space-between;
+  }
+
+  &-action {
+    padding-bottom: 15px;
+    white-space: nowrap;
+    display: flex;
+    align-items: flex-end;
+  }
+  &-tips {
+    font-size: 14px;
+    line-height: 25px;
+    color: $--color-text-regular;
+    margin-bottom: 15px;
   }
 }
 .part-title {
@@ -440,3 +470,20 @@
 .form-item-content {
   color: $--color-text-regular;
 }
+.action-column {
+  .cell {
+    overflow: visible;
+  }
+}
+.inline-block {
+  display: inline-block;
+  vertical-align: top;
+}
+.custom-tree-node {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  font-size: 14px;
+  padding-right: 8px;
+}

+ 12 - 12
src/assets/styles/icons.scss

@@ -27,37 +27,37 @@
     width: 16px;
     height: 16px;
   }
-  &-exam-center {
-    background-image: url(../images/icon-exam-center.png);
+  &-exam {
+    background-image: url(../images/icon-exam.png);
   }
-  &-exam-center-gray {
-    background-image: url(../images/icon-exam-center-gray.png);
-    width: 24px;
-    height: 24px;
+  &-exam-gray {
+    background-image: url(../images/icon-exam-gray.png);
+    width: 20px;
+    height: 20px;
   }
   &-score-paper {
     background-image: url(../images/icon-score-paper.png);
   }
   &-score-paper-gray {
     background-image: url(../images/icon-score-paper-gray.png);
-    width: 24px;
-    height: 24px;
+    width: 20px;
+    height: 20px;
   }
   &-analyze {
     background-image: url(../images/icon-analyze.png);
   }
   &-analyze-gray {
     background-image: url(../images/icon-analyze-gray.png);
-    width: 24px;
-    height: 24px;
+    width: 20px;
+    height: 20px;
   }
   &-base {
     background-image: url(../images/icon-base.png);
   }
   &-base-gray {
     background-image: url(../images/icon-base-gray.png);
-    width: 24px;
-    height: 24px;
+    width: 20px;
+    height: 20px;
   }
   &-account {
     background-image: url(../images/icon-account.png);

+ 38 - 1
src/assets/styles/pages.scss

@@ -146,7 +146,7 @@
 }
 // business-fields
 .business-fields {
-  padding: 25px;
+  padding: 10px 25px;
   border-radius: $--border-radius;
   border: 1px solid $--color-border;
   .el-form-item {
@@ -163,3 +163,40 @@
   bottom: 0;
   z-index: 99;
 }
+// label-edit
+.label-edit {
+  .label-item {
+    display: inline-block;
+    vertical-align: top;
+    border: 1px solid $--border-color-light;
+    border-radius: $--border-radius;
+    padding: 8px 40px 8px 10px;
+    position: relative;
+    margin: 0 10px 10px 0;
+    line-height: 26px;
+  }
+  .label-item-content {
+    margin: 0;
+    line-height: 26px;
+    vertical-align: middle;
+  }
+  .label-item-delete {
+    position: absolute;
+    width: 20px;
+    height: 20px;
+    right: 10px;
+    top: 50%;
+    margin-top: -10px;
+    z-index: 99;
+    font-size: 20px;
+    color: $--color-text-secondary;
+    cursor: pointer;
+    &:hover {
+      color: $--color-danger;
+    }
+  }
+}
+
+// rule-business
+.rule-business {
+}

+ 4 - 5
src/assets/styles/variables.scss

@@ -1,8 +1,8 @@
 // color ------------------->
 $--color-text-primary: #545454 !default;
 $--color-text-regular: #878787 !default;
-$--color-text-secondary: #bbbbbb !default;
-$--color-text-placeholder: #cccccc !default;
+$--color-text-secondary: #aaa !default;
+$--color-text-placeholder: #ccc !default;
 $--border-color-base: #dcdfe6 !default;
 $--border-color-light: #e4e7ed !default;
 $--border-color-lighter: #ebeef5 !default;
@@ -17,10 +17,9 @@ $--color-info: #909399 !default;
 $--color-blue: #556dff !default;
 $--color-blue-white: #667cff !default;
 $--color-white: #ffffff;
+$--color-dark: #21252b;
 // skin
 $--color-background: #f5f5f5;
-$--color-background-dark: #21252b;
-$--color-background-act-dark: #2c313a;
 // border
 $--color-border: #e2e2e2;
 $--color-border-light: #e8e8e8;
@@ -31,7 +30,7 @@ $--shadow-light: 0 0 1px rgba(0, 0, 0, 0.15) !default;
 $--font-size-base: 14px !default;
 $--font-size-large: 18px !default;
 $--font-size-medium: 16px !default;
-$--border-radius: 10px;
+$--border-radius: 8px;
 
 $--font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
   "Microsoft YaHei", Arial, sans-serif;

+ 26 - 21
src/constants/enumerate.js

@@ -73,7 +73,7 @@ export const CARD_BUSINESS_FIELDS = {
       code: "name"
     },
     {
-      name: "科目名称",
+      name: "课程名称",
       code: "courseName"
     }
   ],
@@ -101,14 +101,26 @@ export const CARD_SOURCE_TYPE = {
 };
 
 export const EXAM_NUMBER_STYLE = {
-  0: "印刷条码",
-  1: "粘贴条码",
-  2: "考号填涂"
+  PRINT: "印刷条码",
+  PASTE: "粘贴条码",
+  FILL: "考号填涂"
 };
 
 export const PAPER_TYPE = {
-  0: "印刷",
-  1: "填涂"
+  PRINT: "印刷",
+  FILL: "填涂"
+};
+
+export const TEMPLATE_TYPE = {
+  GENERIC: "通卡模板",
+  VARIABLE: "变量印品模板",
+  ORDINARY: "普通印品模板"
+};
+
+export const TEMPLATE_CLASSIFY = {
+  SIGN: "签到表",
+  PACKAGE: "卷袋贴",
+  CHECK_IN: "登记表"
 };
 
 export const PRINT_CONTENT_TYPE = {
@@ -120,21 +132,14 @@ export const PRINT_CONTENT_TYPE = {
 
 export const PAPER_TYPE_FIELDS = ["A", "B"];
 
-export const MENU_ROUTER_DICT = {
-  basic: "base",
-  userManager: "UserManage",
-  ruleManager: "RuleManage",
-  exam: "exam-center",
-  todoTaskManager: "WaitTask",
-  doneTaskManager: "DoneTask",
-  examManager: "ExamManage",
-  cardManager: "CardManage",
-  printManager: "PrintManage",
-  cardAuditingManager: "CardAudit",
-  courseManager: "CourseManage",
-  examTaskAudit: "ExamTaskAudit",
-  topicTaskManage: "TopicTaskManage",
-  todoExam: "TodoExam"
+export const CONFIRM_PRINT_TYPE = {
+  MANUAL: "手动",
+  AUTO: "自动"
+};
+
+export const PRIVILEGE_TYPE = {
+  M: "菜单",
+  F: "操作"
 };
 
 export const keepAliveRoutesPairs = [

+ 126 - 87
src/constants/navs.js

@@ -1,119 +1,122 @@
 const navs = [
   {
     title: "考试中心",
-    router: "exam-center",
+    name: "exam",
     children: [
       {
-        title: "待办任务",
-        router: "WaitTask",
+        title: "我的工作台",
+        name: "work",
+        icon: "el-icon-s-cooperation",
         children: [
           {
-            title: "任务详情",
-            router: "WaitTaskDetail"
-          }
-        ]
-      },
-      {
-        title: "已办任务",
-        router: "DoneTask",
-        children: [
+            title: "待办任务",
+            router: "WaitTask",
+            children: [
+              {
+                title: "任务详情",
+                router: "WaitTaskDetail"
+              }
+            ]
+          },
           {
-            title: "任务详情",
-            router: "DoneTaskDetail"
+            title: "已办任务",
+            router: "DoneTask",
+            children: [
+              {
+                title: "任务详情",
+                router: "DoneTaskDetail"
+              }
+            ]
           }
         ]
       },
       {
-        title: "考试管理",
-        router: "ExamManage",
+        title: "命题管理",
+        name: "paper",
+        icon: "el-icon-s-order",
         children: [
           {
-            title: "考场详情",
-            router: "ExamRoomDetail"
-          },
-          {
-            title: "考试任务详情",
-            router: "ExamTaskDetail"
+            title: "命题任务管理",
+            router: "TaskManage",
+            children: [
+              {
+                title: "查看命题任务",
+                router: "TaskDetail"
+              },
+              {
+                title: "新建命题任务",
+                router: "TaskAdd"
+              },
+              {
+                title: "编辑命题任务",
+                router: "TaskEdit"
+              },
+              {
+                title: "批量新增命题任务",
+                router: "ExamBatchAdd"
+              }
+            ]
           },
           {
-            title: "考生详情",
-            router: "ExamRoomStudentDetail"
+            title: "入库申请",
+            router: "ApplyManage",
+            children: [
+              {
+                title: "申请入库",
+                router: "ApplyAdd"
+              },
+              {
+                title: "申请详情",
+                router: "ApplyDetail"
+              }
+            ]
           },
           {
-            title: "新增考试",
-            router: "ExamAdd"
+            title: "入库审核",
+            router: "CheckApply"
           },
           {
-            title: "编辑考试",
-            router: "ExamEdit"
+            title: "卷库查询",
+            router: "PaperManage"
           }
         ]
       },
       {
-        title: "题卡管理",
-        router: "CardManage",
+        title: "印刷管理",
+        name: "paper",
+        icon: "el-icon-s-check",
         children: [
           {
-            title: "题卡编辑",
-            router: "CardDesign"
+            title: "印刷计划管理",
+            router: "PlanManage"
           },
           {
-            title: "题卡预览",
-            router: "CardPreview"
-          }
-        ]
-      },
-      {
-        title: "印刷管理",
-        router: "PrintManage"
-      },
-      {
-        title: "题卡审核",
-        router: "CardAudit"
-      },
-      {
-        title: "考试任务审核",
-        router: "ExamTaskAudit",
-        children: [
+            title: "考务数据导入",
+            router: "BusinessDataExport"
+          },
           {
-            title: "考试任务审核详情",
-            router: "ExamTaskAuditEdit"
-          }
-        ]
-      },
-      {
-        title: "命题任务管理",
-        router: "TopicTaskManage",
-        children: [
+            title: "考务明细查询",
+            router: "BusinessDataDetail"
+          },
           {
-            title: "编辑任务",
-            router: "TopicTaskEdit"
+            title: "关联试卷管理",
+            router: "PlanLinkPaper"
           },
           {
-            title: "新增任务",
-            router: "TopicTaskAdd"
+            title: "印刷任务管理",
+            router: "PrintManage"
+          },
+          {
+            title: "印刷监控查询",
+            router: "PrintProgressManage"
           }
         ]
-      },
-      {
-        title: "待办任务",
-        router: "TodoExam"
-      }
-    ]
-  },
-  {
-    title: "成绩报表",
-    router: "score-paper",
-    children: [
-      {
-        title: "班级报表",
-        router: "ClassPaper"
       }
     ]
   },
   {
     title: "教研分析",
-    router: "analyze",
+    name: "analyze",
     children: [
       {
         title: "分数分析",
@@ -123,25 +126,61 @@ const navs = [
   },
   {
     title: "基础配置",
-    router: "base",
+    name: "base",
     children: [
       {
         title: "用户管理",
-        router: "UserManage",
+        name: "user",
+        icon: "el-icon-user-solid",
         children: [
           {
-            title: "修改",
-            router: "UserEdit"
+            title: "组织架构",
+            router: "OrganizationManage"
+          },
+          {
+            title: "用户管理",
+            router: "UserManage"
+          },
+          {
+            title: "角色管理",
+            router: "RoleManage"
+          },
+          {
+            title: "权限管理",
+            router: "MenuManage"
           }
         ]
       },
       {
-        title: "规则管理",
-        router: "RuleManage"
-      },
-      {
-        title: "科目管理",
-        router: "CourseManage"
+        title: "配置管理",
+        name: "rule",
+        icon: "el-icon-s-tools",
+        children: [
+          {
+            title: "通用规则",
+            router: "CommonRule"
+          },
+          {
+            title: "题卡规则管理",
+            router: "CardRule"
+          },
+          {
+            title: "通卡模板",
+            router: "CommonCardTemplate"
+          },
+          {
+            title: "变量印品模板",
+            router: "ParamPrintTemplate"
+          },
+          {
+            title: "普通印品模板",
+            router: "CommonPrintTemplate"
+          },
+          {
+            title: "课程管理",
+            router: "CourseManage"
+          }
+        ]
       }
     ]
   }

+ 2 - 1
src/main.js

@@ -8,6 +8,7 @@ import globalVuePlugins from "./plugins/globalVuePlugins";
 import GLOBAL from "./config";
 import { jsonBigNumberToString } from "./plugins/utils";
 import "./plugins/keepAlive";
+import "./plugins/filters";
 // import { getAuthorisation } from "./plugins/crypto";
 
 // https://github.com/RobinCK/vue-ls
@@ -16,7 +17,7 @@ import ElementUI from "element-ui";
 import "element-ui/lib/theme-chalk/index.css";
 import "./assets/styles/index.scss";
 import "../card/assets/styles/module.scss";
-Vue.use(ElementUI);
+Vue.use(ElementUI, { size: "medium" });
 
 Vue.use(VueLocalStorage, { storage: "session" });
 Vue.use(globalVuePlugins);

+ 0 - 19
src/modules/analyze/api.js

@@ -1,19 +0,0 @@
-import { $get, $post } from "@/plugins/axios";
-
-// course-manage
-export const courseList = datas => {
-  return $get("/backend/course/listCoursePage", datas);
-};
-export const updateCourse = datas => {
-  if (datas.id) {
-    return $post("/backend/course/updateCourse", datas);
-  } else {
-    return $post("/backend/course/addCourse", datas);
-  }
-};
-export const deleteCourse = id => {
-  return $post("/backend/course/deleteCourse", { id });
-};
-export const updateCourseStatus = ({ id, status }) => {
-  return $post("/backend/course/updateCourseStatus", { id, status });
-};

+ 0 - 114
src/modules/analyze/components/ModifyData.vue

@@ -1,114 +0,0 @@
-<template>
-  <el-dialog
-    class="modify-data"
-    :visible.sync="modalIsShow"
-    :title="title"
-    top="10vh"
-    :close-on-click-modal="false"
-    :close-on-press-escape="false"
-    append-to-body
-    @open="visibleChange"
-  >
-    <el-form
-      ref="modalFormComp"
-      :model="modalForm"
-      :rules="rules"
-      :key="modalForm.id"
-      label-width="100px"
-    >
-      <el-form-item prop="name" label="年级名称">
-        <el-input
-          v-model.trim="modalForm.name"
-          placeholder="请输入年级名称"
-          clearable
-        ></el-input>
-      </el-form-item>
-    </el-form>
-    <div slot="footer">
-      <el-button type="danger" @click="cancel" plain>取消</el-button>
-      <el-button type="primary" :disabled="isSubmit" @click="submit"
-        >确认</el-button
-      >
-    </div>
-  </el-dialog>
-</template>
-
-<script>
-import { updateCourse } from "../api";
-
-const initModalForm = {
-  id: "",
-  name: ""
-};
-
-export default {
-  name: "modify-data",
-  props: {
-    instance: {
-      type: Object,
-      default() {
-        return {};
-      }
-    }
-  },
-  computed: {
-    isEdit() {
-      return !!this.instance.id;
-    },
-    title() {
-      return (this.isEdit ? "编辑" : "新增") + "年级";
-    }
-  },
-  data() {
-    return {
-      modalIsShow: false,
-      isSubmit: false,
-      modalForm: { ...initModalForm },
-      rules: {
-        name: [
-          {
-            required: true,
-            message: "请输入年级名称",
-            trigger: "change"
-          }
-        ]
-      }
-    };
-  },
-  methods: {
-    initData(val) {
-      if (val.id) {
-        this.modalForm = this.$objAssign(initModalForm, val);
-      } else {
-        this.modalForm = { ...initModalForm };
-      }
-    },
-    visibleChange() {
-      this.initData(this.instance);
-    },
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    },
-    async submit() {
-      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
-      if (!valid) return;
-
-      if (this.isSubmit) return;
-      this.isSubmit = true;
-      const data = await updateCourse(this.modalForm).catch(() => {
-        this.isSubmit = false;
-      });
-
-      if (!data) return;
-
-      this.isSubmit = false;
-      this.$message.success(this.title + "成功!");
-      this.$emit("modified");
-      this.cancel();
-    }
-  }
-};
-</script>

+ 0 - 9
src/modules/analyze/router.js

@@ -1,9 +0,0 @@
-import ScoreAnalyze from "./views/ScoreAnalyze.vue";
-
-export default [
-  {
-    path: "/analyze/score-analyze",
-    name: "ScoreAnalyze",
-    component: ScoreAnalyze
-  }
-];

+ 0 - 186
src/modules/analyze/views/ScoreAnalyze.vue

@@ -1,186 +0,0 @@
-<template>
-  <div class="data-manage">
-    <div class="part-box">
-      <el-form ref="FilterForm" label-position="left" label-width="80px" inline>
-        <el-form-item label="年级名称">
-          <el-input
-            v-model.trim="filter.name"
-            placeholder="年级名称模糊查询"
-            clearable
-          ></el-input>
-        </el-form-item>
-        <el-form-item label="年级状态">
-          <el-select v-model="filter.status" style="width: 150px;" clearable>
-            <el-option
-              v-for="(val, key) in ABLE_TYPE"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="ios-search" @click="toPage(1)"
-            >查询</el-button
-          >
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <div class="part-title">
-        <div class="part-title-infos">
-          <el-button type="primary" icon="md-add" @click="toAdd"
-            >新增</el-button
-          >
-        </div>
-      </div>
-      <el-table ref="TableList" :data="grades" border>
-        <el-table-column
-          type="index"
-          label="序号"
-          width="70"
-          align="center"
-          :index="indexMethod"
-        >
-        </el-table-column>
-        <el-table-column prop="name" label="年级名称" min-width="200">
-        </el-table-column>
-        <el-table-column prop="status" label="状态" min-width="200">
-          <template slot-scope="scope">
-            <span>{{ ABLE_TYPE[scope.row.status] }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column min-width="200" align="center">
-          <template slot-scope="scope">
-            <el-button
-              size="mini"
-              type="primary"
-              icon="el-icon-edit"
-              @click="toEdit(scope.row)"
-              >编辑</el-button
-            >
-            <el-button
-              size="mini"
-              type="danger"
-              icon="el-icon-delete"
-              @click="toDelete(scope.row)"
-              >删除</el-button
-            >
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-
-    <!-- modify-data -->
-    <modify-data
-      :instance="curCourse"
-      @modified="getList"
-      ref="ModifyData"
-    ></modify-data>
-  </div>
-</template>
-
-<script>
-import { ABLE_TYPE } from "@/constants/enumerate";
-import { courseList, deleteCourse } from "../api";
-import ModifyData from "../components/ModifyData";
-
-export default {
-  name: "data-manage",
-  components: { ModifyData },
-  data() {
-    return {
-      filter: {
-        name: "",
-        status: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      visible: false,
-      grades: [
-        {
-          id: "11",
-          name: "名称1",
-          status: "ENABLE"
-        },
-        {
-          id: "22",
-          name: "名称2",
-          status: "ENABLE"
-        },
-        {
-          id: "33",
-          name: "名称3",
-          status: "ENABLE"
-        }
-      ],
-      curCourse: {},
-      ABLE_TYPE
-    };
-  },
-  created() {
-    // this.getList();
-  },
-  methods: {
-    indexMethod(index) {
-      return (this.current - 1) * this.size + index + 1;
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        current: this.current,
-        size: this.size
-      };
-      const data = await courseList(datas);
-      this.grades = data.list.map(item => {
-        return {
-          id: item.id,
-          name: item.name,
-          status: item.status,
-          createTime: item.createTime
-        };
-      });
-      this.total = data.totalCount;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    toAdd() {
-      this.curCourse = {};
-      this.$refs.ModifyData.open();
-    },
-    toEdit(row) {
-      this.curCourse = row;
-      this.$refs.ModifyData.open();
-    },
-    toDelete(row) {
-      this.$confirm("确定要删除当前学校吗?", "删除警告", {
-        cancelButtonClass: "el-button--danger is-plain",
-        confirmButtonClass: "el-button--primary",
-        type: "warning"
-      })
-        .then(async () => {
-          await deleteCourse(row.id);
-          this.$message.success("删除成功!");
-          // 解决最后一项删除后的问题
-          this.deletePageLastItem();
-        })
-        .catch(() => {});
-    }
-  }
-};
-</script>

+ 83 - 39
src/modules/base/api.js

@@ -1,63 +1,110 @@
 import { $get, $post } from "@/plugins/axios";
 
+// organization-manage
+export const organizationList = datas => {
+  return $get("/api/sys/org/list", datas);
+};
+export const updateOrganization = datas => {
+  return $post("/api/sys/org/save", datas);
+};
+export const ableOrganization = ({ id, enable }) => {
+  return $post("/api/sys/org/enable", { id, enable });
+};
+export const deleteOrganization = id => {
+  return $post("/api/sys/org/remove", { id });
+};
+
 // user-manage
 export const userListPage = datas => {
-  return $get("/api/print/basic/user/list", datas);
-};
-export const userDetail = id => {
-  return $get("/api/print/basic/sys/userQuery", { id });
+  return $get("/api/sys/user/list", datas);
 };
 export const updateUser = datas => {
-  return $post("/api/print/basic/user/update", datas);
+  return $post("/api/sys/user/save", datas);
 };
-export const ableUser = datas => {
-  return $post("/api/print/basic/user/enable", datas);
+export const userBindRoles = ({ id, roleIds }) => {
+  return $post("/api/sys/user/bindRoles", { id, roleIds });
 };
-export const updatePwd = datas => {
-  return $post("/api/print/basic/user/updatePwd", datas);
+export const ableUser = ({ id, enable }) => {
+  return $post("/api/sys/user/enable", { id, enable });
 };
-export const courseList = datas => {
-  return $get("/api/print/basic/sys/courseList", datas);
+export const updatePwd = id => {
+  return $post("/api/sys/user/reset", { id });
 };
 
-// rule-manage
-export const cardRuleDetail = schoolId => {
-  return $get("/api/print/basic/cardRule/selectBySchoolId", { schoolId });
+// role-manage
+export const roleListPage = datas => {
+  return $get("/api/sys/role/list", datas);
 };
-export const saveCardRule = datas => {
-  return $post("/api/print/basic/cardRule/add", datas);
+export const rolePrivilegeList = roleId => {
+  return $get("/api/sys/privilege/boundPrivileges", { roleId });
+};
+export const ableRole = ({ id, enable }) => {
+  return $post("/api/sys/role/enable", { id, enable });
+};
+export const updateRole = datas => {
+  return $post("/api/sys/role/save", datas);
+};
+export const deleteRole = datas => {
+  return $post("/api/sys/role/remove", datas);
+};
+// menu-manage
+export const menuList = datas => {
+  return $get("/api/sys/privilege/list", datas);
 };
-export const warningRuleDetail = schoolId => {
-  return $get("/api/print/basic/warnRule/listBySchoolId", { schoolId });
+export const updateMenu = datas => {
+  return $post("/api/sys/privilege/save", datas);
 };
-export const saveWarningRule = datas => {
-  return $post("/api/print/basic/warnRule/add", datas);
+export const deleteMenu = datas => {
+  return $post("/api/sys/privilege/remove", datas);
 };
-export const importExtendColums = datas => {
-  return $post("/api/print/basic/cardRule/impExtendColums", datas);
+
+// --------------------------------->
+// common-rule
+export const commonRuleDetail = schoolId => {
+  return $get("/api/sys/examRule/list", { schoolId });
+};
+export const saveCommonBusinessRule = datas => {
+  return $post("/api/sys/examRule/save", datas);
+};
+// card-rule
+export const cardRuleListPage = datas => {
+  return $get("/api/basic/cardRule/list", datas);
+};
+export const cardRuleDetail = id => {
+  return $get("/api/basic/cardRule/getOne", { id });
+};
+export const saveCardRule = datas => {
+  return $post("/api/basic/cardRule/save", datas);
 };
-export const checkinExamList = datas => {
-  return $get("/api/print/basic/checkin/exam/listPage", datas);
+export const ableCardRule = ({ id, enable }) => {
+  return $post("/api/basic/cardRule/enable", { id, enable });
 };
-export const saveCheckinExam = datas => {
-  return $post("/api/print/basic/checkin/save", datas);
+// common-card-template / common-print-template / param-print-template
+export const templateListPage = datas => {
+  return $get("/api/basic/template/list", datas);
 };
-export const deleteCheckinExam = id => {
-  return $post("/api/print/basic/checkin/delete", { id });
+export const updateTemplate = datas => {
+  return $post("/api/basic/template/save", datas);
 };
+export const ableTemplate = ({ id, enable }) => {
+  return $post("/api/basic/template/enable", { id, enable });
+};
+export const templateCategoryList = type => {
+  return $get("/api/basic/template/list", type);
+};
+
 // course-manage
 export const courseListPage = datas => {
-  return $get("/api/print/basic/course/list", datas);
+  return $get("/api/basic/course/list", datas);
 };
-export const deleteCourse = courseId => {
-  return $get("/api/print/basic/course/delete", { courseId });
+export const courseList = datas => {
+  return $get("/api/basic/course/list", datas);
+};
+export const deleteCourse = id => {
+  return $get("/api/basic/course/remove", { id });
 };
 export const updateCourse = datas => {
-  if (datas.courseId) {
-    return $post("/api/print/basic/course/update", datas);
-  } else {
-    return $post("/api/print/basic/course/add", datas);
-  }
+  return $post("/api/basic/course/save", datas);
 };
 
 // common
@@ -66,6 +113,3 @@ export const uploadFile = datas => {
 };
 
 // system
-export const roleList = datas => {
-  return $get("/api/print/basic/sys/roleList", datas);
-};

+ 1 - 15
src/modules/base/components/BusinessFields.vue

@@ -1,5 +1,6 @@
 <template>
   <div class="business-fields">
+    <h3>题卡版头变量印刷字段配置:</h3>
     <el-form ref="ModalForm" label-width="90px">
       <el-form-item label="必选字段:">
         <el-checkbox
@@ -18,30 +19,15 @@
           >{{ column.name }}</el-checkbox
         >
       </el-form-item>
-      <el-form-item>
-        <upload-button
-          btn-icon="icon icon-share-gray"
-          btn-content="导入考务扩展字段"
-          :upload-data="examExtendColumn"
-          :upload-url="uploadUrl"
-          :format="['xls', 'xlsx']"
-          @upload-error="uplaodError"
-          @upload-success="uploadSuccess"
-          style="margin:10px 0 0;"
-        >
-        </upload-button>
-      </el-form-item>
     </el-form>
   </div>
 </template>
 
 <script>
 import { CARD_BUSINESS_FIELDS } from "@/constants/enumerate";
-import UploadButton from "@/components/UploadButton";
 
 export default {
   name: "business-fields",
-  components: { UploadButton },
   props: {
     data: {
       type: Object

+ 397 - 0
src/modules/base/components/ModifyCardRule.vue

@@ -0,0 +1,397 @@
+<template>
+  <el-dialog
+    class="modify-card-rule"
+    :visible.sync="modalIsShow"
+    :title="title"
+    top="10px"
+    width="950px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @open="visibleChange"
+  >
+    <div class="part-box part-box-pad part-box-border">
+      <el-form
+        ref="modalFormComp"
+        label-width="130px"
+        :rules="rules"
+        :model="modalForm"
+      >
+        <el-form-item prop="cardRuleName" label="题卡规则名称:">
+          <el-input
+            v-model.trim="modalForm.cardRuleName"
+            placeholder="建议不超过30个字,规则名称不允许重复"
+            style="width: 100%"
+            clearable
+            :disabled="!editable"
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="remark" label="备注:">
+          <el-input
+            v-model.trim="modalForm.remark"
+            type="textarea"
+            resize="none"
+            :rows="2"
+            :maxlength="50"
+            :disabled="!editable"
+            clearable
+            show-word-limit
+            placeholder="建议不超过50个字"
+          ></el-input>
+        </el-form-item>
+        <el-form-item
+          prop="examNumberStyle"
+          label="考号版式:"
+          class="inline-block"
+        >
+          <el-select
+            v-model="modalForm.examNumberStyle"
+            style="width: 142px;"
+            @change="numStyleChange"
+            placeholder="请选择"
+            :disabled="!editable"
+          >
+            <el-option
+              v-for="(val, key) in EXAM_NUMBER_STYLE"
+              :key="key"
+              :value="key"
+              :label="val"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="paperType" label="AB卷版式:" class="inline-block">
+          <el-select
+            v-model="modalForm.paperType"
+            style="width: 142px;"
+            placeholder="请选择"
+            :disabled="!editable"
+          >
+            <el-option
+              v-for="(val, key) in PAPER_TYPE"
+              :key="key"
+              :value="key"
+              :label="val"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item class="inline-block" label-width="30px">
+          <el-checkbox v-model="modalForm.examAbsent" :disabled="!editable"
+            >启用“缺考填涂”</el-checkbox
+          >
+        </el-form-item>
+        <el-form-item class="inline-block" label-width="30px">
+          <el-checkbox
+            v-model="modalForm.writeSign"
+            :disabled="modalForm.examNumberStyle === 'FILL' || !editable"
+            >启用“手写签名”</el-checkbox
+          >
+        </el-form-item>
+        <div class="part-box part-box-pad part-box-border">
+          <h4 class="part-box-tips">题卡版头变量印刷字段配置:</h4>
+          <el-form-item label="必选字段:" label-width="115px" required>
+            <el-checkbox
+              v-for="column in requiredFields"
+              :key="column.code"
+              v-model="column.select"
+              :disabled="!editable"
+              >{{ column.name }}</el-checkbox
+            >
+          </el-form-item>
+          <el-form-item label="扩展字段:" label-width="115px">
+            <el-checkbox
+              v-for="column in extendFields"
+              :key="column.code"
+              v-model="column.select"
+              :disabled="!editable"
+              >{{ column.name }}</el-checkbox
+            >
+          </el-form-item>
+        </div>
+        <el-form-item prop="titleRule" label="题卡标题规则:">
+          <el-input
+            v-model="modalForm.titleRule"
+            :disabled="!editable"
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="attention" label="注意事项:">
+          <el-input
+            type="textarea"
+            :rows="4"
+            v-model="modalForm.attention"
+            :disabled="!editable"
+          ></el-input>
+          <p class="tips-info">
+            提示:换行之后,题卡注意事项会展示为多条内容,内容序号会被自动添加。
+          </p>
+        </el-form-item>
+        <el-form-item prop="objectiveAttention" label="客观题注意事项:">
+          <el-input
+            v-model="modalForm.objectiveAttention"
+            :disabled="!editable"
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="subjectiveAttention" label="主观题注意事项:">
+          <el-input
+            v-model="modalForm.subjectiveAttention"
+            :disabled="!editable"
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="collegeIds" label="适用学院范围:">
+          <el-checkbox-group
+            v-model="modalForm.collegeIds"
+            :disabled="!editable"
+          >
+            <el-checkbox
+              v-for="item in colleges"
+              :key="item.id"
+              :label="item.id"
+              >{{ item.name }}</el-checkbox
+            >
+          </el-checkbox-group>
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <div slot="footer">
+      <el-button type="primary" :disabled="isSubmit" @click="submit"
+        >确认</el-button
+      >
+      <el-button type="danger" @click="cancel" plain>取消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import {
+  EXAM_NUMBER_STYLE,
+  PAPER_TYPE,
+  CARD_BUSINESS_FIELDS
+} from "@/constants/enumerate";
+import { organizationList, cardRuleDetail, saveCardRule } from "../api";
+
+const initModalForm = {
+  id: null,
+  cardRuleName: "",
+  remark: "",
+  examNumberStyle: "",
+  paperType: "",
+  examAbsent: true,
+  writeSign: true,
+  requiredFields: "",
+  extendFields: "",
+  titleRule: "",
+  attention: "",
+  objectiveAttention: "",
+  subjectiveAttention: "",
+  collegeIds: []
+};
+
+export default {
+  name: "modify-card-rule",
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    editable: {
+      type: Boolean,
+      default: true
+    }
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return (this.isEdit ? "编辑" : "新增") + "题卡规则";
+    }
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: {},
+      EXAM_NUMBER_STYLE,
+      PAPER_TYPE,
+      dataReady: false,
+      requiredFields: [],
+      extendFields: [],
+      colleges: [
+        {
+          id: 1,
+          name: "外语学院"
+        },
+        {
+          id: 2,
+          name: "数学学院"
+        },
+        {
+          id: 3,
+          name: "计算机学院"
+        }
+      ],
+      rules: {
+        cardRuleName: [
+          {
+            required: true,
+            message: "题卡规则名称不能超过30个字",
+            max: 30,
+            trigger: "change"
+          }
+        ],
+        examNumberStyle: [
+          {
+            required: true,
+            message: "请选择考号版式",
+            trigger: "change"
+          }
+        ],
+        paperType: [
+          {
+            required: true,
+            message: "请选择AB卷版式",
+            trigger: "change"
+          }
+        ],
+        titleRule: [
+          {
+            required: true,
+            message: "请输入题卡标题规则",
+            trigger: "change"
+          }
+        ],
+        attention: [
+          {
+            required: true,
+            message: "请输入注意事项",
+            trigger: "change"
+          },
+          {
+            validator: (rule, value, callback) => {
+              const val = value.replace(/\n/g, "");
+              if (val.length > 200) {
+                callback(new Error("注意事项最多只能输入200个字符"));
+              } else {
+                callback();
+              }
+            },
+            trigger: "change"
+          }
+        ],
+        objectiveAttention: [
+          {
+            required: true,
+            message: "请输入客观题注意事项",
+            trigger: "change"
+          },
+          {
+            max: 26,
+            message: "客观题注意事项最多只能输入26个汉字",
+            trigger: "change"
+          }
+        ],
+        subjectiveAttention: [
+          {
+            required: true,
+            message: "请输入主观题注意事项",
+            trigger: "change"
+          },
+          {
+            max: 26,
+            message: "主观题注意事项最多只能输入26个汉字",
+            trigger: "change"
+          }
+        ],
+        collegeIds: [
+          {
+            required: true,
+            validator: (rule, value, callback) => {
+              if (value.length) {
+                callback();
+              } else {
+                callback(new Error("请选择适用学院"));
+              }
+            },
+            trigger: "change"
+          }
+        ]
+      }
+    };
+  },
+  mounted() {
+    // this.getCardRule();
+    // this.getColleges();
+    this.requiredFields = CARD_BUSINESS_FIELDS.must.map(item => {
+      item.select = false;
+      return item;
+    });
+    this.extendFields = CARD_BUSINESS_FIELDS.extend.map(item => {
+      item.select = false;
+      return item;
+    });
+  },
+  methods: {
+    async getColleges() {
+      this.colleges = await organizationList();
+    },
+    initData(val) {
+      if (val.id) {
+        this.modalForm = this.$objAssign(initModalForm, val);
+        this.requiredFields = JSON.parse(val.requiredFields);
+        this.extendFields = JSON.parse(val.extendFields);
+        this.modalForm.examAbsent = Boolean(val.examAbsent);
+        this.modalForm.writeSign = Boolean(val.writeSign);
+        this.modalForm.collegeIds = val.collegeIds.split();
+      } else {
+        this.modalForm = { ...initModalForm };
+      }
+    },
+    visibleChange() {
+      this.initData(this.instance);
+
+      this.$nextTick(() => {
+        this.$refs.modalFormComp.clearValidate();
+      });
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async getCardRule() {
+      const data = await cardRuleDetail();
+      this.modalForm = Object.assign(initModalForm, data);
+      this.modalForm.examAbsent = Boolean(this.modalForm.examAbsent);
+      this.modalForm.writeSign = Boolean(this.modalForm.writeSign);
+      this.dataReady = true;
+    },
+    numStyleChange() {
+      this.modalForm.writeSign = this.modalForm.examNumberStyle !== "FILL";
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      let modals = {
+        ...this.modalForm
+      };
+      modals.requiredFields = JSON.stringify(this.requiredFields);
+      modals.extendFields = JSON.stringify(this.extendFields);
+      modals.examAbsent = Number(modals.examAbsent);
+      modals.writeSign = Number(modals.writeSign);
+      const data = await saveCardRule(modals).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$message.success("保存成功!");
+      this.$emit("modified");
+      this.cancel();
+    }
+  }
+};
+</script>

+ 10 - 10
src/modules/base/components/ModifyCourse.vue

@@ -1,6 +1,6 @@
 <template>
   <el-dialog
-    class="modify-data"
+    class="modify-course"
     :visible.sync="modalIsShow"
     :title="title"
     top="10vh"
@@ -17,17 +17,17 @@
       :key="modalForm.id"
       label-width="100px"
     >
-      <el-form-item prop="courseName" label="科目名称:">
+      <el-form-item prop="courseName" label="课程名称:">
         <el-input
           v-model.trim="modalForm.courseName"
-          placeholder="请输入科目名称"
+          placeholder="请输入课程名称"
           clearable
         ></el-input>
       </el-form-item>
-      <el-form-item prop="courseCode" label="科目编码:">
+      <el-form-item prop="courseCode" label="课程编码:">
         <el-input
           v-model.trim="modalForm.courseCode"
-          placeholder="请输入科目编码"
+          placeholder="请输入课程编码"
           clearable
         ></el-input>
       </el-form-item>
@@ -45,13 +45,13 @@
 import { updateCourse } from "../api";
 
 const initModalForm = {
-  courseId: "",
+  id: "",
   courseName: "",
   courseCode: ""
 };
 
 export default {
-  name: "modify-data",
+  name: "modify-course",
   props: {
     instance: {
       type: Object,
@@ -65,7 +65,7 @@ export default {
       return !!this.instance.id;
     },
     title() {
-      return (this.isEdit ? "编辑" : "新增") + "科目";
+      return (this.isEdit ? "编辑" : "新增") + "课程";
     }
   },
   data() {
@@ -77,14 +77,14 @@ export default {
         courseName: [
           {
             required: true,
-            message: "请输入科目名称",
+            message: "请输入课程名称",
             trigger: "change"
           }
         ],
         courseCode: [
           {
             required: true,
-            message: "请输入科目编码",
+            message: "请输入课程编码",
             trigger: "change"
           }
         ]

+ 99 - 0
src/modules/base/components/ModifyField.vue

@@ -0,0 +1,99 @@
+<template>
+  <el-dialog
+    class="modify-field"
+    :visible.sync="modalIsShow"
+    title="新增扩展字段"
+    top="10vh"
+    width="500px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @opened="visibleChange"
+  >
+    <div class="part-box part-box-pad part-box-border">
+      <el-form
+        ref="modalFormComp"
+        :model="modalForm"
+        :rules="rules"
+        label-width="100px"
+      >
+        <el-form-item prop="name" label="字段名称:">
+          <el-input
+            style="width:282px;"
+            v-model.trim="modalForm.name"
+            placeholder="请输入字段名称"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="code" label="字段变量名:">
+          <el-input
+            style="width:282px;"
+            v-model.trim="modalForm.code"
+            placeholder="请输入字段变量名"
+            clearable
+          ></el-input>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div slot="footer">
+      <el-button type="primary" @click="submit">确认</el-button>
+      <el-button type="danger" @click="cancel" plain>取消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+const initModalForm = {
+  name: "",
+  code: ""
+};
+
+export default {
+  name: "modify-field",
+  data() {
+    return {
+      modalIsShow: false,
+      modalForm: {},
+      rules: {
+        name: [
+          {
+            required: true,
+            pattern: /^[\u4E00-\u9FA5]{1,10}$/,
+            message: "字段名称只能输入汉字,长度不能超过10",
+            trigger: "change"
+          }
+        ],
+        code: [
+          {
+            required: true,
+            pattern: /^[a-zA-Z]{3,30}$/,
+            message: "字段变量名只能由字母组成,长度在3-30之间",
+            trigger: "change"
+          }
+        ]
+      }
+    };
+  },
+  methods: {
+    visibleChange() {
+      this.modalForm = { ...initModalForm };
+      this.$nextTick(() => {
+        this.$refs.modalFormComp.clearValidate();
+      });
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      this.$emit("confirm", this.modalForm);
+      this.cancel();
+    }
+  }
+};
+</script>

+ 164 - 0
src/modules/base/components/ModifyMenu.vue

@@ -0,0 +1,164 @@
+<template>
+  <el-dialog
+    class="modify-menu"
+    :visible.sync="modalIsShow"
+    :title="title"
+    top="10vh"
+    width="500px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @opened="visibleChange"
+  >
+    <div class="part-box part-box-pad part-box-border">
+      <el-form
+        ref="modalFormComp"
+        :model="modalForm"
+        :rules="rules"
+        label-width="100px"
+      >
+        <el-form-item prop="name" label="菜单名称:">
+          <el-input
+            style="width:100%;"
+            v-model.trim="modalForm.name"
+            placeholder="请输入菜单名称"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="url" label="URL地址:">
+          <el-input
+            style="width:100%;"
+            v-model.trim="modalForm.url"
+            placeholder="请输入URL地址"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="上级菜单:">
+          <el-input
+            style="width:100%;"
+            v-model.trim="modalForm.parentName"
+            disabled
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="菜单类型:">
+          <el-select
+            v-model="modalForm.type"
+            style="width: 100px;"
+            placeholder="请选择"
+          >
+            <el-option
+              v-for="(val, key) in PRIVILEGE_TYPE"
+              :key="key"
+              :value="key"
+              :label="val"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="备注:">
+          <el-input
+            style="width:100%;"
+            v-model.trim="modalForm.remark"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div slot="footer">
+      <el-button type="primary" :disabled="isSubmit" @click="submit"
+        >确认</el-button
+      >
+      <el-button type="danger" @click="cancel" plain>取消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { PRIVILEGE_TYPE } from "@/constants/enumerate";
+import { updateMenu } from "../api";
+
+const initModalForm = {
+  id: null,
+  name: "",
+  url: "",
+  parentId: null,
+  parentName: "",
+  type: "M",
+  remark: ""
+};
+
+export default {
+  name: "modify-menu",
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      }
+    }
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return (this.isEdit ? "编辑" : "新增") + "权限";
+    }
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: {},
+      PRIVILEGE_TYPE,
+      rules: {
+        name: [
+          {
+            required: true,
+            pattern: /^[\u4E00-\u9FA5/]{1,30}$/,
+            message: "菜单名称只能输入汉字和斜线,长度不能超过30",
+            trigger: "change"
+          }
+        ],
+        url: [
+          {
+            required: true,
+            pattern: /^[a-zA-Z_\-[](){}]{3,30}$/,
+            message: "URL地址只能由字母短横线括号组成,长度在3-30之间",
+            trigger: "change"
+          }
+        ]
+      }
+    };
+  },
+  methods: {
+    initData(val) {
+      this.modalForm = this.$objAssign(initModalForm, val);
+    },
+    visibleChange() {
+      this.initData(this.instance);
+      this.$nextTick(() => {
+        this.$refs.modalFormComp.clearValidate();
+      });
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const datas = { ...this.modalForm };
+      const data = await updateMenu(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$emit("confirm", this.modalForm);
+      this.cancel();
+    }
+  }
+};
+</script>

+ 157 - 0
src/modules/base/components/ModifyOrganization.vue

@@ -0,0 +1,157 @@
+<template>
+  <el-dialog
+    class="modify-organization"
+    :visible.sync="modalIsShow"
+    :title="title"
+    top="10vh"
+    width="500px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @opened="visibleChange"
+  >
+    <div class="part-box part-box-pad part-box-border">
+      <el-form
+        ref="modalFormComp"
+        :model="modalForm"
+        :rules="rules"
+        label-width="100px"
+      >
+        <el-form-item prop="orgName" label="机构名称:">
+          <el-input
+            style="width:282px;"
+            v-model.trim="modalForm.orgName"
+            placeholder="请输入机构名称"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="orgCode" label="机构代码:">
+          <el-input
+            style="width:282px;"
+            v-model.trim="modalForm.orgCode"
+            placeholder="请输入机构代码"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="上级机构:">
+          <el-input
+            style="width:282px;"
+            v-model.trim="modalForm.parentName"
+            disabled
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="启用/禁用:">
+          <el-select
+            v-model="modalForm.enable"
+            style="width: 100px;"
+            placeholder="请选择"
+          >
+            <el-option
+              v-for="(val, key) in ABLE_TYPE"
+              :key="key"
+              :value="key * 1"
+              :label="val"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div slot="footer">
+      <el-button type="primary" :disabled="isSubmit" @click="submit"
+        >确认</el-button
+      >
+      <el-button type="danger" @click="cancel" plain>取消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { ABLE_TYPE } from "@/constants/enumerate";
+import { updateOrganization } from "../api";
+
+const initModalForm = {
+  id: null,
+  orgName: "",
+  orgCode: "",
+  parentId: null,
+  parentName: "",
+  enable: 1
+};
+
+export default {
+  name: "modify-organization",
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      }
+    }
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return (this.isEdit ? "编辑" : "新增") + "机构";
+    }
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: {},
+      ABLE_TYPE,
+      rules: {
+        orgName: [
+          {
+            required: true,
+            pattern: /^[\u4E00-\u9FA5]{1,30}$/,
+            message: "机构名称只能输入汉字,长度不能超过30",
+            trigger: "change"
+          }
+        ],
+        orgCode: [
+          {
+            required: true,
+            pattern: /^[a-zA-Z_\-[](){}]{3,30}$/,
+            message: "机构代码只能由字母短横线括号组成,长度在3-30之间",
+            trigger: "change"
+          }
+        ]
+      }
+    };
+  },
+  methods: {
+    initData(val) {
+      this.modalForm = this.$objAssign(initModalForm, val);
+    },
+    visibleChange() {
+      this.initData(this.instance);
+      this.$nextTick(() => {
+        this.$refs.modalFormComp.clearValidate();
+      });
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const datas = { ...this.modalForm };
+      const data = await updateOrganization(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$emit("confirm", this.modalForm);
+      this.cancel();
+    }
+  }
+};
+</script>

+ 177 - 0
src/modules/base/components/ModifyRole.vue

@@ -0,0 +1,177 @@
+<template>
+  <el-dialog
+    class="modify-role"
+    :visible.sync="modalIsShow"
+    :title="title"
+    top="10vh"
+    width="600px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @opened="visibleChange"
+  >
+    <div class="part-box part-box-pad part-box-border">
+      <el-form
+        ref="modalFormComp"
+        :model="modalForm"
+        :rules="rules"
+        label-width="100px"
+      >
+        <el-form-item prop="roleName" label="角色名称:">
+          <el-input
+            style="width:100%;"
+            v-model.trim="modalForm.roleName"
+            placeholder="请输入角色名称"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="privilegeIds" label="角色权限:">
+          <div class="part-box part-box-pad part-box-border">
+            <el-tree
+              :data="menus"
+              show-checkbox
+              default-expand-all
+              node-key="id"
+              ref="MenuTree"
+              highlight-current
+              :props="defaultProps"
+              check-on-click-node
+              :expand-on-click-node="false"
+              @check-change="checkChange"
+            >
+            </el-tree>
+          </div>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div slot="footer">
+      <el-button type="primary" @click="submit">确认</el-button>
+      <el-button type="danger" @click="cancel" plain>取消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { updateRole, rolePrivilegeList } from "../api";
+const initModalForm = {
+  id: null,
+  roleName: "",
+  privilegeIds: []
+};
+
+export default {
+  name: "modify-role",
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    menus: {
+      type: Array,
+      default() {
+        return [];
+      }
+    }
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return (this.isEdit ? "编辑" : "新增") + "角色";
+    }
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      modalForm: {},
+      defaultProps: {
+        label: "name"
+      },
+      rules: {
+        roleName: [
+          {
+            required: true,
+            pattern: /^[\u4E00-\u9FA5]{1,10}$/,
+            message: "角色名称只能输入汉字,长度不能超过10",
+            trigger: "change"
+          }
+        ],
+        privilegeIds: [
+          {
+            required: true,
+            validator: (rule, value, callback) => {
+              if (value.length) {
+                callback();
+              } else {
+                callback(new Error("请选择扩展字段"));
+              }
+            },
+            trigger: "change"
+          }
+        ]
+      }
+    };
+  },
+  methods: {
+    async visibleChange() {
+      if (this.instance.id) {
+        this.modalForm = this.$objassign(initModalForm, this.instance);
+        let privilegeIds = await rolePrivilegeList(this.instance.id);
+        let checkedIds = [];
+        const getCheckedIds = list => {
+          list.forEach(item => {
+            if (item["children"]) {
+              getCheckedIds(item.children);
+            } else {
+              const isChecked = privilegeIds.includes(item.id);
+              if (isChecked) checkedIds.push(item.id);
+            }
+          });
+        };
+        getCheckedIds(this.menus);
+        console.log(checkedIds);
+        this.$refs.MenuTree.setCheckedKeys(checkedIds);
+        this.modalForm.privilegeIds = checkedIds;
+      } else {
+        this.modalForm = { ...initModalForm };
+      }
+      this.$nextTick(() => {
+        this.$refs.modalFormComp.clearValidate();
+      });
+    },
+    getHalfCheckedIds(list) {},
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    checkChange() {
+      this.modalForm.privilegeIds = this.$refs.MenuTree.getCheckedKeys();
+      this.$refs.modalFormComp.validateField("privilegeIds");
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const datas = { ...this.modalForm };
+      const privilegeIds = [
+        ...this.$refs.MenuTree.getCheckedKeys(),
+        ...this.$refs.MenuTree.getHalfCheckedKeys()
+      ];
+      data.privilegeIds = privilegeIds.join();
+      const data = await updateRole(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$emit("confirm", this.modalForm);
+      this.cancel();
+    }
+  }
+};
+</script>

+ 254 - 0
src/modules/base/components/ModifyTemplate.vue

@@ -0,0 +1,254 @@
+<template>
+  <el-dialog
+    class="modify-template"
+    :visible.sync="modalIsShow"
+    :title="title"
+    top="10px"
+    width="950px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @open="visibleChange"
+  >
+    <div class="part-box part-box-pad part-box-border">
+      <el-form
+        ref="modalFormComp"
+        label-width="130px"
+        :rules="rules"
+        :model="modalForm"
+      >
+        <el-form-item prop="templateName" label="模板名称:">
+          <el-input
+            v-model.trim="modalForm.templateName"
+            placeholder="建议不超过30个字,规则名称不允许重复"
+            style="width: 100%"
+            clearable
+            :disabled="!editable"
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="remark" label="备注:">
+          <el-input
+            v-model.trim="modalForm.remark"
+            type="textarea"
+            resize="none"
+            :rows="2"
+            :maxlength="50"
+            :disabled="!editable"
+            clearable
+            show-word-limit
+            placeholder="建议不超过50个字"
+          ></el-input>
+        </el-form-item>
+        <el-form-item
+          v-if="modalForm.templateType !== 'GENERIC'"
+          prop="classify"
+          label="分类:"
+        >
+          <el-select
+            v-model="modalForm.classify"
+            style="width: 439px;"
+            placeholder="请选择"
+            clearable
+          >
+            <el-option
+              v-for="item in categories"
+              :key="item.code"
+              :value="item.code"
+              :label="item.name"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="attachmentId" label="上传模板文件:">
+          <upload-file-view
+            :upload-url="uploadUrl"
+            :disabled="!editable"
+            @upload-error="uplaodError"
+            @upload-success="uploadSuccess"
+            ref="UploadFileView"
+          ></upload-file-view>
+        </el-form-item>
+        <el-form-item prop="orgs" label="适用学院范围:">
+          <el-checkbox-group v-model="modalForm.orgs" :disabled="!editable">
+            <el-checkbox
+              v-for="item in organizations"
+              :key="item.id"
+              :label="item.id"
+              >{{ item.name }}</el-checkbox
+            >
+          </el-checkbox-group>
+        </el-form-item>
+      </el-form>
+    </div>
+
+    <div slot="footer">
+      <el-button type="primary" :disabled="isSubmit" @click="submit"
+        >确认</el-button
+      >
+      <el-button type="danger" @click="cancel" plain>取消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { organizationList, updateTemplate, templateCategoryList } from "../api";
+import UploadFileView from "@/components/UploadFileView";
+
+const initModalForm = {
+  id: null,
+  templateName: "",
+  templateType: "GENERIC",
+  remark: "",
+  classify: "",
+  attachmentId: "",
+  orgs: []
+};
+
+export default {
+  name: "modify-template",
+  components: { UploadFileView },
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    editable: {
+      type: Boolean,
+      default: true
+    }
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return (this.isEdit ? "编辑" : "新增") + "模板";
+    }
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: {},
+      organizations: [
+        {
+          id: 1,
+          name: "外语学院"
+        },
+        {
+          id: 2,
+          name: "数学学院"
+        },
+        {
+          id: 3,
+          name: "计算机学院"
+        }
+      ],
+      categories: [],
+      rules: {
+        templateName: [
+          {
+            required: true,
+            message: "题卡规则名称不能超过30个字",
+            max: 30,
+            trigger: "change"
+          }
+        ],
+        classify: [
+          {
+            required: true,
+            message: "请选择分类",
+            trigger: "change"
+          }
+        ],
+        attachmentId: [
+          {
+            required: true,
+            message: "请上传模板文件",
+            trigger: "change"
+          }
+        ],
+        orgs: [
+          {
+            required: true,
+            validator: (rule, value, callback) => {
+              if (value.length) {
+                callback();
+              } else {
+                callback(new Error("请选择适用学院"));
+              }
+            },
+            trigger: "change"
+          }
+        ]
+      },
+      // upload
+      uploadUrl: "/api/exam/file/upload"
+    };
+  },
+  mounted() {
+    // this.getColleges();
+    // if (this.modalForm.templateType !== 'GENERIC') this.getCategories();
+  },
+  methods: {
+    async getColleges() {
+      this.organizations = await organizationList();
+    },
+    async getCategories() {
+      this.categories = await templateCategoryList(
+        this.modalForm.modalForm.templateType
+      );
+    },
+    initData(val) {
+      this.modalForm = this.$objAssign(initModalForm, val);
+      if (val.id) {
+        this.modalForm.orgs = val.orgs.map(item => item.orgCode);
+        this.$refs.UploadFileView.setAttachmentName(
+          `${val.tcPAttachment.name}${val.tcPAttachment.type}`
+        );
+      }
+    },
+    visibleChange() {
+      this.initData(this.instance);
+
+      this.$nextTick(() => {
+        this.$refs.modalFormComp.clearValidate();
+      });
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      let datas = {
+        ...this.modalForm
+      };
+      const data = await updateTemplate(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$message.success("保存成功!");
+      this.$emit("modified");
+      this.cancel();
+    },
+    uplaodError(errorData) {
+      this.$notify.error({ title: "错误提示", message: errorData.message });
+    },
+    uploadSuccess(res) {
+      this.$message.success("上传成功!");
+      const data = res.data;
+
+      this.modalForm.attachmentId = data.id;
+      this.$refs.modalFormComp.validateField("attachmentId");
+    }
+  }
+};
+</script>

+ 239 - 0
src/modules/base/components/ModifyUser.vue

@@ -0,0 +1,239 @@
+<template>
+  <el-dialog
+    class="modify-user"
+    :visible.sync="modalIsShow"
+    :title="title"
+    top="10vh"
+    width="600px"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    @open="visibleChange"
+  >
+    <div class="part-box part-box-pad part-box-border">
+      <el-form
+        ref="modalFormComp"
+        :model="modalForm"
+        :rules="rules"
+        label-width="100px"
+      >
+        <el-form-item prop="loginName" label="用户名:">
+          <el-input
+            style="width:100%;"
+            v-model.trim="modalForm.loginName"
+            placeholder="请输入用户名"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="realName" label="姓名:">
+          <el-input
+            style="width:100%;"
+            v-model.trim="modalForm.realName"
+            placeholder="请输入姓名"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="phone" label="手机号:">
+          <el-input
+            style="width:100%;"
+            v-model.trim="modalForm.phone"
+            placeholder="请输入手机号"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="roleIds" label="角色:">
+          <el-select
+            style="width:100%;"
+            v-model="modalForm.roleIds"
+            placeholder="请选择角色"
+            multiple
+          >
+            <el-option
+              v-for="item in roles"
+              :key="item.id"
+              :label="item.roleName"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          prop="courseCodes"
+          label="课程:"
+          v-if="modalForm.roleIds === 'QUESTION_TEACHER'"
+        >
+          <el-select
+            style="width:100%;"
+            v-model="modalForm.courseCodes"
+            placeholder="请选择课程"
+            multiple
+            filterable
+          >
+            <el-option
+              v-for="item in courses"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div slot="footer">
+      <el-button type="primary" :disabled="isSubmit" @click="submit"
+        >确认</el-button
+      >
+      <el-button type="danger" @click="cancel" plain>取消</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+import { updateUser, courseList } from "../api";
+import { logout } from "../../login/api";
+import { phone } from "@/plugins/formRules";
+
+const initModalForm = {
+  id: "",
+  loginName: "",
+  realName: "",
+  phone: "",
+  roleIds: "",
+  courseCodes: []
+};
+
+export default {
+  name: "modify-user",
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    roles: {
+      type: Array,
+      default() {
+        return [];
+      }
+    }
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return (this.isEdit ? "编辑" : "新增") + "用户";
+    }
+  },
+  data() {
+    const courseCodesValidator = (rule, value, callback) => {
+      if (!value || !value.length) {
+        callback(new Error("请选择课程"));
+      } else {
+        callback();
+      }
+    };
+
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: {},
+      rules: {
+        phone,
+        name: [
+          {
+            required: true,
+            message: "请输入用户名",
+            trigger: "change"
+          }
+        ],
+        loginName: [
+          {
+            required: true,
+            message: "请输入姓名",
+            trigger: "change"
+          }
+        ],
+        roleIds: [
+          {
+            required: true,
+            message: "请选择角色",
+            trigger: "change"
+          }
+        ],
+        courseCodes: [
+          {
+            required: true,
+            validator: courseCodesValidator,
+            trigger: "change"
+          }
+        ]
+      },
+      user: {},
+      courses: []
+    };
+  },
+  created() {
+    this.getCourseList();
+  },
+  methods: {
+    initData(val) {
+      if (val.id) {
+        this.modalForm = this.$objAssign(initModalForm, val);
+        this.modalForm.roleIds = val.roles.map(item => item.roleId);
+        this.modalForm.courseCodes = val.courses.map(item => item.courseCode);
+      } else {
+        this.modalForm = { ...initModalForm };
+      }
+    },
+    visibleChange() {
+      this.initData(this.instance);
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    async getCourseList() {
+      const data = await courseList();
+      this.courses = data.records.map(course => {
+        return {
+          id: course.courseCode,
+          name: `${course.courseName}(${course.courseCode})`
+        };
+      });
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+
+      const datas = { ...this.modalForm };
+      // TODO:
+      if (datas.roleIds !== "QUESTION_TEACHER") delete datas.courseCodes;
+      const data = await updateUser(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$message.success("修改成功!");
+
+      // 自己把自己的角色改了之后要重新登录,重新获取权限
+      // TODO:
+      if (
+        this.instance.roleIds !== this.modalForm.roleIds &&
+        this.$ls.get("user").id === this.instance.id
+      ) {
+        await logout(this.$ls.get("user", { id: "" }).id);
+        this.$ls.clear();
+        this.$router.push({ name: "Login" });
+        this.$message.info("您的权限已经变更,请重新登录系统!");
+      }
+    }
+  }
+};
+</script>

+ 36 - 34
src/modules/base/components/ResetPwd.vue

@@ -10,40 +10,42 @@
     append-to-body
     @open="visibleChange"
   >
-    <el-form
-      ref="modalFormComp"
-      :model="resetModel"
-      :rules="resetRules"
-      label-width="100px"
-    >
-      <el-form-item prop="password" label="旧密码:">
-        <el-input
-          size="large"
-          type="password"
-          v-model="resetModel.password"
-          placeholder="请输入旧密码"
-          clearable
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="newPassword" label="新密码:">
-        <el-input
-          size="large"
-          type="password"
-          v-model="resetModel.newPassword"
-          placeholder="请输入新密码"
-          clearable
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="rePassword" label="再次密码:">
-        <el-input
-          size="large"
-          type="password"
-          v-model="resetModel.rePassword"
-          placeholder="请再次输入新密码"
-          clearable
-        ></el-input>
-      </el-form-item>
-    </el-form>
+    <div class="part-box part-box-pad part-box-border">
+      <el-form
+        ref="modalFormComp"
+        :model="resetModel"
+        :rules="resetRules"
+        label-width="100px"
+      >
+        <el-form-item prop="password" label="旧密码:">
+          <el-input
+            size="large"
+            type="password"
+            v-model="resetModel.password"
+            placeholder="请输入旧密码"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="newPassword" label="新密码:">
+          <el-input
+            size="large"
+            type="password"
+            v-model="resetModel.newPassword"
+            placeholder="请输入新密码"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="rePassword" label="再次密码:">
+          <el-input
+            size="large"
+            type="password"
+            v-model="resetModel.rePassword"
+            placeholder="请再次输入新密码"
+            clearable
+          ></el-input>
+        </el-form-item>
+      </el-form>
+    </div>
     <div slot="footer">
       <el-button type="primary" :disabled="isSubmit" @click="submit"
         >确认</el-button

+ 210 - 0
src/modules/base/components/RuleBusiness.vue

@@ -0,0 +1,210 @@
+<template>
+  <div class="rule-business part-box part-box-pad part-box-border">
+    <h4 class="part-box-tips">变量印刷考务字段配置:</h4>
+    <el-form
+      ref="modalFormComp"
+      :model="modalForm"
+      :rules="rules"
+      label-width="170px"
+    >
+      <el-form-item prop="requiredFields" label="必选字段:">
+        <el-checkbox
+          v-for="field in modalForm.requiredFields"
+          :key="field.code"
+          v-model="field.select"
+          @change="validateRequiredFields"
+          >{{ field.name }}</el-checkbox
+        >
+      </el-form-item>
+      <el-form-item prop="extendFields" label="扩展字段:">
+        <div class="part-box part-box-pad part-box-border">
+          <div class="label-edit">
+            <div
+              v-for="field in modalForm.extendFields"
+              :key="field.code"
+              class="label-item"
+            >
+              <el-checkbox
+                v-model="field.select"
+                class="label-item-content"
+                @change="validateExtendFields"
+                >{{ field.name }}</el-checkbox
+              >
+              <i
+                class="label-item-delete el-icon-error"
+                @click="deleteField(field)"
+              ></i>
+            </div>
+          </div>
+          <div>
+            <el-button type="text" icon="el-icon-plus" @click="toAddField"
+              >添加</el-button
+            >
+          </div>
+        </div>
+      </el-form-item>
+      <el-form-item label="是否启用入库审核:" required>
+        <el-radio-group v-model="modalForm.review">
+          <el-radio
+            v-for="(val, key) in ABLE_TYPE"
+            :key="key"
+            :label="key * 1"
+            >{{ val }}</el-radio
+          >
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="入库强制包含试卷:" required>
+        <el-radio-group v-model="modalForm.includePaper">
+          <el-radio
+            v-for="(val, key) in ABLE_TYPE"
+            :key="key"
+            :label="key * 1"
+            >{{ val }}</el-radio
+          >
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="是否启用客服制卡:" required>
+        <el-radio-group v-model="modalForm.customCard">
+          <el-radio
+            v-for="(val, key) in ABLE_TYPE"
+            :key="key"
+            :label="key * 1"
+            >{{ val }}</el-radio
+          >
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item label="提交印刷方式:" required>
+        <el-radio-group v-model="modalForm.printMethod">
+          <el-radio
+            v-for="(val, key) in CONFIRM_PRINT_TYPE"
+            :key="key"
+            :label="key"
+            >{{ val }}</el-radio
+          >
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="submit" :disabled="isSubmit"
+          >保存</el-button
+        >
+      </el-form-item>
+    </el-form>
+
+    <!-- ModifyField -->
+    <modify-field ref="ModifyField" @confirm="addField"></modify-field>
+  </div>
+</template>
+
+<script>
+import ModifyField from "../components/ModifyField";
+import {
+  ABLE_TYPE,
+  CONFIRM_PRINT_TYPE,
+  CARD_BUSINESS_FIELDS
+} from "@/constants/enumerate";
+import { commonRuleDetail, saveCommonBusinessRule } from "../api";
+
+const initModalForm = {
+  review: 1,
+  includePaper: 1,
+  customCard: 1,
+  printMethod: "AUTO",
+  requiredFields: [],
+  extendFields: []
+};
+
+export default {
+  name: "rule-business",
+  components: { ModifyField },
+  data() {
+    return {
+      modalForm: { ...initModalForm },
+      isSubmit: false,
+      requiredFields: [],
+      extendFields: [],
+      rules: {
+        requiredFields: [
+          {
+            required: true,
+            validator: (rule, value, callback) => {
+              const selected = value.some(item => item.select);
+              if (selected) {
+                callback();
+              } else {
+                callback(new Error("请选择必选字段"));
+              }
+            },
+            trigger: "change"
+          }
+        ],
+        extendFields: [
+          {
+            required: true,
+            validator: (rule, value, callback) => {
+              const selected = value.some(item => item.select);
+              if (selected) {
+                callback();
+              } else {
+                callback(new Error("请选择扩展字段"));
+              }
+            },
+            trigger: "change"
+          }
+        ]
+      },
+      ABLE_TYPE,
+      CONFIRM_PRINT_TYPE
+    };
+  },
+  mounted() {
+    // this.init()
+    this.modalForm.requiredFields = CARD_BUSINESS_FIELDS.must;
+    this.modalForm.extendFields = CARD_BUSINESS_FIELDS.extend;
+  },
+  methods: {
+    async init() {
+      await this.getBusinessFieldsList();
+      const data = await commonRuleDetail();
+      this.modalForm = Object.assign(initModalForm, data);
+      // this.requiredFields = data.requiredFields;
+      // this.extendFields = data.extendFields;
+    },
+    validateRequiredFields() {
+      this.$refs.modalFormComp.validateField("requiredFields");
+    },
+    validateExtendFields() {
+      this.$refs.modalFormComp.validateField("extendFields");
+    },
+    toAddField() {
+      this.$refs.ModifyField.open();
+    },
+    addField(field) {
+      this.extendFields.push({ ...field });
+    },
+    deleteField(field) {
+      const index = this.modalForm.extendFields.findIndex(
+        item => item.code === field.code
+      );
+      if (index !== -1) this.modalForm.extendFields.splice(index, 1);
+      this.validateExtendFields();
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const datas = {
+        ...this.modalForm
+      };
+      data.requiredFields = JSON.stringify(datas.requiredFields);
+      data.extendFields = JSON.stringify(datas.extendFields);
+      const data = await saveCommonBusinessRule(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$message.success("保存成功!");
+    }
+  }
+};
+</script>

+ 44 - 15
src/modules/base/router.js

@@ -1,32 +1,61 @@
-import RuleManage from "./views/RuleManage.vue";
+// user
+import OrganizationManage from "./views/OrganizationManage.vue";
+import RoleManage from "./views/RoleManage.vue";
 import UserManage from "./views/UserManage.vue";
-import UserEdit from "./views/UserEdit.vue";
-import PswdManage from "./views/PswdManage.vue";
+import MenuManage from "./views/MenuManage.vue";
+// rule
+import CommonRule from "./views/CommonRule.vue";
+import CardRule from "./views/CardRule.vue";
+import CommonCardTemplate from "./views/CommonCardTemplate.vue";
+import ParamPrintTemplate from "./views/ParamPrintTemplate.vue";
+import CommonPrintTemplate from "./views/CommonPrintTemplate.vue";
 import CourseManage from "./views/CourseManage.vue";
 
 export default [
+  {
+    path: "/base/organization-manage",
+    name: "OrganizationManage",
+    component: OrganizationManage
+  },
+  {
+    path: "/base/role-manage",
+    name: "RoleManage",
+    component: RoleManage
+  },
   {
     path: "/base/user-manage",
     name: "UserManage",
     component: UserManage
   },
   {
-    path: "/base/user-edit/:userId",
-    name: "UserEdit",
-    component: UserEdit,
-    meta: {
-      relate: "UserManage/UserEdit"
-    }
+    path: "/base/menu-manage",
+    name: "MenuManage",
+    component: MenuManage
+  },
+  {
+    path: "/base/common-rule",
+    name: "CommonRule",
+    component: CommonRule
+  },
+  {
+    path: "/base/card-rule",
+    name: "CardRule",
+    component: CardRule
+  },
+  {
+    path: "/base/common-card-template",
+    name: "CommonCardTemplate",
+    component: CommonCardTemplate
   },
   {
-    path: "/base/pswd-manage",
-    name: "PswdManage",
-    component: PswdManage
+    path: "/base/param-print-template",
+    name: "ParamPrintTemplate",
+    component: ParamPrintTemplate
   },
   {
-    path: "/base/rule-manage",
-    name: "RuleManage",
-    component: RuleManage
+    path: "/base/common-print-template",
+    name: "CommonPrintTemplate",
+    component: CommonPrintTemplate
   },
   {
     path: "/base/course-manage",

+ 195 - 0
src/modules/base/views/CardRule.vue

@@ -0,0 +1,195 @@
+<template>
+  <div class="card-rule">
+    <div class="part-box part-box-filter part-box-flex">
+      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
+        <el-form-item label="规则名称:">
+          <el-input
+            style="width: 200px;"
+            v-model.trim="filter.name"
+            placeholder="请输入内容"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="创建时间:">
+          <el-date-picker
+            v-model="filter.createdTime"
+            type="datetime"
+            placeholder="选择日期时间"
+          >
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="启用/禁用:" label-width="90px">
+          <el-select
+            v-model="filter.enable"
+            style="width: 100px;"
+            placeholder="请选择"
+            clearable
+          >
+            <el-option
+              v-for="(val, key) in ABLE_TYPE"
+              :key="key"
+              :value="key"
+              :label="val"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
+            >查询</el-button
+          >
+        </el-form-item>
+      </el-form>
+      <div class="part-box-action">
+        <el-button type="warning" icon="icon icon-plus" @click="toAdd"
+          >添加</el-button
+        >
+      </div>
+    </div>
+    <div class="part-box">
+      <el-table ref="TableList" :data="rules" border stripe>
+        <el-table-column
+          type="index"
+          label="序号"
+          width="70"
+          align="center"
+          :index="indexMethod"
+        ></el-table-column>
+        <el-table-column
+          prop="cardRuleName"
+          label="题卡规则名称"
+        ></el-table-column>
+        <el-table-column prop="college" label="适用学院"> </el-table-column>
+        <el-table-column prop="remark" label="备注"></el-table-column>
+        <el-table-column prop="enable" label="启用/禁用">
+          <template slot-scope="scope">
+            {{ scope.row.enable | enableFilter }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="createTime" label="创建时间"></el-table-column>
+        <el-table-column
+          class-name="action-column"
+          label="操作"
+          align="center"
+          width="120px"
+        >
+          <template slot-scope="scope">
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-edit"
+              @click="toEdit(scope.row)"
+              title="编辑"
+            ></el-button>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-circle-right"
+              @click="toDetail(scope.row)"
+              title="查看"
+            ></el-button>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              :icon="
+                scope.row.enable
+                  ? 'icon icon-circle-stop'
+                  : 'icon icon-circle-caret-right'
+              "
+              @click="toEnable(scope.row)"
+              :title="scope.row.enable ? '禁用' : '启用'"
+            ></el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="part-page">
+        <el-pagination
+          background
+          layout="total,prev, pager, next"
+          :current-page="current"
+          :total="total"
+          :page-size="size"
+          @current-change="toPage"
+        >
+        </el-pagination>
+      </div>
+    </div>
+    <!-- ModifyCardRule -->
+    <modify-card-rule
+      ref="ModifyCardRule"
+      :instance="curRule"
+      :editable="ruleCanEdit"
+      @modified="getList"
+    ></modify-card-rule>
+  </div>
+</template>
+
+<script>
+import { ABLE_TYPE } from "@/constants/enumerate";
+import { cardRuleListPage, ableCardRule } from "../api";
+import ModifyCardRule from "../components/ModifyCardRule";
+
+export default {
+  name: "card-rule",
+  components: {
+    ModifyCardRule
+  },
+  data() {
+    return {
+      filter: {
+        enable: null,
+        name: "",
+        createdTime: ""
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      rules: [],
+      curRule: {},
+      ruleCanEdit: true,
+      ABLE_TYPE
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    async getList() {
+      const datas = {
+        ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size
+      };
+      const data = await cardRuleListPage(datas);
+      this.rules = data.records;
+      this.total = data.total;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    toAdd() {
+      this.curRule = {};
+      this.ruleCanEdit = true;
+      this.$refs.ModifyCardRule.open();
+    },
+    toEdit(row) {
+      this.curRule = row;
+      this.ruleCanEdit = true;
+      this.$refs.ModifyCardRule.open();
+    },
+    toDetail(row) {
+      this.curRule = row;
+      this.ruleCanEdit = false;
+      this.$refs.ModifyCardRule.open();
+    },
+    async toEnable(row) {
+      const enable = Number(!row.enable);
+      await ableCardRule({
+        id: row.id,
+        enable
+      });
+      row.enable = enable;
+    }
+  }
+};
+</script>

+ 17 - 0
src/modules/base/views/CommonCardTemplate.vue

@@ -0,0 +1,17 @@
+<template>
+  <template-manage
+    class="common-card-template"
+    template-type="GENERIC"
+  ></template-manage>
+</template>
+
+<script>
+import TemplateManage from "./TemplateManage";
+
+export default {
+  name: "common-card-template",
+  components: {
+    TemplateManage
+  }
+};
+</script>

+ 17 - 0
src/modules/base/views/CommonPrintTemplate.vue

@@ -0,0 +1,17 @@
+<template>
+  <template-manage
+    class="common-print-template"
+    template-type="ORDINARY"
+  ></template-manage>
+</template>
+
+<script>
+import TemplateManage from "./TemplateManage";
+
+export default {
+  name: "common-print-template",
+  components: {
+    TemplateManage
+  }
+};
+</script>

+ 5 - 13
src/modules/base/views/RuleManage.vue → src/modules/base/views/CommonRule.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="rule-manage">
+  <div class="common-rule">
     <div style="margin-bottom: 20px;">
       <el-button
         v-for="item in menus"
@@ -14,24 +14,16 @@
 </template>
 
 <script>
-import RuleCard from "../components/RuleCard";
-import RuleWarning from "../components/RuleWarning";
-import RuleExamroom from "../components/RuleExamroom";
+import RuleBusiness from "../components/RuleBusiness";
 
 export default {
-  name: "rule-manage",
+  name: "common-rule",
   components: {
-    RuleCard,
-    RuleWarning,
-    RuleExamroom
+    RuleBusiness
   },
   data() {
     return {
-      menus: [
-        { id: "1", name: "题卡规则", component: "rule-card" },
-        { id: "2", name: "预警规则", component: "rule-warning" },
-        { id: "3", name: "考场情况登记表", component: "rule-examroom" }
-      ],
+      menus: [{ id: "1", name: "考务规则配置", component: "rule-business" }],
       curMenu: {}
     };
   },

+ 11 - 9
src/modules/base/views/CourseManage.vue

@@ -1,8 +1,8 @@
 <template>
   <div class="course-manage">
-    <div class="part-box part-box-filter">
+    <div class="part-box part-box-filter part-box-flex">
       <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="科目名称:">
+        <el-form-item label="课程名称:">
           <el-input
             style="width: 142px;"
             v-model.trim="filter.courseName"
@@ -10,7 +10,7 @@
             clearable
           ></el-input>
         </el-form-item>
-        <el-form-item label="科目编码:">
+        <el-form-item label="课程编码:">
           <el-input
             style="width: 142px;"
             v-model.trim="filter.courseCode"
@@ -22,16 +22,18 @@
           <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
             >查询</el-button
           >
-          <el-button type="warning" icon="icon icon-plus" @click="toAdd"
-            >新增科目</el-button
-          >
         </el-form-item>
       </el-form>
+      <div class="part-box-action">
+        <el-button type="warning" icon="icon icon-plus" @click="toAdd"
+          >新增课程</el-button
+        >
+      </div>
     </div>
     <div class="part-box">
       <el-table ref="TableList" :data="courses" border stripe>
-        <el-table-column prop="courseName" label="科目名称"></el-table-column>
-        <el-table-column prop="courseCode" label="科目编码"></el-table-column>
+        <el-table-column prop="courseName" label="课程名称"></el-table-column>
+        <el-table-column prop="courseCode" label="课程编码"></el-table-column>
         <el-table-column label="操作" align="center" width="120px">
           <template slot-scope="scope">
             <el-button
@@ -119,7 +121,7 @@ export default {
       this.$refs.ModifyCourse.open();
     },
     toDelete(row) {
-      this.$confirm("确定要删除当前科目吗?", "提示", {
+      this.$confirm("确定要删除当前课程吗?", "提示", {
         cancelButtonClass: "el-button--danger is-plain",
         confirmButtonClass: "el-button--primary",
         type: "warning"

+ 159 - 0
src/modules/base/views/MenuManage.vue

@@ -0,0 +1,159 @@
+<template>
+  <div class="menu-manage">
+    <div class="part-box">
+      <el-button type="primary" size="mini" icon="el-icon-edit" @click="toAdd"
+        >新增</el-button
+      >
+    </div>
+    <div class="part-box part-box-pad part-box-border">
+      <el-tree
+        :data="menus"
+        node-key="id"
+        default-expand-all
+        :expand-on-click-node="false"
+        :props="defaultProps"
+      >
+        <span class="custom-tree-node" slot-scope="{ node, data }">
+          <span
+            ><i class="el-icon-s-check" v-if="data.type === 'F'"></i>
+            {{ node.label }}</span
+          >
+          <span>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-edit"
+              @click="() => edit(node, data)"
+              title="修改"
+            ></el-button>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-delete"
+              @click="() => remove(node, data)"
+              title="删除"
+            ></el-button>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-plus-act"
+              @click="() => append(data)"
+              title="新增"
+            ></el-button>
+          </span>
+        </span>
+      </el-tree>
+    </div>
+
+    <!-- ModifyMenu -->
+    <modify-menu
+      ref="ModifyMenu"
+      :instance="curMenu"
+      @confirm="getList"
+    ></modify-menu>
+  </div>
+</template>
+
+<script>
+import { organizationList, deleteOrganization } from "../api";
+import ModifyMenu from "../components/ModifyMenu";
+
+export default {
+  name: "menu-manage",
+  components: { ModifyMenu },
+  data() {
+    return {
+      menus: [
+        {
+          id: 1,
+          schoolId: 101,
+          name: "基础配置",
+          url: "basic",
+          type: "M",
+          parentId: null,
+          sortNum: 1,
+          createId: 1,
+          createTime: "2021-03-17 14:20:30",
+          children: [
+            {
+              id: 2,
+              schoolId: 101,
+              name: "用户管理",
+              url: "user",
+              type: "M",
+              parentId: 1,
+              sortNum: 1,
+              createId: 1,
+              createTime: "2021-03-17 14:20:30",
+              children: [
+                {
+                  id: 3,
+                  schoolId: 101,
+                  name: "新增",
+                  url: "/api/sys/user/save",
+                  type: "F",
+                  parentId: 2,
+                  sortNum: 1,
+                  createId: 1,
+                  createTime: "2021-03-17 14:20:30"
+                },
+                {
+                  id: 4,
+                  schoolId: 101,
+                  name: "启用/禁用",
+                  url: "/api/sys/user/enable",
+                  type: "F",
+                  parentId: 2,
+                  sortNum: 2,
+                  createId: 1,
+                  createTime: "2021-03-17 14:20:30"
+                }
+              ]
+            }
+          ]
+        }
+      ],
+      curMenu: {},
+      defaultProps: {
+        label: "name"
+      }
+    };
+  },
+  methods: {
+    async getList() {
+      this.menus = await organizationList();
+    },
+    toAdd() {
+      this.curMenu = {};
+      this.$refs.ModifyMenu.open();
+    },
+    edit(node, data) {
+      this.curMenu = {
+        ...data,
+        parentName: data.parentId && node.parent.data.name
+      };
+      this.$refs.ModifyMenu.open();
+    },
+    remove(node, data) {
+      this.$confirm(`确定要删除【${data.name}】吗?`, "提示", {
+        cancelButtonClass: "el-button--danger is-plain",
+        confirmButtonClass: "el-button--primary",
+        type: "warning"
+      }).then(async () => {
+        await deleteOrganization(data.id);
+
+        const parent = node.parent;
+        const children = parent.data.children || parent.data;
+        const index = children.findIndex(d => d.id === data.id);
+        children.splice(index, 1);
+
+        this.$message.success("删除成功!");
+      });
+    },
+    append(data) {
+      this.curMenu = { parentId: data.id, parentName: data.name };
+      this.$refs.ModifyMenu.open();
+    }
+  }
+};
+</script>

+ 140 - 0
src/modules/base/views/OrganizationManage.vue

@@ -0,0 +1,140 @@
+<template>
+  <div class="organization-manage">
+    <div class="part-box">
+      <el-button type="primary" size="mini" icon="el-icon-edit" @click="toAdd"
+        >新增</el-button
+      >
+    </div>
+    <div class="part-box part-box-pad part-box-border">
+      <el-tree
+        :data="orgs"
+        node-key="id"
+        default-expand-all
+        :expand-on-click-node="false"
+        :props="defaultProps"
+      >
+        <span class="custom-tree-node" slot-scope="{ node, data }">
+          <span>{{ node.label }}</span>
+          <span>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-edit"
+              @click="() => edit(node, data)"
+              title="修改"
+            ></el-button>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-delete"
+              @click="() => remove(node, data)"
+              title="删除"
+            ></el-button>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-plus-act"
+              @click="() => append(data)"
+              title="新增"
+            ></el-button>
+          </span>
+        </span>
+      </el-tree>
+    </div>
+
+    <!-- ModifyOrganization -->
+    <modify-organization
+      ref="ModifyOrganization"
+      :instance="curOrg"
+      @confirm="getList"
+    ></modify-organization>
+  </div>
+</template>
+
+<script>
+import { organizationList, deleteOrganization } from "../api";
+import ModifyOrganization from "../components/ModifyOrganization";
+
+export default {
+  name: "organization-manage",
+  components: { ModifyOrganization },
+  data() {
+    return {
+      orgs: [
+        {
+          id: 1,
+          schoolId: 101,
+          orgCode: "A00001",
+          orgName: "学习中心",
+          parentId: null,
+          enable: 1,
+          createId: 1,
+          createTime: "2021-03-17 14:20:30",
+          children: [
+            {
+              id: 2,
+              schoolId: 101,
+              orgCode: "A000011",
+              orgName: "学习中心1",
+              parentId: 1,
+              enable: 1,
+              createId: 1,
+              createTime: "2021-03-17 14:20:30"
+            },
+            {
+              id: 3,
+              schoolId: 101,
+              orgCode: "A000012",
+              orgName: "学习中心2",
+              parentId: 1,
+              enable: 1,
+              createId: 1,
+              createTime: "2021-03-17 14:20:30"
+            }
+          ]
+        }
+      ],
+      curOrg: {},
+      defaultProps: {
+        label: "orgName"
+      }
+    };
+  },
+  methods: {
+    async getList() {
+      this.orgs = await organizationList();
+    },
+    toAdd() {
+      this.curOrg = {};
+      this.$refs.ModifyOrganization.open();
+    },
+    edit(node, data) {
+      this.curOrg = {
+        ...data,
+        parentName: data.parentId && node.parent.data.orgName
+      };
+      this.$refs.ModifyOrganization.open();
+    },
+    remove(node, data) {
+      this.$confirm(`确定要删除【${data.orgName}】吗?`, "提示", {
+        cancelButtonClass: "el-button--danger is-plain",
+        confirmButtonClass: "el-button--primary",
+        type: "warning"
+      }).then(async () => {
+        await deleteOrganization(data.id);
+
+        const parent = node.parent;
+        const children = parent.data.children || parent.data;
+        const index = children.findIndex(d => d.id === data.id);
+        children.splice(index, 1);
+
+        this.$message.success("删除成功!");
+      });
+    },
+    append(data) {
+      this.curOrg = { parentId: data.id, parentName: data.orgName };
+      this.$refs.ModifyOrganization.open();
+    }
+  }
+};
+</script>

+ 17 - 0
src/modules/base/views/ParamPrintTemplate.vue

@@ -0,0 +1,17 @@
+<template>
+  <template-manage
+    class="param-card-template"
+    template-type="VARIABLE"
+  ></template-manage>
+</template>
+
+<script>
+import TemplateManage from "./TemplateManage";
+
+export default {
+  name: "param-card-template",
+  components: {
+    TemplateManage
+  }
+};
+</script>

+ 0 - 15
src/modules/base/views/PswdManage.vue

@@ -1,15 +0,0 @@
-<template>
-  <div class="pswd-manage">
-    pswd-manage
-  </div>
-</template>
-
-<script>
-export default {
-  name: "pswd-manage",
-  data() {
-    return {};
-  },
-  methods: {}
-};
-</script>

+ 281 - 0
src/modules/base/views/RoleManage.vue

@@ -0,0 +1,281 @@
+<template>
+  <div class="role-manage">
+    <div class="part-box part-box-filter part-box-flex">
+      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
+        <el-form-item label="角色名称:">
+          <el-input
+            style="width: 200px;"
+            v-model.trim="filter.roleName"
+            placeholder="请输入内容"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="启用/禁用:" label-width="90px">
+          <el-select
+            v-model="filter.enable"
+            style="width: 100px;"
+            placeholder="请选择"
+            clearable
+          >
+            <el-option
+              v-for="(val, key) in ABLE_TYPE"
+              :key="key"
+              :value="key"
+              :label="val"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
+            >查询</el-button
+          >
+        </el-form-item>
+      </el-form>
+      <div class="part-box-action">
+        <el-button type="warning" icon="icon icon-plus" @click="toAdd"
+          >添加角色</el-button
+        >
+      </div>
+    </div>
+    <div class="part-box">
+      <el-table ref="TableList" :data="roles" border stripe>
+        <el-table-column
+          type="index"
+          label="序号"
+          width="70"
+          align="center"
+          :index="indexMethod"
+        ></el-table-column>
+        <el-table-column prop="roleName" label="角色名称"></el-table-column>
+        <el-table-column prop="enable" label="启用/禁用">
+          <template slot-scope="scope">
+            {{ scope.row.enable | enableFilter }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="createTime" label="创建时间"></el-table-column>
+        <el-table-column
+          class-name="action-column"
+          label="操作"
+          align="center"
+          width="120px"
+        >
+          <template slot-scope="scope">
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-edit"
+              @click="toEdit(scope.row)"
+              title="编辑"
+            ></el-button>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-delete"
+              @click="toDelete(scope.row)"
+              title="删除"
+            ></el-button>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              :icon="
+                scope.row.enable
+                  ? 'icon icon-circle-stop'
+                  : 'icon icon-circle-caret-right'
+              "
+              @click="toEnable(scope.row)"
+              :title="scope.row.enable ? '禁用' : '启用'"
+            ></el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="part-page">
+        <el-pagination
+          background
+          layout="total,prev, pager, next"
+          :current-page="current"
+          :total="total"
+          :page-size="size"
+          @current-change="toPage"
+        >
+        </el-pagination>
+      </div>
+    </div>
+    <!-- ModifyRole -->
+    <modify-role
+      ref="ModifyRole"
+      :instance="curRole"
+      :menus="menus"
+      @modified="getList"
+    ></modify-role>
+  </div>
+</template>
+
+<script>
+import { ABLE_TYPE, TEMPLATE_TYPE } from "@/constants/enumerate";
+import { organizationList, roleListPage, ableRole, deleteRole } from "../api";
+import ModifyRole from "../components/ModifyRole";
+
+export default {
+  name: "role-manage",
+  components: {
+    ModifyRole
+  },
+  props: {
+    templateType: {
+      type: String,
+      default: "GENERIC",
+      validator(val) {
+        return Object.keys(TEMPLATE_TYPE).indexOf(val) !== -1;
+      }
+    }
+  },
+  data() {
+    return {
+      filter: {
+        enable: null,
+        roleName: ""
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      roles: [],
+      curRole: {},
+      ABLE_TYPE,
+      // menus: [],
+      menus: [
+        {
+          id: 1,
+          schoolId: 101,
+          name: "基础配置",
+          url: "basic",
+          type: "M",
+          parentId: null,
+          sortNum: 1,
+          createId: 1,
+          createTime: "2021-03-17 14:20:30",
+          children: [
+            {
+              id: 2,
+              schoolId: 101,
+              name: "用户管理",
+              url: "user",
+              type: "M",
+              parentId: 1,
+              sortNum: 1,
+              createId: 1,
+              createTime: "2021-03-17 14:20:30",
+              children: [
+                {
+                  id: 3,
+                  name: "角色管理",
+                  type: "M",
+                  parentId: 2,
+                  children: [
+                    {
+                      id: 4,
+                      schoolId: 101,
+                      name: "新增",
+                      url: "/api/sys/user/save",
+                      type: "F",
+                      parentId: 3,
+                      sortNum: 1,
+                      createId: 1,
+                      createTime: "2021-03-17 14:20:30"
+                    },
+                    {
+                      id: 5,
+                      schoolId: 101,
+                      name: "启用/禁用",
+                      url: "/api/sys/user/enable",
+                      type: "F",
+                      parentId: 3,
+                      sortNum: 2,
+                      createId: 1,
+                      createTime: "2021-03-17 14:20:30"
+                    },
+                    {
+                      id: 6,
+                      schoolId: 101,
+                      name: "启用",
+                      url: "/api/sys/user/enable",
+                      type: "F",
+                      parentId: 3,
+                      sortNum: 2,
+                      createId: 1,
+                      createTime: "2021-03-17 14:20:30"
+                    }
+                  ]
+                },
+                {
+                  id: 7,
+                  name: "用户管理",
+                  type: "M",
+                  parentId: 2,
+                  children: [
+                    {
+                      id: 8,
+                      name: "新增",
+                      type: "F",
+                      parentId: 7
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }
+      ]
+    };
+  },
+  created() {
+    this.getList();
+    // this.getMenus();
+  },
+  methods: {
+    async getMenus() {
+      this.menus = await organizationList();
+    },
+    async getList() {
+      const datas = {
+        ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size
+      };
+      const data = await roleListPage(datas);
+      this.roles = data.records;
+      this.total = data.total;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    toAdd() {
+      this.curRole = {};
+      this.$refs.ModifyRole.open();
+    },
+    toEdit(row) {
+      this.curRole = row;
+      this.$refs.ModifyRole.open();
+    },
+    toDelete(row) {
+      this.$confirm("确定要删除当前角色吗?", "提示", {
+        cancelButtonClass: "el-button--danger is-plain",
+        confirmButtonClass: "el-button--primary",
+        type: "warning"
+      }).then(async () => {
+        await deleteRole(row.id);
+        this.$message.success("删除成功!");
+        this.deletePageLastItem();
+      });
+    },
+    async toEnable(row) {
+      const enable = Number(!row.enable);
+      await ableRole({
+        id: row.id,
+        enable
+      });
+      row.enable = enable;
+    }
+  }
+};
+</script>

+ 212 - 0
src/modules/base/views/TemplateManage.vue

@@ -0,0 +1,212 @@
+<template>
+  <div class="template-manage">
+    <div class="part-box part-box-filter part-box-flex">
+      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
+        <el-form-item label="模板名称:">
+          <el-input
+            style="width: 200px;"
+            v-model.trim="filter.templateName"
+            placeholder="请输入内容"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="创建时间:">
+          <el-date-picker
+            v-model="filter.createTime"
+            type="date"
+            placeholder="选择日期时间"
+          >
+          </el-date-picker>
+        </el-form-item>
+        <el-form-item label="启用/禁用:" label-width="90px">
+          <el-select
+            v-model="filter.enable"
+            style="width: 100px;"
+            placeholder="请选择"
+            clearable
+          >
+            <el-option
+              v-for="(val, key) in ABLE_TYPE"
+              :key="key"
+              :value="key"
+              :label="val"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
+            >查询</el-button
+          >
+        </el-form-item>
+      </el-form>
+      <div class="part-box-action">
+        <el-button type="warning" icon="icon icon-plus" @click="toAdd"
+          >添加模板</el-button
+        >
+      </div>
+    </div>
+    <div class="part-box">
+      <el-table ref="TableList" :data="templates" border stripe>
+        <el-table-column
+          type="index"
+          label="序号"
+          width="70"
+          align="center"
+          :index="indexMethod"
+        ></el-table-column>
+        <el-table-column prop="templateName" label="模板名称"></el-table-column>
+        <el-table-column
+          prop="classify"
+          label="分类"
+          v-if="templateType !== 'GENERIC'"
+        >
+          <template slot-scope="scope">
+            {{ scope.row.classify | templateClassifyFilter }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="college" label="适用学院"></el-table-column>
+        <el-table-column prop="remark" label="备注"></el-table-column>
+        <el-table-column prop="enable" label="启用/禁用">
+          <template slot-scope="scope">
+            {{ scope.row.enable | enableFilter }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="createTime" label="创建时间"></el-table-column>
+        <el-table-column
+          class-name="action-column"
+          label="操作"
+          align="center"
+          width="120px"
+        >
+          <template slot-scope="scope">
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-edit"
+              @click="toEdit(scope.row)"
+              title="编辑"
+            ></el-button>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              icon="icon icon-circle-right"
+              @click="toDetail(scope.row)"
+              title="查看"
+            ></el-button>
+            <el-button
+              class="btn-table-icon"
+              type="text"
+              :icon="
+                scope.row.enable
+                  ? 'icon icon-circle-stop'
+                  : 'icon icon-circle-caret-right'
+              "
+              @click="toEnable(scope.row)"
+              :title="scope.row.enable ? '禁用' : '启用'"
+            ></el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="part-page">
+        <el-pagination
+          background
+          layout="total,prev, pager, next"
+          :current-page="current"
+          :total="total"
+          :page-size="size"
+          @current-change="toPage"
+        >
+        </el-pagination>
+      </div>
+    </div>
+    <!-- ModifyTemplate -->
+    <modify-template
+      ref="ModifyTemplate"
+      :instance="curTemplate"
+      :editable="templateCanEdit"
+      :template-type="templateType"
+      @modified="getList"
+    ></modify-template>
+  </div>
+</template>
+
+<script>
+import { ABLE_TYPE, TEMPLATE_TYPE } from "@/constants/enumerate";
+import { templateListPage, ableTemplate } from "../api";
+import ModifyTemplate from "../components/ModifyTemplate";
+
+export default {
+  name: "template-manage",
+  components: {
+    ModifyTemplate
+  },
+  props: {
+    templateType: {
+      type: String,
+      default: "GENERIC",
+      validator(val) {
+        return Object.keys(TEMPLATE_TYPE).indexOf(val) !== -1;
+      }
+    }
+  },
+  data() {
+    return {
+      filter: {
+        enable: null,
+        templateName: "",
+        createTime: ""
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      templates: [],
+      curTemplate: {},
+      templateCanEdit: true,
+      ABLE_TYPE
+    };
+  },
+  created() {
+    // this.getList();
+  },
+  methods: {
+    async getList() {
+      const datas = {
+        ...this.filter,
+        templateType: this.templateType,
+        pageNumber: this.current,
+        pageSize: this.size
+      };
+      const data = await templateListPage(datas);
+      this.templates = data.records;
+      this.total = data.total;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    },
+    toAdd() {
+      this.curTemplate = { templateType: this.templateType };
+      this.templateCanEdit = true;
+      this.$refs.ModifyTemplate.open();
+    },
+    toEdit(row) {
+      this.curTemplate = { ...row, templateType: this.templateType };
+      this.templateCanEdit = true;
+      this.$refs.ModifyTemplate.open();
+    },
+    toDetail(row) {
+      this.curTemplate = { ...row, templateType: this.templateType };
+      this.templateCanEdit = false;
+      this.$refs.ModifyTemplate.open();
+    },
+    async toEnable(row) {
+      const enable = Number(!row.enable);
+      await ableTemplate({
+        id: row.id,
+        enable
+      });
+      row.enable = enable;
+    }
+  }
+};
+</script>

+ 0 - 201
src/modules/base/views/UserEdit.vue

@@ -1,201 +0,0 @@
-<template>
-  <div class="user-edit part-box part-box-pad part-box-border">
-    <el-form
-      ref="modalFormComp"
-      :model="modalForm"
-      :rules="rules"
-      label-width="100px"
-    >
-      <el-form-item prop="loginName" label="用户名:">
-        <el-input
-          style="width:282px;"
-          v-model.trim="modalForm.loginName"
-          placeholder="请输入用户名"
-          clearable
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="name" label="姓名:">
-        <el-input
-          style="width:282px;"
-          v-model.trim="modalForm.name"
-          placeholder="请输入姓名"
-          clearable
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="phone" label="手机号:">
-        <el-input
-          style="width:282px;"
-          v-model.trim="modalForm.phone"
-          placeholder="请输入手机号"
-          clearable
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="roleCode" label="角色:">
-        <el-select
-          style="width:282px;"
-          v-model="modalForm.roleCode"
-          placeholder="请选择角色"
-        >
-          <el-option
-            v-for="item in roles"
-            :key="item.id"
-            :label="item.roleName"
-            :value="item.roleCode"
-          >
-          </el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item
-        prop="courseId"
-        label="科目:"
-        v-if="modalForm.roleCode === 'QUESTION_TEACHER'"
-      >
-        <el-select
-          style="width:282px;"
-          v-model="modalForm.courseId"
-          placeholder="请选择科目"
-          multiple
-          filterable
-        >
-          <el-option
-            v-for="item in courses"
-            :key="item.id"
-            :label="item.name"
-            :value="item.id"
-          >
-          </el-option>
-        </el-select>
-      </el-form-item>
-      <el-form-item>
-        <el-button
-          style="width:88px;"
-          type="primary"
-          :disabled="isSubmit"
-          @click="submit('modalFormComp')"
-          >保存</el-button
-        >
-        <el-button style="width:88px;" @click="goback">返回</el-button>
-      </el-form-item>
-    </el-form>
-  </div>
-</template>
-
-<script>
-import { updateUser, userDetail, roleList, courseList } from "../api";
-import { logout } from "../../login/api";
-import { phone } from "@/plugins/formRules";
-
-export default {
-  name: "user-edit",
-  data() {
-    const courseIdValidator = (rule, value, callback) => {
-      if (!value || !value.length) {
-        callback(new Error("请选择科目"));
-      } else {
-        callback();
-      }
-    };
-
-    return {
-      modalForm: {
-        id: "",
-        name: "",
-        phone: "",
-        loginName: "",
-        roleCode: "",
-        courseId: ""
-      },
-      rules: {
-        phone,
-        name: [
-          {
-            required: true,
-            message: "请输入用户名",
-            trigger: "change"
-          }
-        ],
-        loginName: [
-          {
-            required: true,
-            message: "请输入姓名",
-            trigger: "change"
-          }
-        ],
-        roleCode: [
-          {
-            required: true,
-            message: "请选择角色",
-            trigger: "change"
-          }
-        ],
-        courseId: [
-          {
-            required: true,
-            validator: courseIdValidator,
-            trigger: "change"
-          }
-        ]
-      },
-      user: {},
-      roles: [],
-      courses: [],
-      isSubmit: false
-    };
-  },
-  created() {
-    this.init();
-  },
-  methods: {
-    async init() {
-      const data = await roleList();
-      this.roles = data.records;
-      const userRes = await userDetail(this.$route.params.userId);
-      if (!userRes.account) {
-        this.$message.error("当前用户不存在!");
-        return;
-      }
-      this.user = userRes.account;
-      this.modalForm = this.$objAssign(this.modalForm, this.user);
-      this.modalForm.courseId = this.user.courseId
-        ? this.modalForm.courseId.split(",")
-        : [];
-      this.getCourseList();
-    },
-    async getCourseList() {
-      const data = await courseList();
-      this.courses = data.records.map(course => {
-        return {
-          id: course.id,
-          name: `${course.courseName}(${course.courseCode})`
-        };
-      });
-    },
-    async submit(name) {
-      const valid = await this.$refs[name].validate().catch(() => {});
-      if (!valid) return;
-
-      if (this.isSubmit) return;
-      this.isSubmit = true;
-
-      const datas = { ...this.modalForm };
-      if (datas.roleCode !== "QUESTION_TEACHER") delete datas.courseId;
-      const data = await updateUser(datas).catch(() => {});
-      this.isSubmit = false;
-      if (!data) return;
-
-      this.$message.success("修改成功!");
-
-      // 自己把自己的角色改了之后要重新登录,重新获取权限
-      if (
-        this.user.roleCode !== this.modalForm.roleCode &&
-        this.$ls.get("user").id === this.user.id
-      ) {
-        await logout(this.$ls.get("user", { id: "" }).id);
-        this.$ls.clear();
-        this.$router.push({ name: "Login" });
-        this.$message.info("您的权限已经变更,请重新登录系统!");
-      }
-    }
-  }
-};
-</script>

+ 62 - 51
src/modules/base/views/UserManage.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="user-manage">
-    <div class="part-box part-box-filter">
+    <div class="part-box part-box-filter part-box-flex">
       <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
         <el-form-item label="用户名:" label-width="75px">
           <el-input
@@ -12,15 +12,15 @@
         </el-form-item>
         <el-form-item label="角色:" label-width="55px">
           <el-select
-            v-model="filter.roleCode"
+            v-model="filter.roleId"
             style="width: 142px;"
             placeholder="请选择"
             clearable
           >
             <el-option
               v-for="item in roles"
-              :key="item.roleCode"
-              :value="item.roleCode"
+              :key="item.roleId"
+              :value="item.roleId"
               :label="item.roleName"
             ></el-option>
           </el-select>
@@ -45,24 +45,26 @@
           <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
             >查询</el-button
           >
-          <upload-button
-            btn-icon="icon icon-share"
-            btn-type="warning"
-            btn-content="导入"
-            :upload-url="uploadUrl"
-            :format="['xls', 'xlsx']"
-            :upload-data="uploadData"
-            @upload-error="uplaodError"
-            @upload-success="uploadSuccess"
-          >
-          </upload-button>
-          <el-button icon="icon icon-download-act">
-            <a :href="downloadUrl" download="用户导入模板.xlsx"
-              >用户导入模板下载</a
-            >
-          </el-button>
         </el-form-item>
       </el-form>
+      <div class="part-box-action">
+        <upload-button
+          btn-icon="icon icon-share"
+          btn-type="warning"
+          btn-content="导入"
+          :upload-url="uploadUrl"
+          :format="['xls', 'xlsx']"
+          :upload-data="uploadData"
+          @upload-error="uplaodError"
+          @upload-success="uploadSuccess"
+        >
+        </upload-button>
+        <el-button icon="icon icon-download-act">
+          <a :href="downloadUrl" download="用户导入模板.xlsx"
+            >用户导入模板下载</a
+          >
+        </el-button>
+      </div>
     </div>
 
     <div class="part-box">
@@ -75,19 +77,29 @@
           :index="indexMethod"
         ></el-table-column>
         <el-table-column prop="loginName" label="用户名"></el-table-column>
-        <el-table-column prop="name" label="姓名"></el-table-column>
-        <el-table-column prop="roleName" label="角色"></el-table-column>
+        <el-table-column prop="realName" label="姓名"></el-table-column>
+        <el-table-column prop="roles" label="角色">
+          <template slot-scope="scope">
+            {{ scope.row.roles | rolesFilter }}
+          </template>
+        </el-table-column>
         <el-table-column prop="phone" label="手机号"></el-table-column>
-        <el-table-column
-          prop="courseNameCode"
-          label="科目名称(编码)"
-        ></el-table-column>
+        <el-table-column prop="courses" label="课程名称(编码)">
+          <template slot-scope="scope">
+            {{ scope.row.courses | coursesFilter }}
+          </template>
+        </el-table-column>
         <el-table-column prop="enable" label="状态">
           <template slot-scope="scope">
-            {{ ABLE_TYPE[scope.row.enable + ""] }}
+            {{ scope.row.enable | enableFilter }}
           </template>
         </el-table-column>
-        <el-table-column label="操作" align="center" width="120px">
+        <el-table-column
+          class-name="action-column"
+          label="操作"
+          align="center"
+          width="120px"
+        >
           <template slot-scope="scope">
             <el-button
               class="btn-table-icon"
@@ -120,7 +132,7 @@
       <div class="part-page">
         <el-pagination
           background
-          layout="prev, pager, next"
+          layout="total,prev, pager, next"
           :current-page="current"
           :total="total"
           :page-size="size"
@@ -129,25 +141,33 @@
         </el-pagination>
       </div>
     </div>
+
+    <!-- ModifyUser -->
+    <modify-user
+      ref="ModifyUser"
+      :instance="curUser"
+      :roles="roles"
+      @modified="getList"
+    ></modify-user>
   </div>
 </template>
 
 <script>
-import { ABLE_TYPE } from "@/constants/enumerate";
-import { userListPage, ableUser, updatePwd, roleList } from "../api";
 import UploadButton from "@/components/UploadButton";
-import { AES } from "@/plugins/crypto";
+import ModifyUser from "../components/ModifyUser";
+import { ABLE_TYPE } from "@/constants/enumerate";
+import { userListPage, ableUser, updatePwd, roleListPage } from "../api";
 import { logout } from "@/modules/login/api";
 
 export default {
   name: "user-manage",
-  components: { UploadButton },
+  components: { UploadButton, ModifyUser },
   data() {
     return {
       isInit: false,
       filter: {
         loginName: "",
-        roleCode: "",
+        roleId: "",
         enable: ""
       },
       current: 1,
@@ -157,9 +177,10 @@ export default {
       ABLE_TYPE,
       roles: [],
       users: [],
+      curUser: {},
       downloadUrl: "/temps/用户导入模板.xlsx",
       // import
-      uploadUrl: "/api/print/basic/user/add",
+      uploadUrl: "/api/sys/user/import",
       uploadData: {
         schoolId: this.$ls.get("schoolId"),
         userId: this.$ls.get("user", { id: "" }).id
@@ -167,15 +188,12 @@ export default {
     };
   },
   created() {
-    this.getRoleList();
-    this.getList();
+    // this.getRoleList();
+    // this.getList();
   },
   methods: {
-    indexMethod(index) {
-      return (this.current - 1) * this.size + index + 1;
-    },
     async getRoleList() {
-      const data = await roleList();
+      const data = await roleListPage();
       this.roles = data.records;
     },
     async getList() {
@@ -201,18 +219,11 @@ export default {
       row.enable = enable;
     },
     toEdit(row) {
-      this.$router.push({
-        name: "UserEdit",
-        params: {
-          userId: row.id
-        }
-      });
+      this.curUser = row;
+      this.$refs.ModifyUser.open();
     },
     async toResetPwd(row) {
-      await updatePwd({
-        id: row.id,
-        newPassword: AES("123456")
-      });
+      await updatePwd(row.id);
       this.$message.success("密码重置成功!");
 
       // 修改自己时,会强制重新登录

+ 0 - 174
src/modules/exam-center/api.js

@@ -1,174 +0,0 @@
-import { $get, $post } from "@/plugins/axios";
-
-// wait-manage
-export const waitTaskListPage = datas => {
-  return $get("/api/print/exam/examTask/listNotDonePage", datas);
-};
-export const waitTaskDetail = taskId => {
-  return $get("/api/print/exam/examTask/detailNotDone", { taskId });
-};
-export const saveWaitTask = datas => {
-  return $post("/api/print/exam/examTask/draft", datas);
-};
-export const submitWaitTask = datas => {
-  return $post("/api/print/exam/examTask/submit", datas);
-};
-export const waitTaskListCount = () => {
-  return $get("/api/print/exam/examTask/listNotDoneCount", {});
-};
-
-// done-task
-export const doneTaskListPage = datas => {
-  return $get("/api/print/exam/examTask/listDonePage", datas);
-};
-export const doneTaskDetail = taskId => {
-  return $get("/api/print/exam/examTask/detailDone", { taskId });
-};
-// 撤回
-export const revokeDoneTask = ({ taskId, examId }) => {
-  return $post("/api/print/exam/examTask/revoke", { taskId, examId });
-};
-
-// exam-manage
-export const examListPage = datas => {
-  return $get("/api/print/exam/exam/listPage", datas);
-};
-export const examList = () => {
-  return $get("/api/print/exam/exam/list", {});
-};
-export const examSiteRoomList = () => {
-  return $get("/api/print/exam/exam/listRooms", {});
-};
-export const examDetail = examId => {
-  return $get("/api/print/exam/exam/preEdit", { examId });
-};
-export const uploadExam = datas => {
-  if (datas.tcPExam.id) {
-    return $post("/api/print/exam/exam/edit", datas);
-  } else {
-    return $post("/api/print/exam/exam/add", datas);
-  }
-};
-export const examTaskDetail = examId => {
-  return $get("/api/print/exam/exam/detailProgress", { examId });
-};
-export const examRoomDetail = datas => {
-  return $get("/api/print/exam/exam/listExamDetailPage", datas);
-};
-export const examBusinessData = datas => {
-  return $get("/api/print/exam/exam/preViewExamData", datas);
-};
-export const studentDetail = datas => {
-  return $get("/api/print/exam/exam/listExamStudentPage", datas);
-};
-export const deleteExam = examId => {
-  return $post("/api/print/exam/exam/delete", { examId });
-};
-
-// todo-exam
-export const todoExamList = datas => {
-  return $get("/api/print/exam/exam/listExams", datas);
-};
-
-// course
-export const courseList = () => {
-  return $get("/api/print/basic/sys/courseList", {});
-};
-export const examCourseList = examId => {
-  return $get("/api/print/exam/examTask/listCourseByExamId", { examId });
-};
-
-// card-manage
-export const cardList = datas => {
-  return $get("/api/print/card/card/list", datas);
-};
-export const cardListPage = datas => {
-  return $get("/api/print/card/card/listPage", datas);
-};
-export const createCard = datas => {
-  return $post("/api/print/card/card/add", datas);
-};
-export const copyCard = cardId => {
-  return $post("/api/print/card/card/copy", { cardId });
-};
-export const deleteCard = cardId => {
-  return $post("/api/print/card/card/delete", { cardId });
-};
-export const changeOperateStatus = cardId => {
-  return $post("/api/print/card/card/changeOperateStatus", { cardId });
-};
-export const courseByUser = () => {
-  return $get("/api/print/card/card/listCourseByUserId", {});
-};
-export const changeCardStatus = ({ cardId, cardStatus }) => {
-  return $post("/api/print/card/card/changeCardStatus", { cardId, cardStatus });
-};
-export const updateCardDetail = datas => {
-  return $post("/api/print/card/card/updateCardDetail", datas);
-};
-
-// print-manage
-export const printTaskListPage = datas => {
-  return $get("/api/print/exam/exam/listPrintPage", datas);
-};
-export const printRevokeAudit = examId => {
-  return $post("/api/print/exam/exam/revokeAudit", { examId });
-};
-
-// card-audit
-export const auditListPage = datas => {
-  return $get("/api/print/card/card/listAuditPage", datas);
-};
-export const schoolList = () => {
-  return $get("/api/print/card/card/listSchools", {});
-};
-
-// exam-task-audit
-export const examTaskListPage = datas => {
-  return $get("/api/print/exam/taskAudit/listByConditions", datas);
-};
-export const auditExamTask = datas => {
-  return $post("/api/print/exam/taskAudit/audit", datas);
-};
-export const examTaskAudtiHistory = taskId => {
-  return $get("/api/print/exam/taskAudit/listHis", { taskId });
-};
-
-// topic-task-manage
-export const topicTaskListPage = datas => {
-  return $get("/api/print/exam/examTask/listTaskPage", datas);
-};
-export const topicTaskDetail = taskId => {
-  return $get("/api/print/exam/examTask/preUpdate", { taskId });
-};
-export const topicTaskExamList = () => {
-  return $get("/api/print/exam/examTask/exams", {});
-};
-export const topicTaskExamCourseList = examId => {
-  return $get("/api/print/exam/examTask/courses", { examId });
-};
-export const topicTaskExamTeacherList = courseCode => {
-  return $get("/api/print/exam/examTask/users", { courseCode });
-};
-export const eableTopicTask = datas => {
-  return $post("/api/print/exam/examTask/enable", datas);
-};
-export const updateTopicTask = datas => {
-  if (datas.taskId) {
-    return $post("/api/print/exam/examTask/update", datas);
-  } else {
-    return $post("/api/print/exam/examTask/add", datas);
-  }
-};
-
-// custom upload-file
-export const customUpload = options => {
-  let formData = new FormData();
-  formData.append(options.filename, options.file);
-  Object.entries(options.data).forEach(([key, val]) => {
-    formData.append(key, val);
-  });
-  return $post(options.action, formData, {
-    headers: options.headers
-  });
-};

+ 0 - 115
src/modules/exam-center/components/BusinessData.vue

@@ -1,115 +0,0 @@
-<template>
-  <el-dialog
-    class="business-data"
-    :visible.sync="modalIsShow"
-    title="导入考务数据预览"
-    top="10vh"
-    width="840px"
-    :close-on-click-modal="false"
-    :close-on-press-escape="false"
-    append-to-body
-    @open="visibleChange"
-  >
-    <el-table ref="TableList" :data="dataList" border stripe>
-      <el-table-column
-        prop="sceneNumberId"
-        label="场次ID"
-        width="80"
-      ></el-table-column>
-      <el-table-column prop="examSite" label="考点名称"></el-table-column>
-      <el-table-column prop="examRoom" label="考场名称"></el-table-column>
-      <el-table-column
-        prop="courseCodeAndName"
-        label="科目名称(编码)"
-      ></el-table-column>
-      <el-table-column
-        prop="examTotal"
-        label="应考科次"
-        width="100"
-      ></el-table-column>
-    </el-table>
-    <div class="table-tips">
-      将导入 <span>{{ total }}</span> 条数据
-    </div>
-    <div class="part-page">
-      <el-pagination
-        background
-        layout="prev, pager, next"
-        :current-page="current"
-        :total="total"
-        :page-size="size"
-        @current-change="toPage"
-      >
-      </el-pagination>
-    </div>
-    <div slot="footer" style="text-align: right">
-      <el-button type="primary" @click="cancel">确定</el-button>
-    </div>
-  </el-dialog>
-</template>
-
-<script>
-import { examBusinessData } from "../api";
-
-export default {
-  name: "business-data",
-  props: {
-    examCode: {
-      type: [String, Number]
-    }
-  },
-  data() {
-    return {
-      modalIsShow: false,
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      dataList: [],
-      res: {
-        success: true,
-        msg: ""
-      }
-    };
-  },
-  methods: {
-    visibleChange() {
-      this.toPage(1);
-    },
-    async getList() {
-      if (!this.examCode) return;
-      const datas = {
-        examCode: this.examCode,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const data = await examBusinessData(datas);
-      this.dataList = data.records;
-      this.total = data.total;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    },
-    confirm() {
-      this.$emit("confirm");
-    }
-  }
-};
-</script>
-
-<style lang="css" scoped>
-.table-tips {
-  color: #888;
-  float: left;
-  margin-top: 21px;
-}
-.table-tips > span {
-  color: rgba(254, 108, 105, 1);
-}
-</style>

+ 0 - 256
src/modules/exam-center/components/CardOptionDialog.vue

@@ -1,256 +0,0 @@
-<template>
-  <div class="card-option-dialog">
-    <el-dialog
-      class="card-option-dialog"
-      :visible.sync="modalIsShow"
-      title="选择制卡方式"
-      top="10vh"
-      width="559px"
-      :close-on-click-modal="false"
-      :close-on-press-escape="false"
-      append-to-body
-      @open="visibleChange"
-    >
-      <div class="card-option-body">
-        <p>请您选择创建题卡方式:</p>
-        <p>1.自助创建:使用题卡工具自助设计题卡,操作简单,即刻生成;</p>
-        <p>
-          2.申请客服制卡:需提交试卷,由客服后台统一处理,处理完毕后您可查看或微调。
-        </p>
-        <div class="card-type">
-          <el-radio-group v-model="modalForm.cardSource">
-            <el-radio
-              v-for="item in cardSourceTypes"
-              :key="item.type"
-              :label="item.type"
-              :disabled="item.disabled"
-              >{{ item.name }}</el-radio
-            >
-          </el-radio-group>
-        </div>
-        <!-- card-select -->
-        <div class="card-select" v-if="modalForm.cardSource === '0'">
-          <el-select
-            v-model="modalForm.refCardId"
-            style="width: 300px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in cards"
-              :key="item.id"
-              :value="item.id"
-              :label="item.name"
-            >
-            </el-option>
-          </el-select>
-          <span class="card-view" @click="toPreview">预览</span>
-        </div>
-        <div class="card-select" v-if="modalForm.cardSource !== '0' && noExam">
-          <el-select
-            v-model="modalForm.courseCode"
-            style="width: 193px;"
-            placeholder="请选择科目"
-            @change="cousreChange"
-          >
-            <el-option
-              v-for="item in courses"
-              :key="item.courseCode"
-              :value="item.courseCode"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </div>
-      </div>
-      <div slot="footer" style="text-align: right;">
-        <el-button type="primary" @click="confirm">确定</el-button>
-        <el-button @click="cancel">返回</el-button>
-      </div>
-    </el-dialog>
-
-    <!-- upload-sample-paper-dialog -->
-    <upload-sample-paper-dialog
-      @confirm="uploadSampleOver"
-      :data="modalForm"
-      ref="UploadSamplePaperDialog"
-    ></upload-sample-paper-dialog>
-  </div>
-</template>
-
-<script>
-import { CARD_SOURCE_TYPE } from "@/constants/enumerate";
-import { cardList, courseByUser } from "../api";
-import UploadSamplePaperDialog from "./UploadSamplePaperDialog";
-
-export default {
-  name: "card-option-dialog-view",
-  props: {
-    data: {
-      type: Object,
-      default() {
-        return {};
-      }
-    }
-  },
-  components: { UploadSamplePaperDialog },
-  data() {
-    return {
-      modalIsShow: false,
-      modalForm: {
-        taskId: "",
-        examId: "",
-        courseNameCode: "",
-        enablePaperType: "",
-        paperAttachmentId: "",
-        paperConfirmAttachmentId: "",
-        courseName: "",
-        courseCode: "",
-        cardSource: "",
-        refCardId: ""
-      },
-      noExam: false,
-      onlySelect: false,
-      cards: [],
-      courses: [],
-      cardSourceTypes: [],
-      CARD_SOURCE_TYPE
-    };
-  },
-  methods: {
-    visibleChange() {
-      this.noExam = !this.data["examId"];
-      this.onlySelect = this.data["cardSource"] === 0;
-      this.getCardSourceTypes();
-      this.modalForm.cardSource = this.cardSourceTypes[0].type;
-      this.modalForm = this.$objAssign(this.modalForm, this.data);
-      this.modalForm.cardSource += "";
-
-      if (this.noExam) {
-        this.getCourseByUser();
-      } else {
-        this.getCardList();
-      }
-    },
-    getCardSourceTypes() {
-      let cardSourceTypes = [];
-      Object.keys(CARD_SOURCE_TYPE).forEach(key => {
-        if (key === "0" && this.noExam) return;
-        cardSourceTypes.push({
-          type: key,
-          name: CARD_SOURCE_TYPE[key],
-          disabled: this.onlySelect && key !== "0"
-        });
-      });
-      this.cardSourceTypes = cardSourceTypes;
-    },
-    cousreChange(val) {
-      const course = this.courses.find(item => item.courseCode === val);
-      this.modalForm.courseName = course.courseName;
-    },
-    async getCardList() {
-      const data = await cardList({
-        taskId: this.modalForm.taskId,
-        courseNameCode: this.modalForm.courseNameCode,
-        enablePaperType: this.modalForm.enablePaperType
-      });
-      this.cards = data.map(item => {
-        return {
-          id: item.id,
-          name: `${item.title}(${item.cardCode})`
-        };
-      });
-    },
-    async getCourseByUser() {
-      const data = await courseByUser();
-      if (data && data.length) {
-        this.courses = data.map(item => {
-          item.name = `${item.courseName}(${item.courseCode})`;
-          return item;
-        });
-        this.modalForm.courseCode = this.courses[0].courseCode;
-        this.modalForm.courseName = this.courses[0].courseName;
-      }
-    },
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    },
-    uploadSampleOver() {
-      this.cancel();
-      this.$emit("upload-sample-over");
-    },
-    confirm() {
-      if (this.modalForm.cardSource !== "0" && !this.modalForm.courseCode) {
-        this.$message.error("请选择科目!");
-        return;
-      }
-
-      if (this.modalForm.cardSource === "2") {
-        this.$emit("draft-task");
-        this.$refs.UploadSamplePaperDialog.open();
-        return;
-      }
-
-      if (this.modalForm.cardSource === "1") {
-        // 暂存任务,确保以上传的试卷信息正常保存
-        this.$emit("draft-task");
-        // 打开题卡编辑页,创建题卡,并预设需要绑定的任务
-        this.$ls.set("prepareTcPCard", this.modalForm);
-        this.$router.push({
-          name: "CardDesign"
-        });
-        return;
-      }
-
-      if (this.modalForm.cardSource === "0" && !this.modalForm.refCardId) {
-        this.$message.error("请选择已有的题卡!");
-        return;
-      }
-
-      const data = { ...this.modalForm };
-      if (data.cardSource !== "0") data.refCardId = "";
-      data.cardSource = data.cardSource * 1;
-      this.$emit("confirm", data);
-      this.cancel();
-    },
-    toPreview() {
-      if (!this.modalForm.refCardId) {
-        this.$message.error("请先选择题卡!");
-        return;
-      }
-      window.open(
-        this.getRouterPath({
-          name: "CardPreview",
-          params: {
-            cardId: this.modalForm.refCardId,
-            viewType: "view"
-          }
-        })
-      );
-    }
-  }
-};
-</script>
-
-<style scoped>
-.card-option-body {
-  color: #878787;
-}
-.card-type {
-  margin: 32px 0;
-}
-.card-select {
-  margin-bottom: 10px;
-}
-.card-view {
-  display: inline-block;
-  margin-left: 10px;
-  color: rgba(35, 196, 185, 1);
-  cursor: pointer;
-}
-.card-view:hover {
-  color: rgba(28, 208, 161, 1);
-}
-</style>

+ 0 - 47
src/modules/exam-center/components/ExamPlanData.vue

@@ -1,47 +0,0 @@
-<template>
-  <el-dialog
-    class="exam-plan-data"
-    :visible.sync="modalIsShow"
-    title="导入考试计划数据预览"
-    top="10vh"
-    width="540px"
-    :close-on-click-modal="false"
-    :close-on-press-escape="false"
-    append-to-body
-  >
-    <el-table ref="TableList" :data="datas" border stripe>
-      <el-table-column prop="courseName" label="科目名称"></el-table-column>
-      <el-table-column prop="courseCode" label="科目代码"></el-table-column>
-    </el-table>
-    <div slot="footer" style="text-align: right">
-      <el-button type="primary" @click="cancel">确定</el-button>
-    </div>
-  </el-dialog>
-</template>
-
-<script>
-export default {
-  name: "exam-plan-data",
-  props: {
-    datas: {
-      type: Array,
-      default() {
-        return [];
-      }
-    }
-  },
-  data() {
-    return {
-      modalIsShow: false
-    };
-  },
-  methods: {
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    }
-  }
-};
-</script>

+ 0 - 131
src/modules/exam-center/components/UploadPaperDialog.vue

@@ -1,131 +0,0 @@
-<template>
-  <el-dialog
-    class="upload-paper-dialog"
-    :visible.sync="modalIsShow"
-    :title="`上传${curConfig.title}`"
-    top="10vh"
-    width="710px"
-    :close-on-click-modal="false"
-    :close-on-press-escape="false"
-    append-to-body
-    @opened="visibleChange"
-  >
-    <div class="file-upload-body">
-      <el-form
-        label-position="right"
-        :label-width="uploadType === 'paper' ? '80px' : '150px'"
-      >
-        <el-form-item label="科目名称:" v-if="attachment.courseNameCode">
-          <div>{{ attachment.courseNameCode }}</div>
-        </el-form-item>
-        <el-form-item :label="`${curConfig.title}:`">
-          <upload-file-view
-            input-width="270px"
-            :format="curConfig.format"
-            :upload-url="uploadUrl"
-            @upload-error="uplaodError"
-            @upload-success="uploadSuccess"
-            ref="UploadFileView"
-          ></upload-file-view>
-          <el-button @click="toPreview" style="margin-left: 10px;"
-            >预览</el-button
-          >
-        </el-form-item>
-      </el-form>
-    </div>
-    <div slot="footer" style="text-align: right">
-      <el-button type="primary" @click="confirm">保存</el-button>
-      <el-button @click="cancel">返回</el-button>
-    </div>
-  </el-dialog>
-</template>
-
-<script>
-import UploadFileView from "@/components/UploadFileView";
-import { attachmentPreview } from "../../login/api";
-
-export default {
-  name: "upload-paper-dialog",
-  components: { UploadFileView },
-  props: {
-    paperAttachment: {
-      type: Object,
-      default() {
-        return {};
-      }
-    },
-    uploadType: {
-      type: String,
-      default: "paper",
-      validator(val) {
-        return ["paper", "paperConfirm"].includes(val);
-      }
-    }
-  },
-  data() {
-    return {
-      modalIsShow: false,
-      attachment: {},
-      config: {
-        paper: { title: "试卷文件", format: ["pdf"] },
-        paperConfirm: {
-          title: "试卷审核确认书文件",
-          format: ["jpg", "png"]
-        }
-      },
-      curConfig: {},
-      // import
-      uploadUrl: "/api/print/basic/sys/saveAttachment"
-    };
-  },
-  methods: {
-    visibleChange() {
-      this.$refs.UploadFileView.setAttachmentName(
-        `${this.paperAttachment.filename || ""}`
-      );
-      this.attachment = { ...this.paperAttachment };
-      this.curConfig = this.config[this.uploadType];
-    },
-    // upload-handler
-    uplaodError(errorData) {
-      this.$notify.error({
-        title: "错误提示",
-        message: errorData.message
-      });
-    },
-    uploadSuccess(res) {
-      this.$message.success("上传成功!");
-      let infos = {
-        attachmentId: res.data.id,
-        filename: `${res.data.name}${res.data.type}`
-      };
-      if (this.uploadType === "paper") infos.pages = res.data.pages;
-      this.attachment = Object.assign(this.attachment, infos);
-    },
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    },
-    confirm() {
-      this.$emit("confirm", this.attachment, this.uploadType);
-      this.cancel();
-    },
-    async toPreview() {
-      if (!this.attachment.attachmentId) {
-        this.$message.error("请先上传附件!");
-        return;
-      }
-      const data = await attachmentPreview(this.attachment.attachmentId);
-      window.open(data.path);
-    }
-  }
-};
-</script>
-
-<style lang="css" scoped>
-.file-upload-body {
-  min-height: 150px;
-}
-</style>

+ 0 - 154
src/modules/exam-center/components/UploadSamplePaperDialog.vue

@@ -1,154 +0,0 @@
-<template>
-  <el-dialog
-    class="upload-sample-paper-dialog"
-    :visible.sync="modalIsShow"
-    title="上传样卷或试卷结构文件"
-    top="10vh"
-    width="560px"
-    :close-on-click-modal="false"
-    :close-on-press-escape="false"
-    append-to-body
-    @opened="visibleChange"
-  >
-    <div class="file-upload-body">
-      <el-form
-        ref="ModalForm"
-        :model="modalForm"
-        :rules="rules"
-        label-width="90px"
-        label-position="left"
-      >
-        <el-form-item prop="title" label="文件标题:">
-          <el-input
-            style="width:386px"
-            v-model.trim="modalForm.title"
-            placeholder="请输入文件标题"
-          ></el-input>
-        </el-form-item>
-        <el-form-item prop="paperAttachmentId">
-          <upload-button
-            btn-icon="icon icon-upload"
-            btn-type="default"
-            btn-content="选择上传文件"
-            :upload-url="uploadUrl"
-            :format="format"
-            :max-size="maxSize"
-            :upload-data="uploadData"
-            @upload-error="uplaodError"
-            @upload-success="uploadSuccess"
-            style="margin: 0;"
-          ></upload-button>
-          <span style="margin-left: 10px;"
-            >上传的单个试卷文件大小不超过20M</span
-          >
-        </el-form-item>
-      </el-form>
-    </div>
-    <div slot="footer" style="text-align: right;">
-      <el-button type="primary" :disabled="isSubmit" @click="confirm"
-        >确定</el-button
-      >
-      <el-button @click="cancel">返回</el-button>
-    </div>
-  </el-dialog>
-</template>
-
-<script>
-import UploadButton from "@/components/UploadButton";
-import { createCard } from "../api";
-
-export default {
-  name: "upload-sample-paper-dialog",
-  props: {
-    data: {
-      type: Object,
-      default() {
-        return {};
-      }
-    }
-  },
-  components: { UploadButton },
-  data() {
-    return {
-      modalIsShow: false,
-      modalForm: {
-        title: "",
-        cardSource: "2",
-        courseName: "",
-        courseCode: "",
-        paperAttachmentId: ""
-      },
-      rules: {
-        title: [
-          {
-            required: true,
-            message: "请输入文件标题",
-            trigger: "change"
-          }
-        ],
-        paperAttachmentId: [
-          {
-            required: true,
-            message: "请上传样卷或试卷结构文件",
-            trigger: "change"
-          }
-        ]
-      },
-      isSubmit: false,
-      // upload
-      format: [],
-      uploadData: {
-        schoolId: this.$ls.get("schoolId"),
-        userId: this.$ls.get("user", { id: "" }).id
-      },
-      maxSize: 20 * 1024 * 1024,
-      uploadUrl: "/api/print/basic/sys/saveAttachment"
-    };
-  },
-  methods: {
-    visibleChange() {
-      this.modalForm.title = "";
-      this.modalForm.cardSource = this.data.cardSource;
-      this.modalForm.courseName = this.data.courseName;
-      this.modalForm.courseCode = this.data.courseCode;
-      this.modalForm.paperAttachmentId = "";
-    },
-    uplaodError(errorData) {
-      this.$notify.error({ title: "错误提示", message: errorData.message });
-    },
-    uploadSuccess(res) {
-      this.$message.success("上传成功!");
-      this.modalForm.paperAttachmentId = res.data.id;
-      this.$refs["ModalForm"].validateField("paperAttachmentId");
-    },
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    },
-    async confirm() {
-      const valid = await this.$refs["ModalForm"].validate().catch(() => {});
-      if (!valid) return;
-
-      if (this.isSubmit) return;
-      this.isSubmit = true;
-      const datas = {
-        tcPCard: this.modalForm
-      };
-      if (this.data.taskId && this.data.cardSource === "2") {
-        datas.tcPExamTaskDetail = this.data;
-        datas.tcPCard.enablePaperType = this.data.enablePaperType;
-      }
-
-      const res = await createCard(datas).catch(() => {});
-      this.isSubmit = false;
-      if (!res) return;
-
-      this.$message.success("申请成功!");
-      this.$emit("confirm");
-      this.cancel();
-    }
-  }
-};
-</script>

+ 0 - 145
src/modules/exam-center/router.js

@@ -1,145 +0,0 @@
-import WaitTask from "./views/WaitTask.vue";
-import WaitTaskDetail from "./views/WaitTaskDetail.vue";
-import CardAudit from "./views/CardAudit.vue";
-import PrintManage from "./views/PrintManage.vue";
-import DoneTask from "./views/DoneTask.vue";
-import DoneTaskDetail from "./views/DoneTaskDetail.vue";
-import ExamManage from "./views/ExamManage.vue";
-import ExamModify from "./views/ExamModify.vue";
-import ExamTaskDetail from "./views/ExamTaskDetail.vue";
-import ExamRoomDetail from "./views/ExamRoomDetail.vue";
-import ExamRoomStudentDetail from "./views/ExamRoomStudentDetail.vue";
-import CardManage from "./views/CardManage.vue";
-import ExamTaskAudit from "./views/ExamTaskAudit.vue";
-import ExamTaskAuditEdit from "./views/ExamTaskAuditEdit.vue";
-import TopicTaskManage from "./views/TopicTaskManage.vue";
-import TopicTaskModify from "./views/TopicTaskModify.vue";
-import TodoExam from "./views/TodoExam.vue";
-
-export default [
-  {
-    path: "/exam-center/done-task",
-    name: "DoneTask",
-    component: DoneTask
-  },
-  {
-    path: "/exam-center/done-task-detail/:taskId",
-    name: "DoneTaskDetail",
-    component: DoneTaskDetail,
-    meta: {
-      relate: "DoneTask/DoneTaskDetail"
-    }
-  },
-  {
-    path: "/exam-center/print-manage",
-    name: "PrintManage",
-    component: PrintManage
-  },
-  {
-    path: "/exam-center/exam-manage",
-    name: "ExamManage",
-    component: ExamManage
-  },
-  {
-    path: "/exam-center/exam-add",
-    name: "ExamAdd",
-    component: ExamModify,
-    meta: {
-      relate: "ExamManage/ExamAdd"
-    }
-  },
-  {
-    path: "/exam-center/exam-edit/:examId",
-    name: "ExamEdit",
-    component: ExamModify,
-    meta: {
-      relate: "ExamManage/ExamEdit"
-    }
-  },
-  {
-    path: "/exam-center/exam-task-detail/:examId?",
-    name: "ExamTaskDetail",
-    component: ExamTaskDetail,
-    meta: {
-      relate: "ExamManage/ExamTaskDetail"
-    }
-  },
-  {
-    path: "/exam-center/exam-room-detail/:examId?",
-    name: "ExamRoomDetail",
-    component: ExamRoomDetail,
-    meta: {
-      relate: "ExamManage/ExamRoomDetail"
-    }
-  },
-  {
-    path: "/exam-center/exam-room-student-detail/:examRoomInfo?",
-    name: "ExamRoomStudentDetail",
-    component: ExamRoomStudentDetail,
-    meta: {
-      relate: "ExamManage/ExamRoomDetail/ExamRoomStudentDetail"
-    }
-  },
-  {
-    path: "/exam-center/card-manage",
-    name: "CardManage",
-    component: CardManage
-  },
-  {
-    path: "/exam-center/card-audit",
-    name: "CardAudit",
-    component: CardAudit
-  },
-  {
-    path: "/exam-center/wait-task",
-    name: "WaitTask",
-    component: WaitTask
-  },
-  {
-    path: "/exam-center/wait-task-detail/:taskId",
-    name: "WaitTaskDetail",
-    component: WaitTaskDetail,
-    meta: {
-      relate: "WaitTask/WaitTaskDetail"
-    }
-  },
-  {
-    path: "/exam-center/exam-task-audit",
-    name: "ExamTaskAudit",
-    component: ExamTaskAudit
-  },
-  {
-    path: "/exam-center/exam-task-audit-edit/:taskId",
-    name: "ExamTaskAuditEdit",
-    component: ExamTaskAuditEdit,
-    meta: {
-      relate: "ExamTaskAudit/ExamTaskAuditEdit"
-    }
-  },
-  {
-    path: "/exam-center/topic-task-manage",
-    name: "TopicTaskManage",
-    component: TopicTaskManage
-  },
-  {
-    path: "/exam-center/topic-task-add",
-    name: "TopicTaskAdd",
-    component: TopicTaskModify,
-    meta: {
-      relate: "TopicTaskManage/TopicTaskAdd"
-    }
-  },
-  {
-    path: "/exam-center/topic-task-edit/:taskId",
-    name: "TopicTaskEdit",
-    component: TopicTaskModify,
-    meta: {
-      relate: "TopicTaskManage/TopicTaskEdit"
-    }
-  },
-  {
-    path: "/exam-center/todo-exam",
-    name: "TodoExam",
-    component: TodoExam
-  }
-];

+ 0 - 25
src/modules/exam-center/store.js

@@ -1,25 +0,0 @@
-import { waitTaskListCount } from "./api";
-
-const state = {
-  waitTaskCount: 0
-};
-
-const mutations = {
-  setNotDoneTaskCount(state, waitTaskCount) {
-    state.waitTaskCount = waitTaskCount;
-  }
-};
-
-const actions = {
-  async updateWaitTaskCount({ commit }) {
-    const count = await waitTaskListCount();
-    commit("setNotDoneTaskCount", count);
-  }
-};
-
-export default {
-  namespaced: true,
-  state,
-  mutations,
-  actions
-};

+ 0 - 254
src/modules/exam-center/views/CardAudit.vue

@@ -1,254 +0,0 @@
-<template>
-  <div class="card-check">
-    <div style="margin-bottom: 20px;">
-      <el-button
-        v-for="(val, key) in auditingStatus"
-        :key="key"
-        :type="key == filter.auditingStatus ? 'primary' : 'default'"
-        @click="selectAuditStatus(key)"
-        >{{ val }}</el-button
-      >
-    </div>
-    <div class="part-box part-box-filter">
-      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="学校名称:">
-          <el-select
-            v-model="filter.schId"
-            style="width: 142px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in schools"
-              :key="item.id"
-              :value="item.id"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <!-- <el-form-item label="学院:" v-if="filter.auditingStatus == 0">
-          <el-select
-            v-model="filter.collegeId"
-            style="width: 142px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in colleges"
-              :key="item.id"
-              :value="item.id"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item> -->
-        <el-form-item label="题卡ID:" label-width="70px">
-          <el-input
-            style="width: 210px;"
-            v-model.trim="filter.cardCode"
-            placeholder="请输入内容"
-            clearable
-          ></el-input>
-        </el-form-item>
-
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
-            >查询</el-button
-          >
-          <el-button
-            type="warning"
-            icon="icon icon-download"
-            @click="toDownloadAll"
-            v-if="filter.auditingStatus == 0"
-            >批量下载试卷文件</el-button
-          >
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <el-table ref="TableList" :data="cards" border stripe>
-        <el-table-column prop="schoolName" label="学校名称"></el-table-column>
-        <!-- <el-table-column prop="title" label="学院"></el-table-column> -->
-        <el-table-column prop="cardCode" label="题卡ID"></el-table-column>
-        <el-table-column prop="createTime" label="申请时间"></el-table-column>
-        <el-table-column prop="userName" label="申请人"></el-table-column>
-        <el-table-column prop="title" label="标题">
-          <template slot-scope="scope">
-            <p
-              v-if="filter.auditingStatus == 0"
-              class="cont-link"
-              @click="downloadPaper(scope.row)"
-              title="点击下载试卷文件"
-            >
-              {{ scope.row.title }}
-            </p>
-            <p v-else>{{ scope.row.title }}</p>
-          </template>
-        </el-table-column>
-        <el-table-column label="操作" align="center">
-          <template slot-scope="scope">
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-modify"
-              @click="toEdit(scope.row)"
-              title="设计题卡"
-              v-if="filter.auditingStatus == 0"
-            ></el-button>
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-circle-right"
-              @click="toPreview(scope.row)"
-              title="查看"
-              v-else
-            ></el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { AUDITING_STATUS } from "@/constants/enumerate";
-import { download } from "@/plugins/utils";
-import { auditListPage, schoolList } from "../api";
-
-export default {
-  name: "card-audit",
-  data() {
-    return {
-      filter: {
-        auditingStatus: "0",
-        cardCode: "",
-        schId: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      visible: false,
-      auditingStatus: {},
-      AUDITING_STATUS,
-      schools: [],
-      colleges: [],
-      cards: [],
-      curExam: {}
-    };
-  },
-  created() {
-    let auditingStatus = {};
-    Object.keys(AUDITING_STATUS)
-      .filter(key => key !== "9")
-      .map(key => {
-        auditingStatus[key] = AUDITING_STATUS[key];
-      });
-    this.auditingStatus = auditingStatus;
-    this.getList();
-    this.getSchoolList();
-  },
-  methods: {
-    async getSchoolList() {
-      this.schools = await schoolList();
-      this.filter.schId = this.$ls.get("schoolId");
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const data = await auditListPage(datas);
-      this.cards = data.records;
-      this.total = data.total;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    async downloadPaper(row) {
-      let load = this.$message({
-        iconClass: "el-message__icon el-icon-loading",
-        message: "Loading...",
-        duration: 0
-      });
-      const data = await download({
-        type: "get",
-        url: `/api/print/card/card/downloadSimplePaper?cardId=${row.cardId}`,
-        fileName: `${row.schoolName}_${row.cardId}${row.attachentType}`,
-        header: {
-          token: this.$ls.get("token")
-        }
-      }).catch(error => {
-        this.$message.error(error);
-      });
-
-      load.close();
-      if (!data) return;
-      this.$message.success("文件已开始下载!");
-    },
-    async toDownloadAll() {
-      let load = this.$message({
-        iconClass: "el-message__icon el-icon-loading",
-        message: "Loading...",
-        duration: 0
-      });
-
-      let filterNams = [AUDITING_STATUS[this.filter.auditingStatus]];
-      if (this.filter.cardCode) filterNams.push(this.filter.cardCode);
-      filterNams.push(`page-${this.current}.zip`);
-
-      const cardIds = this.cards.map(item => item.cardId).join(",");
-
-      const data = await download({
-        type: "get",
-        url: `/api/print/card/card/downloadPapers?cardIds=${cardIds}`,
-        fileName: filterNams.join("-"),
-        header: {
-          token: this.$ls.get("token")
-        }
-      }).catch(error => {
-        this.$message.error(error);
-      });
-
-      load.close();
-      if (!data) return;
-      this.$message.success("文件已开始下载!");
-    },
-    selectAuditStatus(val) {
-      this.filter.auditingStatus = val * 1;
-      this.toPage(1);
-    },
-    toEdit(row) {
-      this.$router.push({
-        name: "CardDesign",
-        params: {
-          cardId: row.cardId
-        }
-      });
-    },
-    toPreview(row) {
-      window.open(
-        this.getRouterPath({
-          name: "CardPreview",
-          params: {
-            cardId: row.cardId,
-            viewType: "view"
-          }
-        })
-      );
-    }
-  }
-};
-</script>

+ 0 - 391
src/modules/exam-center/views/CardManage.vue

@@ -1,391 +0,0 @@
-<template>
-  <div class="card-check">
-    <div class="part-box part-box-filter">
-      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="审核状态:">
-          <el-select
-            v-model="filter.auditingStatus"
-            style="width: 142px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="(val, key) in AUDITING_STATUS"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="打印时间:">
-          <el-date-picker
-            v-model="filter.printTime"
-            value-format="yyyy-MM-dd"
-            format="yyyy-MM-dd"
-            type="date"
-            placeholder="请选择日期"
-          >
-          </el-date-picker>
-        </el-form-item>
-        <el-form-item label="标题:" label-width="55px">
-          <el-input
-            style="width: 210px;"
-            v-model.trim="filter.title"
-            placeholder="请输入内容"
-            clearable
-          ></el-input>
-        </el-form-item>
-
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
-            >查询</el-button
-          >
-          <el-button type="warning" icon="icon icon-plus" @click="toAdd"
-            >创建题卡</el-button
-          >
-          <upload-button
-            btn-icon="icon icon-upload"
-            btn-type="default"
-            btn-content="导入题卡"
-            :upload-url="uploadUrl"
-            :format="['html']"
-            :upload-data="uploadData"
-            @upload-error="uplaodError"
-            @upload-success="uploadSuccess"
-            v-if="IS_ADMIN"
-          ></upload-button>
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <el-table
-        ref="TableList"
-        :data="cards"
-        :row-class-name="tableRowClassName"
-        border
-        stripe
-      >
-        <el-table-column prop="cardCode" label="题卡ID"></el-table-column>
-        <el-table-column label="科目名称(编码)">
-          <template slot-scope="scope">
-            <span
-              >{{ scope.row.courseName
-              }}<i v-if="scope.row.courseCode"
-                >({{ scope.row.courseCode }})</i
-              ></span
-            >
-          </template>
-        </el-table-column>
-        <el-table-column prop="title" label="标题"></el-table-column>
-        <el-table-column prop="printTime" label="打印时间"></el-table-column>
-        <el-table-column
-          prop="cardStatusName"
-          label="处理节点"
-        ></el-table-column>
-        <el-table-column prop="overTime" label="剩余时间"></el-table-column>
-        <el-table-column
-          prop="auditingTime"
-          label="提交审核时间"
-        ></el-table-column>
-        <el-table-column
-          prop="auditingStatusName"
-          label="审核状态"
-        ></el-table-column>
-        <el-table-column label="操作" align="center" width="120">
-          <template slot-scope="scope">
-            <div v-if="!scope.row.isImport">
-              <el-button
-                class="btn-table-icon"
-                type="text"
-                icon="icon icon-edit"
-                @click="toEdit(scope.row)"
-                title="编辑"
-                v-if="scope.row.cardStatus === 0"
-              ></el-button>
-              <el-button
-                class="btn-table-icon"
-                type="text"
-                icon="icon icon-delete"
-                @click="toDelete(scope.row)"
-                title="删除"
-                v-if="scope.row.cardStatus === 0"
-              ></el-button>
-              <el-button
-                class="btn-table-icon"
-                type="text"
-                icon="icon icon-copy"
-                @click="toCopy(scope.row)"
-                title="复制"
-                v-if="scope.row.auditingStatus !== 0"
-              ></el-button>
-            </div>
-            <div v-else>
-              <el-button
-                class="btn-table-icon"
-                type="text"
-                icon="icon icon-circle-right"
-                @click="toPreview(scope.row)"
-                title="预览"
-              ></el-button>
-              <el-button
-                class="btn-table-icon"
-                type="text"
-                icon="icon icon-copy"
-                @click="toCopyCommon(scope.row)"
-                title="复制"
-              ></el-button>
-            </div>
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-
-    <!-- card-option-dialog -->
-    <card-option-dialog
-      ref="CardOptionDialog"
-      @upload-sample-over="getList"
-      @confirm="cardConfirm"
-    ></card-option-dialog>
-  </div>
-</template>
-
-<script>
-import { AUDITING_STATUS } from "@/constants/enumerate";
-import {
-  cardListPage,
-  copyCard,
-  deleteCard,
-  changeCardStatus,
-  changeOperateStatus,
-  updateCardDetail
-} from "../api";
-import { cardConfigInfos, cardTempDetail } from "@/modules/card/api";
-import { transformField } from "@/modules/card/enumerate";
-import CardOptionDialog from "../components/CardOptionDialog";
-import UploadButton from "@/components/UploadButton";
-
-export default {
-  name: "card-manage",
-  components: {
-    CardOptionDialog,
-    UploadButton
-  },
-  data() {
-    return {
-      filter: {
-        title: "",
-        auditingStatus: "",
-        printTime: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      visible: false,
-      AUDITING_STATUS,
-      cards: [],
-      // import card
-      IS_ADMIN: false,
-      uploadData: {
-        schoolId: this.$ls.get("schoolId"),
-        userId: this.$ls.get("user", { id: "" }).id
-      },
-      uploadUrl: "/api/print/card/card/impHtml"
-    };
-  },
-  created() {
-    const cardFilter = this.$ls.get("cardFilter");
-    if (cardFilter) {
-      this.filter = this.$objAssign(this.filter, cardFilter);
-      this.current = cardFilter.pageNumber;
-    }
-
-    const roleCode = this.$ls.get("user", { roleCode: "" }).roleCode;
-    this.IS_ADMIN =
-      roleCode.includes("ADMIN") || roleCode.includes("SUPER_ADMIN");
-    this.getList();
-  },
-  methods: {
-    async getList() {
-      const datas = {
-        ...this.filter,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const data = await cardListPage(datas);
-      this.cards = data.records;
-      this.total = data.total;
-      this.$ls.set("cardFilter", datas);
-      // cardStatus '处理节点,0:设计题卡,1:提交印刷,2:已完成
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    tableRowClassName({ row }) {
-      return row.warning ? "row-danger" : "";
-    },
-    toAdd() {
-      this.$refs.CardOptionDialog.open();
-    },
-    cardConfirm() {
-      this.$router.push({
-        name: "CardDesign"
-      });
-    },
-    async toEdit(row) {
-      const result = await changeOperateStatus(row.id).catch(() => {});
-      if (!result) return;
-
-      this.$router.push({
-        name: "CardDesign",
-        params: {
-          cardId: row.id
-        }
-      });
-    },
-    toExport() {
-      // 暂时不做了
-    },
-    async toCopy(row) {
-      // 复制题卡
-      const cardInfo = await copyCard(row.id);
-      // 判断规则是否更新:获取最新规则,比对题卡规则判断规则是否更新
-      const tempData = await cardTempDetail(cardInfo.cardId);
-      const cont = JSON.parse(tempData.content);
-      const info = await cardConfigInfos();
-      const sysCardConfig = transformField(info);
-      const cardConfigIsChange = this.compareCardConfig(
-        sysCardConfig,
-        cont.cardConfig
-      );
-
-      if (cardConfigIsChange) {
-        // 更新题卡数据结构,主要是卡头数据
-        const newCardConfig = Object.assign({}, cont.cardConfig, sysCardConfig);
-        cont.pages.forEach((page, pindex) => {
-          // 奇数页
-          if (!(pindex % 2)) {
-            page.columns[0].elements[0] = Object.assign(
-              page.columns[0].elements[0],
-              newCardConfig
-            );
-          }
-        });
-        // 保存题卡数据结构
-        cont.cardConfig = newCardConfig;
-        const datas = {
-          id: cardInfo.cardDetailId,
-          content: JSON.stringify(cont)
-        };
-        await updateCardDetail(datas);
-
-        this.$alert(
-          "复制成功!题卡规则有变动,将默认应用当前最新规则,请仔细核实题卡板式!",
-          {
-            confirmButtonText: "确定",
-            customClass: "alert-message",
-            showClose: false
-          }
-        );
-      } else {
-        this.$message.success("复制成功!");
-      }
-
-      this.getList();
-    },
-    toPreview(row) {
-      window.open(
-        this.getRouterPath({
-          name: "CardPreview",
-          params: {
-            cardId: row.id,
-            viewType: "view"
-          }
-        })
-      );
-    },
-    async toCopyCommon(row) {
-      await copyCard(row.id);
-      this.$message.success("复制成功!");
-      this.getList();
-    },
-    compareCardConfig(sysConfig, curConfig) {
-      let isChange = false;
-      Object.keys(sysConfig).forEach(key => {
-        let isSame = true;
-        if (key === "schoolName") {
-          isSame = true;
-        } else if (key === "businessParams" || key === "noticeHead") {
-          isSame =
-            JSON.stringify(sysConfig[key]) === JSON.stringify(curConfig[key]);
-        } else {
-          isSame = sysConfig[key] === curConfig[key];
-        }
-        console.log(`${key}:${isSame}`);
-        isChange = isChange || !isSame;
-      });
-      return isChange;
-    },
-    toPrint(row) {
-      this.$confirm(
-        "一旦准备印刷,题卡将不可再编辑,确定要提交印刷吗?",
-        "警告",
-        {
-          cancelButtonClass: "el-button--danger is-plain",
-          confirmButtonClass: "el-button--primary",
-          type: "warning"
-        }
-      )
-        .then(async () => {
-          await changeCardStatus({
-            cardId: row.id,
-            cardStatus: 1
-          });
-          this.getList();
-          this.$message.success("提交成功!");
-        })
-        .catch(() => {});
-    },
-    toDelete(row) {
-      this.$confirm("确定要删除当前题卡吗?", "删除警告", {
-        cancelButtonClass: "el-button--danger is-plain",
-        confirmButtonClass: "el-button--primary",
-        type: "warning"
-      })
-        .then(async () => {
-          await deleteCard(row.id);
-          this.$message.success("删除成功!");
-          // 解决最后一项删除后的问题
-          this.deletePageLastItem();
-        })
-        .catch(() => {});
-    },
-    // import card
-    uplaodError(errorData) {
-      this.$notify.error({ title: "错误提示", message: errorData.message });
-    },
-    uploadSuccess(res) {
-      this.$message.success("上传成功!");
-      this.getList();
-    }
-  },
-  beforeRouteLeave(to, from, next) {
-    if (to.name !== "CardDesign") {
-      this.$destroy();
-    }
-    next();
-  }
-};
-</script>

+ 0 - 134
src/modules/exam-center/views/DoneTask.vue

@@ -1,134 +0,0 @@
-<template>
-  <div class="done-task">
-    <div class="part-box part-box-filter">
-      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="考试名称:">
-          <el-select
-            v-model="filter.examId"
-            style="width: 315px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in exams"
-              :key="item.id"
-              :value="item.id"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
-            >查询</el-button
-          >
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <el-table ref="TableList" :data="tasks" border stripe>
-        <el-table-column prop="examCode" label="考试ID"></el-table-column>
-        <el-table-column prop="examName" label="考试名称"></el-table-column>
-        <el-table-column prop="courseNameCode" label="科目名称(编码)">
-        </el-table-column>
-        <el-table-column prop="paperStatus" label="试卷"></el-table-column>
-        <el-table-column prop="cardStatus" label="答题卡"></el-table-column>
-        <el-table-column prop="createTime" label="创建时间"></el-table-column>
-        <el-table-column prop="printStatus" label="打印状态"></el-table-column>
-        <el-table-column prop="cancelStatus" label="撤回状态"></el-table-column>
-        <el-table-column label="操作" align="center">
-          <template slot-scope="scope">
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-circle-right"
-              @click="toDetail(scope.row)"
-              title="详情"
-            ></el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { doneTaskListPage, examList } from "../api";
-
-export default {
-  name: "done-task",
-  data() {
-    return {
-      isInit: false,
-      filter: {
-        examId: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      visible: false,
-      exams: [],
-      tasks: []
-    };
-  },
-  created() {
-    this.init();
-  },
-  methods: {
-    init() {
-      this.getExamList();
-      this.getList();
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const result = await doneTaskListPage(datas);
-      const data = result || { records: [], total: 0 };
-      this.tasks = data.records;
-      this.total = data.total;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    async getExamList() {
-      const data = await examList();
-      this.exams = data.map(item => {
-        return {
-          id: item.id,
-          name: item.examName
-        };
-      });
-    },
-    toDetail(row) {
-      this.$router.push({
-        name: "DoneTaskDetail",
-        params: {
-          taskId: row.id
-        }
-      });
-    }
-  },
-  activated() {
-    if (this.isInit) {
-      this.toPage(this.current);
-    } else {
-      this.isInit = true;
-    }
-  }
-};
-</script>

+ 0 - 157
src/modules/exam-center/views/DoneTaskDetail.vue

@@ -1,157 +0,0 @@
-<template>
-  <div class="done-task-detail task-detail">
-    <div class="task-title">
-      <h2>
-        <span>考试名称: {{ task.examName }} </span>
-        <span>科目名称:{{ task.courseNameCode }}</span>
-      </h2>
-    </div>
-    <div class="task-body">
-      <table class="table">
-        <tr>
-          <th>试卷类型</th>
-          <th v-if="task.examPaper">试卷文件</th>
-          <th v-if="task.examPaper">试卷审核确认书</th>
-          <th v-if="task.answerSheet">答题卡</th>
-          <!-- <th>标答</th>
-          <th>试卷结构</th> -->
-        </tr>
-        <tr
-          v-for="(attachment, index) in paperAttachments"
-          :key="attachment.id"
-        >
-          <td>{{ attachment.name }}卷</td>
-          <td class="td-link" v-if="task.examPaper">
-            <span @click="downloadPaper(attachment)" title="点击下载试卷">
-              <i class="icon icon-download-act"></i>{{ attachment.filename }}
-            </span>
-          </td>
-          <td
-            class="td-link"
-            :rowspan="pTypeEnable ? paperAttachments.length : 1"
-            v-if="index === 0 && task.examPaper"
-          >
-            <span @click="downloadPaperConfirm" title="点击下载确认书文件">
-              <i class="icon icon-download-act"></i
-              >{{ paperConfirmAttachmentId.filename }}
-            </span>
-          </td>
-          <td
-            class="td-link"
-            :rowspan="pTypeEnable ? paperAttachments.length : 1"
-            v-if="index === 0 && task.answerSheet"
-          >
-            <span @click="toPreviewCard" title="点击预览答题卡内容">{{
-              task.cardName
-            }}</span>
-          </td>
-          <!-- <td class="td-link">
-            <span @click="downloadStdAns(attachment)"
-              ><i class="icon icon-download-act"></i
-              >{{ attachment.name }}卷标答下载</span
-            >
-          </td>
-          <td
-            class="td-link"
-            :rowspan="pTypeEnable ? paperAttachments.length : 1"
-            v-if="index === 0"
-          >
-            <span @click="downloadPaperStructure">
-              <i class="icon icon-download-act"></i>试卷结构下载
-            </span>
-          </td> -->
-        </tr>
-      </table>
-
-      <div class="task-action">
-        <el-button type="danger" @click="toRevoke" style="width:88px;"
-          >撤回</el-button
-        >
-        <el-button @click="goback" style="width:88px;">返回</el-button>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { doneTaskDetail, revokeDoneTask } from "../api";
-import { attachmentPreview } from "../../login/api";
-
-export default {
-  name: "done-task-detail",
-  data() {
-    return {
-      taskId: this.$route.params.taskId,
-      task: {},
-      pTypeEnable: false,
-      paperConfirmAttachmentId: {},
-      paperAttachments: [],
-      curAttachment: {}
-    };
-  },
-  mounted() {
-    this.getData();
-  },
-  methods: {
-    async getData() {
-      const data = await doneTaskDetail(this.taskId);
-      const nameCode = data.courseNameCode.split(/\(|\)/);
-      this.task = Object.assign(this.task, data, {
-        courseName: nameCode[0],
-        courseCode: nameCode[1]
-      });
-      this.pTypeEnable = this.task.enablePaperType.split(",").length > 1;
-      this.parsePaperAttachment();
-      this.paperConfirmAttachmentId = this.task.paperConfirmAttachmentId
-        ? JSON.parse(this.task.paperConfirmAttachmentId)
-        : { attachmentId: "", filename: "" };
-    },
-    parsePaperAttachment() {
-      const paperAttachment =
-        this.task.paperAttachmentId && JSON.parse(this.task.paperAttachmentId);
-      if (!paperAttachment) return;
-
-      this.paperAttachments = paperAttachment.paper;
-    },
-    toRevoke() {
-      this.$confirm("确定要撤回当前任务吗?", "提示", {
-        cancelButtonClass: "el-button--danger is-plain",
-        confirmButtonClass: "el-button--primary",
-        type: "warning"
-      }).then(async () => {
-        await revokeDoneTask(this.task);
-        this.goback();
-      });
-    },
-    async downloadPaper(attachment) {
-      const data = await attachmentPreview(attachment.attachmentId);
-      window.open(data.path);
-    },
-    async downloadPaperConfirm() {
-      if (!this.paperConfirmAttachmentId.attachmentId) return;
-      const data = await attachmentPreview(
-        this.paperConfirmAttachmentId.attachmentId
-      );
-      window.open(data.path);
-    },
-    toPreviewCard() {
-      window.open(
-        this.getRouterPath({
-          name: "CardPreview",
-          params: {
-            cardId: this.task.cardId,
-            viewType: "view"
-          }
-        })
-      );
-    },
-    downloadStdAns(attachment) {
-      // TODO:
-      window.open(attachment.path);
-    },
-    downloadPaperStructure() {
-      // TODO:
-    }
-  }
-};
-</script>

+ 0 - 338
src/modules/exam-center/views/ExamManage.vue

@@ -1,338 +0,0 @@
-<template>
-  <div class="exam-manage">
-    <div class="part-box part-box-filter">
-      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="考试名称:">
-          <el-select
-            v-model="filter.examId"
-            style="width: 193px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in exams"
-              :key="item.id"
-              :value="item.id"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="打印状态:">
-          <el-select
-            v-model="filter.printStatus"
-            style="width: 140px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in PRINT_STATUS"
-              :key="item.key"
-              :value="item.key"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-          <el-popover
-            class="tips-icon"
-            placement="bottom-start"
-            width="350"
-            trigger="hover"
-          >
-            <p>未开始:所有命题任务都未有暂存动作和提交动作。</p>
-            <p>命题中:有部分命题任务已提交或已暂存。</p>
-            <p>待打印:所有命题任务均已提交,等待打印员打印。</p>
-            <p>打印中:正在打印中。</p>
-            <p>已打印:打印完成。</p>
-            <i class="el-icon-question" slot="reference"></i>
-          </el-popover>
-        </el-form-item>
-        <el-form-item label="打印时间:">
-          <el-date-picker
-            v-model="filter.printTime"
-            value-format="yyyy-MM-dd"
-            format="yyyy-MM-dd"
-            type="date"
-            placeholder="请选择日期"
-          >
-          </el-date-picker>
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
-            >查询</el-button
-          >
-          <el-button type="warning" icon="icon icon-plus" @click="toAdd"
-            >新建考试</el-button
-          >
-          <el-button
-            type="warning"
-            icon="icon icon-download"
-            @click="toExportPackageData"
-            >导出卷袋贴条码核对数据</el-button
-          >
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <el-table
-        ref="TableList"
-        :data="examPages"
-        :row-class-name="tableRowClassName"
-        border
-        stripe
-      >
-        <el-table-column prop="examCode" label="考试ID"></el-table-column>
-        <el-table-column prop="examName" label="考试名称"></el-table-column>
-        <el-table-column prop="beginTime" label="开始时间"></el-table-column>
-        <el-table-column prop="printTime" label="打印时间"></el-table-column>
-        <el-table-column prop="name" label="创建人"></el-table-column>
-        <el-table-column prop="createTime" label="创建时间"></el-table-column>
-        <el-table-column prop="printStatus" label="打印状态"></el-table-column>
-        <el-table-column prop="endTime" label="完成时间"></el-table-column>
-        <el-table-column label="操作" align="center" width="185">
-          <template slot-scope="scope">
-            <!-- <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-modify"
-              @click="toTaskDetail(scope.row)"
-              title="任务详情"
-            ></el-button> -->
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-edit"
-              @click="toEdit(scope.row)"
-              title="任务详情"
-            ></el-button>
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-delete"
-              @click="toDelete(scope.row)"
-              title="删除"
-            ></el-button>
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-download-act"
-              @click="toExport(scope.row)"
-              title="导出打印数量"
-              v-if="scope.row.printStatus === '已打印'"
-            ></el-button>
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-circle-share"
-              @click="toExportPaper(scope.row)"
-              title="导出试卷数量统计"
-              v-if="
-                IS_SUPER_ADMIN &&
-                  (scope.row.printStatus === '待打印' ||
-                    scope.row.printStatus === '打印中' ||
-                    scope.row.printStatus === '已打印')
-              "
-            ></el-button>
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-circle-right"
-              @click="toDetail(scope.row)"
-              title="考场详情"
-            ></el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { PRINT_STATUS } from "@/constants/enumerate";
-import { examListPage, examList, deleteExam } from "../api";
-import { download } from "@/plugins/utils";
-
-export default {
-  name: "exam-manage",
-  data() {
-    return {
-      isInit: false,
-      filter: {
-        examId: "",
-        printStatus: "",
-        printTime: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      visible: false,
-      PRINT_STATUS,
-      exams: [],
-      examPages: [],
-      IS_SUPER_ADMIN: false
-    };
-  },
-  created() {
-    this.init();
-  },
-  methods: {
-    init() {
-      const roleCode = this.$ls.get("user", { roleCode: "" }).roleCode;
-      this.IS_SUPER_ADMIN = roleCode.includes("SUPER_ADMIN");
-      this.getList();
-      this.getExamList();
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const data = await examListPage(datas);
-      this.examPages = data.records;
-      this.total = data.total;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    tableRowClassName({ row }) {
-      return row.warning ? "row-danger" : "";
-    },
-    async getExamList() {
-      const data = await examList();
-      this.exams = data.map(item => {
-        return {
-          id: item.id,
-          name: item.examName
-        };
-      });
-    },
-    toDelete(row) {
-      const msg = row.isConfirm
-        ? "当前已有命题老师上传试卷或答题卡,确定要删除此条考试任务吗?"
-        : "确定要删除此条考试任务吗?";
-      this.$confirm(msg, "提示", {
-        cancelButtonClass: "el-button--danger is-plain",
-        confirmButtonClass: "el-button--primary",
-        type: "warning"
-      }).then(async () => {
-        await deleteExam(row.id);
-        this.$message.success("删除成功!");
-        this.deletePageLastItem();
-      });
-    },
-    toAdd() {
-      this.$router.push({
-        name: "ExamAdd"
-      });
-    },
-    toEdit(row) {
-      this.$router.push({
-        name: "ExamEdit",
-        params: {
-          examId: row.id
-        }
-      });
-    },
-    // toTaskDetail(row) {
-    //   console.log(row);
-    //   this.$router.push({
-    //     name: "ExamTaskDetail",
-    //     params: {
-    //       examId: row.id
-    //     }
-    //   });
-    // },
-    async toExport(row) {
-      let load = this.$message({
-        iconClass: "el-message__icon el-icon-loading",
-        message: "Loading...",
-        duration: 0
-      });
-      const data = await download({
-        type: "get",
-        // url: `/api/print/exam/exam/expPrintCount?examId=1267628105772736513`,
-        url: `/api/print/exam/exam/expPrintCount?examId=${row.id}`,
-        fileName: `${row.examName}_打印数量.xls`,
-        header: {
-          token: this.$ls.get("token")
-        }
-      }).catch(error => {
-        this.$message.error(error);
-      });
-
-      load.close();
-      if (!data) return;
-      this.$message.success("文件已开始下载!");
-    },
-    async toExportPaper(row) {
-      let load = this.$message({
-        iconClass: "el-message__icon el-icon-loading",
-        message: "Loading...",
-        duration: 0
-      });
-      const data = await download({
-        type: "get",
-        url: `/api/print/exam/exam/expPrePrintCount?examId=${row.id}`,
-        fileName: `${row.examName}_试卷数量统计.xls`,
-        header: {
-          token: this.$ls.get("token")
-        }
-      }).catch(error => {
-        this.$message.error(error);
-      });
-
-      load.close();
-      if (!data) return;
-      this.$message.success("文件已开始下载!");
-    },
-    async toExportPackageData() {
-      let load = this.$message({
-        iconClass: "el-message__icon el-icon-loading",
-        message: "Loading...",
-        duration: 0
-      });
-      const data = await download({
-        type: "get",
-        url: "/api/print/exam/exam/expPaperCodeCheckData",
-        fileName: `卷袋贴条码核对数据.xls`,
-        header: {
-          token: this.$ls.get("token")
-        }
-      }).catch(error => {
-        this.$message.error(error);
-      });
-
-      load.close();
-      if (!data) return;
-      this.$message.success("文件已开始下载!");
-    },
-    toDetail(row) {
-      this.$router.push({
-        name: "ExamRoomDetail",
-        params: {
-          examId: row.id
-        }
-      });
-    }
-  },
-  activated() {
-    if (this.isInit) {
-      this.toPage(this.current);
-    } else {
-      this.isInit = true;
-    }
-  }
-};
-</script>

+ 0 - 484
src/modules/exam-center/views/ExamModify.vue

@@ -1,484 +0,0 @@
-<template>
-  <div class="exam-modify part-box part-box-border part-box-pad">
-    <el-form
-      ref="ModalForm"
-      :model="modalForm"
-      :rules="rules"
-      label-width="180px"
-      style="min-width:800px;"
-    >
-      <el-form-item prop="examName" label="考试名称:">
-        <el-input
-          style="width: 439px;"
-          v-model.trim="modalForm.examName"
-          placeholder="请输入考试名称"
-          clearable
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="examPlanCodeTemp" label="考试计划表:">
-        <upload-file-view
-          :upload-url="uploadExamPlanUrl"
-          :upload-data="uploadExamPlanData"
-          :disabled="!canEdit"
-          @upload-error="uplaodError"
-          @upload-success="uploadExamPlanSuccess"
-          ref="ExamPlanUploadFileView"
-        ></upload-file-view>
-        <el-button @click="toPreviewExamPlan" style="margin-left:16px;"
-          >预览</el-button
-        >
-        <el-button
-          type="warning"
-          icon="icon icon-download"
-          style="margin-left:10px;"
-        >
-          <a :href="planDownloadUrl" download="考试计划导入模板.xlsx"
-            >考试计划导入模板下载</a
-          >
-        </el-button>
-      </el-form-item>
-      <el-form-item label="考务编排文件:">
-        <upload-file-view
-          :upload-url="uploadExamBusinessUrl"
-          :upload-data="uploadData"
-          :disabled="!modalForm.examPlanAttachmentId"
-          @upload-error="uplaodError"
-          @upload-success="uploadExamBusinessSuccess"
-          ref="ExamBusinessUploadFileView"
-        ></upload-file-view>
-        <el-button @click="toPreviewExamBusiness" style="margin-left:16px;"
-          >预览</el-button
-        >
-        <el-button
-          type="warning"
-          icon="icon icon-download"
-          style="margin-left:10px;"
-        >
-          <a :href="businessDownloadUrl" download="考务编排导入模板.xlsx"
-            >考务编排导入模板下载</a
-          >
-        </el-button>
-      </el-form-item>
-      <el-form-item prop="beginTime" label="考试开始时间:">
-        <el-date-picker
-          v-model="modalForm.beginTime"
-          type="datetime"
-          value-format="yyyy-MM-dd HH:mm:ss"
-          placeholder="请选择时间"
-        >
-        </el-date-picker>
-      </el-form-item>
-      <el-form-item prop="printTime" label="打印时间:">
-        <el-date-picker
-          v-model="modalForm.printTime"
-          type="datetime"
-          value-format="yyyy-MM-dd HH:mm:ss"
-          placeholder="请选择时间"
-        >
-        </el-date-picker>
-      </el-form-item>
-      <el-form-item prop="printContent" label="打印内容:">
-        <el-checkbox
-          v-model="printContentCheckAll"
-          @change="handleCheckAllChange"
-          >全选</el-checkbox
-        >
-        <el-checkbox-group
-          v-model="modalForm.printContent"
-          @change="handleCheckedChange"
-        >
-          <el-checkbox
-            v-for="(val, key) in PRINT_CONTENT_TYPE"
-            :label="key"
-            :key="key"
-            >{{ val }}</el-checkbox
-          >
-        </el-checkbox-group>
-      </el-form-item>
-      <el-form-item
-        prop="review"
-        label="试卷内容是否复核:"
-        v-if="printContentIncludeExamPaper"
-      >
-        <el-radio-group v-model="modalForm.review">
-          <el-radio
-            v-for="(val, key) in BOOLEAN_TYPE"
-            :key="key"
-            :label="key * 1"
-            >{{ val }}</el-radio
-          >
-        </el-radio-group>
-      </el-form-item>
-      <el-form-item prop="backup" label="备用方式:">
-        <el-radio-group v-model="modalForm.backup">
-          <el-radio
-            v-for="(val, key) in RESERVE_TYPE"
-            :key="key"
-            :label="key * 1"
-            >{{ val }}</el-radio
-          >
-        </el-radio-group>
-        <el-popover
-          class="tips-icon"
-          placement="top-start"
-          width="300"
-          trigger="hover"
-        >
-          <p>
-            考试任务备用方式:按照整个考试任务为一个基础单位进行备份的方式;<br />考场备用方式:按照一个考场为一个基础单位进行备份的方式。
-          </p>
-          <i class="el-icon-question" slot="reference"></i>
-        </el-popover>
-      </el-form-item>
-      <el-form-item prop="backupCard" label="备用各科试卷题卡份数:">
-        <el-input-number
-          style="width:220px;"
-          v-model="modalForm.backupCard"
-          :min="1"
-          :max="999"
-          :step="1"
-          step-strictly
-          :controls="false"
-        ></el-input-number>
-        <el-popover
-          class="tips-icon"
-          placement="top-start"
-          width="300"
-          trigger="hover"
-        >
-          <p>
-            此处将根据备份方式的不同设置每个科目的试卷及题卡备份份数。
-          </p>
-          <i class="el-icon-question" slot="reference"></i>
-        </el-popover>
-      </el-form-item>
-      <el-form-item prop="teacher" label="指派命题老师:">
-        <el-table
-          class="el-table--noback"
-          :data="courses"
-          style="width: 420px;"
-          border
-        >
-          <el-table-column prop="courseName" label="科目">
-            <span slot-scope="scope">
-              {{ scope.row.courseName }}({{ scope.row.courseCode }})
-            </span>
-          </el-table-column>
-          <el-table-column label="命题老师" width="180px">
-            <template slot-scope="scope">
-              <el-select
-                v-model="scope.row.teacherId"
-                size="small"
-                style="width: 156px;"
-                placeholder="请选择"
-                :disabled="!scope.row.canEdit"
-              >
-                <el-option
-                  v-for="user in scope.row.users"
-                  :key="user.id"
-                  :value="user.id"
-                  :label="user.name"
-                ></el-option>
-              </el-select>
-            </template>
-          </el-table-column>
-          <el-table-column prop="status" label="状态"></el-table-column>
-        </el-table>
-      </el-form-item>
-
-      <el-form-item>
-        <el-button type="primary" :disabled="isSubmit" @click="save"
-          >保存</el-button
-        >
-        <el-button @click="goback">返回</el-button>
-      </el-form-item>
-    </el-form>
-
-    <!-- business-data -->
-    <business-data
-      :exam-code="modalForm.examCodeTemp"
-      ref="BusinessData"
-    ></business-data>
-    <!-- exam-plan -->
-    <exam-plan-data :datas="courses" ref="ExamPlanData"></exam-plan-data>
-  </div>
-</template>
-
-<script>
-import {
-  RESERVE_TYPE,
-  BOOLEAN_TYPE,
-  PRINT_CONTENT_TYPE
-} from "@/constants/enumerate";
-import { uploadExam, examDetail } from "../api";
-import BusinessData from "../components/BusinessData";
-import ExamPlanData from "../components/ExamPlanData";
-import UploadFileView from "@/components/UploadFileView";
-
-export default {
-  name: "exam-modify",
-  components: { BusinessData, ExamPlanData, UploadFileView },
-  data() {
-    const printTimeValidator = (rule, value, callback) => {
-      if (!this.checkDateRangeValid(value, this.modalForm.beginTime)) {
-        callback(new Error("打印时间不能为空,且不得晚于考试开始时间"));
-      } else {
-        callback();
-      }
-    };
-    const teacherValidator = (rule, value, callback) => {
-      if (!this.checkTeacherSelected()) {
-        callback(new Error("请选择各科目的命题老师"));
-      } else {
-        callback();
-      }
-    };
-    const printContentValidator = (rule, value, callback) => {
-      if (!value.length) {
-        callback(new Error("请选择打印内容"));
-      } else if (
-        !value.includes("examPaper") &&
-        !value.includes("answerSheet")
-      ) {
-        callback(new Error("试卷和答题卡必须选择一个"));
-      } else {
-        callback();
-      }
-    };
-
-    return {
-      examId: this.$route.params.examId,
-      modalForm: {
-        id: null,
-        examName: "",
-        beginTime: "",
-        printTime: "",
-        printContent: [],
-        backup: 0,
-        review: 0,
-        backupCard: "",
-        examPlanCodeTemp: "",
-        examPlanAttachmentId: "",
-        examCodeTemp: "",
-        attachmentId: ""
-      },
-      rules: {
-        examName: [
-          {
-            required: true,
-            message: "请输入考试名称",
-            trigger: "change"
-          }
-        ],
-        examPlanCodeTemp: [
-          {
-            required: true,
-            message: "请上传考试计划表",
-            trigger: "change"
-          }
-        ],
-        beginTime: [
-          {
-            required: true,
-            message: "请选择考试开始时间",
-            trigger: "change"
-          }
-        ],
-        printTime: [
-          {
-            required: true,
-            validator: printTimeValidator,
-            trigger: "change"
-          }
-        ],
-        backup: [
-          {
-            required: true,
-            message: "请选择备用方式",
-            trigger: "change"
-          }
-        ],
-        review: [
-          {
-            required: true,
-            message: "请选择是否复核",
-            trigger: "change"
-          }
-        ],
-        backupCard: [
-          {
-            required: true,
-            message: "请输入备用各科试卷题卡份数",
-            trigger: "change"
-          }
-        ],
-        printContent: [
-          {
-            required: true,
-            validator: printContentValidator
-          }
-        ],
-        teacher: [
-          {
-            required: true,
-            validator: teacherValidator
-          }
-        ]
-      },
-      RESERVE_TYPE,
-      BOOLEAN_TYPE,
-      PRINT_CONTENT_TYPE,
-      printContentAll: Object.keys(PRINT_CONTENT_TYPE),
-      printContentCheckAll: false,
-      courses: [],
-      isSubmit: false,
-      canEdit: true,
-      planDownloadUrl: this.GLOBAL.domain + "/temps/考试计划导入模板.xlsx",
-      businessDownloadUrl: this.GLOBAL.domain + "/temps/考务编排导入模板.xlsx",
-      // import
-      uploadExamPlanUrl: "/api/print/exam/exam/impExamPlanData",
-      uploadExamBusinessUrl: "/api/print/exam/exam/impExamData",
-      uploadExamPlanData: {
-        examId: ""
-      },
-      uploadData: {
-        examId: "",
-        examPlanCodeTemp: ""
-      }
-    };
-  },
-  computed: {
-    isEdit() {
-      return !!this.examId;
-    },
-    printContentIncludeExamPaper() {
-      return this.modalForm.printContent.includes("examPaper");
-    }
-  },
-  mounted() {
-    if (this.isEdit) {
-      this.getExamDetail();
-      this.uploadData.examId = this.examId;
-      this.uploadExamPlanData.examId = this.examId;
-    }
-  },
-  methods: {
-    async getExamDetail() {
-      const data = await examDetail(this.examId);
-      this.modalForm = this.$objAssign(this.modalForm, data.tcPExam);
-      this.modalForm.printContent = this.printContentAll.filter(
-        key => data.tcPExam[key]
-      );
-      this.courses = data.userCourses.map(item => {
-        item.canEdit = item.status === "未开始";
-        return item;
-      });
-      this.canEdit = !this.courses.some(item => !item.canEdit);
-      this.handleCheckedChange();
-      this.$refs.ExamPlanUploadFileView.setAttachmentName(
-        `${data.tcPPlanAttachment.name}${data.tcPPlanAttachment.type}`
-      );
-      if (
-        data.tcPAttachment &&
-        data.tcPAttachment["name"] &&
-        data.tcPAttachment["type"]
-      )
-        this.$refs.ExamBusinessUploadFileView.setAttachmentName(
-          `${data.tcPAttachment.name}${data.tcPAttachment.type}`
-        );
-      this.uploadData.examPlanCodeTemp = this.modalForm.examPlanCodeTemp;
-    },
-    checkDateRangeValid(startTime, endTime) {
-      if (startTime && endTime) {
-        var st = new Date(startTime.replace(/-/g, "/")).getTime();
-        var et = new Date(endTime.replace(/-/g, "/")).getTime();
-
-        return st < et;
-      }
-      return;
-    },
-    checkTeacherSelected() {
-      return !this.courses.some(course => !course.teacherId);
-    },
-    handleCheckAllChange(val) {
-      this.modalForm.printContent = val ? this.printContentAll : [];
-    },
-    handleCheckedChange() {
-      this.printContentCheckAll =
-        this.modalForm.printContent.length === this.printContentAll.length;
-    },
-    async save() {
-      const valid = await this.$refs["ModalForm"].validate().catch(() => {});
-      if (!valid) return;
-
-      if (this.isSubmit) return;
-      this.isSubmit = true;
-      let tcPExam = {
-        ...this.modalForm
-      };
-      delete tcPExam.printContent;
-      this.printContentAll.map(key => {
-        tcPExam[key] = this.modalForm.printContent.includes(key) ? 1 : 0;
-      });
-
-      const datas = {
-        tcPExam,
-        tcPExamCourseUsers: this.courses.map(course => {
-          return {
-            courseName: course.courseName,
-            courseCode: course.courseCode,
-            userId: course.teacherId
-          };
-        })
-      };
-      const data = await uploadExam(datas).catch(() => {});
-      this.isSubmit = false;
-      if (!data) return;
-      this.$message.success("保存成功!");
-      this.goback();
-    },
-    toPreviewExamPlan() {
-      if (!this.modalForm.examPlanCodeTemp) {
-        this.$message.error("请先上传考试计划表!");
-        return;
-      }
-      this.$refs.ExamPlanData.open();
-    },
-    toPreviewExamBusiness() {
-      if (!this.modalForm.examCodeTemp) {
-        this.$message.error("请先上传考试计划表!");
-        return;
-      }
-      this.$refs.BusinessData.open();
-    },
-    // upload-handler
-    uplaodError(errorData) {
-      this.$notify.error({ title: "错误提示", message: errorData.message });
-    },
-    uploadExamPlanSuccess(res) {
-      this.$message.success("上传成功!");
-      const data = res.data;
-
-      this.modalForm.examPlanCodeTemp = data.examPlanCodeTemp;
-      this.uploadData.examPlanCodeTemp = data.examPlanCodeTemp;
-      this.modalForm.examPlanAttachmentId = data.attachmentId;
-      this.$refs["ModalForm"].validateField("examPlanCodeTemp");
-
-      this.courses = data.userCourses.map(item => {
-        item.canEdit = item.status === "未开始";
-        item.teacherId = item.users.length === 1 ? item.users[0].id + "" : "";
-        return item;
-      });
-      this.canEdit = !this.courses.some(item => !item.canEdit);
-    },
-    uploadExamBusinessSuccess(res) {
-      this.$message.success("上传成功!");
-      const data = res.data;
-
-      this.modalForm.examCodeTemp = data.examCode;
-      this.modalForm.attachmentId = data.attachmentId;
-      this.$refs["ModalForm"].validateField("examCodeTemp");
-    }
-  }
-};
-</script>

+ 0 - 207
src/modules/exam-center/views/ExamRoomDetail.vue

@@ -1,207 +0,0 @@
-<template>
-  <div class="exam-room-detail">
-    <div class="part-box part-box-filter">
-      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="考试名称:">
-          <el-select
-            v-model="filter.examId"
-            style="width: 193px;"
-            placeholder="请选择"
-            @change="examChange"
-            @clear="examChange"
-            clearable
-          >
-            <el-option
-              v-for="item in exams"
-              :key="item.code"
-              :value="item.code"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="场次ID:" label-width="75px">
-          <el-select
-            v-model="filter.sceneNumberId"
-            style="width: 193px;"
-            placeholder="请选择"
-            @change="sceneChange"
-            @clear="sceneChange"
-            clearable
-          >
-            <el-option
-              v-for="item in scenes"
-              :key="item.code"
-              :value="item.code"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="考点:" label-width="55px">
-          <el-select
-            v-model="filter.examSite"
-            style="width: 193px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in sites"
-              :key="item.code"
-              :value="item.code"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
-            >查询</el-button
-          >
-          <el-button @click="goback">返回</el-button>
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <el-table ref="TableList" :data="examPages" border stripe>
-        <el-table-column prop="sceneNumberId" label="场次ID"></el-table-column>
-        <el-table-column
-          prop="startTime"
-          label="场次开始时间"
-        ></el-table-column>
-        <el-table-column prop="endTime" label="场次结束时间"></el-table-column>
-        <el-table-column prop="examSite" label="考点名称"></el-table-column>
-        <el-table-column prop="examRoom" label="考场名称"></el-table-column>
-        <el-table-column
-          prop="courseCodeAndName"
-          label="科目名称(编码)"
-        ></el-table-column>
-        <el-table-column prop="examTotal" label="应考科次"></el-table-column>
-        <el-table-column label="操作" align="center">
-          <template slot-scope="scope">
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-circle-right"
-              @click="toDetail(scope.row)"
-              title="详情"
-            ></el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { examRoomDetail, examSiteRoomList } from "../api";
-
-export default {
-  name: "exam-room-detail",
-  data() {
-    return {
-      isInit: false,
-      filter: {
-        examId: this.$route.params.examId,
-        examSite: "",
-        sceneNumberId: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      visible: false,
-      exams: [],
-      scenes: [],
-      sites: [],
-      examPages: []
-    };
-  },
-  created() {
-    this.init();
-  },
-  methods: {
-    init() {
-      this.getList();
-      this.getExamSiteRoomList();
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const data = await examRoomDetail(datas);
-      this.examPages = data.records;
-      this.total = data.total;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    async getExamSiteRoomList() {
-      this.exams = await examSiteRoomList();
-      this.examChange();
-    },
-    examChange() {
-      const curExam = this.exams.find(exam => exam.code === this.filter.examId);
-      if (!curExam) return;
-      this.scenes = curExam.sceneNumbers;
-      this.filter.sceneNumberId = "";
-      this.sites = [];
-      this.filter.examSite = "";
-    },
-    sceneChange() {
-      const curScene = this.scenes.find(
-        scene => scene.code === this.filter.sceneNumberId
-      );
-      if (!curScene) return;
-      this.sites = curScene.examSites;
-      this.filter.examSite = "";
-    },
-    toDetail(row) {
-      this.$router.push({
-        name: "ExamRoomStudentDetail",
-        params: {
-          examRoomInfo: `${row.examId}-${row.sceneNumberId}-${row.examSite}-${row.examRoomId}`
-        }
-      });
-    }
-  },
-  activated() {
-    if (this.isInit) {
-      this.toPage(this.current);
-    } else {
-      this.isInit = true;
-    }
-  },
-  beforeRouteEnter(to, from, next) {
-    if (from.name === "ExamRoomStudentDetail") {
-      next(vm => {
-        vm.$store.commit("setRestoreKeepAliveRoutes");
-        vm.toPage(vm.current);
-      });
-    } else {
-      next();
-    }
-  },
-  beforeRouteLeave(to, from, next) {
-    console.log(to.name);
-    if (to.name === "ExamRoomStudentDetail") {
-      this.$store.commit("setRestoreKeepAliveRoutes");
-      this.$store.commit("addKeepAliveRouteItem", "exam-room-detail");
-    } else {
-      this.$store.commit("removeKeepAliveRouteItem", "exam-room-detail");
-    }
-    next();
-  }
-};
-</script>

+ 0 - 245
src/modules/exam-center/views/ExamRoomStudentDetail.vue

@@ -1,245 +0,0 @@
-<template>
-  <div class="exam-room-detail">
-    <div class="part-box part-box-filter">
-      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="考试名称:">
-          <el-select
-            v-model="filter.examId"
-            style="width: 193px;"
-            placeholder="请选择"
-            @change="examChange"
-            @clear="examChange"
-            clearable
-          >
-            <el-option
-              v-for="item in exams"
-              :key="item.code"
-              :value="item.code"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="场次ID:" label-width="75px">
-          <el-select
-            v-model="filter.sceneNumberId"
-            style="width: 193px;"
-            placeholder="请选择"
-            @change="sceneChange"
-            @clear="sceneChange"
-            clearable
-          >
-            <el-option
-              v-for="item in scenes"
-              :key="item.code"
-              :value="item.code"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="考点:" label-width="55px">
-          <el-select
-            v-model="filter.examSite"
-            style="width: 193px;"
-            placeholder="请选择"
-            @change="siteChange"
-            @clear="siteChange"
-            clearable
-          >
-            <el-option
-              v-for="item in sites"
-              :key="item.code"
-              :value="item.code"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="考场:" label-width="55px">
-          <el-select
-            v-model="filter.examRoomId"
-            style="width: 193px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in rooms"
-              :key="item.code"
-              :value="item.code"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="学号:" label-width="55px">
-          <el-input
-            v-model="filter.studentCode"
-            placeholder="请输入"
-            style="width: 193px;"
-            clearable
-          ></el-input>
-          <!-- <el-select
-            v-model="filter.studentCode"
-            style="width: 193px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in students"
-              :key="item.id"
-              :value="item.id"
-              :label="item.name"
-            ></el-option>
-          </el-select> -->
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
-            >查询</el-button
-          >
-          <el-button @click="goback">返回</el-button>
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <el-table ref="TableList" :data="studentList" border stripe>
-        <el-table-column
-          prop="sceneNumberId"
-          label="场次ID"
-          width="80"
-        ></el-table-column>
-        <el-table-column prop="examSite" label="考点名称"></el-table-column>
-        <el-table-column prop="examName" label="考试名称"></el-table-column>
-        <el-table-column prop="examRoom" label="考场名称"></el-table-column>
-        <el-table-column
-          prop="courseNameCode"
-          label="科目名称(编码)"
-          min-width="100"
-        >
-        </el-table-column>
-        <el-table-column prop="examNumber" label="考号"></el-table-column>
-        <el-table-column prop="name" label="姓名"></el-table-column>
-        <el-table-column prop="studentCode" label="学号"></el-table-column>
-        <el-table-column
-          prop="gender"
-          label="性别"
-          width="60"
-        ></el-table-column>
-        <el-table-column prop="classNo" label="教学班号"></el-table-column>
-        <el-table-column prop="siteNumber" label="座位号"></el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { studentDetail, examSiteRoomList } from "../api";
-
-export default {
-  name: "exam-room-student-detail",
-  data() {
-    return {
-      filter: {
-        examId: "",
-        sceneNumberId: "",
-        examSite: "",
-        examRoomId: "",
-        studentCode: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      visible: false,
-      exams: [],
-      scenes: [],
-      sites: [],
-      rooms: [],
-      studentList: []
-    };
-  },
-  created() {
-    this.init();
-  },
-  methods: {
-    async init() {
-      const examRoomInfo = this.$route.params.examRoomInfo;
-      if (!examRoomInfo) return;
-
-      const [examId, sceneNumberId, examSite, examRoomId] = examRoomInfo.split(
-        "-"
-      );
-
-      // review selected
-      await this.getExamSiteRoomList();
-      this.filter.examId = examId;
-      this.examChange();
-      this.filter.sceneNumberId = sceneNumberId;
-      this.sceneChange();
-      this.filter.examSite = examSite;
-      this.siteChange();
-      this.filter.examRoomId = examRoomId;
-
-      this.getList();
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const data = await studentDetail(datas);
-      this.studentList = data.records;
-      this.total = data.total;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    async getExamSiteRoomList() {
-      this.exams = await examSiteRoomList();
-    },
-    examChange() {
-      const curExam = this.exams.find(exam => exam.code === this.filter.examId);
-      if (!curExam) return;
-      this.scenes = curExam.sceneNumbers;
-      this.filter.sceneNumberId = "";
-      this.sites = [];
-      this.filter.examSite = "";
-      this.rooms = [];
-      this.filter.examRoomId = "";
-    },
-    sceneChange() {
-      const curScene = this.scenes.find(
-        scene => scene.code === this.filter.sceneNumberId
-      );
-      if (!curScene) return;
-      this.sites = curScene.examSites;
-      this.filter.examSite = "";
-      this.rooms = [];
-      this.filter.examRoomId = "";
-    },
-    siteChange() {
-      const curSite = this.sites.find(
-        site => site.code === this.filter.examSite
-      );
-      if (!curSite) return;
-      this.rooms = curSite.examRooms;
-      this.filter.examRoomId = "";
-    }
-  },
-  beforeRouteLeave(to, from, next) {
-    if (to.name === "ExamRoomDetail") {
-      this.$store.commit("setRestoreKeepAliveRoutes");
-    }
-    next();
-  }
-};
-</script>

+ 0 - 173
src/modules/exam-center/views/ExamTaskAudit.vue

@@ -1,173 +0,0 @@
-<template>
-  <div class="exam-task-audit">
-    <div class="part-box part-box-filter">
-      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="考试名称:">
-          <el-select
-            v-model="filter.examId"
-            style="width: 193px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in exams"
-              :key="item.id"
-              :value="item.id"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="审核状态:">
-          <el-select
-            v-model="filter.status"
-            style="width: 142px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="(val, key) in AUDITING_STATUS"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
-            >查询</el-button
-          >
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <el-table
-        ref="TableList"
-        :data="dataList"
-        :row-class-name="tableRowClassName"
-        border
-        stripe
-      >
-        <el-table-column prop="examCode" label="考试ID"></el-table-column>
-        <el-table-column prop="examName" label="考试名称"></el-table-column>
-        <el-table-column prop="courseNameCode" label="科目名称(编码)">
-        </el-table-column>
-        <el-table-column prop="paperStatus" label="试卷"></el-table-column>
-        <el-table-column prop="cardStatus" label="答题卡"></el-table-column>
-        <el-table-column prop="endTime" label="任务截止日期"></el-table-column>
-        <el-table-column prop="overTime" label="剩余时间"></el-table-column>
-        <el-table-column prop="auditStatus" label="审核状态"></el-table-column>
-        <el-table-column label="操作" align="center" width="120">
-          <template slot-scope="scope">
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-edit"
-              @click="toDetail(scope.row)"
-              title="审核"
-              v-if="scope.row.auditStatus === '未审核'"
-            ></el-button>
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-circle-right"
-              @click="toDetail(scope.row)"
-              title="详情"
-              v-else
-            ></el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { examTaskListPage, examList } from "../api";
-
-export default {
-  name: "exam-task-audit",
-  data() {
-    return {
-      isInit: false,
-      filter: {
-        status: "",
-        examId: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      AUDITING_STATUS: { 0: "未审核", 1: "已审核" },
-      exams: [],
-      dataList: [
-        {
-          id: "111",
-          taskId: "1"
-        }
-      ]
-    };
-  },
-  mounted() {
-    this.init();
-  },
-  methods: {
-    init() {
-      this.getList();
-      this.getExamList();
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const data = await examTaskListPage(datas);
-      this.dataList = data.records;
-      this.total = data.total;
-      // cardStatus '处理节点,0:设计题卡,1:提交印刷,2:已完成
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    tableRowClassName({ row }) {
-      return row.warning ? "row-danger" : "";
-    },
-    async getExamList() {
-      const data = await examList();
-      this.exams = data.map(item => {
-        return {
-          id: item.id,
-          name: item.examName
-        };
-      });
-    },
-    toDetail(row) {
-      this.$router.push({
-        name: "ExamTaskAuditEdit",
-        params: {
-          taskId: row.id
-        }
-      });
-    }
-  },
-  activated() {
-    if (this.isInit) {
-      this.toPage(this.current);
-    } else {
-      this.isInit = true;
-    }
-  }
-};
-</script>

+ 0 - 214
src/modules/exam-center/views/ExamTaskAuditEdit.vue

@@ -1,214 +0,0 @@
-<template>
-  <div class="exam-task-audit-edit task-detail">
-    <div class="task-title">
-      <h2>
-        <span>考试名称: {{ task.examName }} </span>
-        <span>科目名称:{{ task.courseName }}</span>
-      </h2>
-    </div>
-    <div class="task-body">
-      <table class="table">
-        <tr>
-          <th>试卷类型</th>
-          <th v-if="task.examPaper">试卷文件</th>
-          <th v-if="task.examPaper">试卷审核确认书</th>
-          <th v-if="task.answerSheet">答题卡</th>
-        </tr>
-        <tr v-for="(attachment, index) in paperAttachments" :key="index">
-          <td>{{ attachment.name }}卷</td>
-          <td class="td-link" v-if="task.examPaper">
-            <span @click="downloadPaper(attachment)" title="点击下载试卷">
-              <i class="icon icon-download-act"></i>{{ attachment.filename }}
-            </span>
-          </td>
-          <td
-            class="td-link"
-            :rowspan="pTypeEnable ? paperAttachments.length : 1"
-            v-if="index === 0 && task.examPaper"
-          >
-            <span @click="downloadPaperConfirm" title="点击下载确认书文件">
-              <i class="icon icon-download-act"></i
-              >{{ paperConfirmAttachmentId.filename }}
-            </span>
-          </td>
-          <td
-            class="td-link"
-            :rowspan="pTypeEnable ? paperAttachments.length : 1"
-            v-if="index === 0 && task.answerSheet"
-          >
-            <span @click="toPreviewCard" title="点击预览答题卡内容">{{
-              task.cardName
-            }}</span>
-          </td>
-        </tr>
-      </table>
-
-      <!-- task-form -->
-      <el-form
-        ref="ModalForm"
-        :model="modalForm"
-        :rules="rules"
-        label-width="180px"
-        style="min-width:800px;"
-      >
-        <el-form-item prop="status" label="审核结果:">
-          <el-radio-group v-model="modalForm.status" :disabled="hasAudited">
-            <el-radio
-              v-for="item in AUDIT_TYPE"
-              :key="item.key"
-              :label="item.key"
-              >{{ item.name }}</el-radio
-            >
-          </el-radio-group>
-        </el-form-item>
-        <el-form-item
-          prop="remark"
-          label="审核意见:"
-          v-if="modalForm.status === 2"
-        >
-          <el-input
-            type="textarea"
-            style="width: 439px;"
-            v-model.trim="modalForm.remark"
-            :disabled="hasAudited"
-            :maxlength="200"
-            :rows="5"
-            show-word-limit
-            placeholder="请输入审核意见"
-            clearable
-          ></el-input>
-        </el-form-item>
-        <el-form-item>
-          <el-button
-            type="primary"
-            :disabled="isSubmit"
-            @click="save"
-            v-if="!hasAudited"
-            >提交</el-button
-          >
-          <el-button @click="goback">{{
-            hasAudited ? "返回" : "取消"
-          }}</el-button>
-        </el-form-item>
-      </el-form>
-    </div>
-  </div>
-</template>
-
-<script>
-import { waitTaskDetail, auditExamTask } from "../api";
-import { attachmentPreview } from "../../login/api";
-
-export default {
-  name: "exam-task-audit-edit",
-  data() {
-    return {
-      taskId: this.$route.params.taskId,
-      task: {},
-      pTypeEnable: false,
-      paperConfirmAttachmentId: {},
-      paperAttachments: [],
-      curAttachment: {},
-      isSubmit: false,
-      hasAudited: false,
-      AUDIT_TYPE: [
-        {
-          key: 1,
-          name: "通过"
-        },
-        {
-          key: 2,
-          name: "不通过"
-        }
-      ],
-      modalForm: { status: 1, remark: "" },
-      rules: {
-        status: [
-          {
-            required: true,
-            message: "请选择审核结果",
-            trigger: "change"
-          }
-        ],
-        remark: [
-          {
-            required: true,
-            message: "请输入审核意见",
-            trigger: "change"
-          }
-        ]
-      }
-    };
-  },
-  mounted() {
-    this.getData();
-  },
-  methods: {
-    async getData() {
-      const data = await waitTaskDetail(this.taskId);
-      const nameCode = data.courseNameCode.split(/\(|\)/);
-      this.task = Object.assign(this.task, data, {
-        courseName: nameCode[0],
-        courseCode: nameCode[1]
-      });
-      this.pTypeEnable = this.task.enablePaperType.split(",").length > 1;
-      this.parsePaperAttachment();
-      this.paperConfirmAttachmentId = this.task.paperConfirmAttachmentId
-        ? JSON.parse(this.task.paperConfirmAttachmentId)
-        : { attachmentId: "", filename: "" };
-      this.hasAudited = this.task.auditStatus !== 0;
-      this.modalForm = {
-        status: this.hasAudited ? data.auditStatus : 1,
-        remark: data.remark
-      };
-    },
-    parsePaperAttachment() {
-      const paperAttachment =
-        this.task.paperAttachmentId && JSON.parse(this.task.paperAttachmentId);
-      if (!paperAttachment) return;
-
-      this.paperAttachments = paperAttachment.paper;
-    },
-    async downloadPaper(attachment) {
-      const data = await attachmentPreview(attachment.attachmentId);
-      window.open(data.path);
-    },
-    async downloadPaperConfirm() {
-      if (!this.paperConfirmAttachmentId.attachmentId) return;
-      const data = await attachmentPreview(
-        this.paperConfirmAttachmentId.attachmentId
-      );
-      window.open(data.path);
-    },
-    toPreviewCard() {
-      window.open(
-        this.getRouterPath({
-          name: "CardPreview",
-          params: {
-            cardId: this.task.cardId,
-            viewType: "view"
-          }
-        })
-      );
-    },
-    async save() {
-      const valid = await this.$refs["ModalForm"].validate().catch(() => {});
-      if (!valid) return;
-
-      if (this.isSubmit) return;
-      this.isSubmit = true;
-      const datas = {
-        ...this.modalForm,
-        taskId: this.taskId,
-        examId: this.task.examId
-      };
-      const result = await auditExamTask(datas).catch(() => {});
-      this.isSubmit = false;
-      if (!result) return;
-
-      this.$message.success("审核成功!");
-      this.goback();
-    }
-  }
-};
-</script>

+ 0 - 50
src/modules/exam-center/views/ExamTaskDetail.vue

@@ -1,50 +0,0 @@
-<template>
-  <div class="exam-task-detail task-detail">
-    <div class="task-title">
-      <h2>
-        <span>考试名称:{{ examInfo.examName }}</span>
-        <span>考试开始时间:{{ examInfo.beginTime }}</span>
-        <span>考试打印时间:{{ examInfo.printTime }}</span>
-      </h2>
-      <div class="task-title-infos">
-        <el-button @click="goback">返回</el-button>
-      </div>
-    </div>
-
-    <div class="task-body">
-      <el-table :data="dataList" border stripe>
-        <el-table-column prop="courseName" label="科目名称"></el-table-column>
-        <el-table-column prop="name" label="命题老师"></el-table-column>
-        <el-table-column prop="status" label="状态"></el-table-column>
-      </el-table>
-    </div>
-  </div>
-</template>
-
-<script>
-import { examTaskDetail } from "../api";
-
-export default {
-  name: "exam-task-detail",
-  data() {
-    return {
-      examId: this.$route.params.examId,
-      dataList: [],
-      examInfo: {}
-    };
-  },
-  created() {
-    this.init();
-  },
-  methods: {
-    init() {
-      this.getData();
-    },
-    async getData() {
-      const data = await examTaskDetail(this.examId);
-      this.dataList = data.list;
-      this.examInfo = data.tcPExam;
-    }
-  }
-};
-</script>

+ 0 - 184
src/modules/exam-center/views/PrintManage.vue

@@ -1,184 +0,0 @@
-<template>
-  <div class="exam-manage">
-    <div class="part-box part-box-filter">
-      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="考试名称:">
-          <el-select
-            v-model="filter.examId"
-            style="width: 193px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in exams"
-              :key="item.id"
-              :value="item.id"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="打印时间:">
-          <el-date-picker
-            v-model="filter.printTime"
-            value-format="yyyy-MM-dd"
-            format="yyyy-MM-dd"
-            type="date"
-            placeholder="请选择日期"
-          >
-          </el-date-picker>
-        </el-form-item>
-        <el-form-item label="撤回申请:">
-          <el-select
-            v-model="filter.revokeStatus"
-            style="width: 142px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="(val, key) in REVOKE_STATUS"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
-            >查询</el-button
-          >
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <el-table ref="TableList" :data="dataList" border stripe>
-        <el-table-column prop="examCode" label="考试ID"></el-table-column>
-        <el-table-column prop="examName" label="考试名称"></el-table-column>
-        <el-table-column prop="totalCourse" label="总科次"></el-table-column>
-        <el-table-column prop="printTime" label="打印时间"></el-table-column>
-        <el-table-column prop="printProgress" label="打印进度">
-          <template slot-scope="scope">{{ scope.row.printProgress }}%</template>
-        </el-table-column>
-        <el-table-column
-          prop="revokeStatusName"
-          label="撤回申请"
-        ></el-table-column>
-        <el-table-column label="操作" align="center" v-if="!IS_PRINTER">
-          <template slot-scope="scope">
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-confirm"
-              @click="toConfirm(scope.row)"
-              title="确认"
-              v-if="scope.row.revokeStatus === '0'"
-            ></el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { REVOKE_STATUS } from "@/constants/enumerate";
-import { printTaskListPage, examList, printRevokeAudit } from "../api";
-
-export default {
-  name: "print-manage",
-  data() {
-    return {
-      filter: {
-        examId: "",
-        revokeStatus: "",
-        printTime: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      visible: false,
-      REVOKE_STATUS,
-      exams: [],
-      dataList: [],
-      IS_PRINTER: false,
-      loopRunning: false,
-      loopSetTs: []
-    };
-  },
-  created() {
-    this.init();
-  },
-  methods: {
-    init() {
-      this.IS_PRINTER = this.$ls
-        .get("user", { roleCode: "" })
-        .roleCode.includes("PRINT");
-      this.getExamList();
-      this.loopRunning = true;
-      this.timerUpdatePage();
-    },
-    clearLoopSetTs() {
-      if (!this.loopSetTs.length) return;
-      this.loopSetTs.forEach(sett => {
-        clearTimeout(sett);
-      });
-      this.loopSetTs = [];
-    },
-    async timerUpdatePage() {
-      this.clearLoopSetTs();
-      if (!this.loopRunning) return;
-
-      await this.getList().catch(() => {});
-
-      this.loopSetTs.push(
-        setTimeout(() => {
-          this.timerUpdatePage();
-        }, 30 * 1000)
-      );
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const data = await printTaskListPage(datas);
-      this.dataList = data.records;
-      this.total = data.total;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    async getExamList() {
-      const data = await examList();
-      this.exams = data.map(item => {
-        return {
-          id: item.id,
-          name: item.examName
-        };
-      });
-    },
-    async toConfirm(row) {
-      await printRevokeAudit(row.id);
-      this.$message.success("确认成功!");
-      this.getList();
-    }
-  },
-  beforeDestroy() {
-    this.loopRunning = false;
-    this.clearLoopSetTs();
-  }
-};
-</script>

+ 0 - 140
src/modules/exam-center/views/TodoExam.vue

@@ -1,140 +0,0 @@
-<template>
-  <div class="todo-exam">
-    <div class="part-box part-box-filter">
-      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="考试名称:">
-          <el-select
-            v-model="filter.examId"
-            style="width: 193px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in exams"
-              :key="item.id"
-              :value="item.id"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="icon icon-search" @click="toPage(1)">
-            查询
-          </el-button>
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <el-table
-        ref="TableList"
-        :data="dataList"
-        :row-class-name="tableRowClassName"
-        border
-        stripe
-      >
-        <el-table-column prop="examCode" label="考试ID"></el-table-column>
-        <el-table-column prop="examName" label="考试名称"></el-table-column>
-        <el-table-column
-          prop="printTime"
-          label="任务截止日期"
-          min-width="100"
-        ></el-table-column>
-        <el-table-column
-          prop="overTime"
-          label="剩余时间"
-          min-width="100"
-        ></el-table-column>
-        <el-table-column
-          prop="createTime"
-          label="接收时间"
-          min-width="100"
-        ></el-table-column>
-        <el-table-column
-          label="操作"
-          align="center"
-          width="120"
-          class-name="tb-action-column"
-        >
-          <template slot-scope="scope">
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-edit"
-              @click="toEdit(scope.row)"
-              title="编辑"
-            ></el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-    </div>
-  </div>
-</template>
-
-<script>
-import { examList, todoExamList } from "../api";
-
-export default {
-  name: "todo-exam",
-  data() {
-    return {
-      isInit: false,
-      filter: {
-        examId: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      exams: [],
-      dataList: []
-    };
-  },
-  mounted() {
-    this.getExamList();
-    this.getList();
-  },
-  methods: {
-    async getList() {
-      const datas = {
-        ...this.filter,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const data = await todoExamList(datas);
-      this.dataList = data.records;
-      this.total = data.total;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    async getExamList() {
-      const data = await examList();
-      this.exams = data.map(item => {
-        return {
-          id: item.id,
-          name: item.examName
-        };
-      });
-    },
-    tableRowClassName({ row }) {
-      return row.warning ? "row-danger" : "";
-    },
-    toEdit(row) {
-      this.$router.push({
-        name: "ExamEdit",
-        params: {
-          examId: row.id
-        }
-      });
-    }
-  },
-  activated() {
-    if (this.isInit) {
-      this.toPage(this.current);
-    } else {
-      this.isInit = true;
-    }
-  }
-};
-</script>

+ 0 - 331
src/modules/exam-center/views/TopicTaskManage.vue

@@ -1,331 +0,0 @@
-<template>
-  <div class="exam-task-manage">
-    <div class="part-box part-box-filter">
-      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="考试名称:">
-          <el-select
-            v-model="filter.examId"
-            style="width: 193px;"
-            placeholder="请选择"
-            @change="examChange"
-            clearable
-          >
-            <el-option
-              v-for="item in exams"
-              :key="item.id"
-              :value="item.id"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="科目(代码):" label-width="110px">
-          <el-select
-            v-model="filter.courseCode"
-            style="width: 193px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in courses"
-              :key="item.courseCode"
-              :value="item.courseCode"
-              :label="item.courseName"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="状态:" label-width="60px">
-          <el-select
-            v-model="filter.status"
-            style="width: 142px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="(val, key) in TASK_TYPES"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="提交印刷:">
-          <el-select
-            v-model="filter.printStatus"
-            style="width: 142px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="(val, key) in BOOLEAN_TYPE"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="启用:" label-width="60px">
-          <el-select
-            v-model="filter.enable"
-            style="width: 142px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="(val, key) in BOOLEAN_TYPE"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="打印起始时间:" label-width="110px">
-          <el-date-picker
-            v-model="printTime"
-            type="daterange"
-            @change="printTimeChange"
-            range-separator="至"
-            start-placeholder="开始日期"
-            end-placeholder="结束日期"
-            value-format="yyyy-MM-dd"
-            format="yyyy-MM-dd"
-          >
-          </el-date-picker>
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="icon icon-search" @click="toPage(1)">
-            查询
-          </el-button>
-          <el-button type="warning" icon="icon icon-plus" @click="toAdd">
-            新增命题任务
-          </el-button>
-        </el-form-item>
-      </el-form>
-    </div>
-    <div class="part-box">
-      <el-table ref="TableList" :data="dataList" border stripe>
-        <el-table-column prop="examCode" label="考试ID"></el-table-column>
-        <el-table-column prop="examName" label="考试名称"></el-table-column>
-        <el-table-column prop="courseNameCode" label="科目名称(编码)">
-        </el-table-column>
-        <el-table-column
-          prop="questionTeacherName"
-          label="命题老师"
-        ></el-table-column>
-        <el-table-column
-          prop="printTime"
-          label="打印时间"
-          min-width="100"
-        ></el-table-column>
-        <el-table-column
-          prop="beginTime"
-          label="考试时间"
-          min-width="160"
-        ></el-table-column>
-        <el-table-column prop="status" label="状态">
-          <span slot-scope="scope">
-            {{ TASK_TYPES[scope.row.status] }}
-          </span>
-        </el-table-column>
-        <el-table-column prop="printStatus" label="提交印刷">
-          <span slot-scope="scope">
-            {{ BOOLEAN_TYPE[scope.row.printStatus] }}
-          </span>
-        </el-table-column>
-        <el-table-column prop="enable" label="是否启用">
-          <span
-            :class="{ 'color-danger': !scope.row.enable }"
-            slot-scope="scope"
-            >{{ BOOLEAN_TYPE[scope.row.enable] }}</span
-          >
-        </el-table-column>
-        <el-table-column
-          label="操作"
-          align="center"
-          width="120"
-          class-name="tb-action-column"
-        >
-          <template slot-scope="scope">
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              :icon="
-                scope.row.enable
-                  ? 'icon icon-circle-stop'
-                  : 'icon icon-circle-caret-right'
-              "
-              @click="toEnable(scope.row)"
-              :title="scope.row.enable ? '取消' : '启用'"
-              v-if="!scope.row.printStatus"
-            ></el-button>
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-edit"
-              @click="toEdit(scope.row)"
-              v-if="scope.row.status === 0 || scope.row.status === 1"
-              title="编辑"
-            ></el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { BOOLEAN_TYPE } from "@/constants/enumerate";
-import {
-  topicTaskListPage,
-  examList,
-  examCourseList,
-  eableTopicTask
-} from "../api";
-
-export default {
-  name: "topic-task-manage",
-  data() {
-    return {
-      isInit: false,
-      filter: {
-        examId: "",
-        courseCode: "",
-        status: "",
-        printStatus: null,
-        enable: null,
-        printStartTime: "",
-        printEndTime: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      BOOLEAN_TYPE,
-      TASK_TYPES: {
-        0: "未开始",
-        1: "进行中",
-        2: "待审核",
-        3: "已完成"
-      },
-      printTime: "",
-      exams: [],
-      courses: [],
-      dataList: []
-    };
-  },
-  mounted() {
-    this.getExamList();
-    this.getList();
-  },
-  methods: {
-    async getList() {
-      const datas = {
-        ...this.filter,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const data = await topicTaskListPage(datas);
-      this.dataList = data.records;
-      this.total = data.total;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    async getExamList() {
-      const data = await examList();
-      this.exams = data.map(item => {
-        return {
-          id: item.id,
-          name: item.examName
-        };
-      });
-    },
-    async getCourses() {
-      if (!this.filter.examId) return;
-      this.courses = await examCourseList(this.filter.examId);
-    },
-    examChange() {
-      this.filter.courseCode = "";
-      this.courses = [];
-      this.getCourses();
-    },
-    printTimeChange(vals) {
-      const dvals = vals || [];
-      this.filter.printStartTime = dvals[0] || null;
-      this.filter.printEndTime = dvals[1] || null;
-    },
-    toAdd() {
-      this.$router.push({ name: "TopicTaskAdd" });
-    },
-    toEnable(row) {
-      if (row.enable) {
-        const h = this.$createElement;
-        const tips = [
-          "命题老师无法查看到该任务的待办。",
-          "若试卷正在审核,则无法继续审核流程,审核界面也无法查看到该命题任务。",
-          "若试卷已经绑定了题卡,则会取消题卡绑定,但题卡仍可以在题卡管理里查看到,可与其它命题任务重新进行绑定。",
-          "被取消的命题任务不会发送印刷。",
-          "任务的数据系统和流程进度系统仍然保留。"
-        ];
-        let msgs = tips.map((item, index) =>
-          h("p", null, `${index + 1}、${item}`)
-        );
-        msgs.unshift(h("p", null, "任务取消后,会有如下影响:"));
-        msgs.push(
-          h(
-            "p",
-            { style: "margin-top: 20px;color: rgba(254, 108, 105, 1)" },
-            "确定要取消当前任务吗?"
-          )
-        );
-        this.$msgbox({
-          title: "操作警告",
-          message: h("div", { style: "text-align: left" }, msgs),
-          cancelButtonClass: "el-button--danger is-plain",
-          confirmButtonClass: "el-button--primary",
-          showCancelButton: true
-        })
-          .then(async () => {
-            this.enableTask(row);
-          })
-          .catch(() => {});
-      } else {
-        this.enableTask(row);
-      }
-    },
-    async enableTask(row) {
-      const enable = Number(!row.enable);
-      await eableTopicTask({
-        taskId: row.taskId,
-        enable
-      });
-      row.enable = enable;
-    },
-    toEdit(row) {
-      this.$router.push({
-        name: "TopicTaskEdit",
-        params: {
-          taskId: row.taskId
-        }
-      });
-    }
-  },
-  activated() {
-    if (this.isInit) {
-      this.toPage(this.current);
-    } else {
-      this.isInit = true;
-    }
-  }
-};
-</script>

+ 0 - 227
src/modules/exam-center/views/TopicTaskModify.vue

@@ -1,227 +0,0 @@
-<template>
-  <div class="topic-task-modify part-box part-box-border part-box-pad">
-    <el-form
-      ref="ModalForm"
-      :model="modalForm"
-      :rules="rules"
-      label-width="180px"
-      style="min-width:800px;"
-    >
-      <el-form-item prop="examId" label="考试名称:">
-        <el-select
-          v-model="modalForm.examId"
-          style="width: 439px;"
-          placeholder="请选择"
-          @change="examChange"
-          clearable
-          v-if="!isEdit"
-        >
-          <el-option
-            v-for="item in exams"
-            :key="item.id"
-            :value="item.id"
-            :label="item.name"
-          ></el-option>
-        </el-select>
-        <el-input
-          v-model.trim="modalForm.examName"
-          style="width: 439px;"
-          readonly
-          v-else
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="courseCode" label="科目:">
-        <el-select
-          v-model="modalForm.courseCode"
-          style="width: 439px;"
-          placeholder="请选择"
-          @change="courseChange"
-          clearable
-          filterable
-          v-if="!isEdit"
-        >
-          <el-option
-            v-for="item in courses"
-            :key="item.courseCode"
-            :value="item.courseCode"
-            :label="item.label"
-          ></el-option>
-        </el-select>
-        <el-input
-          v-model.trim="modalForm.courseName"
-          style="width: 439px;"
-          readonly
-          v-else
-        ></el-input>
-      </el-form-item>
-      <el-form-item label="考试开始时间:">
-        <el-input
-          v-model.trim="modalForm.beginTime"
-          style="width: 439px;"
-          readonly
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="questionTeacherId" label="命题老师:">
-        <el-select
-          v-model="modalForm.questionTeacherId"
-          style="width: 439px;"
-          placeholder="请选择"
-          clearable
-        >
-          <el-option
-            v-for="item in teachers"
-            :key="item.id"
-            :value="item.id"
-            :label="item.name"
-          ></el-option>
-        </el-select>
-      </el-form-item>
-
-      <el-form-item>
-        <el-button type="primary" :disabled="isSubmit" @click="save"
-          >保存</el-button
-        >
-        <el-button @click="goback">返回</el-button>
-      </el-form-item>
-    </el-form>
-  </div>
-</template>
-
-<script>
-import {
-  updateTopicTask,
-  topicTaskDetail,
-  topicTaskExamList,
-  topicTaskExamCourseList,
-  topicTaskExamTeacherList
-} from "../api";
-
-export default {
-  name: "topic-task-modify",
-  data() {
-    return {
-      taskId: this.$route.params.taskId,
-      modalForm: {
-        examId: "",
-        examName: "",
-        courseCode: "",
-        courseName: "",
-        beginTime: "",
-        questionTeacherId: ""
-      },
-      curExam: {},
-      rules: {
-        examId: [
-          {
-            required: true,
-            message: "请选择考试",
-            trigger: "change"
-          }
-        ],
-        courseCode: [
-          {
-            required: true,
-            message: "请选择科目",
-            trigger: "change"
-          }
-        ],
-        questionTeacherId: [
-          {
-            required: true,
-            message: "请选择命题老师",
-            trigger: "change"
-          }
-        ]
-      },
-      exams: [],
-      courses: [],
-      teachers: [],
-      isSubmit: false
-    };
-  },
-  computed: {
-    isEdit() {
-      return !!this.taskId;
-    }
-  },
-  mounted() {
-    this.initData();
-  },
-  methods: {
-    async initData() {
-      if (this.isEdit) {
-        await this.getTaskDetail();
-        this.getTeachers();
-      } else {
-        this.getExams();
-      }
-    },
-    async getTaskDetail() {
-      const data = await topicTaskDetail(this.taskId);
-      this.modalForm = this.$objAssign(this.modalForm, data);
-    },
-    async getExams() {
-      const data = await topicTaskExamList();
-      this.exams = data.map(item => {
-        return {
-          id: item.id,
-          name: item.examName,
-          beginTime: item.beginTime
-        };
-      });
-    },
-    async getCourses() {
-      const data = await topicTaskExamCourseList(this.modalForm.examId);
-      this.courses = data.map(item => {
-        item.label = `${item.courseName}(${item.courseCode})`;
-        return item;
-      });
-    },
-    async getTeachers() {
-      this.teachers = await topicTaskExamTeacherList(this.modalForm.courseCode);
-    },
-    examChange() {
-      this.modalForm.courseCode = "";
-      this.modalForm.questionTeacherId = "";
-      this.courses = [];
-      this.teachers = [];
-      if (!this.modalForm.examId) {
-        this.curExam = {};
-        return;
-      }
-      this.curExam = this.exams.find(item => item.id === this.modalForm.examId);
-      this.modalForm.beginTime = this.curExam.beginTime;
-      this.getCourses();
-    },
-    courseChange() {
-      this.modalForm.questionTeacherId = "";
-      this.teachers = [];
-      if (!this.modalForm.courseCode) return;
-      this.getTeachers();
-    },
-    async save() {
-      const valid = await this.$refs["ModalForm"].validate().catch(() => {});
-      if (!valid) return;
-
-      if (this.isSubmit) return;
-      this.isSubmit = true;
-      const datas = {
-        ...this.modalForm
-      };
-      if (this.isEdit) {
-        datas.taskId = this.taskId;
-      } else {
-        const curCourse = this.courses.find(
-          item => item.courseCode === datas.courseCode
-        );
-        datas.courseName = curCourse.courseName;
-      }
-      const data = await updateTopicTask(datas).catch(() => {});
-      this.isSubmit = false;
-      if (!data) return;
-      this.$message.success("保存成功!");
-      this.goback();
-    }
-  }
-};
-</script>

+ 0 - 152
src/modules/exam-center/views/WaitTask.vue

@@ -1,152 +0,0 @@
-<template>
-  <div class="wait-task">
-    <div class="part-box part-box-filter">
-      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
-        <el-form-item label="考试名称:">
-          <el-select
-            v-model="filter.examId"
-            style="width: 315px;"
-            placeholder="请选择"
-            clearable
-          >
-            <el-option
-              v-for="item in exams"
-              :key="item.id"
-              :value="item.id"
-              :label="item.name"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
-            >查询</el-button
-          >
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <el-table
-        ref="TableList"
-        :data="tasks"
-        :row-class-name="tableRowClassName"
-        border
-        stripe
-      >
-        <el-table-column prop="examCode" label="考试ID"></el-table-column>
-        <el-table-column prop="examName" label="考试名称"></el-table-column>
-        <el-table-column prop="courseNameCode" label="科目名称(编码)">
-        </el-table-column>
-        <el-table-column prop="paperStatus" label="试卷"></el-table-column>
-        <el-table-column prop="cardStatus" label="答题卡"></el-table-column>
-        <el-table-column prop="endTime" label="任务截止日期"></el-table-column>
-        <el-table-column prop="overTime" label="剩余时间"></el-table-column>
-        <el-table-column prop="receiveTime" label="接收时间"></el-table-column>
-        <el-table-column label="操作" align="center">
-          <template slot-scope="scope">
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-circle-right"
-              @click="toDetail(scope.row)"
-              title="详情"
-            ></el-button>
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { waitTaskListPage, examList } from "../api";
-import { mapActions } from "vuex";
-
-export default {
-  name: "wait-task",
-  data() {
-    return {
-      isInit: false,
-      filter: {
-        examId: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      visible: false,
-      exams: [],
-      tasks: []
-    };
-  },
-  created() {
-    const waitFilter = this.$ls.get("waitFilter");
-    if (waitFilter) {
-      this.filter.examId = waitFilter.examId;
-      this.current = waitFilter.pageNumber;
-    }
-    this.init();
-  },
-  methods: {
-    ...mapActions("examCenter", ["updateWaitTaskCount"]),
-    init() {
-      this.getExamList();
-      this.toPage(1);
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        pageNumber: this.current,
-        pageSize: this.size
-      };
-      const result = await waitTaskListPage(datas);
-      const data = result || { records: [], total: 0 };
-      this.tasks = data.records;
-      this.total = data.total;
-      this.$ls.set("waitFilter", datas);
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-      this.updateWaitTaskCount();
-    },
-    async getExamList() {
-      const data = await examList();
-      this.exams = data.map(item => {
-        return {
-          id: item.id,
-          name: item.examName
-        };
-      });
-    },
-    tableRowClassName({ row }) {
-      return row.warning ? "row-danger" : "";
-    },
-    toDetail(row) {
-      this.$router.push({
-        name: "WaitTaskDetail",
-        params: {
-          taskId: row.id
-        }
-      });
-    }
-  },
-  activated() {
-    if (this.isInit) {
-      this.toPage(this.current);
-    } else {
-      this.isInit = true;
-    }
-  }
-};
-</script>

+ 0 - 401
src/modules/exam-center/views/WaitTaskDetail.vue

@@ -1,401 +0,0 @@
-<template>
-  <div class="wait-task-detail task-detail">
-    <div class="task-title">
-      <h2>
-        <span>考试名称: {{ task.examName }} </span>
-        <span>科目名称:{{ task.courseNameCode }}</span>
-      </h2>
-      <div class="task-title-infos">
-        <el-checkbox v-model="pTypeEnable" disabled
-          >启用{{ paperTypeFieldContent }}卷</el-checkbox
-        >
-        <span class="task-title-add" @click="addAtachment">
-          <i class="icon icon-plus-act"></i>增加卷型
-        </span>
-      </div>
-    </div>
-    <div class="task-body">
-      <table class="table">
-        <tr>
-          <th>试卷类型</th>
-          <th v-if="task.examPaper">试卷文件</th>
-          <th v-if="task.examPaper">试卷审核确认书</th>
-          <th v-if="task.answerSheet">答题卡</th>
-          <th>操作</th>
-        </tr>
-        <tr v-for="(attachment, index) in curPaperAttachments" :key="index">
-          <td>{{ attachment.name }}卷</td>
-          <td class="td-link" v-if="task.examPaper">
-            <span @click="toUpload(attachment)" title="点击上传试卷">
-              <i
-                :class="[
-                  'icon',
-                  attachment.attachmentId ? 'icon-files-act' : 'icon-files'
-                ]"
-              ></i
-              >{{
-                attachment.attachmentId
-                  ? attachment.filename
-                  : "点击上传试卷文件"
-              }}
-            </span>
-          </td>
-          <td
-            class="td-link"
-            :rowspan="pTypeEnable ? curPaperAttachments.length : 1"
-            v-if="index === 0 && task.examPaper"
-          >
-            <span @click="toUploadPaperConfirm" title="点击上传确认书文件">
-              <i
-                :class="[
-                  'icon',
-                  paperConfirmAttachmentId.attachmentId
-                    ? 'icon-files-act'
-                    : 'icon-files'
-                ]"
-              ></i
-              >{{
-                paperConfirmAttachmentId.attachmentId
-                  ? paperConfirmAttachmentId.filename
-                  : "点击上传确认书文件"
-              }}
-            </span>
-          </td>
-          <td
-            class="td-link"
-            :rowspan="pTypeEnable ? curPaperAttachments.length : 1"
-            v-if="index === 0 && task.answerSheet"
-          >
-            <span @click="toCreateCard"
-              ><i class="icon icon-plus-act"></i>{{ cardTodoName }}</span
-            >
-          </td>
-          <td>
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-delete"
-              title="删除"
-              @click="deleteAttachment(index)"
-            ></el-button>
-          </td>
-        </tr>
-      </table>
-
-      <div class="task-audit" v-if="task.review && task.auditStatus === 2">
-        <p>
-          <span>打回意见:</span
-          ><span class="color-danger">{{ task.remark }}</span>
-          <span class="task-audit-history" @click="modalIsShow = true"
-            >历史意见 <i class="el-icon-caret-right"></i>
-          </span>
-        </p>
-      </div>
-
-      <div class="task-action">
-        <el-button
-          type="primary"
-          style="width:105px;"
-          @click="toSubmit"
-          :disabled="!curPaperAttachments.length"
-          >确认提交</el-button
-        >
-        <el-button
-          style="width:88px;"
-          @click="toSave"
-          :disabled="!curPaperAttachments.length"
-          >暂存</el-button
-        >
-        <el-button @click="goback" style="width:88px;">取消</el-button>
-      </div>
-    </div>
-
-    <!-- audit msg history -->
-    <el-dialog
-      :visible.sync="modalIsShow"
-      title="历史意见"
-      top="10vh"
-      width="600px"
-      :close-on-click-modal="false"
-      :close-on-press-escape="false"
-      append-to-body
-    >
-      <el-table :data="auditHistory" border stripe>
-        <el-table-column prop="createTime" label="时间"></el-table-column>
-        <el-table-column prop="remark" label="意见"></el-table-column>
-      </el-table>
-      <div slot="footer"></div>
-    </el-dialog>
-
-    <!-- upload-paper-dialog -->
-    <upload-paper-dialog
-      :paper-attachment="curAttachment"
-      :upload-type="curUploadType"
-      @confirm="uploadConfirm"
-      ref="UploadPaperDialog"
-    ></upload-paper-dialog>
-    <!-- card-option-dialog -->
-    <card-option-dialog
-      :data="task"
-      ref="CardOptionDialog"
-      @upload-sample-over="getData"
-      @draft-task="silentSave"
-      @confirm="cardConfirm"
-    ></card-option-dialog>
-  </div>
-</template>
-
-<script>
-import { mapActions } from "vuex";
-import {
-  waitTaskDetail,
-  saveWaitTask,
-  submitWaitTask,
-  examTaskAudtiHistory
-} from "../api";
-import UploadPaperDialog from "../components/UploadPaperDialog";
-import CardOptionDialog from "../components/CardOptionDialog";
-import { PAPER_TYPE_FIELDS } from "@/constants/enumerate";
-
-export default {
-  name: "wait-task-detail",
-  components: {
-    UploadPaperDialog,
-    CardOptionDialog
-  },
-  data() {
-    return {
-      taskId: this.$route.params.taskId,
-      PAPER_TYPE_FIELDS,
-      task: {
-        id: "",
-        taskId: "",
-        enablePaperType: "A",
-        paperAttachmentId: "",
-        cardId: "",
-        cardSource: "",
-        refCardId: "",
-        examPaper: 1,
-        answerSheet: 1,
-        signIn: 0,
-        paperSticker: 0,
-        review: 1,
-        auditStatus: 0,
-        remark: ""
-      },
-      paperConfirmAttachmentId: { attachmentId: "", filename: "" },
-      paperAttachments: [],
-      curPaperAttachments: [],
-      curAttachment: {},
-      curUploadType: "paper",
-      attachmentLimitCount: 4,
-      abc: "",
-      // audit history
-      modalIsShow: false,
-      auditHistory: []
-    };
-  },
-  computed: {
-    paperTypeFieldContent() {
-      return this.PAPER_TYPE_FIELDS.join("/");
-    },
-    pTypeEnable() {
-      return this.curPaperAttachments.length > 1;
-    },
-    cardTodoName() {
-      let name = "创建答题卡";
-      if (this.task.cardId) {
-        if (this.task.cardSource === 0) {
-          name = "选择题卡";
-        } else if (this.task.cardSource === 1) {
-          name = "编辑题卡";
-        } else {
-          // 已经审核的题卡可以自行编辑,未审核的题卡只能查看
-          name = this.task.auditingStatus ? "编辑题卡" : "查看题卡";
-        }
-      }
-      return name;
-    }
-  },
-  mounted() {
-    this.abc = "abcdefghijklmnopqrstuvwxyz"
-      .toUpperCase()
-      .slice(0, this.attachmentLimitCount);
-    this.getData();
-  },
-  methods: {
-    ...mapActions("examCenter", ["updateWaitTaskCount"]),
-    async getData() {
-      const data = await waitTaskDetail(this.taskId);
-      const nameCode = data.courseNameCode.split(/\(|\)/);
-      this.task = Object.assign(this.task, data, {
-        courseName: nameCode[0],
-        courseCode: nameCode[1]
-      });
-
-      const paperAttachment =
-        this.task.paperAttachmentId && JSON.parse(this.task.paperAttachmentId);
-      this.paperAttachments = paperAttachment ? paperAttachment.paper : [];
-      this.curPaperAttachments = this.paperAttachments.map(item => {
-        return { ...item };
-      });
-      if (!this.curPaperAttachments.length) this.addAtachment();
-      this.paperConfirmAttachmentId = this.task.paperConfirmAttachmentId
-        ? JSON.parse(this.task.paperConfirmAttachmentId)
-        : { attachmentId: "", filename: "" };
-      this.task.enablePaperType = this.getEnablePaperType();
-
-      if (this.task.review && this.task.auditStatus === 2)
-        this.getHistoryList();
-    },
-    async getHistoryList() {
-      this.auditHistory = await examTaskAudtiHistory(this.taskId);
-    },
-    addAtachment() {
-      if (this.curPaperAttachments.length >= this.attachmentLimitCount) return;
-
-      const newAttachment = {
-        name: this.abc[this.curPaperAttachments.length],
-        attachmentId: "",
-        filename: "",
-        pages: 0
-      };
-      this.curPaperAttachments.push(newAttachment);
-    },
-    deleteAttachment(index) {
-      if (this.curPaperAttachments.length <= 1) {
-        this.$message.error("试卷类型数量不得少于1");
-        return;
-      }
-      this.curPaperAttachments.splice(index, 1);
-      this.curPaperAttachments.forEach((item, itemIndex) => {
-        item.name = this.abc[itemIndex];
-      });
-    },
-    toUpload(attachment) {
-      this.curUploadType = "paper";
-      this.curAttachment = {
-        ...attachment,
-        courseNameCode: this.task.courseNameCode
-      };
-      this.$refs.UploadPaperDialog.open();
-    },
-    toUploadPaperConfirm() {
-      this.curUploadType = "paperConfirm";
-      this.curAttachment = {
-        ...this.paperConfirmAttachmentId,
-        courseNameCode: this.task.courseNameCode
-      };
-      this.$refs.UploadPaperDialog.open();
-    },
-    uploadConfirm(attachment, uploadType) {
-      if (uploadType === "paper") {
-        const index = this.curPaperAttachments.findIndex(
-          item => item.name === attachment.name
-        );
-        this.curPaperAttachments.splice(index, 1, { ...attachment });
-      } else {
-        this.paperConfirmAttachmentId = { ...attachment };
-      }
-    },
-    toCreateCard() {
-      this.task = this.getTaskData().tcPExamTaskDetail;
-      if (this.task.cardId) {
-        if (this.task.cardSource === 0) {
-          this.$refs.CardOptionDialog.open();
-        } else if (this.task.cardSource === 1) {
-          this.$router.push({
-            name: "CardDesign",
-            params: {
-              cardId: this.task.cardId
-            }
-          });
-        } else {
-          if (this.task.auditingStatus) {
-            this.$router.push({
-              name: "CardDesign",
-              params: {
-                cardId: this.task.cardId
-              }
-            });
-          } else {
-            window.open(
-              this.getRouterPath({
-                name: "CardPreview",
-                params: {
-                  cardId: this.task.cardId,
-                  viewType: "view"
-                }
-              })
-            );
-          }
-        }
-        return;
-      }
-      this.$refs.CardOptionDialog.open();
-    },
-    cardConfirm(options) {
-      this.task = Object.assign(this.task, options);
-    },
-    getEnablePaperType() {
-      return this.curPaperAttachments.map(item => item.name).join(",");
-    },
-    getTaskData() {
-      let datas = { ...this.task };
-      datas.taskId = this.taskId;
-      datas.paperAttachmentId = JSON.stringify({
-        paper: this.curPaperAttachments
-      });
-      datas.paperConfirmAttachmentId = JSON.stringify(
-        this.paperConfirmAttachmentId
-      );
-      datas.enablePaperType = this.getEnablePaperType();
-      return { tcPExamTaskDetail: datas };
-    },
-    checkDataValid() {
-      const attachmentValid = !this.curPaperAttachments.some(
-        item => !item.attachmentId
-      );
-      if (this.task.examPaper && !attachmentValid) {
-        this.$message.error("请完成试卷文件上传!");
-        return;
-      }
-      if (this.task.examPaper && !this.paperConfirmAttachmentId.attachmentId) {
-        this.$message.error("请完成试卷审核确认书上传!");
-        return;
-      }
-
-      if (this.task.answerSheet && !this.task.cardId && !this.task.refCardId) {
-        this.$message.error("请选择题卡创建方式!");
-        return;
-      }
-      return true;
-    },
-    toSubmit() {
-      this.$confirm(
-        "任务确定提交后,则不可更改试卷及答题卡内容,确定提交该任务?",
-        "提示",
-        {
-          cancelButtonClass: "el-button--danger is-plain",
-          confirmButtonClass: "el-button--primary",
-          type: "warning"
-        }
-      ).then(async () => {
-        if (!this.checkDataValid()) return;
-        await submitWaitTask(this.getTaskData());
-        this.$message.success("提交成功!");
-        this.goback();
-        this.updateWaitTaskCount();
-      });
-    },
-    async toSave() {
-      await saveWaitTask(this.getTaskData());
-      this.$message.success("保存成功!");
-      this.goback();
-    },
-    async silentSave() {
-      await saveWaitTask(this.getTaskData());
-    }
-  }
-};
-</script>

+ 0 - 19
src/modules/example/api.js

@@ -1,19 +0,0 @@
-import { $get, $post } from "@/plugins/axios";
-
-// course-manage
-export const courseList = datas => {
-  return $get("/backend/course/listCoursePage", datas);
-};
-export const updateCourse = datas => {
-  if (datas.id) {
-    return $post("/backend/course/updateCourse", datas);
-  } else {
-    return $post("/backend/course/addCourse", datas);
-  }
-};
-export const deleteCourse = id => {
-  return $post("/backend/course/deleteCourse", { id });
-};
-export const updateCourseStatus = ({ id, status }) => {
-  return $post("/backend/course/updateCourseStatus", { id, status });
-};

+ 0 - 114
src/modules/example/components/ModifyData.vue

@@ -1,114 +0,0 @@
-<template>
-  <el-dialog
-    class="modify-data"
-    :visible.sync="modalIsShow"
-    :title="title"
-    top="10vh"
-    :close-on-click-modal="false"
-    :close-on-press-escape="false"
-    append-to-body
-    @open="visibleChange"
-  >
-    <el-form
-      ref="modalFormComp"
-      :model="modalForm"
-      :rules="rules"
-      :key="modalForm.id"
-      label-width="100px"
-    >
-      <el-form-item prop="name" label="年级名称">
-        <el-input
-          v-model.trim="modalForm.name"
-          placeholder="请输入年级名称"
-          clearable
-        ></el-input>
-      </el-form-item>
-    </el-form>
-    <div slot="footer">
-      <el-button type="danger" @click="cancel" plain>取消</el-button>
-      <el-button type="primary" :disabled="isSubmit" @click="submit"
-        >确认</el-button
-      >
-    </div>
-  </el-dialog>
-</template>
-
-<script>
-import { updateCourse } from "../api";
-
-const initModalForm = {
-  id: "",
-  name: ""
-};
-
-export default {
-  name: "modify-data",
-  props: {
-    instance: {
-      type: Object,
-      default() {
-        return {};
-      }
-    }
-  },
-  computed: {
-    isEdit() {
-      return !!this.instance.id;
-    },
-    title() {
-      return (this.isEdit ? "编辑" : "新增") + "年级";
-    }
-  },
-  data() {
-    return {
-      modalIsShow: false,
-      isSubmit: false,
-      modalForm: { ...initModalForm },
-      rules: {
-        name: [
-          {
-            required: true,
-            message: "请输入年级名称",
-            trigger: "change"
-          }
-        ]
-      }
-    };
-  },
-  methods: {
-    initData(val) {
-      if (val.id) {
-        this.modalForm = this.$objAssign(initModalForm, val);
-      } else {
-        this.modalForm = { ...initModalForm };
-      }
-    },
-    visibleChange() {
-      this.initData(this.instance);
-    },
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    },
-    async submit() {
-      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
-      if (!valid) return;
-
-      if (this.isSubmit) return;
-      this.isSubmit = true;
-      const data = await updateCourse(this.modalForm).catch(() => {
-        this.isSubmit = false;
-      });
-
-      if (!data) return;
-
-      this.isSubmit = false;
-      this.$message.success(this.title + "成功!");
-      this.$emit("modified");
-      this.cancel();
-    }
-  }
-};
-</script>

+ 0 - 9
src/modules/example/router.js

@@ -1,9 +0,0 @@
-import DataManage from "./views/DataManage.vue";
-
-export default [
-  {
-    path: "/example/data-manage",
-    name: "DataManage",
-    component: DataManage
-  }
-];

+ 0 - 186
src/modules/example/views/DataManage.vue

@@ -1,186 +0,0 @@
-<template>
-  <div class="data-manage">
-    <div class="part-box">
-      <el-form ref="FilterForm" label-position="left" label-width="80px" inline>
-        <el-form-item label="年级名称">
-          <el-input
-            v-model.trim="filter.name"
-            placeholder="年级名称模糊查询"
-            clearable
-          ></el-input>
-        </el-form-item>
-        <el-form-item label="年级状态">
-          <el-select v-model="filter.status" style="width: 150px;" clearable>
-            <el-option
-              v-for="(val, key) in ABLE_TYPE"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="ios-search" @click="toPage(1)"
-            >查询</el-button
-          >
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <div class="part-title">
-        <div class="part-title-infos">
-          <el-button type="primary" icon="md-add" @click="toAdd"
-            >新增</el-button
-          >
-        </div>
-      </div>
-      <el-table ref="TableList" :data="grades" border>
-        <el-table-column
-          type="index"
-          label="序号"
-          width="70"
-          align="center"
-          :index="indexMethod"
-        >
-        </el-table-column>
-        <el-table-column prop="name" label="年级名称" min-width="200">
-        </el-table-column>
-        <el-table-column prop="status" label="状态" min-width="200">
-          <template slot-scope="scope">
-            <span>{{ ABLE_TYPE[scope.row.status] }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column min-width="200" align="center">
-          <template slot-scope="scope">
-            <el-button
-              size="mini"
-              type="primary"
-              icon="el-icon-edit"
-              @click="toEdit(scope.row)"
-              >编辑</el-button
-            >
-            <el-button
-              size="mini"
-              type="danger"
-              icon="el-icon-delete"
-              @click="toDelete(scope.row)"
-              >删除</el-button
-            >
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-
-    <!-- modify-data -->
-    <modify-data
-      :instance="curCourse"
-      @modified="getList"
-      ref="ModifyData"
-    ></modify-data>
-  </div>
-</template>
-
-<script>
-import { ABLE_TYPE } from "@/constants/enumerate";
-import { courseList, deleteCourse } from "../api";
-import ModifyData from "../components/ModifyData";
-
-export default {
-  name: "data-manage",
-  components: { ModifyData },
-  data() {
-    return {
-      filter: {
-        name: "",
-        status: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      visible: false,
-      grades: [
-        {
-          id: "11",
-          name: "名称1",
-          status: "ENABLE"
-        },
-        {
-          id: "22",
-          name: "名称2",
-          status: "ENABLE"
-        },
-        {
-          id: "33",
-          name: "名称3",
-          status: "ENABLE"
-        }
-      ],
-      curCourse: {},
-      ABLE_TYPE
-    };
-  },
-  created() {
-    // this.getList();
-  },
-  methods: {
-    indexMethod(index) {
-      return (this.current - 1) * this.size + index + 1;
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        current: this.current,
-        size: this.size
-      };
-      const data = await courseList(datas);
-      this.grades = data.list.map(item => {
-        return {
-          id: item.id,
-          name: item.name,
-          status: item.status,
-          createTime: item.createTime
-        };
-      });
-      this.total = data.totalCount;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    toAdd() {
-      this.curCourse = {};
-      this.$refs.ModifyData.open();
-    },
-    toEdit(row) {
-      this.curCourse = row;
-      this.$refs.ModifyData.open();
-    },
-    toDelete(row) {
-      this.$confirm("确定要删除当前学校吗?", "删除警告", {
-        cancelButtonClass: "el-button--danger is-plain",
-        confirmButtonClass: "el-button--primary",
-        type: "warning"
-      })
-        .then(async () => {
-          await deleteCourse(row.id);
-          this.$message.success("删除成功!");
-          // 解决最后一项删除后的问题
-          this.deletePageLastItem();
-        })
-        .catch(() => {});
-    }
-  }
-};
-</script>

+ 2 - 2
src/modules/login/views/Login.vue

@@ -47,7 +47,7 @@
           </el-form-item>
           <el-form-item>
             <el-button
-              style="width:116px;"
+              style="width:100%;"
               type="primary"
               :disabled="isSubmit"
               @click="submit('loginForm')"
@@ -98,7 +98,7 @@ export default {
       nameWaitTime,
       loginModel: {
         loginName: "",
-        code: "",
+        code: "qmth",
         password: ""
       },
       loginRules: {

+ 0 - 19
src/modules/score-paper/api.js

@@ -1,19 +0,0 @@
-import { $get, $post } from "@/plugins/axios";
-
-// course-manage
-export const courseList = datas => {
-  return $get("/backend/course/listCoursePage", datas);
-};
-export const updateCourse = datas => {
-  if (datas.id) {
-    return $post("/backend/course/updateCourse", datas);
-  } else {
-    return $post("/backend/course/addCourse", datas);
-  }
-};
-export const deleteCourse = id => {
-  return $post("/backend/course/deleteCourse", { id });
-};
-export const updateCourseStatus = ({ id, status }) => {
-  return $post("/backend/course/updateCourseStatus", { id, status });
-};

+ 0 - 114
src/modules/score-paper/components/ModifyData.vue

@@ -1,114 +0,0 @@
-<template>
-  <el-dialog
-    class="modify-data"
-    :visible.sync="modalIsShow"
-    :title="title"
-    top="10vh"
-    :close-on-click-modal="false"
-    :close-on-press-escape="false"
-    append-to-body
-    @open="visibleChange"
-  >
-    <el-form
-      ref="modalFormComp"
-      :model="modalForm"
-      :rules="rules"
-      :key="modalForm.id"
-      label-width="100px"
-    >
-      <el-form-item prop="name" label="年级名称">
-        <el-input
-          v-model.trim="modalForm.name"
-          placeholder="请输入年级名称"
-          clearable
-        ></el-input>
-      </el-form-item>
-    </el-form>
-    <div slot="footer">
-      <el-button type="danger" @click="cancel" plain>取消</el-button>
-      <el-button type="primary" :disabled="isSubmit" @click="submit"
-        >确认</el-button
-      >
-    </div>
-  </el-dialog>
-</template>
-
-<script>
-import { updateCourse } from "../api";
-
-const initModalForm = {
-  id: "",
-  name: ""
-};
-
-export default {
-  name: "modify-data",
-  props: {
-    instance: {
-      type: Object,
-      default() {
-        return {};
-      }
-    }
-  },
-  computed: {
-    isEdit() {
-      return !!this.instance.id;
-    },
-    title() {
-      return (this.isEdit ? "编辑" : "新增") + "年级";
-    }
-  },
-  data() {
-    return {
-      modalIsShow: false,
-      isSubmit: false,
-      modalForm: { ...initModalForm },
-      rules: {
-        name: [
-          {
-            required: true,
-            message: "请输入年级名称",
-            trigger: "change"
-          }
-        ]
-      }
-    };
-  },
-  methods: {
-    initData(val) {
-      if (val.id) {
-        this.modalForm = this.$objAssign(initModalForm, val);
-      } else {
-        this.modalForm = { ...initModalForm };
-      }
-    },
-    visibleChange() {
-      this.initData(this.instance);
-    },
-    cancel() {
-      this.modalIsShow = false;
-    },
-    open() {
-      this.modalIsShow = true;
-    },
-    async submit() {
-      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
-      if (!valid) return;
-
-      if (this.isSubmit) return;
-      this.isSubmit = true;
-      const data = await updateCourse(this.modalForm).catch(() => {
-        this.isSubmit = false;
-      });
-
-      if (!data) return;
-
-      this.isSubmit = false;
-      this.$message.success(this.title + "成功!");
-      this.$emit("modified");
-      this.cancel();
-    }
-  }
-};
-</script>

+ 0 - 9
src/modules/score-paper/router.js

@@ -1,9 +0,0 @@
-import ClassPaper from "./views/ClassPaper.vue";
-
-export default [
-  {
-    path: "/score-paper/class-paper",
-    name: "ClassPaper",
-    component: ClassPaper
-  }
-];

+ 0 - 186
src/modules/score-paper/views/ClassPaper.vue

@@ -1,186 +0,0 @@
-<template>
-  <div class="data-manage">
-    <div class="part-box">
-      <el-form ref="FilterForm" label-position="left" label-width="80px" inline>
-        <el-form-item label="年级名称">
-          <el-input
-            v-model.trim="filter.name"
-            placeholder="年级名称模糊查询"
-            clearable
-          ></el-input>
-        </el-form-item>
-        <el-form-item label="年级状态">
-          <el-select v-model="filter.status" style="width: 150px;" clearable>
-            <el-option
-              v-for="(val, key) in ABLE_TYPE"
-              :key="key"
-              :value="key"
-              :label="val"
-            ></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label-width="0px">
-          <el-button type="primary" icon="ios-search" @click="toPage(1)"
-            >查询</el-button
-          >
-        </el-form-item>
-      </el-form>
-    </div>
-
-    <div class="part-box">
-      <div class="part-title">
-        <div class="part-title-infos">
-          <el-button type="primary" icon="md-add" @click="toAdd"
-            >新增</el-button
-          >
-        </div>
-      </div>
-      <el-table ref="TableList" :data="grades" border>
-        <el-table-column
-          type="index"
-          label="序号"
-          width="70"
-          align="center"
-          :index="indexMethod"
-        >
-        </el-table-column>
-        <el-table-column prop="name" label="年级名称" min-width="200">
-        </el-table-column>
-        <el-table-column prop="status" label="状态" min-width="200">
-          <template slot-scope="scope">
-            <span>{{ ABLE_TYPE[scope.row.status] }}</span>
-          </template>
-        </el-table-column>
-        <el-table-column min-width="200" align="center">
-          <template slot-scope="scope">
-            <el-button
-              size="mini"
-              type="primary"
-              icon="el-icon-edit"
-              @click="toEdit(scope.row)"
-              >编辑</el-button
-            >
-            <el-button
-              size="mini"
-              type="danger"
-              icon="el-icon-delete"
-              @click="toDelete(scope.row)"
-              >删除</el-button
-            >
-          </template>
-        </el-table-column>
-      </el-table>
-      <div class="part-page">
-        <el-pagination
-          background
-          layout="prev, pager, next"
-          :current-page="current"
-          :total="total"
-          :page-size="size"
-          @current-change="toPage"
-        >
-        </el-pagination>
-      </div>
-    </div>
-
-    <!-- modify-data -->
-    <modify-data
-      :instance="curCourse"
-      @modified="getList"
-      ref="ModifyData"
-    ></modify-data>
-  </div>
-</template>
-
-<script>
-import { ABLE_TYPE } from "@/constants/enumerate";
-import { courseList, deleteCourse } from "../api";
-import ModifyData from "../components/ModifyData";
-
-export default {
-  name: "data-manage",
-  components: { ModifyData },
-  data() {
-    return {
-      filter: {
-        name: "",
-        status: ""
-      },
-      current: 1,
-      size: this.GLOBAL.pageSize,
-      total: 0,
-      visible: false,
-      grades: [
-        {
-          id: "11",
-          name: "名称1",
-          status: "ENABLE"
-        },
-        {
-          id: "22",
-          name: "名称2",
-          status: "ENABLE"
-        },
-        {
-          id: "33",
-          name: "名称3",
-          status: "ENABLE"
-        }
-      ],
-      curCourse: {},
-      ABLE_TYPE
-    };
-  },
-  created() {
-    // this.getList();
-  },
-  methods: {
-    indexMethod(index) {
-      return (this.current - 1) * this.size + index + 1;
-    },
-    async getList() {
-      const datas = {
-        ...this.filter,
-        current: this.current,
-        size: this.size
-      };
-      const data = await courseList(datas);
-      this.grades = data.list.map(item => {
-        return {
-          id: item.id,
-          name: item.name,
-          status: item.status,
-          createTime: item.createTime
-        };
-      });
-      this.total = data.totalCount;
-    },
-    toPage(page) {
-      this.current = page;
-      this.getList();
-    },
-    toAdd() {
-      this.curCourse = {};
-      this.$refs.ModifyData.open();
-    },
-    toEdit(row) {
-      this.curCourse = row;
-      this.$refs.ModifyData.open();
-    },
-    toDelete(row) {
-      this.$confirm("确定要删除当前学校吗?", "删除警告", {
-        cancelButtonClass: "el-button--danger is-plain",
-        confirmButtonClass: "el-button--primary",
-        type: "warning"
-      })
-        .then(async () => {
-          await deleteCourse(row.id);
-          this.$message.success("删除成功!");
-          // 解决最后一项删除后的问题
-          this.deletePageLastItem();
-        })
-        .catch(() => {});
-    }
-  }
-};
-</script>

+ 15 - 0
src/plugins/filters.js

@@ -0,0 +1,15 @@
+import Vue from "vue";
+import { ABLE_TYPE, TEMPLATE_CLASSIFY } from "../constants/enumerate";
+
+Vue.filter("enableFilter", function(val) {
+  return ABLE_TYPE[val];
+});
+Vue.filter("templateClassifyFilter", function(val) {
+  return TEMPLATE_CLASSIFY[val];
+});
+Vue.filter("rolesFilter", function(val) {
+  return val.map(item => item.roleName).join(",");
+});
+Vue.filter("coursesFilter", function(val) {
+  return val.map(item => `${item.courseName}(${item.courseCode})`).join(",");
+});

+ 5 - 0
src/plugins/mixins.js

@@ -13,6 +13,11 @@ export default {
     getRouterPath(location) {
       const { href } = this.$router.resolve(location);
       return href;
+    },
+    indexMethod(index) {
+      const current = this.current || 1;
+      const size = this.size || 10;
+      return (current - 1) * size + index + 1;
     }
   }
 };

+ 4 - 4
src/router.js

@@ -7,9 +7,9 @@ import NotFound from "./views/404.vue";
 import login from "./modules/login/router";
 // module-example
 import base from "./modules/base/router";
-import examCenter from "./modules/exam-center/router";
-import scorePaper from "./modules/score-paper/router";
-import analyze from "./modules/analyze/router";
+// import examCenter from "./modules/exam-center/router";
+// import scorePaper from "./modules/score-paper/router";
+// import analyze from "./modules/analyze/router";
 // card part
 import card from "./modules/card/router";
 
@@ -39,7 +39,7 @@ export default new Router({
       path: "/home",
       name: "Home",
       component: Home,
-      children: [...base, ...examCenter, ...scorePaper, ...analyze]
+      children: [...base]
     },
     { ...login },
     ...card,

+ 3 - 3
src/store.js

@@ -6,7 +6,7 @@ Vue.use(Vuex);
 
 // modules
 import card from "./modules/card/store";
-import examCenter from "./modules/exam-center/store";
+// import examCenter from "./modules/exam-center/store";
 
 export default new Vuex.Store({
   state: {
@@ -33,7 +33,7 @@ export default new Vuex.Store({
   },
   actions: {},
   modules: {
-    card,
-    examCenter
+    card
+    // examCenter
   }
 });

+ 142 - 214
src/views/Home.vue

@@ -7,31 +7,31 @@
       <div class="head-menu menu-list">
         <ul>
           <li
-            v-for="(nav, index) in navs"
+            v-for="(menu, index) in menus"
             :key="index"
-            @click="toPage(index, 0)"
-            :class="{ 'menu-item-act': curMainIndex === index }"
+            :class="[
+              'menu-item',
+              { 'menu-item-act': curMenu.name === menu.name }
+            ]"
+            @click="toMenu(menu)"
           >
-            <div class="menu-item">
-              <i :class="['icon', `icon-${nav.router}`]"></i>
-              <span>{{ nav.title }}</span>
-            </div>
+            <i :class="['icon', `icon-${menu.name}`]"></i>
+            <span>{{ menu.title }}</span>
           </li>
         </ul>
       </div>
       <div class="head-user menu-list">
         <ul>
-          <li @click="$refs.ResetPwd.open()">
-            <div class="menu-item menu-item-account">
-              <i class="icon icon-account"></i>
-              <span :title="username">{{ username }}</span>
-            </div>
+          <li
+            class="menu-item menu-item-account"
+            @click="$refs.ResetPwd.open()"
+          >
+            <i class="icon icon-account"></i>
+            <span :title="username">{{ username }}</span>
           </li>
-          <li @click="toLogout">
-            <div class="menu-item">
-              <i class="icon icon-shut"></i>
-              <span>退出登录</span>
-            </div>
+          <li class="menu-item" @click="toLogout">
+            <i class="icon icon-shut"></i>
+            <span>退出登录</span>
           </li>
         </ul>
       </div>
@@ -40,112 +40,35 @@
       </div>
     </div>
 
-    <div class="home-navs" v-if="curNav">
-      <div class="nav-head">
-        <i :class="['icon', `icon-${curNav.router}-gray`]"></i>
-        <span>{{ curNav.title }}</span>
-      </div>
-      <ul class="nav-list">
-        <li
-          class="nav-item"
-          v-for="(nav, subNo) in curNav.children"
-          :key="subNo"
-        >
-          <div
-            :class="[
-              'nav-item-main',
-              { 'nav-item-main-act': curSubIndex === subNo }
-            ]"
-            @click="switchNav(subNo)"
-          >
-            <p class="nav-item-cont">{{ nav.title }}</p>
-            <span class="nav-item-icon nav-item-icon-right">
-              <i
-                :class="[
-                  'icon',
-                  curSubIndex === subNo
-                    ? 'icon-arrow-right-act'
-                    : 'icon-arrow-right'
-                ]"
-              ></i>
-            </span>
-            <span
-              class="nav-item-info"
-              v-if="nav.router === 'WaitTask' && waitTaskCount"
-              >{{ waitTaskCount }}</span
-            >
-          </div>
-        </li>
-      </ul>
-    </div>
-
-    <div class="home-body">
-      <div class="home-main">
-        <div class="home-breadcrumb" v-if="breadcrumbs.length">
-          <el-breadcrumb separator=">">
-            <el-breadcrumb-item :to="{ name: 'Home' }">
-              <i class="icon icon-home" style="margin-top: -2px;"></i>
-            </el-breadcrumb-item>
-            <el-breadcrumb-item
-              v-for="(bread, index) in breadcrumbs"
-              :key="index"
-              >{{ bread.title }}</el-breadcrumb-item
-            >
-          </el-breadcrumb>
-        </div>
-
-        <!-- home-view: page detail -->
-        <div class="home-view">
-          <!-- <router-view /> -->
-          <keep-alive :include="keepAliveRoutes">
-            <router-view />
-          </keep-alive>
-        </div>
-      </div>
-    </div>
-
-    <!-- popover menu-->
-    <el-dialog
-      class="menu-dialog"
-      :visible.sync="menuDailogIsShow"
-      title="导航菜单"
-      top="60px"
-      fullscreen
-      :close-on-click-modal="false"
-      :close-on-press-escape="false"
-      append-to-body
-    >
+    <div class="home-navs" v-if="curMenu.children">
       <div
-        class="home-navs home-navs-full"
-        v-for="(mainNav, mainNo) in navs"
-        :key="mainNo"
+        v-for="(submenu, sindex) in curMenu.children"
+        :key="sindex"
+        class="nav-part"
       >
         <div class="nav-head">
-          <i :class="['icon', `icon-${mainNav.router}-gray`]"></i>
-          <span>{{ mainNav.title }}</span>
+          <i :class="submenu.icon"></i>
+          <span>{{ submenu.title }}</span>
         </div>
         <ul class="nav-list">
           <li
             class="nav-item"
-            v-for="(nav, subNo) in mainNav.children"
-            :key="subNo"
+            v-for="(nav, navNo) in submenu.children"
+            :key="navNo"
           >
             <div
               :class="[
                 'nav-item-main',
-                {
-                  'nav-item-main-act':
-                    curMainIndex === mainNo && curSubIndex === subNo
-                }
+                { 'nav-item-main-act': curActNav === nav.router }
               ]"
-              @click="switchNavDetail(mainNo, subNo)"
+              @click="toNav(nav)"
             >
               <p class="nav-item-cont">{{ nav.title }}</p>
               <span class="nav-item-icon nav-item-icon-right">
                 <i
                   :class="[
                     'icon',
-                    curMainIndex === mainNo && curSubIndex === subNo
+                    curActNav === nav.router
                       ? 'icon-arrow-right-act'
                       : 'icon-arrow-right'
                   ]"
@@ -160,20 +83,45 @@
           </li>
         </ul>
       </div>
-      <div class="menu-logout" @click="toLogout">
-        <i class="el-icon-switch-button"></i>
+    </div>
+
+    <div class="home-body">
+      <div class="home-main">
+        <div class="home-breadcrumb" v-if="breadcrumbs.length">
+          <el-breadcrumb separator=">">
+            <el-breadcrumb-item>
+              <i class="icon icon-home" style="margin-top: -2px;"></i>
+            </el-breadcrumb-item>
+            <el-breadcrumb-item
+              v-for="(bread, index) in breadcrumbs"
+              :key="index"
+              >{{ bread.title }}</el-breadcrumb-item
+            >
+          </el-breadcrumb>
+        </div>
+
+        <!-- home-view: page detail -->
+        <div class="home-view">
+          <!-- <router-view /> -->
+          <keep-alive :include="keepAliveRoutes">
+            <router-view />
+          </keep-alive>
+        </div>
       </div>
-    </el-dialog>
+    </div>
+
+    <!-- popover menu-->
+    <!-- TODO: -->
+
     <!-- 修改密码 -->
     <reset-pwd @modified="logoutAction" ref="ResetPwd"></reset-pwd>
   </div>
 </template>
 
 <script>
-import { mapState, mapActions } from "vuex";
+// import { mapState, mapActions } from "vuex";
 import localNavs from "@/constants/navs";
 import { deepCopy } from "@/plugins/utils";
-import { MENU_ROUTER_DICT } from "@/constants/enumerate";
 import { logout, sysMenu } from "../modules/login/api";
 import ResetPwd from "../modules/base/components/ResetPwd";
 
@@ -182,47 +130,49 @@ export default {
   components: { ResetPwd },
   data() {
     return {
-      navs: [],
-      validRoutes: [],
-      curMainIndex: 0,
-      curSubIndex: 0,
+      menus: [],
+      curMenu: { name: "" },
+      curActNav: "",
       breadcrumbs: [],
+      validRoutes: [],
       username: this.$ls.get("user", { name: "" }).name,
       IS_SUPER_ADMIN: this.$ls
         .get("user", { roleCode: "" })
         .roleCode.includes("SUPER_ADMIN"),
-      menuDailogIsShow: false
+      menuDailogIsShow: false,
+      waitTaskCount: 0
     };
   },
   watch: {
     $route(val) {
+      if (val.name === "Home") return;
       this.actCurNav();
     }
   },
   computed: {
-    ...mapState("examCenter", ["waitTaskCount"]),
-    curNav() {
-      return this.navs[this.curMainIndex];
-    },
+    // ...mapState("examCenter", ["waitTaskCount"]),
     keepAliveRoutes() {
       return this.$store.state.keepAliveRoutes;
     }
   },
   created() {
     this.getMenus();
-    // this.navs = localNavs;
+    // this.menus = localNavs;
     // this.actCurNav();
   },
   methods: {
-    ...mapActions("examCenter", ["updateWaitTaskCount"]),
+    // ...mapActions("examCenter", ["updateWaitTaskCount"]),
     async getMenus() {
       const data = await sysMenu();
-      this.navs = this.menusToTree(data.records);
+      const { menus, firstRouter } = this.menusToTree(data.records);
+      console.log(menus, firstRouter);
+      this.menus = menus;
 
       if (this.$route.name === "Home") {
         this.$router.replace({
-          name: this.navs[0].children[0].router
+          name: firstRouter
         });
+        return;
       } else {
         if (!this.validRoutes.includes(this.$route.name)) {
           this.$router.replace({
@@ -230,116 +180,95 @@ export default {
           });
           return;
         }
-      }
 
-      this.actCurNav();
-      if (
-        this.validRoutes.includes("WaitTask") &&
-        this.navs[this.curMainIndex].router === "exam-center"
-      ) {
-        this.updateWaitTaskCount();
+        this.actCurNav();
       }
     },
     menusToTree(menus) {
-      if (this.IS_SUPER_ADMIN) {
-        const names = {
-          todoExam: "待办任务(考务)",
-          todoTaskManager: "待办任务(命题)",
-          doneTaskManager: "已办任务(命题)"
-        };
-        menus.forEach(item => {
-          item.name = names[item.url] || item.name;
-        });
-      }
       let navTree = deepCopy(localNavs);
       let validRoutes = [];
-      const anchorNav = (menu, navs) => {
-        const name = MENU_ROUTER_DICT[menu.url];
-        navs.forEach(item => {
-          if (item.router === name) {
-            item.fixed = true;
-            item.title = menu.name;
-            validRoutes.push(item.router);
+      let validMenuDict = {};
+      let firstRouter = "";
+      menus.forEach(item => (validMenuDict[item.url] = item.name));
 
-            if (menu.parentId !== null && item["children"]) {
-              item.children.map(el => {
-                el.fixed = true;
-                validRoutes.push(el.router);
-              });
-            }
-            return;
-          } else {
-            if (item["children"]) anchorNav(menu, item.children);
-          }
-        });
-      };
-      const clearNoFixed = navs => {
+      const anchorNav = menus => {
         let list = [];
-        navs.forEach(nav => {
-          if (nav["fixed"]) {
-            let navItem = { title: nav.title, router: nav.router };
-            if (nav["children"])
-              navItem.children = clearNoFixed(nav["children"]);
-            list.push(navItem);
+        menus.forEach(item => {
+          const routerOrName = item["router"] || item["name"];
+          if (!validMenuDict[routerOrName]) return;
+
+          if (!firstRouter && item["router"]) firstRouter = item["router"];
+          item.title = validMenuDict[routerOrName];
+          validRoutes.push(routerOrName);
+          let navItem = { ...item };
+          if (item["children"]) {
+            navItem.children = anchorNav(item.children);
           }
+          list.push(navItem);
         });
         return list;
       };
 
-      menus.forEach(menu => {
-        anchorNav(menu, navTree);
-      });
       this.validRoutes = validRoutes;
-      return clearNoFixed(navTree);
+
+      return { menus: anchorNav(navTree), firstRouter };
+    },
+    toMenu(menu) {
+      this.curMenu = menu;
+      const firstRouter = menu.children[0].children[0];
+      this.toNav(firstRouter);
     },
-    switchNav(subNo) {
-      const curSubItem = this.curNav.children[subNo];
-      if (curSubItem.router === this.$route.name) return;
-      this.$router.push({ name: curSubItem.router });
+    toNav(nav) {
+      if (nav.router === this.$route.name) return;
+      this.curActNav = nav.router;
+      this.$router.push({ name: nav.router });
     },
     actCurNav() {
-      const relate = this.$route.meta && this.$route.meta.relate;
-      const routerName = relate ? relate.split("/")[0] : this.$route.name;
-
-      this.navs.forEach((item, index) => {
-        item.children.forEach((elem, pindex) => {
-          if (elem.router === routerName) {
-            this.curSubIndex = pindex;
-            this.curMainIndex = index;
-            this.breadcrumbs = [
-              { title: item.title, router: item.router },
-              { title: elem.title, router: elem.router }
+      const routerName = this.$route.name;
+      let breadcrumbs = [];
+      const getRouterPath = (navs, pathList) => {
+        navs.forEach(nav => {
+          let navPathList = [...pathList];
+          if (breadcrumbs.length) return;
+          if (nav["router"] === routerName) {
+            breadcrumbs = [
+              ...navPathList,
+              { title: nav.title, router: nav.router, isRouter: true }
+            ];
+            return;
+          } else {
+            const routerOrName = nav["router"] || nav["name"];
+            navPathList = [
+              ...navPathList,
+              {
+                title: nav.title,
+                router: routerOrName,
+                isRouter: !!nav["router"]
+              }
             ];
+            if (nav["children"]) {
+              getRouterPath(nav.children, navPathList);
+            }
           }
         });
-      });
+      };
 
-      if (relate) this.getMoreBreadcrumbs(relate);
-    },
-    getMoreBreadcrumbs(relate) {
-      const curSubNav = this.navs[this.curMainIndex].children[this.curSubIndex];
-      if (!curSubNav.children || !curSubNav.children.length) return;
+      getRouterPath(this.menus, []);
 
-      relate
-        .split("/")
-        .slice(1)
-        .map(routerName => {
-          const matchRouter = curSubNav.children.find(
-            elem => elem.router === routerName
-          );
-          if (matchRouter)
-            this.breadcrumbs.push({
-              title: matchRouter.title,
-              router: matchRouter.router
-            });
-        });
-    },
-    toPage(mainIndex, subIndex) {
-      const elem = this.navs[mainIndex].children[subIndex];
-      if (elem.router === this.$route.name) return;
-      this.$router.push({
-        name: elem.router
-      });
+      const curRouter = breadcrumbs.find(item => item.isRouter);
+      this.curActNav = curRouter.router;
+      this.curMenu = this.menus.find(
+        menu => menu.name === breadcrumbs[0].router
+      );
+
+      this.breadcrumbs = breadcrumbs;
+
+      if (
+        this.validRoutes.includes("WaitTask") &&
+        this.curMenu.name === "exam"
+      ) {
+        // this.updateWaitTaskCount();
+      }
     },
     toLogout() {
       this.$confirm("确定要退出登录吗?", "提示", {
@@ -361,9 +290,8 @@ export default {
     showMenu() {
       this.menuDailogIsShow = !this.menuDailogIsShow;
     },
-    switchNavDetail(mainNo, subNo) {
-      this.curMainIndex = mainNo;
-      this.switchNav(subNo);
+    toNavDetail(mainNo, subNo) {
+      this.toNav(subNo);
       this.showMenu();
     }
   }

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.