zhangjie 3 vuotta sitten
vanhempi
commit
1f95d93496

+ 101 - 76
src/constants/navs.js

@@ -1,180 +1,205 @@
 const navs = [
   {
-    title: "考试中心",
-    name: "exam",
+    name: "考试中心",
+    url: "exam",
     icon: "el-icon-receiving",
     children: [
       {
-        title: "我的工作台",
-        name: "work",
+        name: "我的工作台",
+        url: "work",
         icon: "el-icon-s-cooperation",
         children: [
           {
-            title: "待办任务",
-            router: "WaitTask"
+            name: "待办任务",
+            url: "WaitTask",
+            isRouter: true
           }
           // {
-          //   title: "已办任务",
-          //   router: "DoneTask"
+          //   name: "已办任务",
+          //   url: "DoneTask",isRouter: true
           // }
         ]
       },
       {
-        title: "命题管理",
-        name: "paper",
+        name: "命题管理",
+        url: "paper",
         icon: "el-icon-s-order",
         children: [
           {
-            title: "命题任务管理",
-            router: "ExamTaskManage"
+            name: "命题任务管理",
+            url: "ExamTaskManage",
+            isRouter: true
           },
           {
-            title: "入库申请",
-            router: "TaskApplyManage"
+            name: "入库申请",
+            url: "TaskApplyManage",
+            isRouter: true
           },
           {
-            title: "入库审核",
-            router: "TaskReviewManage"
+            name: "入库审核",
+            url: "TaskReviewManage",
+            isRouter: true
           },
           {
-            title: "卷库查询",
-            router: "TaskPaperManage"
+            name: "卷库查询",
+            url: "TaskPaperManage",
+            isRouter: true
           }
         ]
       },
       {
-        title: "印刷管理",
-        name: "print",
+        name: "印刷管理",
+        url: "print",
         icon: "el-icon-s-check",
         children: [
           {
-            title: "印刷计划管理",
-            router: "PrintPlanManage"
+            name: "印刷计划管理",
+            url: "PrintPlanManage",
+            isRouter: true
           },
           {
-            title: "考务数据导入",
-            router: "BusinessDataExport"
+            name: "考务数据导入",
+            url: "BusinessDataExport",
+            isRouter: true
           },
           {
-            title: "考务明细查询",
-            router: "BusinessDataDetail"
+            name: "考务明细查询",
+            url: "BusinessDataDetail",
+            isRouter: true
           },
           {
-            title: "关联试卷管理",
-            router: "PlanLinkPaper"
+            name: "关联试卷管理",
+            url: "PlanLinkPaper",
+            isRouter: true
           },
           {
-            title: "印刷任务管理",
-            router: "PrintTaskManage"
+            name: "印刷任务管理",
+            url: "PrintTaskManage",
+            isRouter: true
           }
-          // {
-          //   title: "印刷监控查询",
-          //   router: "PrintProgressManage"
-          // }
         ]
       },
       {
-        title: "数据管理",
-        name: "data",
+        name: "数据管理",
+        url: "data",
         icon: "el-icon-set-up",
         children: [
           {
-            title: "任务管理",
-            router: "DataTaskManage"
+            name: "任务管理",
+            url: "DataTaskManage",
+            isRouter: true
           }
         ]
       }
     ]
   },
   {
-    title: "基础配置",
-    name: "base",
+    name: "基础配置",
+    url: "base",
     icon: "el-icon-setting",
     children: [
       {
-        title: "用户管理",
-        name: "user",
+        name: "用户管理",
+        url: "user",
         icon: "el-icon-user-solid",
         children: [
           {
-            title: "组织架构",
-            router: "OrganizationManage"
+            name: "组织架构",
+            url: "OrganizationManage",
+            isRouter: true
           },
           {
-            title: "用户管理",
-            router: "UserManage"
+            name: "用户管理",
+            url: "UserManage",
+            isRouter: true
           },
           {
-            title: "角色管理",
-            router: "RoleManage"
+            name: "角色管理",
+            url: "RoleManage",
+            isRouter: true
           }
         ]
       },
       {
-        title: "配置管理",
-        name: "rule",
+        name: "配置管理",
+        url: "rule",
         icon: "el-icon-s-tools",
         children: [
           {
-            title: "通用规则",
-            router: "CommonRule"
+            name: "通用规则",
+            url: "CommonRule",
+            isRouter: true
+          },
+          {
+            name: "题卡规则管理",
+            url: "CardRuleManage",
+            isRouter: true
           },
           {
-            title: "题卡规则管理",
-            router: "CardRuleManage"
+            name: "通卡模板",
+            url: "CommonCardTemplate",
+            isRouter: true
           },
           {
-            title: "通卡模板",
-            router: "CommonCardTemplate"
+            name: "变量印品模板",
+            url: "ParamPrintTemplate",
+            isRouter: true
           },
           {
-            title: "变量印品模板",
-            router: "ParamPrintTemplate"
+            name: "普通印品模板",
+            url: "CommonPrintTemplate",
+            isRouter: true
           },
           {
-            title: "普通印品模板",
-            router: "CommonPrintTemplate"
+            name: "审批记录管理",
+            url: "ApproveRecord",
+            isRouter: true
           },
           {
-            title: "印刷计划合并管理",
-            router: "PrintPlanPushManage"
+            name: "印刷计划合并管理",
+            url: "PrintPlanPushManage",
+            isRouter: true
           }
         ]
       },
       {
-        title: "字典管理",
-        name: "rule",
+        name: "字典管理",
+        url: "rule",
         icon: "el-icon-s-tools",
         children: [
           {
-            title: "校区管理",
-            router: "CampusManage"
+            name: "校区管理",
+            url: "CampusManage",
+            isRouter: true
           },
           {
-            title: "学生基本信息管理",
-            router: "StudentManage"
+            name: "学生基本信息管理",
+            url: "StudentManage",
+            isRouter: true
           },
           {
-            title: "课程管理",
-            router: "CourseManage"
+            name: "课程管理",
+            url: "CourseManage",
+            isRouter: true
           }
         ]
       }
     ]
   },
   {
-    title: "客服制卡",
-    name: "customer",
+    name: "客服制卡",
+    url: "customer",
     icon: "el-icon-service",
     children: [
       {
-        title: "客服制卡",
-        name: "customer",
+        name: "客服制卡",
+        url: "customer",
         icon: "el-icon-s-custom",
         children: [
           {
-            title: "题卡审核",
-            router: "CustomerCard"
+            name: "题卡审核",
+            url: "CustomerCard",
+            isRouter: true
           }
         ]
       }

+ 11 - 0
src/modules/base/api.js

@@ -47,6 +47,9 @@ export const userBoundRoles = userId => {
 export const menuAuthList = datas => {
   return $postParam("/api/admin/sys/privilege/list_auth", datas);
 };
+export const privilegeList = datas => {
+  return $postParam("/api/admin/sys/privilege/list", datas);
+};
 export const roleBoundPrivileges = roleId => {
   return $postParam("/api/admin/sys/privilege/get_role_privileges", { roleId });
 };
@@ -117,6 +120,14 @@ export const deleteCourse = idList => {
 export const updateCourse = datas => {
   return $post("/api/admin/basic/course/save", datas);
 };
+// flow-manage
+export const flowListPage = datas => {
+  return $postParam("/api/admin/flow/list", datas);
+};
+// approve-record
+export const approveRecordListPage = datas => {
+  return $postParam("/api/admin/flow/approve/list", datas);
+};
 
 // dict --------------------------------->
 // campus-manage

+ 35 - 15
src/modules/base/components/ModifyRole.vue

@@ -42,14 +42,13 @@
 </template>
 
 <script>
-import { updateRole, menuAuthList, roleBoundPrivileges } from "../api";
+import { updateRole, privilegeList, roleBoundPrivileges } from "../api";
 import PrivilegeSet from "./PrivilegeSet";
-import navs from "./privilege/navs.json";
+// import navs from "./privilege/navs.json";
 
 const initModalForm = {
   id: null,
   name: "",
-  type: "CUSTOM",
   privilegeIds: []
 };
 
@@ -76,7 +75,7 @@ export default {
     return {
       modalIsShow: false,
       isSubmit: false,
-      menus: navs,
+      menus: [],
       modalForm: {},
       rules: {
         name: [
@@ -92,31 +91,52 @@ export default {
   },
   created() {
     // this.getMenus();
+    // this.buildMenuTree(navs);
   },
   methods: {
     async getMenus() {
-      const data = await menuAuthList();
+      const data = await privilegeList();
       const needHideModules = ["common", "customer"];
       if (data)
-        this.menus = data.filter(item => !needHideModules.includes(item.url));
+        this.menus = data
+          .filter(item => !needHideModules.includes(item.url))
+          .map(item => {
+            item.parentId = null;
+            return item;
+          });
+    },
+    buildMenuTree(menus) {
+      const buildTree = list => {
+        list.forEach(item => {
+          const children = menus.filter(m => m.parentId === item.id);
+          if (children.length) {
+            item.children = children;
+            buildTree(children);
+          }
+        });
+        return list;
+      };
+
+      const navs = menus.filter(m => m.parentId === "-1");
+      this.menus = buildTree(navs);
+
+      this.menus.forEach(item => {
+        item.parentId = null;
+      });
     },
     async visibleChange() {
+      let privilegeIds = [];
       if (this.instance.id) {
         this.modalForm = this.$objAssign(initModalForm, this.instance);
-        if (this.instance.type === "CUSTOM") {
-          let privilegeIds = await roleBoundPrivileges(this.instance.id);
-          privilegeIds = privilegeIds || [];
-          this.modalForm.privilegeIds = privilegeIds;
-          this.$nextTick(() => {
-            this.$refs.PrivilegeSet.buildTableData(privilegeIds);
-          });
-        }
+        privilegeIds = await roleBoundPrivileges(this.instance.id);
+        privilegeIds = privilegeIds || [];
+        this.modalForm.privilegeIds = privilegeIds;
       } else {
         this.modalForm = { ...initModalForm };
-        this.$refs.MenuTree.setCheckedKeys([]);
       }
       this.$nextTick(() => {
         this.$refs.modalFormComp.clearValidate();
+        this.$refs.PrivilegeSet.buildTableData(privilegeIds);
       });
     },
     cancel() {

+ 21 - 9
src/modules/base/components/PrivilegeSet.vue

@@ -19,7 +19,11 @@
               v-for="item in col.datas"
               :key="item.field"
             >
-              <el-checkbox v-model="item.enable">{{ item.name }}</el-checkbox>
+              <el-checkbox
+                v-model="item.enable"
+                @change="enable => typeSelectChange(row, enable)"
+                >{{ item.name }}</el-checkbox
+              >
             </div>
           </div>
           <div v-else></div>
@@ -54,6 +58,7 @@ export default {
     initData() {
       this.maxDeep = this.getNavsDeep();
       this.tableHead = this.buildTableHead();
+      // this.buildTableData();
     },
     getNavsDeep() {
       let maxDeep = 0;
@@ -78,17 +83,17 @@ export default {
       headers = [
         ...headers,
         "页面",
-        "查询条件限制",
-        "功能按钮可用性",
-        "列表展示",
-        "操作列权限"
+        "查询条件",
+        "功能按钮",
+        "列表展示",
+        "操作列"
       ];
       return headers;
     },
     buildTableData(privilegeIds = []) {
       let tableData = [];
-      let tableColumnCount = this.maxDeep + 6;
-      const pageSetTypes = ["querys", "buttons", "columns", "links"];
+      let tableColumnCount = this.maxDeep + 5;
+      const pageSetTypes = ["conditions", "buttons", "lists", "links"];
       const buildData = (navs, deep) => {
         ++deep;
         navs.forEach(nav => {
@@ -107,7 +112,7 @@ export default {
                 ? []
                 : nav[type].map(elem => {
                     let data = { ...elem };
-                    // todo:data.status
+                    data.enable = privilegeIds.includes(elem.id);
                     return data;
                   });
               columns[this.maxDeep + index + 1] = { type, datas };
@@ -117,7 +122,7 @@ export default {
           tableData.push({
             id: nav.id,
             name: nav.name,
-            enable: true,
+            enable: privilegeIds.includes(nav.id),
             type: nav.type,
             parentId: nav.parentId,
             isPage,
@@ -158,6 +163,13 @@ export default {
       this.changeParentNodeSelected(row.parentId, enable);
       this.changeChildrenNodeSelected(row.id, enable);
     },
+    typeSelectChange(row, enable) {
+      if (!row.enable && enable) {
+        row.enable = enable;
+        this.changeParentNodeSelected(row.parentId, enable);
+        this.changeChildrenNodeSelected(row.id, enable);
+      }
+    },
     changRowColumnEnable(row, enable) {
       if (!row.isPage) return;
       row.columns.forEach(column => {

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 610 - 489
src/modules/base/components/privilege/navs.json


+ 0 - 288
src/modules/base/components/privilege/privilege.json

@@ -1,288 +0,0 @@
-[
-  {
-    "id": "001",
-    "name": "基础管理",
-    "url": "base",
-    "selected": true,
-    "parentId": null
-  },
-  {
-    "id": "002",
-    "name": "机构管理",
-    "url": "org",
-    "selected": true,
-    "parentId": "001"
-  },
-  {
-    "id": "003",
-    "name": "学校列表",
-    "url": "RightManage",
-    "selected": true,
-    "parentId": "002",
-    "pageSet": {
-      "query": {
-        "schoolCode": "none",
-        "schoolName": "none",
-        "status": "none"
-      },
-      "button": {
-        "search": "valid",
-        "create": "valid",
-        "batDisable": "valid",
-        "batEnable": "valid"
-      },
-      "columns": {
-        "schoolCode": "show",
-        "schoolName": "show",
-        "status": "show",
-        "comment": "show",
-        "action": "show"
-      },
-      "rowAction": {
-        "edit": "valid",
-        "enable": "valid"
-      }
-    }
-  },
-  {
-    "id": "004",
-    "name": "合作方列表",
-    "url": "CustomerManage",
-    "selected": true,
-    "parentId": "002",
-    "pageSet": {
-      "query": {
-        "customerCode": "none",
-        "customerName": "none",
-        "status": "dataRange"
-      },
-      "button": {
-        "search": "valid",
-        "create": "valid",
-        "batDisable": "valid",
-        "batEnable": "valid"
-      },
-      "columns": {
-        "customerCode": "show",
-        "customerName": "show",
-        "status": "show",
-        "comment": "show",
-        "action": "show"
-      },
-      "rowAction": {
-        "edit": "valid",
-        "enable": "valid"
-      }
-    }
-  },
-  {
-    "id": "005",
-    "name": "角色管理",
-    "url": "role",
-    "selected": true,
-    "parentId": "001"
-  },
-  {
-    "id": "006",
-    "name": "角色列表",
-    "url": "RoleManage",
-    "selected": true,
-    "parentId": "005"
-  },
-  {
-    "id": "007",
-    "name": "用户管理",
-    "url": "user",
-    "selected": true,
-    "parentId": "001"
-  },
-  {
-    "id": "008",
-    "name": "角色列表",
-    "url": "UserManage",
-    "selected": true,
-    "parentId": "007"
-  },
-  {
-    "id": "009",
-    "name": "单元管理",
-    "url": "unit",
-    "selected": true,
-    "parentId": "001"
-  },
-  {
-    "id": "010",
-    "name": "课程单元",
-    "url": "CourseUnit",
-    "selected": true,
-    "parentId": "009"
-  },
-  {
-    "id": "011",
-    "name": "机构单元",
-    "url": "OrgUnit",
-    "selected": true,
-    "parentId": "009"
-  },
-  {
-    "id": "101",
-    "name": "子机构页面",
-    "url": "SubOrgUnit",
-    "selected": true,
-    "parentId": "011"
-  },
-  {
-    "id": "012",
-    "name": "资源管理",
-    "url": "source",
-    "selected": true,
-    "parentId": null
-  },
-  {
-    "id": "013",
-    "name": "学生管理",
-    "url": "student",
-    "selected": true,
-    "parentId": "012"
-  },
-  {
-    "id": "014",
-    "name": "学生列表",
-    "url": "StudentManage",
-    "selected": true,
-    "parentId": "013"
-  },
-  {
-    "id": "015",
-    "name": "考生列表",
-    "url": "ExamStudentManage",
-    "selected": true,
-    "parentId": "013"
-  },
-  {
-    "id": "016",
-    "name": "试卷管理",
-    "url": "paper",
-    "selected": true,
-    "parentId": "012"
-  },
-  {
-    "id": "017",
-    "name": "试卷列表",
-    "url": "PaperManage",
-    "selected": true,
-    "parentId": "016"
-  },
-  {
-    "id": "018",
-    "name": "模板管理",
-    "url": "template",
-    "selected": true,
-    "parentId": "012"
-  },
-  {
-    "id": "019",
-    "name": "通用模板",
-    "url": "CommonTemplate",
-    "selected": true,
-    "parentId": "018"
-  },
-  {
-    "id": "020",
-    "name": "自定义模板",
-    "url": "CustomTemplate",
-    "selected": true,
-    "parentId": "018"
-  },
-  {
-    "id": "021",
-    "name": "进程管理",
-    "url": "process",
-    "selected": true,
-    "parentId": null
-  },
-  {
-    "id": "022",
-    "name": "任务管理",
-    "url": "task",
-    "selected": true,
-    "parentId": "021"
-  },
-  {
-    "id": "023",
-    "name": "任务列表",
-    "url": "TaskManage",
-    "selected": true,
-    "parentId": "022"
-  },
-  {
-    "id": "102",
-    "name": "规则详情",
-    "url": "RuleDetail",
-    "selected": true,
-    "parentId": "023"
-  },
-  {
-    "id": "024",
-    "name": "任务详情",
-    "url": "TaskDetail",
-    "selected": true,
-    "parentId": "022"
-  },
-  {
-    "id": "103",
-    "name": "任务清单",
-    "url": "TaskList",
-    "selected": true,
-    "parentId": "024"
-  },
-  {
-    "id": "104",
-    "name": "日志记录",
-    "url": "TaskLog",
-    "selected": true,
-    "parentId": "024"
-  },
-  {
-    "id": "025",
-    "name": "验证管理",
-    "url": "check",
-    "selected": true,
-    "parentId": "021"
-  },
-  {
-    "id": "026",
-    "name": "验证总览",
-    "url": "CheckOverview",
-    "selected": true,
-    "parentId": "025"
-  },
-  {
-    "id": "105",
-    "name": "数据验证",
-    "url": "DataCheck",
-    "selected": true,
-    "parentId": "026"
-  },
-  {
-    "id": "106",
-    "name": "机构进度详情",
-    "url": "OrgProcessDetail",
-    "selected": true,
-    "parentId": "026"
-  },
-  {
-    "id": "027",
-    "name": "邮寄管理",
-    "url": "mail",
-    "selected": true,
-    "parentId": "021"
-  },
-  {
-    "id": "028",
-    "name": "箱贴目录",
-    "url": "MailManage",
-    "selected": true,
-    "parentId": "027"
-  }
-]

+ 14 - 7
src/modules/base/router.js

@@ -8,10 +8,12 @@ import CardRuleManage from "./views/CardRuleManage.vue";
 import CommonCardTemplate from "./views/CommonCardTemplate.vue";
 import ParamPrintTemplate from "./views/ParamPrintTemplate.vue";
 import CommonPrintTemplate from "./views/CommonPrintTemplate.vue";
+import PrintPlanPushManage from "./views/PrintPlanPushManage.vue";
+import ApproveRecord from "./views/ApproveRecord.vue";
+// dict
 import CampusManage from "./views/CampusManage.vue";
-import CourseManage from "./views/CourseManage.vue";
 import StudentManage from "./views/StudentManage.vue";
-import PrintPlanPushManage from "./views/PrintPlanPushManage.vue";
+import CourseManage from "./views/CourseManage.vue";
 
 export default [
   {
@@ -54,6 +56,16 @@ export default [
     name: "CommonPrintTemplate",
     component: CommonPrintTemplate
   },
+  {
+    path: "/base/print-plan-push-manage",
+    name: "PrintPlanPushManage",
+    component: PrintPlanPushManage
+  },
+  {
+    path: "/base/approve-record",
+    name: "ApproveRecord",
+    component: ApproveRecord
+  },
   {
     path: "/base/course-manage",
     name: "CourseManage",
@@ -68,10 +80,5 @@ export default [
     path: "/base/student-manage",
     name: "StudentManage",
     component: StudentManage
-  },
-  {
-    path: "/base/print-plan-push-manage",
-    name: "PrintPlanPushManage",
-    component: PrintPlanPushManage
   }
 ];

+ 107 - 0
src/modules/base/views/ApproveRecord.vue

@@ -0,0 +1,107 @@
+<template>
+  <div class="approve-record">
+    <div class="part-box part-box-filter part-box-border">
+      <el-form ref="FilterForm" label-position="left" label-width="85px" inline>
+        <el-form-item label="发起人:" label-width="75px">
+          <el-input
+            style="width: 142px;"
+            v-model.trim="filter.startName"
+            placeholder="请输入发起人"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item label-width="0px">
+          <el-button type="primary" icon="el-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
+          type="index"
+          label="序号"
+          width="70"
+          align="center"
+          :index="indexMethod"
+        ></el-table-column>
+        <el-table-column prop="flowId" label="流程ID"></el-table-column>
+        <el-table-column prop="startName" label="发起人"></el-table-column>
+        <el-table-column prop="createTime" label="创建时间">
+          <span slot-scope="scope">{{
+            scope.row.createTime | timestampFilter
+          }}</span>
+        </el-table-column>
+        <el-table-column
+          prop="primaryApproveName"
+          label="第一级审核人"
+        ></el-table-column>
+        <el-table-column
+          prop="primaryApproveRemark"
+          label="审核意见"
+        ></el-table-column>
+        <el-table-column prop="secondApproveName" label="第二级审核人">
+        </el-table-column>
+        <el-table-column prop="secondApproveRemark" label="审核意见">
+        </el-table-column>
+        <el-table-column prop="statusStr" label="状态"> </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>
+  </div>
+</template>
+
+<script>
+import { approveRecordListPage } from "../api";
+
+export default {
+  name: "approve-record",
+  data() {
+    return {
+      filter: {
+        startName: ""
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      dataList: []
+    };
+  },
+  computed: {
+    IS_SCHOOL_ADMIN() {
+      return this.userRoles.includes("SCHOOL_ADMIN");
+    }
+  },
+  created() {
+    this.toPage(1);
+  },
+  methods: {
+    async getList() {
+      const datas = {
+        ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size
+      };
+      const data = await approveRecordListPage(datas);
+      this.dataList = data.records;
+      this.total = data.total;
+    },
+    toPage(page) {
+      this.current = page;
+      this.getList();
+    }
+  }
+};
+</script>

+ 2 - 2
src/modules/base/views/CourseManage.vue

@@ -115,7 +115,7 @@
 </template>
 
 <script>
-import { courseQuery, deleteCourse } from "../api";
+import { courseListPage, deleteCourse } from "../api";
 import pickerOptions from "@/constants/datePickerOptions";
 import ModifyCourse from "../components/ModifyCourse";
 import UploadButton from "../../../components/UploadButton";
@@ -158,7 +158,7 @@ export default {
         datas.startCreateTime = this.createTime[0];
         datas.endCreateTime = this.createTime[1];
       }
-      const data = await courseQuery(datas);
+      const data = await courseListPage(datas);
       this.courses = data.records;
       this.total = data.total;
     },

+ 132 - 0
src/modules/base/views/FlowManage.vue

@@ -0,0 +1,132 @@
+<template>
+  <div class="flow-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.name"
+            placeholder="请输入内容"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" icon="el-icon-search" @click="toPage(1)"
+            >查询</el-button
+          >
+        </el-form-item>
+      </el-form>
+      <div class="part-box-action">
+        <el-button
+          type="primary"
+          icon="el-icon-circle-plus-outline"
+          @click="toAdd"
+          >添加流程</el-button
+        >
+      </div>
+    </div>
+    <div class="part-box">
+      <el-table ref="TableList" :data="dataList" border stripe>
+        <el-table-column
+          type="index"
+          label="序号"
+          width="70"
+          align="center"
+          :index="indexMethod"
+        ></el-table-column>
+        <el-table-column prop="name" 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>
+          </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"
+      @modified="getList"
+    ></modify-role>
+  </div>
+</template>
+
+<script>
+import { flowListPage } from "../api";
+import ModifyRole from "../components/ModifyRole";
+
+export default {
+  name: "flow-manage",
+  components: {
+    ModifyRole
+  },
+  data() {
+    return {
+      filter: {
+        name: ""
+      },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
+      dataList: [],
+      curRole: {}
+    };
+  },
+  created() {
+    this.toPage(1);
+  },
+  methods: {
+    async getList() {
+      const datas = {
+        ...this.filter,
+        pageNumber: this.current,
+        pageSize: this.size
+      };
+      const data = await flowListPage(datas);
+      this.dataList = 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();
+    }
+  }
+};
+</script>

+ 7 - 0
src/modules/exam/api.js

@@ -69,6 +69,13 @@ export const updateTaskApply = datas => {
 export const cancelOrRestartTaskApply = ({ id, status }) => {
   return $post("/api/admin/exam/task/apply_status", { id, status });
 };
+// 命题老师创建命题任务
+export const teacherCreateTaskApply = datas => {
+  return $post("/api/admin/exam/task/save_task_apply", datas);
+};
+export const switchCardCreateMethod = examTaskId => {
+  return $post("/api/admin/exam/task/switch_card", { examTaskId });
+};
 
 // task-review-manage
 export const taskReviewUnauditedListPage = datas => {

+ 14 - 7
src/modules/exam/components/ApplyContent.vue

@@ -87,7 +87,7 @@
 
       <el-form-item label="单次抽卷卷型数量:" label-width="150">
         <el-input-number
-          v-model="curTaskApply.fetchCount"
+          v-model="curTaskApply.drawCount"
           :min="1"
           :max="maxFetchCount"
           :step="1"
@@ -217,7 +217,12 @@
 <script>
 import UploadPaperDialog from "./UploadPaperDialog";
 import CardOptionDialog from "./CardOptionDialog";
-import { taskApplyDetail, updateTaskApply, updateTaskReview } from "../api";
+import {
+  taskApplyDetail,
+  updateTaskApply,
+  updateTaskReview,
+  switchCardCreateMethod
+} from "../api";
 import { attachmentPreview } from "../../login/api";
 import SimpleImagePreview from "@/components/SimpleImagePreview";
 import { CARD_SOURCE_TYPE } from "@/constants/enumerate";
@@ -233,7 +238,7 @@ const initTaskApply = {
   remark: "",
   courseCode: "",
   courseName: "",
-  fetchCount: 1,
+  drawCount: 1,
   // 题卡状态
   status: "",
   // 考务规则
@@ -473,10 +478,12 @@ export default {
       this.clearMakeMethod();
       this.toCreateOrViewCard();
     },
-    clearMakeMethod() {
-      this.curTaskApply.makeMethod = "";
-      this.curTaskApply.cardId = "";
-      // TODO:清除后台记录的题卡
+    async clearMakeMethod() {
+      // 清除后台记录的题卡
+      if (this.examTask.id) await switchCardCreateMethod(this.examTask.id);
+
+      this.examTaskDetail.makeMethod = "";
+      this.examTaskDetail.cardId = "";
     },
     getTaskData() {
       let data = { ...this.curTaskApply };

+ 525 - 33
src/modules/exam/components/CreateTaskApply.vue

@@ -12,8 +12,8 @@
   >
     <div class="part-box part-box-pad part-box-border">
       <el-form
-        ref="modalFormComp"
-        :model="modalForm"
+        ref="examTaskComp"
+        :model="examTask"
         :rules="rules"
         label-width="100px"
       >
@@ -21,13 +21,17 @@
           <el-col :span="12">
             <el-form-item prop="teachingRoomId" label="教研室:">
               <teaching-room-select
-                v-model="modalForm.teachingRoomId"
+                v-model="examTask.teachingRoomId"
+                @change="clearCard"
               ></teaching-room-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
             <el-form-item prop="courseCode" label="课程(代码):">
-              <course-select v-model="modalForm.courseCode"></course-select>
+              <course-select
+                v-model="examTask.courseCode"
+                @change="clearCard"
+              ></course-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -36,9 +40,10 @@
             <el-form-item prop="cardRuleId" label="题卡规则:">
               <card-rule-select
                 ref="CardRuleSelect"
-                v-model.trim="modalForm.cardRuleId"
+                v-model.trim="examTask.cardRuleId"
                 placeholder="请选择"
                 clearable
+                @change="clearCard"
               ></card-rule-select>
               <p class="tips-info">
                 说明:若选择全部通卡,则命题老师只能选择通卡,若选择题卡规则,则专卡和通卡均可选择
@@ -48,7 +53,7 @@
           <el-col :span="12">
             <el-form-item label="试卷编号:">
               <el-input
-                v-model.trim="modalForm.paperNumber"
+                v-model.trim="examTask.paperNumber"
                 placeholder="请输入试卷编号"
                 clearable
               ></el-input>
@@ -59,7 +64,7 @@
           <el-col :span="12">
             <el-form-item label="拟卷教师:">
               <el-input
-                v-model.trim="modalForm.paperNumber"
+                v-model.trim="examTask.teacherName"
                 placeholder="请输入拟卷教师"
                 clearable
               ></el-input>
@@ -68,7 +73,7 @@
           <el-col :span="12">
             <el-form-item label="主讲教师/电话:">
               <el-input
-                v-model.trim="modalForm.paperNumber"
+                v-model.trim="examTask.lecturerName"
                 placeholder="请输入主讲教师/电话"
                 clearable
               ></el-input>
@@ -90,32 +95,236 @@
       </el-steps>
     </div>
 
-    <div class="part-box part-box-pad part-box-border" v-if="modalIsShow">
-      <apply-content
-        ref="ApplyContent"
-        :exam-task="modalForm"
-        :edit-type="editType"
-        @cancel="cancel"
-        @modified="modified"
-      ></apply-content>
-    </div>
+    <div
+      class="part-box part-box-pad part-box-border apply-content task-detail"
+      v-if="modalIsShow"
+    >
+      <p class="tips-info tips-dark mb-2">
+        提示:多卷型试卷由于会绑定一个答题卡模板,因此试卷结构必须相同。多卷型试卷之间客观题要求试题内容相同,可允许大题内的小题题序不同。
+      </p>
+      <div class="task-body">
+        <div class="mb-2 text-right">
+          <el-button
+            type="primary"
+            icon="el-icon-circle-plus-outline"
+            @click="addAtachment"
+            >增加卷型</el-button
+          >
+        </div>
+        <table class="table">
+          <tr>
+            <th>试卷类型</th>
+            <th>试卷文件</th>
+            <th>答题卡创建方式</th>
+            <th>答题卡</th>
+            <th>操作</th>
+          </tr>
+          <tr v-for="(attachment, index) in paperAttachments" :key="index">
+            <td>{{ attachment.name }}卷</td>
+            <td class="td-link">
+              <span @click="toUpload(attachment)" title="点击上传试卷">
+                <i
+                  :class="[
+                    'icon',
+                    attachment.attachmentId ? 'icon-files-act' : 'icon-files'
+                  ]"
+                ></i
+                >{{
+                  attachment.attachmentId
+                    ? attachment.filename
+                    : "点击上传试卷文件"
+                }}
+              </span>
+            </td>
+            <td>{{ createCardTypeName }}</td>
+            <td
+              class="td-link"
+              :rowspan="paperAttachments.length"
+              v-if="index === 0"
+            >
+              <span @click="toCreateOrViewCard"
+                ><i class="icon icon-plus-act"></i>{{ cardTodoName }}</span
+              >
+              <el-button
+                v-if="examTaskDetail.makeMethod"
+                size="mini"
+                type="primary"
+                @click="changeCreateCardType"
+                >切换题卡创建方式</el-button
+              >
+            </td>
+            <td>
+              <el-button
+                class="btn-table-icon"
+                type="text"
+                icon="icon icon-delete"
+                title="删除"
+                @click="deleteAttachment(index)"
+              ></el-button>
+            </td>
+          </tr>
+        </table>
+
+        <el-form-item label="单次抽卷卷型数量:" label-width="150">
+          <el-input-number
+            v-model="examTaskDetail.drawCount"
+            :min="1"
+            :max="maxFetchCount"
+            :step="1"
+            step-strictly
+            :controls="false"
+          ></el-input-number>
+        </el-form-item>
+
+        <h4 class="mb-2">备注说明:</h4>
+        <el-input
+          class="mb-2"
+          v-model="examTaskDetail.remark"
+          type="textarea"
+          resize="none"
+          :rows="2"
+          :maxlength="100"
+          clearable
+          show-word-limit
+          placeholder="建议不超过100个字"
+          :disabled="!IS_APPLY"
+        ></el-input>
+
+        <h4 class="mb-2">上传入库审核表(最多4张)</h4>
+        <div class="image-list">
+          <div
+            class="image-item"
+            v-for="(img, index) in paperConfirmAttachments"
+            :key="index"
+          >
+            <img
+              :src="img.url"
+              :alt="img.filename"
+              title="点击查看大图"
+              @click="toPreview(index)"
+            />
+            <div class="image-delete">
+              <i
+                class="el-icon-delete-solid"
+                @click="deletePaperConfirmAttachment(index)"
+              ></i>
+            </div>
+          </div>
+          <div
+            v-if="paperConfirmAttachments.length < 4 && IS_APPLY"
+            class="image-item image-add"
+            title="上传入库审核表"
+            @click="toUploadPaperConfirm"
+          >
+            <i class="el-icon-plus"></i>
+          </div>
+        </div>
 
+        <!-- audit -->
+        <h4 v-if="IS_AUDIT" class="mb-2">审核意见:</h4>
+        <el-input
+          v-if="IS_AUDIT"
+          class="mb-2"
+          v-model="reason"
+          type="textarea"
+          resize="none"
+          :rows="5"
+          :maxlength="1000"
+          clearable
+          show-word-limit
+          placeholder="建议不超过1000个字"
+          ref="ReasonInput"
+        ></el-input>
+      </div>
+      <div class="task-action">
+        <el-button type="primary" :disabled="isSubmit" @click="submit"
+          >确认提交</el-button
+        >
+        <el-button
+          type="primary"
+          :disabled="isSubmit"
+          style="width:88px;"
+          @click="toSave"
+          >暂存</el-button
+        >
+        <el-button
+          v-if="IS_AUDIT"
+          type="primary"
+          :disabled="isSubmit"
+          @click="toAuditApply('PASS')"
+          >通过</el-button
+        >
+        <el-button
+          v-if="IS_AUDIT"
+          type="danger"
+          plain
+          @click="toAuditApply('NOT_PASS')"
+          >不通过</el-button
+        >
+        <el-button type="danger" @click="cancel" plain>取消</el-button>
+      </div>
+    </div>
     <div slot="footer"></div>
+
+    <!-- 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
+      ref="CardOptionDialog"
+      :data="task"
+      @upload-sample-over="initData"
+      @draft-task="silentSave"
+      @confirm="cardConfirm"
+    ></card-option-dialog>
+    <!-- image-preview -->
+    <simple-image-preview
+      :cur-image="curImage"
+      @on-prev="toPrevImage"
+      @on-next="toNextImage"
+      ref="SimpleImagePreview"
+    ></simple-image-preview>
   </el-dialog>
 </template>
 
 <script>
-import ApplyContent from "./ApplyContent";
 import { examRuleDetail } from "../../base/api";
+import { teacherCreateTaskApply, switchCardCreateMethod } from "../api";
+import UploadPaperDialog from "./UploadPaperDialog";
+import CardOptionDialog from "./CardOptionDialog";
+import SimpleImagePreview from "@/components/SimpleImagePreview";
+import { CARD_SOURCE_TYPE } from "@/constants/enumerate";
 
-const initModalForm = {
+const initExamTask = {
   id: null,
   courseCode: "",
   courseName: "",
   paperNumber: "",
   cardRuleId: "",
-  userId: "",
-  userName: ""
+  teachingRoomId: "",
+  teacherName: "",
+  lecturerName: ""
+};
+
+const initExamTaskDetail = {
+  operateType: "",
+  paperType: "A",
+  cardId: "",
+  paperAttachmentIds: [],
+  paperConfirmAttachmentIds: [],
+  drawCount: 2,
+  remark: "",
+  makeMethod: "",
+  // 题卡状态
+  status: "",
+  // 考务规则
+  review: false,
+  includePaper: false,
+  customCard: false
 };
 
 const STEPS = [
@@ -174,16 +383,15 @@ const STEPS = [
 
 export default {
   name: "create-task-apply",
-  components: { ApplyContent },
+  components: { UploadPaperDialog, CardOptionDialog, SimpleImagePreview },
   data() {
     return {
       modalIsShow: false,
-      modalForm: {},
+      examTask: {},
       needReview: false,
       examRule: {},
       steps: [],
       actStep: "",
-      editType: "APPLY",
       rules: {
         teachingRoomId: [
           {
@@ -206,9 +414,46 @@ export default {
             trigger: "change"
           }
         ]
-      }
+      },
+      // exam-task-detail
+      examTaskDetail: {},
+      paperConfirmAttachmentId: { attachmentId: "", filename: "", url: "" },
+      paperAttachments: [],
+      paperConfirmAttachments: [],
+      curAttachment: {},
+      curUploadType: "paper",
+      attachmentLimitCount: 26,
+      abc: "abcdefghijklmnopqrstuvwxyz".toUpperCase(),
+      // image-preview
+      curImage: {},
+      curImageIndex: 0
     };
   },
+  computed: {
+    cardTodoName() {
+      let name = "创建答题卡";
+      if (this.curTaskApply.cardId) {
+        if (this.curTaskApply.makeMethod === "SELECT") {
+          name = "选择题卡";
+        } else if (this.curTaskApply.makeMethod === "SELF") {
+          name = "编辑题卡";
+        } else {
+          // 已经审核的题卡可以自行编辑,未审核的题卡只能查看
+          name =
+            this.curTaskApply.status === "SUBMIT" ? "编辑题卡" : "查看题卡";
+        }
+      }
+      return name;
+    },
+    createCardTypeName() {
+      return CARD_SOURCE_TYPE[this.curTaskApply.makeMethod] || "";
+    },
+    maxFetchCount() {
+      return this.paperAttachments.length < 1
+        ? 1
+        : this.paperAttachments.length;
+    }
+  },
   created() {
     this.getExamRule();
   },
@@ -219,11 +464,9 @@ export default {
       this.needReview = examRule && examRule.review;
     },
     initData() {
-      this.modalForm = { ...initModalForm };
-      this.modalForm.includePaper = this.examRule.includePaper;
-      this.modalForm.review = this.examRule.review;
-      this.modalForm.customCard = this.examRule.customCard;
-      this.buildSteps();
+      this.examTask = { ...initExamTask };
+      this.examTaskDetail = { ...initExamTaskDetail };
+      // this.buildSteps();
     },
     buildSteps() {
       // TODO:
@@ -245,15 +488,264 @@ export default {
     visibleChange() {
       this.initData();
     },
+    checkData() {
+      return this.$refs.examTaskComp.validate().catch(() => {});
+    },
     cancel() {
       this.modalIsShow = false;
     },
     open() {
       this.modalIsShow = true;
     },
-    modified() {
-      this.cancel();
-      this.$emit("modified");
+    // exam-task-detail edit
+    addAtachment() {
+      if (this.paperAttachments.length >= this.attachmentLimitCount) return;
+
+      const newAttachment = {
+        name: this.abc[this.paperAttachments.length],
+        attachmentId: "",
+        filename: "",
+        pages: 0
+      };
+      this.paperAttachments.push(newAttachment);
+    },
+    deleteAttachment(index) {
+      if (this.paperAttachments.length <= 1) {
+        this.$message.error("试卷类型数量不得少于1");
+        return;
+      }
+      this.paperAttachments.splice(index, 1);
+      this.paperAttachments.forEach((item, itemIndex) => {
+        item.name = this.abc[itemIndex];
+      });
+    },
+    toUpload(attachment) {
+      this.curUploadType = "paper";
+      this.curAttachment = {
+        ...attachment
+      };
+      this.$refs.UploadPaperDialog.open();
+    },
+    toUploadPaperConfirm() {
+      if (this.paperConfirmAttachments.length >= 4) return;
+      this.curUploadType = "paperConfirm";
+      this.curAttachment = {
+        ...this.paperConfirmAttachmentId
+      };
+      this.$refs.UploadPaperDialog.open();
+    },
+    uploadConfirm(attachment, uploadType) {
+      if (uploadType === "paper") {
+        const index = this.paperAttachments.findIndex(
+          item => item.name === attachment.name
+        );
+        this.paperAttachments.splice(index, 1, { ...attachment });
+      } else {
+        this.paperConfirmAttachments.push(attachment);
+      }
+    },
+    deletePaperConfirmAttachment(index) {
+      this.paperConfirmAttachments.splice(index, 1);
+    },
+    toViewCard() {
+      window.open(
+        this.getRouterPath({
+          name: "CardPreview",
+          params: {
+            cardId: this.examTaskDetail.cardId,
+            viewType: "view"
+          }
+        })
+      );
+    },
+    toEditCard() {
+      this.cachePrepareTcpCard();
+      this.$router.push({
+        name: "CardDesign",
+        params: {
+          cardId: this.examTaskDetail.cardId
+        }
+      });
+    },
+    cachePrepareTcpCard() {
+      // TODO:
+      this.$ls.set("prepareTcPCard", {
+        examTaskId: this.examTask.id,
+        courseCode: this.examTask.courseCode,
+        courseName: this.examTask.courseName,
+        makeMethod: this.examTaskDetail.makeMethod,
+        cardRuleId: this.examTask.cardRuleId,
+        paperType: this.paperAttachments.map(item => item.name).join(",")
+      });
+    },
+    async toCreateOrViewCard() {
+      await this.toSave();
+      this.task = this.getTaskDetailData();
+      if (!this.examTaskDetail.cardId) {
+        this.$refs.CardOptionDialog.open();
+        return;
+      }
+
+      if (this.examTaskDetail.makeMethod === "SELECT") {
+        this.$refs.CardOptionDialog.open();
+      } else if (this.examTaskDetail.makeMethod === "SELF") {
+        this.toEditCard();
+      } else {
+        // 客服制卡:制作完毕则可以编辑,未制作完毕则可以查看
+        if (this.examTaskDetail.status === "SUBMIT") {
+          this.toEditCard();
+        } else {
+          this.toViewCard();
+        }
+      }
+    },
+    cardConfirm(data) {
+      this.examTaskDetail = this.$objAssign(this.examTaskDetail, data);
+    },
+    async changeCreateCardType() {
+      const h = this.$createElement;
+      const result = await this.$confirm({
+        title: "切换题卡操作说明",
+        message: h("div", null, [
+          h("p", null, "1、切换题卡会将之前选择题卡数据删除。"),
+          h(
+            "p",
+            null,
+            "2、之前选择专卡进行绘制,切换题卡后再次选择专卡,需要重新开始绘制。"
+          )
+        ]),
+        cancelButtonClass: "el-button--danger is-plain",
+        confirmButtonClass: "el-button--primary",
+        type: "warning"
+      }).catch(() => {});
+      if (result !== "confirm") return;
+      this.clearMakeMethod();
+      this.toCreateOrViewCard();
+    },
+    async clearMakeMethod() {
+      // 清除后台记录的题卡
+      if (this.examTask.id) await switchCardCreateMethod(this.examTask.id);
+
+      this.examTaskDetail.makeMethod = "";
+      this.examTaskDetail.cardId = "";
+    },
+    clearCard() {
+      this.clearMakeMethod();
+    },
+    getTaskDetailData() {
+      let data = { ...this.examTaskDetail };
+      data.paperType = this.paperAttachments.map(item => item.name).join(",");
+      data.paperAttachmentIds = JSON.stringify(this.paperAttachments, (k, v) =>
+        k === "url" ? undefined : v
+      );
+      data.paperConfirmAttachmentIds = JSON.stringify(
+        this.paperConfirmAttachments
+      );
+      return data;
+    },
+    checkDataValid() {
+      const attachmentValid = !this.paperAttachments.some(
+        item => !item.attachmentId
+      );
+      // 设置了入库强制包含试卷时,校验试卷是否上传。
+      if (this.examTaskDetail.includePaper && !attachmentValid) {
+        this.$message.error("请完成试卷文件上传!");
+        return;
+      }
+      // if (!this.paperConfirmAttachments.length) {
+      //   this.$message.error("请上传入库审核表!");
+      //   return;
+      // }
+
+      if (!this.examTaskDetail.cardId) {
+        this.$message.error("请选择题卡创建方式!");
+        return;
+      }
+
+      if (
+        this.examTaskDetail.makeMethod !== "SELECT" &&
+        this.examTaskDetail.status !== "SUBMIT"
+      ) {
+        this.$message.error("请先提交题卡!");
+        return;
+      }
+      return true;
+    },
+    async toSave() {
+      const valid = await this.$refs.examTaskComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const examTaskDetail = this.getTaskDetailData();
+      examTaskDetail.operateType = "STAGE";
+      const datas = {
+        examTaskDetail,
+        examTask: this.examTask
+      };
+      const data = await teacherCreateTaskApply(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$message.success("保存成功!");
+    },
+    async submit() {
+      const valid = await this.$refs.examTaskComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (!this.checkDataValid()) return;
+
+      this.$confirm(
+        "任务确定提交后,则不可更改试卷及答题卡内容,确定提交该任务?",
+        "提示",
+        {
+          cancelButtonClass: "el-button--danger is-plain",
+          confirmButtonClass: "el-button--primary",
+          type: "warning"
+        }
+      )
+        .then(async () => {
+          const examTaskDetail = this.getTaskDetailData();
+          examTaskDetail.operateType = "SUBMIT";
+          const datas = {
+            examTaskDetail,
+            examTask: this.examTask
+          };
+          const data = await teacherCreateTaskApply(datas).catch(() => {});
+
+          if (!data) return;
+          this.$message.success("提交成功!");
+          this.cancel();
+          this.$emit("modified");
+        })
+        .catch(() => {});
+    },
+    // image-preview
+    toPreview(index) {
+      this.curImageIndex = index;
+      this.selectImage(index);
+      this.$refs.SimpleImagePreview.open();
+    },
+    selectImage(index) {
+      this.curImage = this.paperConfirmAttachments[index];
+    },
+    toPrevImage() {
+      if (this.curImageIndex === 0) {
+        this.curImageIndex = this.paperConfirmAttachments.length - 1;
+      } else {
+        this.curImageIndex--;
+      }
+
+      this.selectImage(this.curImageIndex);
+    },
+    toNextImage() {
+      if (this.curImageIndex === this.paperConfirmAttachments.length - 1) {
+        this.curImageIndex = 0;
+      } else {
+        this.curImageIndex++;
+      }
+
+      this.selectImage(this.curImageIndex);
     }
   }
 };

+ 9 - 0
src/modules/exam/views/ExamTaskManage.vue

@@ -33,6 +33,14 @@
             clearable
           ></course-select>
         </el-form-item>
+        <el-form-item label="命题老师:">
+          <question-teacher-user-select
+            v-model="filter.teacherId"
+            :course-code="filter.courseCode"
+            placeholder="请选择"
+          ></question-teacher-user-select>
+        </el-form-item>
+        <!-- TODO:创建人--查询条件 -->
         <el-form-item label="试卷编号:">
           <paper-number-select
             ref="PaperNumberSelect"
@@ -235,6 +243,7 @@ export default {
         cardRuleId: "",
         courseCode: "",
         paperNumber: "",
+        teacherId: "",
         startTime: null,
         endTime: null,
         enable: null

+ 21 - 1
src/modules/exam/views/TaskApplyManage.vue

@@ -48,6 +48,13 @@
             clearable
           ></course-select>
         </el-form-item>
+        <el-form-item label="命题老师:">
+          <question-teacher-user-select
+            v-model="filter.teacherId"
+            :course-code="filter.courseCode"
+            placeholder="请选择"
+          ></question-teacher-user-select>
+        </el-form-item>
         <el-form-item label="试卷编号:">
           <paper-number-select
             ref="PaperNumberSelect"
@@ -76,6 +83,11 @@
           >
         </el-form-item>
       </el-form>
+      <div class="part-box-action">
+        <el-button icon="el-icon-download" type="primary" @click="toAddApply">
+          新建命题申请
+        </el-button>
+      </div>
     </div>
 
     <div class="part-box">
@@ -192,11 +204,14 @@
       :instance="curExamTask"
       @modified="taskModified"
     ></modify-task-apply>
+    <!-- CreateTaskApply -->
+    <create-task-apply ref="CreateTaskApply"></create-task-apply>
   </div>
 </template>
 
 <script>
 import ModifyTaskApply from "../components/ModifyTaskApply";
+import CreateTaskApply from "../components/CreateTaskApply";
 import { AUDITING_STATUS } from "@/constants/enumerate";
 import pickerOptions from "@/constants/datePickerOptions";
 import { taskApplyListPage, cancelOrRestartTaskApply } from "../api";
@@ -205,7 +220,8 @@ import { mapActions } from "vuex";
 export default {
   name: "task-apply-manage",
   components: {
-    ModifyTaskApply
+    ModifyTaskApply,
+    CreateTaskApply
   },
   data() {
     return {
@@ -214,6 +230,7 @@ export default {
         reviewStatus: "",
         cardRuleId: "",
         courseCode: "",
+        teacherId: "",
         paperNumber: "",
         startTime: "",
         endTime: ""
@@ -307,6 +324,9 @@ export default {
     taskModified() {
       this.getList();
       this.updateWaitTaskCount(this.userRoles);
+    },
+    toAddApply() {
+      this.$refs.CreateTaskApply.open();
     }
   },
   beforeRouteLeave(to, from, next) {

+ 29 - 0
src/modules/exam/views/TaskPaperManage.vue

@@ -18,6 +18,24 @@
             clearable
           ></paper-number-select>
         </el-form-item>
+        <el-form-item label="题卡规则:">
+          <card-rule-select
+            v-model="filter.cardRuleId"
+            placeholder="请选择"
+            clearable
+          ></card-rule-select>
+        </el-form-item>
+        <el-form-item label="题卡创建类型:">
+          <el-select v-model="filter.makeMethod" placeholder="请选择" clearable>
+            <el-option
+              v-for="(val, key) in CARD_SOURCE_TYPE"
+              :key="key"
+              :value="key"
+              :label="val"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
         <el-form-item label="入库时间:">
           <el-date-picker
             v-model="createTime"
@@ -32,6 +50,7 @@
           >
           </el-date-picker>
         </el-form-item>
+        <!-- TODO:申请时间-创建人--查询条件 -->
         <el-form-item label-width="0px">
           <el-button type="primary" icon="el-icon-search" @click="toPage(1)"
             >查询</el-button
@@ -94,6 +113,12 @@
           label="未曝光"
           width="100"
         ></el-table-column>
+        <el-table-column prop="cardRuleName" label="题卡规则"></el-table-column>
+        <el-table-column prop="makeMethod" label="题卡创建类型">
+          <span slot-scope="scope">{{
+            scope.row.makeMethod | cardSourceTypeFilter
+          }}</span>
+        </el-table-column>
         <el-table-column prop="enable" label="启用/禁用" width="100">
           <template slot-scope="scope">
             {{ scope.row.enable | enableFilter }}
@@ -178,6 +203,7 @@ import {
 } from "../api";
 import pickerOptions from "@/constants/datePickerOptions";
 import { downloadBlob } from "@/plugins/utils";
+import { CARD_SOURCE_TYPE } from "@/constants/enumerate";
 import ModifyTaskPaper from "../components/ModifyTaskPaper";
 
 export default {
@@ -188,6 +214,8 @@ export default {
       filter: {
         courseCode: "",
         paperNumber: "",
+        cardRuleId: "",
+        makeMethod: "",
         startTime: "",
         endTime: ""
       },
@@ -198,6 +226,7 @@ export default {
       curPaper: {},
       loading: false,
       editType: "EDIT",
+      CARD_SOURCE_TYPE,
       IS_QUESTION_TEACHER: this.$ls
         .get("user", { roleList: [] })
         .roleList.includes("QUESTION_TEACHER"),

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

@@ -175,7 +175,7 @@ export default {
       this.$ls.set("user", data, this.GLOBAL.authTimeout);
 
       // 强制修改密码
-      // if (!data.user.pwdUpdateTime) {
+      // if (!data.pwdCount) {
       //   this.$refs.ResetPwd.open();
       //   return;
       // }
@@ -183,7 +183,7 @@ export default {
       this.$ls.set("token", data.accessToken, this.GLOBAL.authTimeout);
       // this.$store.commit("setUser", data);
 
-      if (data.roleList.includes("ADMIN")) {
+      if (data.roleList && data.roleList.includes("ADMIN")) {
         this.$router.push({
           name: "SelectSchool"
         });

+ 1 - 0
src/modules/login/views/SelectSchool.vue

@@ -1,5 +1,6 @@
 <template>
   <div class="select-school login login-box">
+    <div class="login-theme"></div>
     <div class="login-body">
       <div class="login-title">
         <h1>选择学校</h1>

+ 5 - 1
src/plugins/filters.js

@@ -9,7 +9,8 @@ import {
   DATA_TASK_STATUS,
   DATA_TASK_TYPE,
   DATA_TASK_RESULT,
-  ORG_TYPE
+  ORG_TYPE,
+  CARD_SOURCE_TYPE
 } from "../constants/enumerate";
 import { formatDate } from "../plugins/utils";
 
@@ -60,6 +61,9 @@ Vue.filter("dataTaskResultFilter", function(val) {
 Vue.filter("orgTypeFilter", function(val) {
   return ORG_TYPE[val] || DEFAULT_FIELD;
 });
+Vue.filter("cardSourceTypeFilter", function(val) {
+  return CARD_SOURCE_TYPE[val] || DEFAULT_FIELD;
+});
 Vue.filter("timestampFilter", function(val) {
   return val
     ? formatDate("YYYY-MM-DD HH:mm:ss", new Date(val * 1))

+ 26 - 27
src/views/Home.vue

@@ -12,12 +12,12 @@
             :key="index"
             :class="[
               'menu-item',
-              { 'menu-item-act': curMenu.name === menu.name }
+              { 'menu-item-act': curMenu.url === menu.url }
             ]"
             @click="toMenu(menu)"
           >
             <i :class="menu.icon"></i>
-            <span>{{ menu.title }}</span>
+            <span>{{ menu.name }}</span>
           </li>
         </ul>
       </div>
@@ -53,7 +53,7 @@
       >
         <div class="nav-head">
           <i :class="submenu.icon"></i>
-          <span>{{ submenu.title }}</span>
+          <span>{{ submenu.name }}</span>
         </div>
         <ul class="nav-list">
           <li
@@ -64,16 +64,16 @@
             <div
               :class="[
                 'nav-item-main',
-                { 'nav-item-main-act': curActNav === nav.router }
+                { 'nav-item-main-act': curActNav === nav.url }
               ]"
               @click="toNav(nav)"
             >
-              <p class="nav-item-cont">{{ nav.title }}</p>
+              <p class="nav-item-cont">{{ nav.name }}</p>
               <span class="nav-item-icon nav-item-icon-right">
                 <i
                   :class="[
                     'icon',
-                    curActNav === nav.router
+                    curActNav === nav.url
                       ? 'icon-arrow-right-act'
                       : 'icon-arrow-right'
                   ]"
@@ -81,7 +81,7 @@
               </span>
               <span
                 class="nav-item-info"
-                v-if="nav.router === 'WaitTask' && waitTaskCount"
+                v-if="nav.url === 'WaitTask' && waitTaskCount"
                 >{{ waitTaskCount }}</span
               >
             </div>
@@ -135,7 +135,7 @@
         >
           <div class="nav-head">
             <i :class="submenu.icon"></i>
-            <span>{{ curMenu.title }} - {{ submenu.title }}</span>
+            <span>{{ curMenu.name }} - {{ submenu.name }}</span>
           </div>
           <ul class="nav-list">
             <li
@@ -146,16 +146,16 @@
               <div
                 :class="[
                   'nav-item-main',
-                  { 'nav-item-main-act': curActNav === nav.router }
+                  { 'nav-item-main-act': curActNav === nav.url }
                 ]"
                 @click="toNav(nav)"
               >
-                <p class="nav-item-cont">{{ nav.title }}</p>
+                <p class="nav-item-cont">{{ nav.name }}</p>
                 <span class="nav-item-icon nav-item-icon-right">
                   <i
                     :class="[
                       'icon',
-                      curActNav === nav.router
+                      curActNav === nav.url
                         ? 'icon-arrow-right-act'
                         : 'icon-arrow-right'
                     ]"
@@ -163,7 +163,7 @@
                 </span>
                 <span
                   class="nav-item-info"
-                  v-if="nav.router === 'WaitTask' && waitTaskCount"
+                  v-if="nav.url === 'WaitTask' && waitTaskCount"
                   >{{ waitTaskCount }}</span
                 >
               </div>
@@ -198,7 +198,7 @@ export default {
 
     return {
       menus: [],
-      curMenu: { name: "" },
+      curMenu: { url: "" },
       curActNav: "",
       breadcrumbs: [],
       validRoutes: [],
@@ -285,11 +285,11 @@ export default {
       const anchorNav = menus => {
         let list = [];
         menus.forEach(item => {
-          const routerOrName = item["router"] || item["name"];
+          const routerOrName = item.url;
           if (!validMenuDict[routerOrName]) return;
 
-          if (!firstRouter && item["router"]) firstRouter = item["router"];
-          item.title = validMenuDict[routerOrName];
+          if (!firstRouter && item.isRouter) firstRouter = item.url;
+          item.name = validMenuDict[routerOrName];
           validRoutes.push(routerOrName);
           let navItem = { ...item };
           if (item["children"]) {
@@ -310,9 +310,9 @@ export default {
       this.toNav(firstRouter);
     },
     toNav(nav) {
-      if (nav.router === this.$route.name) return;
-      this.curActNav = nav.router;
-      this.$router.push({ name: nav.router });
+      if (nav.url === this.$route.name) return;
+      this.curActNav = nav.url;
+      this.$router.push({ name: nav.url });
       this.menuDailogIsShow = false;
     },
     actCurNav() {
@@ -322,20 +322,19 @@ export default {
         navs.forEach(nav => {
           let navPathList = [...pathList];
           if (breadcrumbs.length) return;
-          if (nav["router"] === routerName) {
+          if (nav.url === routerName) {
             breadcrumbs = [
               ...navPathList,
-              { title: nav.title, router: nav.router, isRouter: true }
+              { title: nav.name, router: nav.url, isRouter: true }
             ];
             return;
           } else {
-            const routerOrName = nav["router"] || nav["name"];
             navPathList = [
               ...navPathList,
               {
-                title: nav.title,
-                router: routerOrName,
-                isRouter: !!nav["router"]
+                title: nav.name,
+                router: nav.url,
+                isRouter: !!nav.isRouter
               }
             ];
             if (nav["children"]) {
@@ -350,14 +349,14 @@ export default {
       const curRouter = breadcrumbs.find(item => item.isRouter);
       this.curActNav = curRouter.router;
       this.curMenu = this.menus.find(
-        menu => menu.name === breadcrumbs[0].router
+        menu => menu.url === breadcrumbs[0].router
       );
 
       this.breadcrumbs = breadcrumbs;
 
       if (
         this.validRoutes.includes("WaitTask") &&
-        this.curMenu.name === "exam"
+        this.curMenu.url === "exam"
       ) {
         this.updateWaitTaskCount(this.userRoles);
       }

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä