Ver código fonte

exam edit -f

zhangjie 5 anos atrás
pai
commit
a39b297861

+ 5 - 0
src/assets/styles/element-ui-costom.scss

@@ -69,6 +69,11 @@
       font-weight: bold;
       color: rgba(254, 108, 105, 1);
     }
+    &__content {
+      .el-table {
+        line-height: 1;
+      }
+    }
   }
   &--inline {
     .el-form-item {

+ 32 - 51
src/assets/styles/home.scss

@@ -4,7 +4,6 @@
   width: 100%;
   height: 100%;
   z-index: auto;
-  min-width: 1200px;
 }
 .home-body {
   position: absolute;
@@ -32,7 +31,6 @@
   bottom: 0;
   z-index: 99;
   overflow: auto;
-  background: #fff;
   font-size: 16px;
   background: linear-gradient(
     90deg,
@@ -244,35 +242,34 @@
     padding: 20px 20px 0;
     border: 1px solid $--color-border;
   }
+}
+.part-title {
+  font-size: 16px;
+  font-weight: bold;
+  padding: 15px 20px;
+  line-height: 30px;
+  overflow: hidden;
 
-  .part-title {
-    font-size: 16px;
-    font-weight: bold;
-    padding: 15px 20px;
-    line-height: 30px;
-    overflow: hidden;
-
-    h2 {
-      float: left;
-    }
-    &-infos {
-      float: right;
-    }
-  }
-  .part-body {
-    padding: 25px;
-  }
-  .part-page {
-    margin-top: 15px;
-    text-align: right;
+  h2 {
+    float: left;
   }
-  .part-none {
-    padding: 100px;
-    font-size: 20px;
-    color: $--color-text-secondary;
-    text-align: center;
+  &-infos {
+    float: right;
   }
 }
+.part-body {
+  padding: 25px;
+}
+.part-page {
+  margin-top: 15px;
+  text-align: right;
+}
+.part-none {
+  padding: 100px;
+  font-size: 20px;
+  color: $--color-text-secondary;
+  text-align: center;
+}
 
 /* table */
 .table {
@@ -294,9 +291,11 @@
     border: 1px solid $--border-color-light;
 
     &.td-link {
-      cursor: pointer;
-      &:hover {
-        color: $--color-text-primary;
+      span {
+        cursor: pointer;
+        &:hover {
+          color: $--color-text-primary;
+        }
       }
     }
   }
@@ -321,27 +320,6 @@
   margin-right: 320px;
 }
 
-/* user reset */
-h3.account-title {
-  text-align: center;
-  font-weight: 600;
-}
-.account-form {
-  width: 60%;
-  min-width: 600px;
-  margin: 50px auto;
-}
-.vlcode {
-  height: 36px;
-}
-.vlcode-left {
-  margin-right: 135px;
-}
-.vlcode-right {
-  float: right;
-  width: 120px;
-}
-
 // other
 .tips-info {
   font-size: 14px;
@@ -352,3 +330,6 @@ h3.account-title {
 .tips-error {
   color: $--color-danger;
 }
+.form-item-content {
+  color: $--color-text-regular;
+}

+ 5 - 0
src/constants/enumerate.js

@@ -72,3 +72,8 @@ export const CARD_BUSINESS_FIELDS = {
     }
   ]
 };
+
+export const RESERVE_TYPE = {
+  0: "考试任务备用方式",
+  1: "考场备用方式"
+};

+ 8 - 1
src/main.js

@@ -50,13 +50,20 @@ Vue.config.productionTip = false;
 var load = "";
 // 同一时间有多个请求时,会形成队列。在第一个请求创建loading,在最后一个响应关闭loading
 var queue = [];
+// 解决js处理超过16位number时精度丢失的问题
+axios.defaults.transformResponse = [
+  data => {
+    return JSON.parse(data.replace(/([0-9]{16,19})/g, `"$1"`));
+  }
+];
 axios.interceptors.request.use(
   config => {
     // 显示loading提示
     if (!queue.length) {
       load = ElementUI.Message({
         iconClass: "el-message__icon el-icon-loading",
-        message: "Loading..."
+        message: "Loading...",
+        duration: 0
       });
     }
     queue.push(1);

+ 33 - 6
src/modules/exam-center/api.js

@@ -4,8 +4,8 @@ import { $get, $post } from "@/plugins/axios";
 export const waitTaskListPage = datas => {
   return $get("/api/print/exam/examTask/listNotDonePage", datas);
 };
-export const waitTaskDetail = id => {
-  return $get("/api/print/exam/examTask/detailNotDone", { id });
+export const waitTaskDetail = taskId => {
+  return $get("/api/print/exam/examTask/detailNotDone", { taskId });
 };
 export const saveWaitTask = datas => {
   return $post("/api/print/exam/examTask/draft", datas);
@@ -33,17 +33,32 @@ export const examListPage = datas => {
 export const examList = () => {
   return $get("/api/print/exam/exam/list", {});
 };
-export const createExam = datas => {
-  return $post("/api/print/exam/exam/add", datas);
+export const examDetail = examId => {
+  return $get("/api/print/exam/exam/preEdit", { examId });
+};
+export const uploadExam = datas => {
+  if (datas.tcPExam.id) {
+    return $post("/api/print/exam/exam/edit", datas);
+  } else {
+    return $post("/api/print/exam/exam/add", datas);
+  }
 };
 export const examRoomDetail = datas => {
   return $get("/api/print/exam/exam/listExamDetailPage", datas);
 };
+export const examBusinessData = datas => {
+  return $get("/api/print/exam/exam/preViewExamData", datas);
+};
 export const studentDetail = datas => {
   return $get("/api/print/exam/exam/listExamStudentPage", datas);
 };
-export const deleteExam = id => {
-  return $post("/api/print/exam/exam/delete", { id });
+export const deleteExam = examId => {
+  return $post("/api/print/exam/exam/delete", { examId });
+};
+
+// course
+export const courseList = () => {
+  return $get("/api/print/basic/sys/courseList", {});
 };
 
 // card-manage
@@ -57,3 +72,15 @@ export const printTaskListPage = datas => {
 };
 
 // card-audit
+
+// custom upload-file
+export const customUpload = options => {
+  let formData = new FormData();
+  formData.append(options.filename, options.file);
+  Object.entries(options.data).forEach(([key, val]) => {
+    formData.append(key, val);
+  });
+  return $post(options.action, formData, {
+    headers: options.headers
+  });
+};

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

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

+ 172 - 0
src/modules/exam-center/components/ExamBusinessUpload.vue

@@ -0,0 +1,172 @@
+<template>
+  <div class="exam-business-upload">
+    <el-input
+      style="width: 439px;"
+      v-model.trim="attachmentName"
+      placeholder="考务文件"
+      readonly
+    ></el-input>
+    <el-upload
+      :action="uploadUrl"
+      :headers="headers"
+      :max-size="maxSize"
+      :format="format"
+      :data="uploadData"
+      :on-change="handleFileChange"
+      :before-upload="handleBeforeUpload"
+      :on-error="handleError"
+      :on-success="handleSuccess"
+      :http-request="upload"
+      :show-file-list="false"
+      :auto-upload="false"
+      style="display:inline-block;margin: 0 10px;"
+      ref="UploadComp"
+    >
+      <el-button type="primary">选择</el-button>
+    </el-upload>
+    <el-button
+      type="primary"
+      @click="startUpload"
+      v-if="canUpload"
+      :loading="loading"
+      style="margin-right: 10px;"
+      >开始上传</el-button
+    >
+  </div>
+</template>
+
+<script>
+import { fileMD5 } from "@/plugins/md5";
+import ajax from "@/plugins/ajax";
+
+export default {
+  name: "exam-business-upload",
+  props: {
+    format: {
+      type: Array,
+      default() {
+        return ["xls", "xlsx"];
+      }
+    },
+    uploadUrl: {
+      type: String,
+      required: true
+    },
+    uploadData: {
+      type: Object,
+      default() {
+        return {};
+      }
+    },
+    maxSize: {
+      type: Number,
+      default: 10 * 1024 * 1024
+    },
+    addFilenameParam: {
+      type: String,
+      default: "filename"
+    }
+  },
+  data() {
+    return {
+      attachmentName: "",
+      canUpload: false,
+      loading: false,
+      headers: {
+        token: this.$ls.get("token"),
+        md5: ""
+      },
+      res: {}
+    };
+  },
+  methods: {
+    startUpload() {
+      this.loading = true;
+      this.$refs.UploadComp.submit();
+    },
+    checkFileFormat(fileType) {
+      const _file_format = fileType
+        .split(".")
+        .pop()
+        .toLocaleLowerCase();
+      return this.format.some(
+        item => item.toLocaleLowerCase() === _file_format
+      );
+    },
+    handleFileChange(file) {
+      this.attachmentName = file.name;
+      this.canUpload = file.status === "ready";
+    },
+    async handleBeforeUpload(file) {
+      if (this.addFilenameParam)
+        this.uploadData[this.addFilenameParam] = file.name;
+
+      if (file.size > this.maxSize) {
+        this.handleExceededSize();
+        return Promise.reject();
+      }
+
+      if (!this.checkFileFormat(file.name)) {
+        this.handleFormatError();
+        return Promise.reject();
+      }
+
+      const md5 = await fileMD5(file);
+      this.headers["md5"] = md5;
+
+      return true;
+    },
+    upload(options) {
+      return ajax(options);
+    },
+    handleError(error) {
+      this.canUpload = false;
+      this.loading = false;
+      this.res = {
+        success: false,
+        msg: error.message
+      };
+      this.$emit("upload-error", error);
+    },
+    handleSuccess(response) {
+      this.canUpload = false;
+      this.loading = false;
+      if (response.code === "200") {
+        this.res = {
+          success: true,
+          msg: "导入成功!"
+        };
+        this.$emit("upload-success", response);
+      } else {
+        this.handleError(response);
+      }
+    },
+    handleFormatError() {
+      const content = "只支持文件格式为" + this.format.join("/");
+      this.res = {
+        success: false,
+        msg: content
+      };
+      this.$emit("upload-error", content);
+    },
+    handleExceededSize() {
+      const content =
+        "文件大小不能超过" + Math.floor(this.maxSize / 1024) + "M";
+      this.res = {
+        success: false,
+        msg: content
+      };
+      this.$emit("upload-error", content);
+    },
+    setAttachmentName(name) {
+      this.attachmentName = name;
+    }
+  }
+};
+</script>
+
+<style scoped>
+.exam-business-upload {
+  display: inline-block;
+}
+</style>

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

@@ -111,7 +111,7 @@
 
 <script>
 import { AUDITING_STATUS } from "@/constants/enumerate";
-import { printTaskListPage, examList } from "../api";
+import { printTaskListPage } from "../api";
 
 export default {
   name: "card-check",
@@ -152,15 +152,6 @@ export default {
       this.current = page;
       this.getList();
     },
-    async getExamList() {
-      const data = await examList();
-      this.exams = data.map(item => {
-        return {
-          id: item.examCode,
-          name: item.examName
-        };
-      });
-    },
     selectAuditStatus(val) {
       this.filter.auditingStatus = val * 1;
     },

+ 1 - 1
src/modules/exam-center/views/CardManage.vue

@@ -158,7 +158,7 @@ export default {
       const data = await examList();
       this.exams = data.map(item => {
         return {
-          id: item.examCode,
+          id: item.id,
           name: item.examName
         };
       });

+ 1 - 1
src/modules/exam-center/views/DoneTask.vue

@@ -110,7 +110,7 @@ export default {
       const data = await examList();
       this.exams = data.map(item => {
         return {
-          id: item.examCode,
+          id: item.id,
           name: item.examName
         };
       });

+ 8 - 8
src/modules/exam-center/views/ExamManage.vue

@@ -55,13 +55,13 @@
       <el-table ref="TableList" :data="examPages" border stripe>
         <el-table-column prop="id" 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="beginTime" label="开始时间"></el-table-column>
+        <el-table-column prop="printTime" label="打印时间"></el-table-column>
+        <el-table-column prop="name" label="创建人"></el-table-column>
         <el-table-column prop="createTime" label="创建时间"></el-table-column>
         <el-table-column prop="printStatus" label="印刷状态"></el-table-column>
-        <el-table-column prop="revokeStatus" label="完成时间"></el-table-column>
-        <el-table-column label="操作" align="center">
+        <el-table-column prop="endTime" label="完成时间"></el-table-column>
+        <el-table-column label="操作" align="center" width="120">
           <template slot-scope="scope">
             <el-button
               class="btn-table-icon"
@@ -82,7 +82,7 @@
               type="text"
               icon="icon icon-circle-right"
               @click="toDetail(scope.row)"
-              title="详情"
+              title="考场详情"
             ></el-button>
           </template>
         </el-table-column>
@@ -150,13 +150,13 @@ export default {
       const data = await examList();
       this.exams = data.map(item => {
         return {
-          id: item.examCode,
+          id: item.id,
           name: item.examName
         };
       });
     },
     toDelete(row) {
-      this.$confirm("确定要删除当前任务吗?", "提示", {
+      this.$confirm("确定要删除当前考试吗?", "提示", {
         confirmButtonText: "确定",
         cancelButtonText: "取消",
         type: "warning"

+ 213 - 54
src/modules/exam-center/views/ExamModify.vue

@@ -1,42 +1,56 @@
 <template>
   <div class="exam-modify part-box part-box-border part-box-pad">
-    <el-form ref="ModalForm" label-width="170px">
-      <el-form-item label="考试名称:">
+    <el-form
+      ref="ModalForm"
+      :model="modalForm"
+      :rules="rules"
+      label-width="180px"
+      style="min-width:800px;"
+    >
+      <el-form-item prop="examName" label="考试名称:">
         <el-input
           style="width: 439px;"
-          v-model.trim="modalForm.title"
-          placeholder="请输入内容"
+          v-model.trim="modalForm.examName"
+          placeholder="请输入考试名称"
           clearable
         ></el-input>
       </el-form-item>
-      <el-form-item label="考务文件:">
-        <el-input
-          style="width: 439px;margin-right:18px;"
-          v-model.trim="modalForm.title"
-          disabled=""
-        ></el-input>
-        <el-button>选择</el-button>
-        <el-button>预览</el-button>
+      <el-form-item prop="examCodeTemp" label="考务文件:">
+        <exam-business-upload
+          :upload-url="uploadUrl"
+          :upload-data="uploadData"
+          @upload-error="uplaodError"
+          @upload-success="uploadSuccess"
+          ref="ExamBusinessUpload"
+        ></exam-business-upload>
+        <el-button @click="toPreview" style="margin-left:16px;">预览</el-button>
+      </el-form-item>
+      <el-form-item label="考试开始时间:">
+        <p class="form-item-content">{{ modalForm.beginTime }}</p>
       </el-form-item>
-      <el-form-item label="考试开始时间:"><p>2020-5-7 9:00</p> </el-form-item>
-      <el-form-item label="打印时间:">
+      <el-form-item prop="printTime" label="打印时间:">
         <el-date-picker
           v-model="modalForm.printTime"
-          type="date"
+          type="datetime"
+          value-format="yyyy-MM-dd HH:mm:ss"
           placeholder="请选择日期"
         >
         </el-date-picker>
       </el-form-item>
-      <el-form-item label="备用方式:">
-        <el-radio-group v-model="modalForm.type">
-          <el-radio :label="3">考试任务备用方式</el-radio>
-          <el-radio :label="6">考场备用方式</el-radio>
+      <el-form-item prop="backup" label="备用方式:">
+        <el-radio-group v-model="modalForm.backup">
+          <el-radio
+            v-for="(val, key) in RESERVE_TYPE"
+            :key="key"
+            :label="key"
+            >{{ val }}</el-radio
+          >
         </el-radio-group>
       </el-form-item>
-      <el-form-item label="备用各科试卷题卡份数:">
+      <el-form-item prop="backupCard" label="备用各科试卷题卡份数:">
         <el-input-number
           style="width:220px;"
-          v-model="modalForm.startNumber"
+          v-model="modalForm.backupCard"
           :min="1"
           :max="1000"
           :step="1"
@@ -44,33 +58,26 @@
           :controls="false"
         ></el-input-number>
       </el-form-item>
-      <el-form-item label="指派命题老师:">
-        <el-table
-          :data="courses"
-          style="width: 420px;line-height:23px;"
-          border
-          stripe
-        >
+      <el-form-item prop="teacher" label="指派命题老师:">
+        <el-table :data="courses" style="width: 420px;" border stripe>
           <el-table-column
             width="154"
-            prop="name"
+            prop="courseName"
             label="科目"
           ></el-table-column>
           <el-table-column label="命题老师">
             <template slot-scope="scope">
               <el-select
-                v-model="scope.row.teacher"
+                v-model="scope.row.teacherId"
                 size="small"
                 style="width: 156px;"
                 placeholder="请选择"
-                @change="teacherSelect"
-                clearable
               >
                 <el-option
-                  v-for="(val, key) in teachers"
-                  :key="key"
-                  :value="key"
-                  :label="val"
+                  v-for="user in scope.row.users"
+                  :key="user.id"
+                  :value="user.id"
+                  :label="user.name"
                 ></el-option>
               </el-select>
             </template>
@@ -79,38 +86,190 @@
       </el-form-item>
 
       <el-form-item>
-        <el-button type="primary" @click="save">保存</el-button>
+        <el-button type="primary" :disabled="isSubmit" @click="save"
+          >保存</el-button
+        >
         <el-button @click="goback">返回</el-button>
       </el-form-item>
     </el-form>
+
+    <!-- business-data -->
+    <business-data
+      :exam-code="modalForm.examCodeTemp"
+      ref="BusinessData"
+    ></business-data>
   </div>
 </template>
 
 <script>
+import { RESERVE_TYPE } from "@/constants/enumerate";
+import { uploadExam, examDetail } from "../api";
+import BusinessData from "../components/BusinessData";
+import ExamBusinessUpload from "../components/ExamBusinessUpload";
+
 export default {
   name: "exam-modify",
+  components: { BusinessData, ExamBusinessUpload },
   data() {
+    const printTimeValidator = (rule, value, callback) => {
+      if (!this.checkDateRangeValid(value, this.modalForm.beginTime)) {
+        callback(new Error("打印时间不能为空,且不得晚于考试开始时间"));
+      } else {
+        callback();
+      }
+    };
+    const teacherValidator = (rule, value, callback) => {
+      if (!this.checkTeacherSelected()) {
+        callback(new Error("请选择各科目的命题老师"));
+      } else {
+        callback();
+      }
+    };
+
     return {
-      modalForm: {},
-      teachers: [],
-      courses: [
-        {
-          id: "",
-          name: "语文",
-          teacher: ""
-        },
-        {
-          id: "",
-          name: "语文1",
-          teacher: ""
-        }
-      ]
+      examId: this.$route.params.examId,
+      modalForm: {
+        examName: "",
+        beginTime: "",
+        printTime: "",
+        backup: "0",
+        backupCard: "",
+        examCodeTemp: "",
+        attachmentId: ""
+      },
+      rules: {
+        examName: [
+          {
+            required: true,
+            message: "请输入考试名称",
+            trigger: "change"
+          }
+        ],
+        examCode: [
+          {
+            required: true,
+            message: "请上传考务文件",
+            trigger: "change"
+          }
+        ],
+        printTime: [
+          {
+            required: true,
+            validator: printTimeValidator,
+            trigger: "change"
+          }
+        ],
+        backup: [
+          {
+            required: true,
+            message: "请选择备用方式",
+            trigger: "change"
+          }
+        ],
+        backupCard: [
+          {
+            required: true,
+            message: "请输入备用各科试卷题卡份数",
+            trigger: "change"
+          }
+        ],
+        teacher: [
+          {
+            required: true,
+            validator: teacherValidator
+          }
+        ]
+      },
+      RESERVE_TYPE,
+      courses: [],
+      isSubmit: false,
+      // import
+      uploadUrl: "/api/print/exam/exam/impExamData",
+      uploadData: {
+        schoolId: this.$ls.get("schoolId"),
+        userId: this.$ls.get("user", { id: "" }).id
+      }
     };
   },
+  computed: {
+    isEdit() {
+      return !!this.examId;
+    }
+  },
+  mounted() {
+    if (this.isEdit) {
+      this.getExamDetail();
+    }
+  },
   methods: {
-    save() {},
-    teacherSelect() {
-      // TODO: 修改teachers数据;
+    async getExamDetail() {
+      const data = await examDetail(this.examId);
+      this.modalForm = Object.assign({}, this.modalForm, data.tcPExam);
+      this.modalForm.backup += "";
+      this.courses = data.userCourses;
+      this.$refs.ExamBusinessUpload.setAttachmentName(
+        `${data.tcPAttachment.name}${data.tcPAttachment.type}`
+      );
+    },
+    checkDateRangeValid(startTime, endTime) {
+      if (startTime && endTime) {
+        var st = new Date(startTime.replace(/-/g, "/")).getTime();
+        var et = new Date(endTime.replace(/-/g, "/")).getTime();
+
+        return st < et;
+      }
+      return;
+    },
+    checkTeacherSelected() {
+      return !this.courses.some(course => !course.teacherId);
+    },
+    async save() {
+      const valid = await this.$refs["ModalForm"].validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const datas = {
+        tcPExam: this.modalForm,
+        tcPExamCourseUsers: this.courses.map(course => {
+          return {
+            courseName: course.courseName,
+            courseCode: course.courseCode,
+            userId: course.teacherId
+          };
+        })
+      };
+      const data = await uploadExam(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+      this.$message.success("保存成功!");
+      this.goback();
+    },
+    toPreview() {
+      if (!this.modalForm.examCode) {
+        this.$message.error("请先上传考务文件!");
+        return;
+      }
+      this.$refs.BusinessData.open();
+    },
+    // upload-handler
+    uplaodError(msg) {
+      this.$message.error(msg);
+    },
+    uploadSuccess(res) {
+      this.$message.success("上传成功!");
+      const data = res.data;
+
+      this.modalForm.beginTime = data.startTime;
+      this.modalForm.examCodeTemp = data.examCode;
+      this.modalForm.attachmentId = data.attachmentId;
+      console.log(`data.attachmentId=${data.attachmentId}`);
+      this.$refs["ModalForm"].validateField("examCodeTemp");
+
+      this.courses = data.userCourses.map(item => {
+        item.teacherId = "";
+        return item;
+      });
     }
   }
 };

+ 10 - 10
src/modules/exam-center/views/ExamRomeDetail.vue

@@ -95,16 +95,16 @@
 
 <script>
 import { PRINT_STATUS } from "@/constants/enumerate";
-import { examListPage, examList } from "../api";
+import { examRoomDetail, examList } from "../api";
 
 export default {
   name: "exam-room-detail",
   data() {
     return {
       filter: {
-        examId: "",
-        printStatus: "",
-        printTime: ""
+        examId: this.$route.params.examId,
+        examSite: "",
+        sceneNumberId: ""
       },
       current: 1,
       size: this.GLOBAL.pageSize,
@@ -112,12 +112,12 @@ export default {
       visible: false,
       PRINT_STATUS,
       exams: [],
-      examPages: [{ id: "" }],
-      curExam: {}
+      examPages: []
     };
   },
   created() {
-    // this.getList();
+    this.getList();
+    this.getExamList();
   },
   methods: {
     async getList() {
@@ -126,7 +126,7 @@ export default {
         pageNumber: this.current,
         pageSize: this.size
       };
-      const data = await examListPage(datas);
+      const data = await examRoomDetail(datas);
       this.examPages = data.records;
       this.total = data.total;
     },
@@ -136,9 +136,9 @@ export default {
     },
     async getExamList() {
       const data = await examList();
-      this.exams = data.records.map(item => {
+      this.exams = data.map(item => {
         return {
-          id: item.examCode,
+          id: item.id,
           name: item.examName
         };
       });

+ 2 - 2
src/modules/exam-center/views/ExamRomeStudentDetail.vue

@@ -161,9 +161,9 @@ export default {
     },
     async getExamList() {
       const data = await examList();
-      this.exams = data.records.map(item => {
+      this.exams = data.map(item => {
         return {
-          id: item.examCode,
+          id: item.id,
           name: item.examName
         };
       });

+ 1 - 1
src/modules/exam-center/views/PrintManage.vue

@@ -131,7 +131,7 @@ export default {
       const data = await examList();
       this.exams = data.map(item => {
         return {
-          id: item.examCode,
+          id: item.id,
           name: item.examName
         };
       });

+ 3 - 6
src/modules/exam-center/views/WaitTask.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: "1" }]
+      tasks: []
     };
   },
   created() {
@@ -110,7 +107,7 @@ export default {
       const data = await examList();
       this.exams = data.map(item => {
         return {
-          id: item.examCode,
+          id: item.id,
           name: item.examName
         };
       });

+ 3 - 4
src/modules/exam-center/views/WaitTaskDetail.vue

@@ -7,7 +7,7 @@
       </h2>
       <div class="task-title-infos">
         <el-checkbox v-model="pTypeEnable" @change="pTypeEnableChange"
-          >启用{{ checkboxContent }}卷</el-checkbox
+          >启用{{ paperTypeFieldContent }}卷</el-checkbox
         >
       </div>
     </div>
@@ -74,13 +74,12 @@ export default {
     };
   },
   computed: {
-    checkboxContent() {
+    paperTypeFieldContent() {
       return this.PAPER_TYPE_FIELDS.join("/");
     }
   },
   mounted() {
-    this.parsePaperAttachment();
-    this.pTypeEnableChange();
+    this.getData();
   },
   methods: {
     async getData() {

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

@@ -68,7 +68,7 @@ export default {
   data() {
     return {
       loginModel: {
-        loginName: "admin",
+        loginName: "chulin",
         password: "123456",
         roleCode: ""
       },

+ 89 - 0
src/plugins/ajax.js

@@ -0,0 +1,89 @@
+function getError(action, option, xhr) {
+  let msg;
+  if (xhr.response) {
+    msg = `${xhr.response.error || xhr.response}`;
+  } else if (xhr.responseText) {
+    msg = `${xhr.responseText}`;
+  } else {
+    msg = `fail to post ${action} ${xhr.status}`;
+  }
+
+  const err = new Error(msg);
+  err.status = xhr.status;
+  err.method = "post";
+  err.url = action;
+  return err;
+}
+// 解决后台返回的数据中number位数超过16位的情况
+function bigNumberToString(text) {
+  return text.replace(/([0-9]{16,19})/g, '"$1"');
+}
+
+function getBody(xhr) {
+  const text = xhr.responseText || xhr.response;
+  if (!text) {
+    return text;
+  }
+
+  try {
+    return JSON.parse(bigNumberToString(text));
+  } catch (e) {
+    return text;
+  }
+}
+
+export default function upload(option) {
+  if (typeof XMLHttpRequest === "undefined") {
+    return;
+  }
+
+  const xhr = new XMLHttpRequest();
+  const action = option.action;
+
+  if (xhr.upload) {
+    xhr.upload.onprogress = function progress(e) {
+      if (e.total > 0) {
+        e.percent = (e.loaded / e.total) * 100;
+      }
+      option.onProgress(e);
+    };
+  }
+
+  const formData = new FormData();
+
+  if (option.data) {
+    Object.keys(option.data).forEach(key => {
+      formData.append(key, option.data[key]);
+    });
+  }
+
+  formData.append(option.filename, option.file, option.file.name);
+
+  xhr.onerror = function error(e) {
+    option.onError(e);
+  };
+
+  xhr.onload = function onload() {
+    if (xhr.status < 200 || xhr.status >= 300) {
+      return option.onError(getError(action, option, xhr));
+    }
+
+    option.onSuccess(getBody(xhr));
+  };
+
+  xhr.open("post", action, true);
+
+  if (option.withCredentials && "withCredentials" in xhr) {
+    xhr.withCredentials = true;
+  }
+
+  const headers = option.headers || {};
+
+  for (let item in headers) {
+    if (headers.hasOwnProperty(item) && headers[item] !== null) {
+      xhr.setRequestHeader(item, headers[item]);
+    }
+  }
+  xhr.send(formData);
+  return xhr;
+}

+ 8 - 8
src/plugins/axios.js

@@ -106,16 +106,16 @@ const $get = (url, datas) => {
  * @param {String} url 请求地址
  * @param {Object} datas 请求数据
  */
-const $post = (url, datas) => {
-  const sqDatas = mdData(datas);
-  // if (datas.constructor === Object) {
-  //   sqDatas = qs.stringify(datas, { allowDots: true });
-  // } else {
-  //   sqDatas = datas;
-  // }
+const $post = (url, datas, config = {}) => {
+  let sqDatas = {};
+  if (datas.constructor === Object) {
+    sqDatas = mdData(datas);
+  } else {
+    sqDatas = datas;
+  }
 
   return axios
-    .post(url, sqDatas)
+    .post(url, sqDatas, config)
     .then(rep => {
       return successCallback(rep.data);
     })