Explorar o código

新建命题申请调试完成

zhangjie %!s(int64=3) %!d(string=hai) anos
pai
achega
cc578f8e26

+ 4 - 0
src/constants/enumerate.js

@@ -24,6 +24,10 @@ export const AUDITING_RESULT = {
   NOT_PASS: "未通过",
   PASS: "通过"
 };
+export const TASK_AUDIT_RESULT = {
+  REJECT: "驳回",
+  PASS: "通过"
+};
 
 // 权限类型
 export const PRIVILEGE_TYPE = {

+ 2 - 1
src/modules/base/api.js

@@ -136,12 +136,13 @@ export const flowEnd = flowId => {
 export const flowRegister = (datas, headers) => {
   return $post("/api/admin/flow/register", datas, { headers });
 };
+
 // approve-record
 export const approveRecordListPage = datas => {
   return $postParam("/api/admin/flow/approve/list", datas);
 };
 export const deleteApproveRecord = datas => {
-  return $postParam("/api/admin/flow/approve/enable", datas);
+  return $post("/api/admin/flow/approve/enable", datas);
 };
 
 // dict --------------------------------->

+ 3 - 3
src/modules/base/components/RegistFlowDialog.vue

@@ -25,14 +25,14 @@
             placeholder="请输入名称"
           ></el-input>
         </el-form-item>
-        <el-form-item label="是否发布:">
+        <!-- <el-form-item label="是否发布:">
           <el-switch
             v-model="modalForm.publish"
             active-color="#23c4b9"
             inactive-color="#dcdfe6"
           >
           </el-switch>
-        </el-form-item>
+        </el-form-item> -->
         <el-form-item prop="uploadData" label="上传文件:">
           <upload-fetch-file
             input-width="300px"
@@ -77,7 +77,7 @@ export default {
       isSubmit: false,
       modalForm: {
         name: "",
-        publish: false
+        publish: true
       },
       rules: {
         name: [

+ 4 - 4
src/modules/base/views/FlowManage.vue

@@ -42,11 +42,11 @@
           :index="indexMethod"
         ></el-table-column>
         <el-table-column prop="name" label="流程名称"></el-table-column>
-        <el-table-column prop="publish" label="状态">
+        <!-- <el-table-column prop="publish" label="状态">
           <span slot-scope="scope">
             {{ scope.row.publish ? "已发布" : "未发布" }}</span
           >
-        </el-table-column>
+        </el-table-column> -->
         <el-table-column
           class-name="action-column"
           label="操作"
@@ -54,14 +54,14 @@
           width="120px"
         >
           <template slot-scope="scope">
-            <el-button
+            <!-- <el-button
               v-if="checkPrivilege('link', 'publish') && !scope.row.publish"
               class="btn-table-icon"
               type="text"
               icon="icon icon-edit"
               @click="toPublish(scope.row)"
               title="发布"
-            ></el-button>
+            ></el-button> -->
             <el-button
               v-if="checkPrivilege('link', 'delete')"
               class="btn-table-icon"

+ 9 - 2
src/modules/exam/api.js

@@ -69,12 +69,18 @@ export const updateTaskApply = datas => {
 export const cancelOrRestartTaskApply = ({ id, status }) => {
   return $post("/api/admin/exam/task/apply_status", { id, status });
 };
+export const taskAllFlowSetups = flowId => {
+  return $postParam("/api/admin/flow/task/all", { flowId });
+};
 // 命题老师创建命题任务
 export const teacherCreateTaskApply = datas => {
   return $post("/api/admin/exam/task/save_task_apply", datas);
 };
+export const teacherCancelTaskApply = examTaskId => {
+  return $postParam("/api/admin/exam/task/remove_task_apply", { examTaskId });
+};
 export const switchCardCreateMethod = examTaskId => {
-  return $post("/api/admin/exam/task/switch_card", { examTaskId });
+  return $postParam("/api/admin/exam/task/switch_card", { examTaskId });
 };
 
 // task-review-manage
@@ -85,7 +91,8 @@ export const taskReviewAuditedListPage = datas => {
   return $postParam("/api/admin/exam/task/review_list_audited", datas);
 };
 export const updateTaskReview = datas => {
-  return $post("/api/admin/exam/task/review_save", datas);
+  // return $post("/api/admin/exam/task/review_save", datas);
+  return $postParam("/api/admin/flow/task/approve", datas);
 };
 export const batchUpdateTaskReview = datas => {
   return $post("/api/admin/exam/task/review_save_batch", datas);

+ 164 - 75
src/modules/exam/components/ApplyContent.vue

@@ -52,7 +52,9 @@
               <i>{{ attachment.filename }}</i>
             </span>
           </td>
-          <td>{{ createCardTypeName }}</td>
+          <td :rowspan="paperAttachments.length" v-if="index === 0">
+            {{ createCardTypeName }}
+          </td>
           <td
             class="td-link"
             :rowspan="paperAttachments.length"
@@ -66,7 +68,7 @@
               <i>查看题卡</i>
             </span>
             <el-button
-              v-if="curTaskApply.makeMethod"
+              v-if="curTaskApply.makeMethod && IS_APPLY"
               size="mini"
               type="primary"
               @click="changeCreateCardType"
@@ -85,16 +87,19 @@
         </tr>
       </table>
 
-      <el-form-item label="单次抽卷卷型数量:" label-width="150">
-        <el-input-number
-          v-model="curTaskApply.drawCount"
-          :min="1"
-          :max="maxFetchCount"
-          :step="1"
-          step-strictly
-          :controls="false"
-        ></el-input-number>
-      </el-form-item>
+      <el-form>
+        <el-form-item label="单次抽卷卷型数量:" label-width="150">
+          <el-input-number
+            v-model="curTaskApply.drawCount"
+            :min="1"
+            :max="maxFetchCount"
+            :step="1"
+            step-strictly
+            :controls="false"
+            :disabled="!IS_APPLY"
+          ></el-input-number>
+        </el-form-item>
+      </el-form>
 
       <h4 class="mb-2">备注说明:</h4>
       <el-input
@@ -141,20 +146,57 @@
       </div>
 
       <!-- audit -->
-      <h4 v-if="IS_AUDIT" class="mb-2">审核意见:</h4>
-      <el-input
+      <el-form
         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>
+        ref="auditModalComp"
+        :model="auditModal"
+        :rules="auditRules"
+        label-width="90px"
+      >
+        <el-form-item prop="approvePass" label="审批操作:">
+          <el-radio-group v-model="auditModal.approvePass">
+            <el-radio
+              v-for="(val, key) in TASK_AUDIT_RESULT"
+              :key="key"
+              :label="key"
+              >{{ val }}</el-radio
+            >
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item
+          v-if="auditModal.approvePass === 'REJECT'"
+          prop="setup"
+          label="驳回节点:"
+        >
+          <el-select v-model="auditModal.setup" placeholder="请选择">
+            <el-option
+              v-for="item in setups"
+              :key="item.taskKey"
+              :value="item.setup"
+              :label="item.taskName"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item
+          v-if="auditModal.approvePass === 'REJECT'"
+          prop="remark"
+          label="审批意见:"
+        >
+          <el-input
+            class="mb-2"
+            v-model="auditModal.remark"
+            type="textarea"
+            resize="none"
+            :rows="5"
+            :maxlength="1000"
+            clearable
+            show-word-limit
+            placeholder="建议不超过1000个字"
+            ref="ReasonInput"
+          ></el-input>
+        </el-form-item>
+      </el-form>
     </div>
     <div class="task-action">
       <el-button
@@ -176,15 +218,8 @@
         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
+        @click="toAuditApply"
+        >确定</el-button
       >
       <el-button type="danger" @click="cancel" plain>取消</el-button>
     </div>
@@ -225,7 +260,7 @@ import {
 } from "../api";
 import { attachmentPreview } from "../../login/api";
 import SimpleImagePreview from "@/components/SimpleImagePreview";
-import { CARD_SOURCE_TYPE } from "@/constants/enumerate";
+import { CARD_SOURCE_TYPE, TASK_AUDIT_RESULT } from "@/constants/enumerate";
 
 const initTaskApply = {
   examTaskId: "",
@@ -239,6 +274,10 @@ const initTaskApply = {
   courseCode: "",
   courseName: "",
   drawCount: 1,
+  // 流程
+  flowId: "",
+  // 工作台任务id
+  flowTaskId: "",
   // 题卡状态
   status: "",
   // 考务规则
@@ -261,6 +300,12 @@ export default {
       type: String,
       default: "APPLY",
       validator: val => ["APPLY", "PREVIEW", "AUDIT"].includes(val)
+    },
+    flows: {
+      type: Array,
+      default() {
+        return [];
+      }
     }
   },
   data() {
@@ -276,6 +321,47 @@ export default {
       abc: "abcdefghijklmnopqrstuvwxyz".toUpperCase(),
       task: {},
       reason: "",
+      // audit
+      TASK_AUDIT_RESULT,
+      setups: [],
+      auditModal: {
+        approvePass: "PASS",
+        setup: "",
+        remark: ""
+      },
+      auditRules: {
+        approvePass: [
+          {
+            required: true
+          }
+        ],
+        setup: [
+          {
+            required: true,
+            validator: (rule, value, callback) => {
+              if (this.auditModal.approvePass === "REJECT" && !value) {
+                callback(new Error(`请选择要驳回到的节点`));
+              } else {
+                callback();
+              }
+            },
+            trigger: "change"
+          }
+        ],
+        remark: [
+          {
+            required: true,
+            validator: (rule, value, callback) => {
+              if (this.auditModal.approvePass === "REJECT" && !value) {
+                callback(new Error(`请输入审批意见`));
+              } else {
+                callback();
+              }
+            },
+            trigger: "change"
+          }
+        ]
+      },
       // image-preview
       curImage: {},
       curImageIndex: 0
@@ -346,6 +432,12 @@ export default {
       this.paperConfirmAttachments = this.curTaskApply.paperConfirmAttachmentIds
         ? JSON.parse(this.curTaskApply.paperConfirmAttachmentIds)
         : [];
+
+      if (this.flows.length) {
+        const curFlow = this.flows.find(item => item.isCurrent);
+        if (curFlow)
+          this.setups = this.flows.filter(item => item.setup < curFlow.setup);
+      }
     },
     addAtachment() {
       if (this.paperAttachments.length >= this.attachmentLimitCount) return;
@@ -460,7 +552,7 @@ export default {
     },
     async changeCreateCardType() {
       const h = this.$createElement;
-      const result = await this.$confirm({
+      const result = await this.$msgbox({
         title: "切换题卡操作说明",
         message: h("div", null, [
           h("p", null, "1、切换题卡会将之前选择题卡数据删除。"),
@@ -470,20 +562,22 @@ export default {
             "2、之前选择专卡进行绘制,切换题卡后再次选择专卡,需要重新开始绘制。"
           )
         ]),
+        showCancelButton: true,
         cancelButtonClass: "el-button--danger is-plain",
         confirmButtonClass: "el-button--primary",
         type: "warning"
       }).catch(() => {});
       if (result !== "confirm") return;
-      this.clearMakeMethod();
+      await this.clearMakeMethod();
       this.toCreateOrViewCard();
     },
     async clearMakeMethod() {
       // 清除后台记录的题卡
-      if (this.examTask.id) await switchCardCreateMethod(this.examTask.id);
+      if (this.curTaskApply.cardId)
+        await switchCardCreateMethod(this.examTask.id);
 
-      this.examTaskDetail.makeMethod = "";
-      this.examTaskDetail.cardId = "";
+      this.curTaskApply.makeMethod = "";
+      this.curTaskApply.cardId = "";
     },
     getTaskData() {
       let data = { ...this.curTaskApply };
@@ -543,7 +637,7 @@ export default {
     async submit() {
       if (!this.checkDataValid()) return;
 
-      this.$confirm(
+      const result = await this.$confirm(
         "任务确定提交后,则不可更改试卷及答题卡内容,确定提交该任务?",
         "提示",
         {
@@ -551,43 +645,38 @@ export default {
           confirmButtonClass: "el-button--primary",
           type: "warning"
         }
-      )
-        .then(async () => {
-          const datas = this.getTaskData();
-          datas.operateType = "SUBMIT";
-          const data = await updateTaskApply(datas).catch(() => {});
-          if (!data) return;
-          this.$message.success("提交成功!");
-          this.$emit("modified");
-        })
-        .catch(() => {});
-    },
-    toAuditApply(type) {
-      if (type === "NOT_PASS" && !this.reason) {
-        this.$message.error("请输入审核意见!");
-        this.$refs.ReasonInput.focus();
-        return;
-      }
+      ).catch(() => {});
+      if (result !== "confirm") return;
 
-      const actionName = type === "NOT_PASS" ? "不通过" : "通过";
-      this.$confirm(`确定${actionName}该申请吗?`, "提示", {
-        cancelButtonClass: "el-button--danger is-plain",
-        confirmButtonClass: "el-button--primary",
-        type: "warning"
-      })
-        .then(() => {
-          this.auditApply(type);
-        })
-        .catch(() => {});
+      const datas = this.getTaskData();
+      datas.operateType = "SUBMIT";
+      const data = await updateTaskApply(datas).catch(() => {});
+      if (!data) return;
+      this.$message.success("提交成功!");
+      this.$emit("modified");
     },
-    async auditApply(type) {
-      const data = await updateTaskReview({
-        reviewStatus: type,
-        examTaskId: this.examTask.id,
-        reason: this.reason
-      }).catch(() => {});
+    async toAuditApply() {
+      const valid = await this.$refs.auditModalComp.validate().catch(() => {});
+      if (!valid) return;
+
+      const actionName =
+        this.auditModal.approvePass === "REJECT" ? "不通过" : "通过";
+      const result = await this.$confirm(
+        `确定${actionName}该申请吗?`,
+        "提示",
+        {
+          cancelButtonClass: "el-button--danger is-plain",
+          confirmButtonClass: "el-button--primary",
+          type: "warning"
+        }
+      ).catch(() => {});
+      if (result !== "confirm") return;
+
+      let datas = { ...this.auditModal };
+      datas.taskId = this.curTaskApply.flowTaskId;
+      const data = await updateTaskReview(datas).catch(() => {});
       if (!data) return;
-      this.$message.success("审核成功!");
+      this.$message.success("审成功!");
       this.$emit("modified");
     },
     // image-preview

+ 75 - 158
src/modules/exam/components/CreateTaskApply.vue

@@ -2,9 +2,9 @@
   <el-dialog
     class="create-task-apply"
     :visible.sync="modalIsShow"
-    :title="title"
+    title="新增命题申请"
     top="10px"
-    width="900px"
+    width="1000px"
     :close-on-click-modal="false"
     :close-on-press-escape="false"
     append-to-body
@@ -15,7 +15,7 @@
         ref="examTaskComp"
         :model="examTask"
         :rules="rules"
-        label-width="100px"
+        label-width="120px"
       >
         <el-row>
           <el-col :span="12">
@@ -30,7 +30,7 @@
             <el-form-item prop="courseCode" label="课程(代码):">
               <course-select
                 v-model="examTask.courseCode"
-                @change="clearCard"
+                @change="courseChange"
               ></course-select>
             </el-form-item>
           </el-col>
@@ -71,10 +71,10 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="主讲教师/电话:">
+            <el-form-item label="主讲教师:">
               <el-input
                 v-model.trim="examTask.lecturerName"
-                placeholder="请输入主讲教师/电话"
+                placeholder="请输入主讲教师"
                 clearable
               ></el-input>
             </el-form-item>
@@ -83,18 +83,6 @@
       </el-form>
     </div>
 
-    <div class="mb-4">
-      <el-steps align-center>
-        <el-step
-          v-for="(step, index) in steps"
-          :key="index"
-          :title="step.title"
-          :description="step.desc"
-          :status="step.status"
-        ></el-step>
-      </el-steps>
-    </div>
-
     <div
       class="part-box part-box-pad part-box-border apply-content task-detail"
       v-if="modalIsShow"
@@ -136,7 +124,9 @@
                 }}
               </span>
             </td>
-            <td>{{ createCardTypeName }}</td>
+            <td :rowspan="paperAttachments.length" v-if="index === 0">
+              {{ createCardTypeName }}
+            </td>
             <td
               class="td-link"
               :rowspan="paperAttachments.length"
@@ -165,16 +155,18 @@
           </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>
+        <el-form>
+          <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>
+        </el-form>
 
         <h4 class="mb-2">备注说明:</h4>
         <el-input
@@ -187,7 +179,6 @@
           clearable
           show-word-limit
           placeholder="建议不超过100个字"
-          :disabled="!IS_APPLY"
         ></el-input>
 
         <h4 class="mb-2">上传入库审核表(最多4张)</h4>
@@ -211,7 +202,7 @@
             </div>
           </div>
           <div
-            v-if="paperConfirmAttachments.length < 4 && IS_APPLY"
+            v-if="paperConfirmAttachments.length < 4"
             class="image-item image-add"
             title="上传入库审核表"
             @click="toUploadPaperConfirm"
@@ -219,22 +210,6 @@
             <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"
@@ -247,20 +222,6 @@
           @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>
@@ -278,7 +239,6 @@
       ref="CardOptionDialog"
       :data="task"
       @upload-sample-over="initData"
-      @draft-task="silentSave"
       @confirm="cardConfirm"
     ></card-option-dialog>
     <!-- image-preview -->
@@ -293,7 +253,11 @@
 
 <script>
 import { examRuleDetail } from "../../base/api";
-import { teacherCreateTaskApply, switchCardCreateMethod } from "../api";
+import {
+  teacherCreateTaskApply,
+  teacherCancelTaskApply,
+  switchCardCreateMethod
+} from "../api";
 import UploadPaperDialog from "./UploadPaperDialog";
 import CardOptionDialog from "./CardOptionDialog";
 import SimpleImagePreview from "@/components/SimpleImagePreview";
@@ -311,7 +275,7 @@ const initExamTask = {
 };
 
 const initExamTaskDetail = {
-  operateType: "",
+  operateType: "STAGE",
   paperType: "A",
   cardId: "",
   paperAttachmentIds: [],
@@ -327,68 +291,16 @@ const initExamTaskDetail = {
   customCard: false
 };
 
-const STEPS = [
-  {
-    title: "提交申请",
-    status: {
-      wait: {
-        desc: "待进行",
-        range: []
-      },
-      process: {
-        desc: "进行中",
-        range: ["NEW", "READY", "STAGE"]
-      },
-      success: {
-        desc: "已完成",
-        range: ["SUBMIT", "FINISH"]
-      }
-    }
-  },
-  {
-    title: "审核",
-    status: {
-      wait: {
-        desc: "待进行",
-        range: ["NEW", "READY", "STAGE"]
-      },
-      process: {
-        desc: "进行中",
-        range: ["SUBMIT"]
-      },
-      success: {
-        desc: "已完成",
-        range: ["FINISH"]
-      }
-    }
-  },
-  {
-    title: "入库",
-    status: {
-      wait: {
-        desc: "待进行",
-        range: ["NEW", "READY", "STAGE", "SUBMIT"]
-      },
-      process: {
-        desc: "进行中",
-        range: []
-      },
-      success: {
-        desc: "已完成",
-        range: ["FINISH"]
-      }
-    }
-  }
-];
-
 export default {
   name: "create-task-apply",
   components: { UploadPaperDialog, CardOptionDialog, SimpleImagePreview },
   data() {
     return {
       modalIsShow: false,
+      isSubmit: false,
       examTask: {},
       needReview: false,
+      task: {},
       examRule: {},
       steps: [],
       actStep: "",
@@ -432,21 +344,21 @@ export default {
   computed: {
     cardTodoName() {
       let name = "创建答题卡";
-      if (this.curTaskApply.cardId) {
-        if (this.curTaskApply.makeMethod === "SELECT") {
+      if (this.examTaskDetail.cardId) {
+        if (this.examTaskDetail.makeMethod === "SELECT") {
           name = "选择题卡";
-        } else if (this.curTaskApply.makeMethod === "SELF") {
+        } else if (this.examTaskDetail.makeMethod === "SELF") {
           name = "编辑题卡";
         } else {
           // 已经审核的题卡可以自行编辑,未审核的题卡只能查看
           name =
-            this.curTaskApply.status === "SUBMIT" ? "编辑题卡" : "查看题卡";
+            this.examTaskDetail.status === "SUBMIT" ? "编辑题卡" : "查看题卡";
         }
       }
       return name;
     },
     createCardTypeName() {
-      return CARD_SOURCE_TYPE[this.curTaskApply.makeMethod] || "";
+      return CARD_SOURCE_TYPE[this.examTaskDetail.makeMethod] || "";
     },
     maxFetchCount() {
       return this.paperAttachments.length < 1
@@ -466,24 +378,9 @@ export default {
     initData() {
       this.examTask = { ...initExamTask };
       this.examTaskDetail = { ...initExamTaskDetail };
-      // this.buildSteps();
-    },
-    buildSteps() {
-      // TODO:
-      const curStatus = "";
-      // 构建steps
-      const stepList = this.needReview ? STEPS : [STEPS[0], STEPS[2]];
-      this.steps = stepList.map(step => {
-        const validStepStatus = Object.keys(step.status).find(key =>
-          step.status[key].range.includes(curStatus)
-        );
-
-        return {
-          title: step.title,
-          status: validStepStatus,
-          desc: step.status[validStepStatus].desc
-        };
-      });
+      this.examTaskDetail.includePaper = this.examRule.includePaper;
+      this.examTaskDetail.review = this.examRule.review;
+      this.examTaskDetail.customCard = this.examRule.customCard;
     },
     visibleChange() {
       this.initData();
@@ -491,7 +388,14 @@ export default {
     checkData() {
       return this.$refs.examTaskComp.validate().catch(() => {});
     },
-    cancel() {
+    async cancel() {
+      if (this.examTask.id) {
+        await teacherCancelTaskApply(this.examTask.id);
+        this.$message.success("取消命题申请成功!");
+      }
+      this.close();
+    },
+    close() {
       this.modalIsShow = false;
     },
     open() {
@@ -568,7 +472,6 @@ export default {
       });
     },
     cachePrepareTcpCard() {
-      // TODO:
       this.$ls.set("prepareTcPCard", {
         examTaskId: this.examTask.id,
         courseCode: this.examTask.courseCode,
@@ -579,8 +482,13 @@ export default {
       });
     },
     async toCreateOrViewCard() {
-      await this.toSave();
-      this.task = this.getTaskDetailData();
+      const result = await this.toSave(1);
+      if (!result) return;
+      this.task = {
+        ...this.examTask,
+        ...this.examTaskDetail,
+        examTaskId: this.examTask.id
+      };
       if (!this.examTaskDetail.cardId) {
         this.$refs.CardOptionDialog.open();
         return;
@@ -604,7 +512,7 @@ export default {
     },
     async changeCreateCardType() {
       const h = this.$createElement;
-      const result = await this.$confirm({
+      const result = await this.$msgbox({
         title: "切换题卡操作说明",
         message: h("div", null, [
           h("p", null, "1、切换题卡会将之前选择题卡数据删除。"),
@@ -614,21 +522,28 @@ export default {
             "2、之前选择专卡进行绘制,切换题卡后再次选择专卡,需要重新开始绘制。"
           )
         ]),
+        showCancelButton: true,
         cancelButtonClass: "el-button--danger is-plain",
         confirmButtonClass: "el-button--primary",
         type: "warning"
       }).catch(() => {});
       if (result !== "confirm") return;
-      this.clearMakeMethod();
+
+      await this.clearMakeMethod();
       this.toCreateOrViewCard();
     },
     async clearMakeMethod() {
       // 清除后台记录的题卡
-      if (this.examTask.id) await switchCardCreateMethod(this.examTask.id);
+      if (this.examTask.id && this.examTaskDetail.cardId)
+        await switchCardCreateMethod(this.examTask.id);
 
       this.examTaskDetail.makeMethod = "";
       this.examTaskDetail.cardId = "";
     },
+    courseChange(val) {
+      this.examTask.courseName = val.name;
+      this.clearCard();
+    },
     clearCard() {
       this.clearMakeMethod();
     },
@@ -641,7 +556,7 @@ export default {
       data.paperConfirmAttachmentIds = JSON.stringify(
         this.paperConfirmAttachments
       );
-      return data;
+      this.examTaskDetail = data;
     },
     checkDataValid() {
       const attachmentValid = !this.paperAttachments.some(
@@ -671,23 +586,25 @@ export default {
       }
       return true;
     },
-    async toSave() {
+    async toSave(silent) {
       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";
+      this.getTaskDetailData();
       const datas = {
-        examTaskDetail,
+        examTaskDetail: this.examTaskDetail,
         examTask: this.examTask
       };
       const data = await teacherCreateTaskApply(datas).catch(() => {});
       this.isSubmit = false;
       if (!data) return;
 
-      this.$message.success("保存成功!");
+      this.examTask.id = data;
+
+      if (!silent) this.$message.success("保存成功!");
+      return true;
     },
     async submit() {
       const valid = await this.$refs.examTaskComp.validate().catch(() => {});
@@ -705,17 +622,17 @@ export default {
         }
       )
         .then(async () => {
-          const examTaskDetail = this.getTaskDetailData();
-          examTaskDetail.operateType = "SUBMIT";
+          this.getTaskDetailData();
+          this.examTaskDetail.operateType = "SUBMIT";
           const datas = {
-            examTaskDetail,
+            examTaskDetail: this.examTaskDetail,
             examTask: this.examTask
           };
           const data = await teacherCreateTaskApply(datas).catch(() => {});
 
           if (!data) return;
           this.$message.success("提交成功!");
-          this.cancel();
+          this.close();
           this.$emit("modified");
         })
         .catch(() => {});

+ 0 - 14
src/modules/exam/components/ModifyExamTask.vue

@@ -31,20 +31,6 @@
             >{{ modalForm.courseName }}({{ modalForm.courseCode }})</span
           >
         </el-form-item>
-        <el-form-item prop="specialty" label="适用专业(方向):">
-          <el-input
-            v-if="editable"
-            v-model.trim="modalForm.specialty"
-            type="textarea"
-            resize="none"
-            :rows="2"
-            :maxlength="100"
-            clearable
-            show-word-limit
-            placeholder="建议不超过100个字"
-          ></el-input>
-          <span v-else>{{ modalForm.specialty | defaultFieldFilter }}</span>
-        </el-form-item>
         <el-form-item prop="paperNumber" label="试卷编号:">
           <el-input
             v-if="editable"

+ 77 - 80
src/modules/exam/components/ModifyTaskApply.vue

@@ -21,8 +21,8 @@
             </el-form-item>
           </el-col>
           <el-col :span="14">
-            <el-form-item label="适用专业(方向):">
-              <span>{{ modalForm.specialty | defaultFieldFilter }}</span>
+            <el-form-item label="教研室:">
+              <span>{{ modalForm.teachingRoomName | defaultFieldFilter }}</span>
             </el-form-item>
           </el-col>
         </el-row>
@@ -34,10 +34,11 @@
           </el-col>
           <el-col :span="14">
             <el-form-item label="命题时间:">
-              <span>
+              <span v-if="modalForm.startTime && modalForm.endTime">
                 {{ modalForm.startTime | timestampFilter }} 至
                 {{ modalForm.endTime | timestampFilter }}</span
               >
+              <span v-else>--</span>
             </el-form-item>
           </el-col>
         </el-row>
@@ -53,6 +54,18 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row>
+          <el-col :span="10">
+            <el-form-item label="拟卷教师:">
+              <span>{{ modalForm.teacherName | defaultFieldFilter }}</span>
+            </el-form-item>
+          </el-col>
+          <el-col :span="14">
+            <el-form-item label="主讲教师:">
+              <span>{{ modalForm.lecturerName | defaultFieldFilter }}</span>
+            </el-form-item>
+          </el-col>
+        </el-row>
         <el-row>
           <el-col :span="10">
             <el-form-item label="审核状态:">
@@ -79,14 +92,14 @@
       </el-form>
     </div>
 
-    <div class="mb-4">
+    <div class="mb-4" v-if="flows.length">
       <el-steps align-center>
         <el-step
-          v-for="(step, index) in steps"
-          :key="index"
-          :title="step.title"
-          :description="step.desc"
-          :status="step.status"
+          v-for="flow in flows"
+          :key="flow.taskKey"
+          :title="flow.taskName"
+          :description="flow.desc"
+          :status="flow.status"
         ></el-step>
       </el-steps>
     </div>
@@ -102,10 +115,12 @@
     </div>
     <div class="part-box part-box-pad part-box-border" v-if="modalIsShow">
       <apply-content
+        v-if="dataReady"
         v-show="curMenu.id === '1'"
         ref="ApplyContent"
         :exam-task="modalForm"
         :edit-type="editType"
+        :flows="flows"
         @cancel="cancel"
         @modified="modified"
       ></apply-content>
@@ -125,7 +140,7 @@
 import ApplyContent from "./ApplyContent";
 import ApplyAuditHistory from "./ApplyAuditHistory";
 import { examRuleDetail } from "../../base/api";
-import { cancelOrRestartTaskApply } from "../api";
+import { cancelOrRestartTaskApply, taskAllFlowSetups } from "../api";
 
 const initModalForm = {
   id: null,
@@ -137,6 +152,8 @@ const initModalForm = {
   endTime: "",
   cardRuleId: "",
   cardRuleName: "",
+  flowId: "",
+  setup: 0,
   userId: "",
   userName: "",
   auditStatus: "",
@@ -144,60 +161,6 @@ const initModalForm = {
   source: ""
 };
 
-const STEPS = [
-  {
-    title: "提交申请",
-    status: {
-      wait: {
-        desc: "待进行",
-        range: []
-      },
-      process: {
-        desc: "进行中",
-        range: ["NEW", "READY", "STAGE"]
-      },
-      success: {
-        desc: "已完成",
-        range: ["SUBMIT", "FINISH"]
-      }
-    }
-  },
-  {
-    title: "审核",
-    status: {
-      wait: {
-        desc: "待进行",
-        range: ["NEW", "READY", "STAGE"]
-      },
-      process: {
-        desc: "进行中",
-        range: ["SUBMIT"]
-      },
-      success: {
-        desc: "已完成",
-        range: ["FINISH"]
-      }
-    }
-  },
-  {
-    title: "入库",
-    status: {
-      wait: {
-        desc: "待进行",
-        range: ["NEW", "READY", "STAGE", "SUBMIT"]
-      },
-      process: {
-        desc: "进行中",
-        range: []
-      },
-      success: {
-        desc: "已完成",
-        range: ["FINISH"]
-      }
-    }
-  }
-];
-
 export default {
   name: "modify-task-apply",
   components: { ApplyContent, ApplyAuditHistory },
@@ -227,11 +190,11 @@ export default {
   data() {
     return {
       modalIsShow: false,
+      dataReady: false,
       modalForm: {},
       needReview: false,
       examRule: {},
-      steps: [],
-      actStep: "",
+      flows: [],
       menus: [
         { id: "1", name: "命题处理", component: "apply-content" },
         { id: "2", name: "审核意见", component: "apply-audit-history" }
@@ -256,23 +219,57 @@ export default {
       this.modalForm.includePaper = this.examRule.includePaper;
       this.modalForm.review = this.examRule.review;
       this.modalForm.customCard = this.examRule.customCard;
-      this.buildSteps();
+      this.buildSteps(this.modalForm.flowId);
     },
-    buildSteps() {
-      const curStatus = this.instance.status;
-      // 构建steps
-      const stepList = this.needReview ? STEPS : [STEPS[0], STEPS[2]];
-      this.steps = stepList.map(step => {
-        const validStepStatus = Object.keys(step.status).find(key =>
-          step.status[key].range.includes(curStatus)
-        );
+    async buildSteps() {
+      if (!this.modalForm.flowId) {
+        this.dataReady = true;
+        return;
+      }
+
+      const flowStatus = {
+        wait: "待进行",
+        process: "进行中",
+        success: "已完成"
+      };
 
-        return {
-          title: step.title,
-          status: validStepStatus,
-          desc: step.status[validStepStatus].desc
-        };
+      const data = await taskAllFlowSetups(this.modalForm.flowId);
+      const curSetup = this.modalForm.setup;
+      // if (data.length) {
+      //   data.push({
+      //     flowId: this.modalForm.flowId,
+      //     setup: data.length + 1,
+      //     taskKey: this.$randomCode(),
+      //     taskName: "入库"
+      //   });
+      // }
+      this.flows = data.map(item => {
+        item.status =
+          curSetup > item.setup
+            ? "success"
+            : curSetup === item.setup
+            ? "process"
+            : "wait";
+        item.desc = flowStatus[item.status];
+        item.isCurrent = curSetup === item.setup;
+        return item;
       });
+
+      this.dataReady = true;
+      // const curStatus = this.instance.status;
+      // 构建steps
+      // const stepList = this.needReview ? STEPS : [STEPS[0], STEPS[2]];
+      // this.steps = stepList.map(step => {
+      //   const validStepStatus = Object.keys(step.status).find(key =>
+      //     step.status[key].range.includes(curStatus)
+      //   );
+
+      //   return {
+      //     title: step.title,
+      //     status: validStepStatus,
+      //     desc: step.status[validStepStatus].desc
+      //   };
+      // });
     },
     visibleChange() {
       this.initData(this.instance);

+ 3 - 1
src/modules/exam/components/PublishPrintTask.vue

@@ -90,7 +90,6 @@
       </el-table>
       <div class="part-page">
         <el-pagination
-          v-if="papers.length"
           background
           layout="total,prev, pager, next"
           :current-page="current"
@@ -150,6 +149,9 @@ export default {
         courseName: "",
         courseCode: ""
       },
+      current: 1,
+      size: this.GLOBAL.pageSize,
+      total: 0,
       timeDisabled: false,
       tableData: [],
       curRow: {},

+ 4 - 23
src/modules/exam/store.js

@@ -1,9 +1,4 @@
-import {
-  waitExamTaskCount,
-  waitExamTaskNewCount,
-  waitTaskReviewCount
-} from "./api";
-import { calcSum } from "@/plugins/utils";
+import { waitExamTaskCount } from "./api";
 
 const state = {
   waitTaskCount: 0
@@ -16,23 +11,9 @@ const mutations = {
 };
 
 const actions = {
-  async updateWaitTaskCount({ commit }, userRoles = []) {
-    // TODO:需要调整:/api/admin/work/exam/task/ready_count
-    const apis = {
-      QUESTION_TEACHER: [waitExamTaskCount],
-      EXAM_TEACHER: [waitExamTaskNewCount, waitTaskReviewCount]
-    };
-    let countAll = [];
-    Object.keys(apis).forEach(roleCode => {
-      if (userRoles.includes(roleCode))
-        countAll = [...countAll, ...apis[roleCode]];
-    });
-    const counts = await Promise.all(
-      countAll.map(item => item())
-    ).catch(() => {});
-
-    const count = calcSum(counts || [0]);
-    commit("setNotDoneTaskCount", count);
+  async updateWaitTaskCount({ commit }) {
+    const count = await waitExamTaskCount().catch(() => {});
+    commit("setNotDoneTaskCount", count || 0);
   }
 };
 

+ 1 - 6
src/modules/exam/views/ExamTaskManage.vue

@@ -126,10 +126,6 @@
             {{ scope.row.courseName }}({{ scope.row.courseCode }})
           </template>
         </el-table-column>
-        <el-table-column
-          prop="specialty"
-          label="适用专业(方向)"
-        ></el-table-column>
         <el-table-column prop="cardRuleName" label="题卡规则">
         </el-table-column>
         <el-table-column
@@ -268,7 +264,6 @@ export default {
       examTasks: [],
       curExamTask: {},
       curUserId: this.$ls.get("user", { id: "" }).id,
-      userRoles: this.$ls.get("user", { roleList: [] }).roleList,
       // date-picker
       createTime: [],
       pickerOptions
@@ -362,7 +357,7 @@ export default {
     },
     taskModified() {
       this.getList();
-      this.updateWaitTaskCount(this.userRoles);
+      this.updateWaitTaskCount();
     }
   }
 };

+ 5 - 6
src/modules/exam/views/TaskApplyManage.vue

@@ -91,7 +91,7 @@
       </el-form>
       <div class="part-box-action">
         <el-button
-          v-if="checkPrivilege('button', 'add')"
+          v-if="checkPrivilege('button', 'addTask')"
           icon="el-icon-download"
           type="primary"
           @click="toAddApply"
@@ -116,10 +116,6 @@
             {{ scope.row.courseName }}({{ scope.row.courseCode }})
           </template>
         </el-table-column>
-        <el-table-column
-          prop="specialty"
-          label="适用专业(方向)"
-        ></el-table-column>
         <el-table-column prop="cardRuleName" label="题卡规则"></el-table-column>
         <el-table-column
           prop="userName"
@@ -225,7 +221,10 @@
       @modified="taskModified"
     ></modify-task-apply>
     <!-- CreateTaskApply -->
-    <create-task-apply ref="CreateTaskApply"></create-task-apply>
+    <create-task-apply
+      ref="CreateTaskApply"
+      @modified="taskModified"
+    ></create-task-apply>
   </div>
 </template>
 

+ 11 - 6
src/modules/exam/views/TaskPaperManage.vue

@@ -95,10 +95,6 @@
             {{ scope.row.courseName }}({{ scope.row.courseCode }})
           </template>
         </el-table-column>
-        <el-table-column
-          prop="specialty"
-          label="适用专业(方向)"
-        ></el-table-column>
         <el-table-column
           prop="paperType"
           label="卷型"
@@ -211,6 +207,11 @@
       ref="ModifyTaskPaper"
       @modified="getList"
     ></modify-task-paper>
+    <!-- PublishPrintTask -->
+    <publish-print-task
+      :instance="curPaper"
+      ref="PublishPrintTask"
+    ></publish-print-task>
   </div>
 </template>
 
@@ -225,10 +226,11 @@ import pickerOptions from "@/constants/datePickerOptions";
 import { downloadBlob } from "@/plugins/utils";
 import { CARD_SOURCE_TYPE } from "@/constants/enumerate";
 import ModifyTaskPaper from "../components/ModifyTaskPaper";
+import PublishPrintTask from "../components/PublishPrintTask";
 
 export default {
   name: "task-paper-manage",
-  components: { ModifyTaskPaper },
+  components: { ModifyTaskPaper, PublishPrintTask },
   data() {
     return {
       filter: {
@@ -341,7 +343,10 @@ export default {
       this.editType = "PREVIEW";
       this.$refs.ModifyTaskPaper.open();
     },
-    toPublishPrintTask(row) {},
+    toPublishPrintTask(row) {
+      this.curPaper = row;
+      this.$refs.PublishPrintTask.open();
+    },
     async toDownload(row) {
       if (this.loading) return;
 

+ 2 - 11
src/modules/exam/views/TaskReviewManage.vue

@@ -149,10 +149,6 @@
             {{ scope.row.courseName }}({{ scope.row.courseCode }})
           </template>
         </el-table-column>
-        <el-table-column
-          prop="specialty"
-          label="适用专业(方向)"
-        ></el-table-column>
         <el-table-column prop="cardRuleName" label="题卡规则"></el-table-column>
         <el-table-column
           prop="userName"
@@ -191,11 +187,7 @@
               title="查看详情"
             ></el-button>
             <el-button
-              v-if="
-                !AUDITED &&
-                  scope.row.createId === curUserId &&
-                  checkPrivilege('link', 'notReviewEdit')
-              "
+              v-if="!AUDITED && checkPrivilege('link', 'notReviewEdit')"
               class="btn-table-icon"
               type="text"
               icon="icon icon-edit"
@@ -299,7 +291,6 @@ export default {
       multipleSelection: [],
       loading: false,
       curUserId: this.$ls.get("user", { id: "" }).id,
-      userRoles: this.$ls.get("user", { roleList: [] }).roleList,
       // audit-dialog
       auditDialogShow: false,
       auditModal: { reason: "" },
@@ -446,7 +437,7 @@ export default {
     },
     taskModified() {
       this.getList();
-      this.updateWaitTaskCount(this.userRoles);
+      this.updateWaitTaskCount();
     }
   }
 };

+ 25 - 7
src/modules/exam/views/WaitTask.vue

@@ -33,7 +33,6 @@
               class="btn-table-icon"
               type="text"
               icon="icon icon-download-act"
-              :disabled="loading"
               @click="toDo(scope.row)"
               >立即处理</el-button
             >
@@ -52,23 +51,38 @@
         </el-pagination>
       </div>
     </div>
+
+    <!-- ModifyTaskApply -->
+    <modify-task-apply
+      ref="ModifyTaskApply"
+      :edit-type="editType"
+      :instance="curTask"
+      @modified="taskModified"
+    ></modify-task-apply>
   </div>
 </template>
 
 <script>
 import { mapActions } from "vuex";
 import { waitExamTaskListPage } from "../api";
+import ModifyTaskApply from "../components/ModifyTaskApply";
 
 export default {
   name: "wait-task",
+  components: { ModifyTaskApply },
   data() {
     return {
       current: 1,
       size: this.GLOBAL.pageSize,
       total: 0,
-      dataList: []
+      dataList: [],
+      curTask: {},
+      editType: "AUDIT"
     };
   },
+  mounted() {
+    this.toPage(1);
+  },
   methods: {
     ...mapActions("exam", ["updateWaitTaskCount"]),
     async getList() {
@@ -77,20 +91,24 @@ export default {
         pageSize: this.size
       };
       const data = await waitExamTaskListPage(datas);
-      this.tasks = data.records;
+      this.dataList = data.records;
       this.total = data.total;
     },
     toPage(page) {
       this.current = page;
       this.getList();
     },
-    toDo(row) {
-      console.log(row);
-      // TODO:
+    toDo(task) {
+      this.curTask = { ...task, source: "REVIEW" };
+      this.$refs.ModifyTaskApply.open();
+    },
+    taskModified() {
+      this.getList();
+      this.updateWaitTaskCount();
     }
   },
   beforeRouteLeave(to, from, next) {
-    if (to.name === "CardDesign" && this.IS_QUESTION_TEACHER) {
+    if (to.name === "CardDesign") {
       this.$ls.set("cachePageInfo", {
         page: this.$refs.WaitTaskExamTask.current,
         curRowId: this.$refs.WaitTaskExamTask.curTask.id

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

@@ -107,8 +107,8 @@ export default {
       loginModel: {
         schoolCode: ORG_CODE,
         loginName: "",
-        code: "",
-        password: ""
+        code: "qmth",
+        password: "123456"
       },
       loginRules: {
         code: smscode,

+ 17 - 16
src/router.js

@@ -38,7 +38,7 @@ let router = new Router({
       redirect: { name: "Login" }
     },
     {
-      path: "/home",
+      path: "/home/:nextRouter?",
       name: "Home",
       component: Home,
       children: [...base, ...exam, ...print, ...customer]
@@ -64,20 +64,21 @@ let router = new Router({
 });
 
 // route interceptor
-// router.beforeEach((to, from, next) => {
-//   const token = Vue.ls.get("token");
-//   if (to.meta.noRequire) {
-//     next();
-//   } else {
-//     // 需要登录的路由
-//     if (token) {
-//       next();
-//     } else {
-//       // 登录失效的处理
-//       Vue.ls.clear();
-//       next({ name: "Login" });
-//     }
-//   }
-// });
+router.beforeEach((to, from, next) => {
+  const token = Vue.ls.get("token");
+  if (to.meta.noRequire) {
+    next();
+    return;
+  }
+
+  if (!token) {
+    // 登录失效的处理
+    Vue.ls.clear();
+    next({ name: "Login" });
+    return;
+  }
+
+  next();
+});
 
 export default router;

+ 5 - 1
src/store.js

@@ -3,6 +3,10 @@ import Vuex from "vuex";
 
 Vue.use(Vuex);
 
+// TODO:待完善
+const privilegeMapData = window.sessionStorage.getItem("privilegeMap");
+const privilegeMap = privilegeMapData ? JSON.parse(privilegeMapData).value : {};
+
 // modules
 import card from "./modules/card/store";
 import exam from "./modules/exam/store";
@@ -10,7 +14,7 @@ import exam from "./modules/exam/store";
 export default new Vuex.Store({
   state: {
     user: {},
-    privilegeMap: {}
+    privilegeMap
   },
   mutations: {
     setUser(state, user) {

+ 2 - 1
src/views/Home.vue

@@ -276,6 +276,7 @@ export default {
         });
       });
       this.$store.commit("setPrivilegeMap", privilegeMap);
+      this.$ls.set("privilegeMap", privilegeMap);
     },
     menusToTree(menus) {
       let navTree = deepCopy(localNavs);
@@ -360,7 +361,7 @@ export default {
         this.validRoutes.includes("WaitTask") &&
         this.curMenu.url === "exam"
       ) {
-        this.updateWaitTaskCount(this.userRoles);
+        this.updateWaitTaskCount();
       }
     },
     toLogout() {