zhangjie 5 anos atrás
pai
commit
f896e2cee6

+ 13 - 0
src/constants/enumerate.js

@@ -73,3 +73,16 @@ export const PAPER_TYPE = {
   0: "印刷",
   1: "填涂"
 };
+
+export const MENU_ROUTER_DICT = {
+  basic: "base",
+  userManager: "UserManage",
+  ruleManager: "RuleManage",
+  exam: "exam-center",
+  todoTaskManager: "TodoTask",
+  doneTaskManager: "DoneTask",
+  examManager: "ExamManage",
+  cardManager: "CardManage",
+  printManager: "PrintManage",
+  cardAuditingManager: "CardAudit"
+};

+ 15 - 5
src/constants/navs.js

@@ -1,7 +1,7 @@
 const navs = [
   {
     title: "考试中心",
-    type: "exam-center",
+    router: "exam-center",
     children: [
       {
         title: "待办任务",
@@ -47,7 +47,17 @@ const navs = [
       },
       {
         title: "题卡管理",
-        router: "CardManage"
+        router: "CardManage",
+        children: [
+          {
+            title: "题卡编辑",
+            router: "CardDesign"
+          },
+          {
+            title: "题卡预览",
+            router: "CardPreview"
+          }
+        ]
       },
       {
         title: "印刷管理",
@@ -61,7 +71,7 @@ const navs = [
   },
   {
     title: "成绩报表",
-    type: "score-paper",
+    router: "score-paper",
     children: [
       {
         title: "班级报表",
@@ -71,7 +81,7 @@ const navs = [
   },
   {
     title: "教研分析",
-    type: "analyze",
+    router: "analyze",
     children: [
       {
         title: "分数分析",
@@ -81,7 +91,7 @@ const navs = [
   },
   {
     title: "基础配置",
-    type: "base",
+    router: "base",
     children: [
       {
         title: "用户管理",

+ 18 - 6
src/modules/card/views/CardDesign.vue

@@ -269,7 +269,7 @@ export default {
   },
   data() {
     return {
-      cardId: this.$route.params.cardId,
+      cardId: this.$route.params.cardId || this.$ls.get("cardId"),
       cardDetailId: this.$ls.get("cardDetailId"),
       prepareTcPCard: this.$ls.get("prepareTcPCard", {}),
       ELEMENT_LIST,
@@ -329,6 +329,7 @@ export default {
         this.setCardConfig(cont.cardConfig);
       } else {
         // 没有题卡内容时,直接创建新的内容
+        this.setCardConfig({ cardName: detData.title });
         this.initPageData();
       }
     },
@@ -402,7 +403,8 @@ export default {
           courseName: "",
           courseCode: "",
           cardSource: "",
-          title: ""
+          title: "",
+          id: this.cardId
         },
         {
           ...this.prepareTcPCard,
@@ -429,8 +431,9 @@ export default {
       }
       const result = await saveCard(this.getCardData());
       this.cardDetailId = result.cardDetailId;
-      this.$ls.set("cardDetailId", this.cardDetailId);
       this.cardId = result.cardId;
+      this.$ls.set("cardDetailId", this.cardDetailId);
+      this.$ls.set("cardId", this.cardId);
     },
     async toSave() {
       await this.save();
@@ -453,12 +456,21 @@ export default {
         this.cardPreviewUrl = "";
       };
     },
-    async toSubmit() {
-      await this.save();
-      this.cardPreviewUrl = `/#/card/preview/${this.cardId}/frame`;
+    toSubmit() {
+      this.$confirm("确定要提交当前题卡吗?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      })
+        .then(async () => {
+          await this.save();
+          this.cardPreviewUrl = `/#/card/preview/${this.cardId}/frame`;
+        })
+        .catch(() => {});
     }
   },
   beforeDestroy() {
+    this.$ls.remove("cardId");
     this.$ls.remove("cardDetailId");
     this.$ls.remove("prepareTcPCard");
     this.initState();

+ 1 - 1
src/modules/card/views/CardPreview.vue

@@ -127,7 +127,7 @@ export default {
     async init() {
       const tempData = await cardTempDetail(this.cardId);
       if (!tempData) {
-        this.$message.error("当前题卡还没开始创建!");
+        this.$message.error("很抱歉,当前题卡还没开始制作!");
         return;
       }
       let stdInfo = {};

+ 4 - 1
src/modules/exam-center/api.js

@@ -23,7 +23,7 @@ export const doneTaskDetail = taskId => {
 };
 // 撤回
 export const revokeDoneTask = ({ taskId, examId }) => {
-  return $get("/api/print/exam/examTask/revoke", { taskId, examId });
+  return $post("/api/print/exam/examTask/revoke", { taskId, examId });
 };
 
 // exam-manage
@@ -83,6 +83,9 @@ export const deleteCard = cardId => {
 export const courseByUser = () => {
   return $get("/api/print/card/card/listCourseByUserId", {});
 };
+export const changeCardStatus = ({ cardId, cardStatus }) => {
+  return $post("/api/print/card/card/changeCardStatus", { cardId, cardStatus });
+};
 
 // print-manage
 export const printTaskListPage = datas => {

+ 1 - 1
src/modules/exam-center/components/UploadSamplePaperDialog.vue

@@ -94,7 +94,7 @@ export default {
       },
       isSubmit: false,
       // upload
-      format: ["doc", "docx"],
+      format: [],
       uploadData: {
         schoolId: this.$ls.get("schoolId"),
         userId: this.$ls.get("user", { id: "" }).id

+ 3 - 1
src/modules/exam-center/views/CardAudit.vue

@@ -69,18 +69,20 @@
       <el-table ref="TableList" :data="cards" border stripe>
         <el-table-column prop="schoolName" label="学校名称"></el-table-column>
         <!-- <el-table-column prop="title" label="学院"></el-table-column> -->
-        <el-table-column prop="cardId" label="题卡ID"></el-table-column>
+        <el-table-column prop="cardCode" label="题卡ID"></el-table-column>
         <el-table-column prop="createTime" label="申请时间"></el-table-column>
         <el-table-column prop="userName" label="申请人"></el-table-column>
         <el-table-column prop="title" label="标题">
           <template slot-scope="scope">
             <p
+              v-if="filter.auditingStatus == 0"
               class="cont-link"
               @click="downloadPaper(scope.row)"
               title="点击下载试卷文件"
             >
               {{ scope.row.title }}
             </p>
+            <p v-else>{{ scope.row.title }}</p>
           </template>
         </el-table-column>
         <el-table-column label="操作" align="center">

+ 20 - 4
src/modules/exam-center/views/CardManage.vue

@@ -47,7 +47,7 @@
 
     <div class="part-box">
       <el-table ref="TableList" :data="cards" border stripe>
-        <el-table-column prop="id" label="题ID"></el-table-column>
+        <el-table-column prop="id" label="题ID"></el-table-column>
         <el-table-column label="科目(代码)">
           <template slot-scope="scope">
             <span>{{ scope.row.courseName }}({{ scope.row.courseCode }})</span>
@@ -82,7 +82,7 @@
                 class="btn-table-icon"
                 type="text"
                 icon="icon icon-copy"
-                @click="toDelete(scope.row)"
+                @click="toCopy(scope.row)"
                 title="复制"
               ></el-button>
             </div>
@@ -136,7 +136,7 @@
 
 <script>
 import { AUDITING_STATUS } from "@/constants/enumerate";
-import { cardListPage, copyCard, deleteCard } from "../api";
+import { cardListPage, copyCard, deleteCard, changeCardStatus } from "../api";
 import CardOptionDialog from "../components/CardOptionDialog";
 
 export default {
@@ -202,7 +202,23 @@ export default {
       this.$message.success("复制成功!");
       this.getList();
     },
-    toPrint() {},
+    toPrint(row) {
+      this.$confirm(
+        "一旦准备印刷,题卡将不可再编辑,确定要提交印刷吗?",
+        "警告",
+        {
+          callback: async action => {
+            if (action !== "confirm") return;
+            await changeCardStatus({
+              cardId: row.id,
+              cardStatus: 1
+            });
+            this.getList();
+            this.$message.success("提交成功!");
+          }
+        }
+      );
+    },
     toDelete(row) {
       this.$confirm("确定要删除当前题卡吗?", "删除警告", {
         callback: async action => {

+ 2 - 5
src/modules/exam-center/views/DoneTask.vue

@@ -29,10 +29,7 @@
       <el-table ref="TableList" :data="tasks" border stripe>
         <el-table-column prop="id" label="考试ID"></el-table-column>
         <el-table-column prop="examName" label="考试名称"></el-table-column>
-        <el-table-column label="科目名称(ID)">
-          <template slot-scope="scope">
-            <span>{{ scope.row.courseName }}({{ scope.row.courseCode }})</span>
-          </template>
+        <el-table-column prop="courseNameCode" label="科目名称(ID)">
         </el-table-column>
         <el-table-column prop="paperStatus" label="试卷"></el-table-column>
         <el-table-column prop="cardStatus" label="答题卡"></el-table-column>
@@ -81,7 +78,7 @@ export default {
       total: 0,
       visible: false,
       exams: [],
-      tasks: [{ id: "2" }]
+      tasks: []
     };
   },
   created() {

+ 25 - 21
src/modules/exam-center/views/DoneTaskDetail.vue

@@ -12,8 +12,8 @@
           <th>试卷类型</th>
           <th>试卷文件</th>
           <th>答题卡</th>
-          <th>标答</th>
-          <th>试卷结构</th>
+          <!-- <th>标答</th>
+          <th>试卷结构</th> -->
         </tr>
         <tr
           v-for="(attachment, index) in paperAttachments"
@@ -21,9 +21,9 @@
         >
           <td>{{ attachment.name }}卷</td>
           <td class="td-link">
-            <span @click="downloadPaper(attachment)" title="点击下载试卷">{{
-              `${task.examName}试卷${attachment.name}`
-            }}</span>
+            <span @click="downloadPaper(attachment)" title="点击下载试卷">
+              <i class="icon icon-download-act"></i>{{ attachment.filename }}
+            </span>
           </td>
           <td
             class="td-link"
@@ -31,10 +31,10 @@
             v-if="index === 0"
           >
             <span @click="toPreviewCard" title="点击预览答题卡内容">{{
-              task.cardTitle
+              task.cardName
             }}</span>
           </td>
-          <td class="td-link">
+          <!-- <td class="td-link">
             <span @click="downloadStdAns(attachment)"
               ><i class="icon icon-download-act"></i
               >{{ attachment.name }}卷标答下载</span
@@ -48,7 +48,7 @@
             <span @click="downloadPaperStructure">
               <i class="icon icon-download-act"></i>试卷结构下载
             </span>
-          </td>
+          </td> -->
         </tr>
       </table>
 
@@ -64,6 +64,7 @@
 
 <script>
 import { doneTaskDetail, revokeDoneTask } from "../api";
+import { attachmentPreview } from "../../login/api";
 
 export default {
   name: "done-task-detail",
@@ -77,9 +78,17 @@ export default {
       curAttachment: {}
     };
   },
+  mounted() {
+    this.getData();
+  },
   methods: {
     async getData() {
-      this.task = await doneTaskDetail(this.taskId);
+      const data = await doneTaskDetail(this.taskId);
+      const nameCode = data.courseNameCode.split(/\(|\)/);
+      this.task = Object.assign(this.task, data, {
+        courseName: nameCode[0],
+        courseCode: nameCode[1]
+      });
       this.pTypeEnable = this.task.enablePaperType.split(",").length > 1;
       this.parsePaperAttachment();
     },
@@ -96,12 +105,16 @@ export default {
         cancelButtonText: "取消",
         type: "warning"
       }).then(async () => {
-        await revokeDoneTask(this.taskId);
+        await revokeDoneTask(this.task);
         this.goback();
       });
     },
-    downloadPaper(attachment) {
-      window.open(attachment.path);
+    async downloadPaper(attachment) {
+      const data = await attachmentPreview(attachment.attachmentId);
+      window.open(data.path);
+    },
+    toPreviewCard() {
+      window.open(`/#/card/preview/${this.task.cardId}/view`);
     },
     downloadStdAns(attachment) {
       // TODO:
@@ -109,15 +122,6 @@ export default {
     },
     downloadPaperStructure() {
       // TODO:
-    },
-    toPreviewCard() {
-      this.$router.push({
-        name: "CardPreview",
-        params: {
-          cardId: this.task.cardId,
-          viewType: "view"
-        }
-      });
     }
   }
 };

+ 23 - 9
src/modules/exam-center/views/PrintManage.vue

@@ -49,13 +49,15 @@
     </div>
 
     <div class="part-box">
-      <el-table ref="TableList" :data="examPages" border stripe>
-        <el-table-column prop="id" label="考试ID"></el-table-column>
+      <el-table ref="TableList" :data="dataList" border stripe>
+        <el-table-column prop="examCode" label="考试ID"></el-table-column>
         <el-table-column prop="examName" label="考试名称"></el-table-column>
-        <el-table-column prop="paperStatus" label="总科次"></el-table-column>
-        <el-table-column prop="cardStatus" label="打印时间"></el-table-column>
-        <el-table-column prop="createTime" label="打印进度"></el-table-column>
-        <el-table-column prop="createTime" label="撤回申请"></el-table-column>
+        <el-table-column prop="totalCourse" label="总科次"></el-table-column>
+        <el-table-column prop="printTime" label="打印时间"></el-table-column>
+        <el-table-column prop="printProgress" label="打印进度">
+          <template slot-scope="scope">{{ scope.row.printProgress }}%</template>
+        </el-table-column>
+        <el-table-column prop="revokeStatus" label="撤回申请"></el-table-column>
         <el-table-column label="操作" align="center">
           <template slot-scope="scope">
             <el-button
@@ -64,6 +66,7 @@
               icon="icon icon-confirm"
               @click="toConfirm(scope.row)"
               title="确认"
+              v-if="scope.row.revokeStatus === 0"
             ></el-button>
           </template>
         </el-table-column>
@@ -102,17 +105,25 @@ export default {
       visible: false,
       REVOKE_STATUS,
       exams: [],
-      examPages: [{ id: "" }]
+      dataList: [],
+      setT: ""
     };
   },
   created() {
-    // this.init();
+    if (this.setT) clearInterval(this.setT);
+    this.init();
+    this.setInter();
   },
   methods: {
     init() {
       this.getExamList();
       this.getList();
     },
+    setInter() {
+      this.setT = setInterval(() => {
+        this.getList();
+      }, 30 * 1000);
+    },
     async getList() {
       const datas = {
         ...this.filter,
@@ -120,7 +131,7 @@ export default {
         pageSize: this.size
       };
       const data = await printTaskListPage(datas);
-      this.examPages = data.records;
+      this.dataList = data.records;
       this.total = data.total;
     },
     toPage(page) {
@@ -140,6 +151,9 @@ export default {
       // TODO:
       console.log(row);
     }
+  },
+  beforeDestroy() {
+    if (this.setT) clearInterval(this.setT);
   }
 };
 </script>

+ 28 - 2
src/modules/exam-center/views/WaitTaskDetail.vue

@@ -113,7 +113,8 @@ export default {
         } else if (this.task.cardSource === 1) {
           name = "编辑题卡";
         } else {
-          name = "查看题卡";
+          // 已经审核的题卡可以自行编辑,未审核的题卡只能查看
+          name = this.task.auditingStatus ? "编辑题卡" : "查看题卡";
         }
       }
       return name;
@@ -185,7 +186,16 @@ export default {
             }
           });
         } else {
-          window.open(`/#/card/preview/${this.task.cardId}/view`);
+          if (this.task.auditingStatus) {
+            this.$router.push({
+              name: "CardDesign",
+              params: {
+                cardId: this.task.cardId
+              }
+            });
+          } else {
+            window.open(`/#/card/preview/${this.task.cardId}/view`);
+          }
         }
         return;
       }
@@ -206,6 +216,21 @@ export default {
       datas.enablePaperType = this.getEnablePaperType();
       return { tcPExamTaskDetail: datas };
     },
+    checkDataValid() {
+      const attachmentValid = !this.curPaperAttachments.some(
+        item => !item.attachmentId
+      );
+      if (!attachmentValid) {
+        this.$message.error("请完成试卷文件上传!");
+        return;
+      }
+
+      if (!this.task.cardId) {
+        this.$message.error("请选择题卡创建方式!");
+        return;
+      }
+      return true;
+    },
     toSubmit() {
       this.$confirm(
         "任务确定提交后,则不可更改试卷及答题卡内容,确定提交该任务?",
@@ -216,6 +241,7 @@ export default {
           type: "warning"
         }
       ).then(async () => {
+        if (!this.checkDataValid()) return;
         await submitWaitTask(this.getTaskData());
         this.$message.success("提交成功!");
         this.goback();

+ 2 - 2
src/modules/login/api.js

@@ -6,8 +6,8 @@ export const login = datas => {
 export const logout = userId => {
   return $get("/api/print/basic/sys/logout", { userId });
 };
-export const sysMenu = datas => {
-  return $post("/api/print/basic/sys/getMenu", datas);
+export const sysMenu = () => {
+  return $get("/api/print/basic/sys/getMenu", {});
 };
 export const attachmentPreview = attachmentId => {
   return $get("/api/print/basic/sys/attachmentPreview", { attachmentId });

+ 8 - 2
src/router.js

@@ -2,6 +2,8 @@ import Vue from "vue";
 import Router from "vue-router";
 
 import Home from "./views/Home.vue";
+import NotFound from "./views/404.vue";
+
 import login from "./modules/login/router";
 import account from "./modules/account/router";
 // module-example
@@ -24,11 +26,15 @@ export default new Router({
       path: "/home",
       name: "Home",
       component: Home,
-      redirect: { name: "WaitTask" },
       children: [...account, ...base, ...examCenter, ...scorePaper, ...analyze]
     },
     { ...login },
-    ...card
+    ...card,
+    {
+      path: "*",
+      name: "404",
+      component: NotFound
+    }
     // [lazy-loaded] route level code-splitting
     // {
     //   path: "/about",

+ 15 - 0
src/views/404.vue

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

+ 73 - 11
src/views/Home.vue

@@ -13,7 +13,7 @@
             :class="{ 'menu-item-act': curMainIndex === index }"
           >
             <div class="menu-item">
-              <i :class="['icon', `icon-${nav.type}`]"></i>
+              <i :class="['icon', `icon-${nav.router}`]"></i>
               <span>{{ nav.title }}</span>
             </div>
           </li>
@@ -37,9 +37,9 @@
       </div>
     </div>
 
-    <div class="home-navs">
+    <div class="home-navs" v-if="curNav">
       <div class="nav-head">
-        <i :class="['icon', `icon-${curNav.type}-gray`]"></i>
+        <i :class="['icon', `icon-${curNav.router}-gray`]"></i>
         <span>{{ curNav.title }}</span>
       </div>
       <ul class="nav-list">
@@ -71,9 +71,9 @@
       </ul>
     </div>
 
-    <div class="home-body" :class="{ 'home-body-big': isCollapsed }">
+    <div class="home-body">
       <div class="home-main">
-        <div class="home-breadcrumb">
+        <div class="home-breadcrumb" v-if="breadcrumbs.length">
           <el-breadcrumb separator=">">
             <el-breadcrumb-item :to="{ name: 'Home' }">
               <i class="icon icon-home" style="margin-top: -2px;"></i>
@@ -96,15 +96,17 @@
 </template>
 
 <script>
-import navs from "@/constants/navs";
-import { logout } from "../modules/login/api";
+import localNavs from "@/constants/navs";
+import { deepCopy } from "@/plugins/utils";
+import { MENU_ROUTER_DICT } from "@/constants/enumerate";
+import { logout, sysMenu } from "../modules/login/api";
 
 export default {
   name: "home",
   data() {
     return {
-      isCollapsed: false,
-      navs,
+      navs: [],
+      validRoutes: [],
       curMainIndex: 0,
       curSubIndex: 0,
       breadcrumbs: []
@@ -120,12 +122,71 @@ export default {
       return this.navs[this.curMainIndex];
     }
   },
-  mounted() {
-    this.actCurNav();
+  created() {
+    this.getMenus();
   },
   methods: {
+    async getMenus() {
+      const data = await sysMenu();
+      this.navs = this.menusToTree(data.records);
+      console.log(this.$route.name);
+
+      if (this.$route.name === "Home") {
+        this.$router.replace({
+          name: this.navs[0].children[0].router
+        });
+      } else {
+        if (!this.validRoutes.includes(this.$route.name)) {
+          this.$router.replace({
+            name: "404"
+          });
+        }
+      }
+      this.actCurNav();
+    },
+    menusToTree(menus) {
+      let navTree = deepCopy(localNavs);
+      let validRoutes = [];
+      const anchorNav = (menu, navs) => {
+        const name = MENU_ROUTER_DICT[menu.url];
+        navs.forEach(item => {
+          if (item.router === name) {
+            item.fixed = true;
+            validRoutes.push(item.router);
+
+            if (menu.parentId !== null && item["children"]) {
+              item.children.map(el => {
+                el.fixed = true;
+              });
+            }
+            return;
+          } else {
+            if (item["children"]) anchorNav(menu, item.children);
+          }
+        });
+      };
+      const clearNoFixed = navs => {
+        let list = [];
+        navs.forEach(nav => {
+          if (nav["fixed"]) {
+            let navItem = { title: nav.title, router: nav.router };
+            if (nav["children"])
+              navItem.children = clearNoFixed(nav["children"]);
+            list.push(navItem);
+          }
+        });
+        return list;
+      };
+
+      menus.forEach(menu => {
+        anchorNav(menu, navTree);
+      });
+      this.validRoutes = validRoutes;
+      return clearNoFixed(navTree);
+    },
     switchNav(subNo) {
       const curSubItem = this.curNav.children[subNo];
+      if (curSubItem.router === this.$route.name) return;
       this.$router.push({ name: curSubItem.router });
     },
     actCurNav() {
@@ -167,6 +228,7 @@ export default {
     },
     toPage(mainIndex, subIndex) {
       const elem = this.navs[mainIndex].children[subIndex];
+      if (elem.router === this.$route.name) return;
       this.$router.push({
         name: elem.router
       });