فهرست منبع

feat: 考生管理

zhangjie 1 سال پیش
والد
کامیت
d5738dd154

+ 252 - 185
src/modules/base/components/ModifyExamStudent.vue

@@ -18,6 +18,7 @@
       :key="modalForm.id"
       label-width="120px"
     >
+      <!-- 必填信息 -->
       <el-form-item prop="semesterId" label="学期:">
         <semester-select
           v-model="modalForm.semesterId"
@@ -29,108 +30,143 @@
           v-model="modalForm.examId"
           :semester-id="modalForm.semesterId"
           placeholder="考试"
-          @change="examChange"
         ></exam-select>
       </el-form-item>
-      <el-form-item prop="courseId" label="课程:">
-        <course-common-select
-          v-model="modalForm.courseId"
-          placeholder="课程"
-          clearable
-        ></course-common-select>
-      </el-form-item>
-      <el-form-item prop="studentName" label="姓名:">
+      <el-form-item
+        v-if="checkRequiredFieldValid('studentName')"
+        prop="studentName"
+        label="姓名:"
+      >
         <el-input
           v-model.trim="modalForm.studentName"
           placeholder="请输入姓名"
           clearable
         ></el-input>
       </el-form-item>
-      <el-form-item prop="studentCode" label="学号:">
+      <el-form-item
+        v-if="checkRequiredFieldValid('studentCode')"
+        prop="studentCode"
+        label="学号:"
+      >
         <el-input
           v-model.trim="modalForm.studentCode"
           placeholder="请输入学号"
           clearable
         ></el-input>
       </el-form-item>
-      <el-form-item prop="college" label="学院:">
-        <el-input
-          v-model.trim="modalForm.college"
-          placeholder="请输入学院"
-          clearable
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="major" label="专业:">
-        <el-input
-          v-model.trim="modalForm.major"
-          placeholder="请输入专业"
-          clearable
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="teachClazz" label="教学班:">
-        <el-input
-          v-model.trim="modalForm.teachClazz"
-          placeholder="请输入教学班"
-          clearable
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="teacherName" label="任课老师:">
-        <el-input
-          v-model.trim="modalForm.teacherName"
-          placeholder="请输入任课老师"
-          clearable
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="teacherCode" label="任课老师工号:">
-        <el-input
-          v-model.trim="modalForm.teacherCode"
-          placeholder="请输入任课老师工号"
-          clearable
-        ></el-input>
-      </el-form-item>
-      <el-form-item prop="paperNumber" label="试卷编号:">
-        <el-input
-          v-model.trim="modalForm.paperNumber"
-          placeholder="请输入试卷编号"
+      <el-form-item
+        v-if="checkRequiredFieldValid('courseCode')"
+        prop="courseId"
+        label="课程:"
+      >
+        <course-common-select
+          v-model="modalForm.courseId"
+          placeholder="课程"
           clearable
-          @change="updateRules"
-        ></el-input>
+        ></course-common-select>
       </el-form-item>
-      <el-form-item prop="examStartTime" label="考试时间:">
+      <el-form-item
+        v-if="checkRequiredFieldValid('examDate')"
+        prop="examStartTime"
+        label="考试时间:"
+      >
         <el-date-picker
-          v-model="createDate"
+          v-model="examSetDate"
           type="date"
           value-format="timestamp"
           placeholder="考试日期"
           style="width: 150px; margin-bottom: 5px"
+          :clearable="false"
           :editable="false"
           @change="timeChange"
         >
         </el-date-picker>
         <el-time-picker
-          v-model="createTime"
+          v-model="examSetTime"
           is-range
           range-separator="至"
           start-placeholder="考试开始时间"
           end-placeholder="考试结束时间"
           placeholder="选择时间范围"
           value-format="timestamp"
+          :picker-options="{
+            format: 'HH:mm',
+          }"
+          :default-value="defaultTime"
           :editable="false"
           @change="timeChange"
         >
         </el-time-picker>
       </el-form-item>
-      <el-form-item prop="examPlace" label="考点(校区):">
+      <el-form-item
+        v-if="checkRequiredFieldValid('examRoom')"
+        prop="examRoom"
+        label="考场(考试教室):"
+      >
         <el-input
-          v-model.trim="modalForm.examPlace"
-          placeholder="请输入考点(校区)"
+          v-model.trim="modalForm.examRoom"
+          placeholder="请输入考场(考试教室)"
           clearable
         ></el-input>
       </el-form-item>
-      <el-form-item prop="examRoom" label="考场(考试教室):">
+      <el-form-item
+        v-if="checkRequiredFieldValid('collegeName')"
+        prop="collegeName"
+        label="学院:"
+      >
         <el-input
-          v-model.trim="modalForm.examRoom"
-          placeholder="请输入考场(考试教室)"
+          v-model.trim="modalForm.collegeName"
+          placeholder="请输入学院"
+          clearable
+        ></el-input>
+      </el-form-item>
+      <el-form-item
+        v-if="checkRequiredFieldValid('teachClazzName')"
+        prop="teachClazzName"
+        label="教学班:"
+      >
+        <el-input
+          v-model.trim="modalForm.teachClazzName"
+          placeholder="请输入教学班"
+          clearable
+        ></el-input>
+      </el-form-item>
+      <el-form-item
+        v-if="checkRequiredFieldValid('teacherRoomName')"
+        prop="teacherRoomName"
+        label="开课学院:"
+      >
+        <el-input
+          v-model.trim="modalForm.teacherRoomName"
+          placeholder="请输入开课学院"
+          clearable
+        ></el-input>
+      </el-form-item>
+
+      <!-- 选填信息 -->
+      <el-form-item
+        v-for="item in optionalFields"
+        :key="`${item.code}${item.name}`"
+        :prop="item.code"
+        :label="`${item.name}:`"
+      >
+        <el-input
+          v-model.trim="modalForm[item.code]"
+          :placeholder="`请输入${item.name}`"
+          clearable
+        ></el-input>
+      </el-form-item>
+
+      <!-- 扩展字段 -->
+      <el-form-item
+        v-for="item in extendFields"
+        :key="`${item.code}${item.name}`"
+        :prop="item.code"
+        :label="`${item.name}:`"
+      >
+        <el-input
+          v-model.trim="modalForm[item.code]"
+          :placeholder="`请输入${item.name}`"
           clearable
         ></el-input>
       </el-form-item>
@@ -145,26 +181,22 @@
 </template>
 
 <script>
-import { updateExamStudent } from "../api";
+import { updateExamStudent, examRuleDetail } from "../api";
 import { getTimeDatestamp } from "@/plugins/utils";
 
-const initModalForm = {
+const requiredModalForm = {
   id: null,
   semesterId: "",
   examId: "",
-  courseId: "",
   studentName: "",
   studentCode: "",
-  college: "",
-  major: "",
-  teachClazz: "",
-  teacherCode: "",
-  teacherName: "",
-  paperNumber: "",
+  courseId: "",
   examEndTime: "",
   examStartTime: "",
-  examPlace: "",
+  collegeName: "",
   examRoom: "",
+  teachClazzName: "",
+  teacherRoomName: "",
 };
 
 export default {
@@ -189,51 +221,9 @@ export default {
     return {
       modalIsShow: false,
       isSubmit: false,
-      modalForm: { ...initModalForm },
-      rules: {},
-      curExam: {},
-      // date-picker
-      createDate: null,
-      createTime: [null, null],
-    };
-  },
-  methods: {
-    initData(val) {
-      if (val.id) {
-        this.modalForm = this.$objAssign(initModalForm, val);
-        const { examStartTime, examEndTime } = val;
-        if (examStartTime && examEndTime) {
-          this.createTime = [examStartTime, examEndTime];
-          this.createDate = getTimeDatestamp(examStartTime);
-          this.modalForm.examStartTime = this.createTime[0];
-          this.modalForm.examEndTime = this.createTime[1];
-        } else {
-          this.getInitCreateTime();
-        }
-      } else {
-        this.modalForm = { ...initModalForm };
-        this.getInitCreateTime();
-      }
-      this.updateRules();
-    },
-    getInitCreateTime() {
-      // const curDate = getTimeDatestamp(Date.now());
-      // const hour = 60 * 60 * 1000;
-      // this.createTime = [curDate + 8 * hour, curDate + 10 * hour];
-      // this.createDate = null;
-      this.createTime = [null, null];
-      this.createTime = null;
-    },
-    visibleChange() {
-      this.initData(this.instance);
-    },
-    examChange(val) {
-      this.curExam = val || {};
-      this.updateRules();
-    },
-    updateRules() {
-      const paperNumberRequired = this.curExam.examModel === "MODEL4";
-      this.rules = {
+      modalForm: { ...requiredModalForm },
+      initModalForm: {},
+      requiredRules: {
         semesterId: [
           {
             required: true,
@@ -248,13 +238,6 @@ export default {
             trigger: "change",
           },
         ],
-        courseId: [
-          {
-            required: true,
-            message: "请选择课程",
-            trigger: "change",
-          },
-        ],
         studentName: [
           {
             required: true,
@@ -284,106 +267,178 @@ export default {
             trigger: "change",
           },
         ],
-        college: [
-          {
-            required: !!this.modalForm.paperNumber || paperNumberRequired,
-            message: "请输入学院",
-            trigger: "change",
-          },
+        courseId: [
           {
-            message: "学院不能超过30个字",
-            max: 30,
+            required: true,
+            message: "请选择课程",
             trigger: "change",
           },
         ],
-        major: [
-          {
-            required: !!this.modalForm.paperNumber || paperNumberRequired,
-            message: "请输入专业",
-            trigger: "change",
-          },
+        examStartTime: [
           {
-            message: "专业不能超过30个字",
-            max: 30,
+            required: true,
+            message: "请输入考试时间",
             trigger: "change",
           },
         ],
-        teachClazz: [
+        examRoom: [
           {
             required: true,
-            message: "请输入教学班",
+            message: "请输入考场(考试教室)",
             trigger: "change",
           },
           {
-            message: "教学班不能超过30个字",
+            message: "考场(考试教室)不能超过30个字",
             max: 30,
             trigger: "change",
           },
         ],
-        teacherName: [
+        collegeName: [
           {
-            required: !!this.modalForm.paperNumber || paperNumberRequired,
-            message: "请输入任课老师名称",
+            required: true,
+            message: "请输入学院",
             trigger: "change",
           },
           {
-            message: "任课老师名称不能超过30个字",
+            message: "学院不能超过30个字",
             max: 30,
             trigger: "change",
           },
         ],
-        teacherCode: [
+        teachClazzName: [
           {
-            required: !!this.modalForm.paperNumber || paperNumberRequired,
-            message: "请输入任课老师工号",
-            trigger: "change",
-          },
-          {
-            message: "任课老师工号不能超过30个字",
-            max: 30,
+            required: true,
+            message: "请输入教学班",
             trigger: "change",
           },
-        ],
-        paperNumber: [
           {
-            required: paperNumberRequired,
-            message: "试卷编码不能超过30个字",
+            message: "教学班不能超过30个字",
             max: 30,
             trigger: "change",
           },
         ],
-        examStartTime: [
+        teacherRoomName: [
           {
-            required: !!this.modalForm.paperNumber || paperNumberRequired,
-            message: "请输入考试时间",
-            trigger: "change",
-          },
-        ],
-        examPlace: [
-          {
-            required: !!this.modalForm.paperNumber || paperNumberRequired,
-            message: "请输入考点(校区)",
+            required: true,
+            message: "请输入开课学院",
             trigger: "change",
           },
           {
-            message: "考点(校区)不能超过30个字",
+            message: "开课学院不能超过30个字",
             max: 30,
             trigger: "change",
           },
         ],
-        examRoom: [
-          {
-            required: !!this.modalForm.paperNumber || paperNumberRequired,
-            message: "请输入考场(考试教室)",
-            trigger: "change",
-          },
+      },
+      rules: {},
+      requiredFields: [
+        "studentName",
+        "studentCode",
+        "courseCode",
+        "examDate",
+        "examRoom",
+        "collegeName",
+        "teachClazzName",
+        "teacherRoomName",
+      ],
+      optionalFields: [],
+      extendFields: [],
+      // date-picker
+      defaultTime: "",
+      examSetDate: "",
+      examSetTime: [],
+    };
+  },
+  methods: {
+    async initData(val) {
+      await this.initFields();
+
+      if (val.id) {
+        this.modalForm = this.$objAssign(this.initModalForm, val);
+
+        const { examStartTime, examEndTime } = val;
+        if (examStartTime && examEndTime) {
+          this.examSetTime = [examStartTime, examEndTime];
+          this.examSetDate = getTimeDatestamp(examStartTime);
+          this.modalForm.examStartTime = this.examSetTime[0];
+          this.modalForm.examEndTime = this.examSetTime[1];
+        } else {
+          this.getInitCreateTime();
+        }
+
+        const extendFieldData = val.extendFields
+          ? JSON.parse(val.extendFields)
+          : [];
+        extendFieldData.forEach((item) => {
+          this.modalForm[item.code] = item.value;
+        });
+      } else {
+        this.modalForm = { ...this.initModalForm };
+        this.getInitCreateTime();
+      }
+
+      this.defaultTime = getTimeDatestamp(Date.now());
+
+      this.$nextTick(() => {
+        this.$refs.modalFormComp.clearValidate();
+      });
+    },
+    async initFields() {
+      const examRule = await examRuleDetail();
+      if (!examRule.id) {
+        this.$message.warning("当前系统还没有考务规则,请修改保存!");
+        return;
+      }
+
+      const requiredFieldData = JSON.parse(examRule.requiredFields);
+      this.requiredFields = requiredFieldData
+        .filter((item) => item.disabled)
+        .map((item) => item.code);
+      this.optionalFields = requiredFieldData.filter(
+        (item) => !item.disabled && item.enable
+      );
+      const extendFieldData = examRule.extendFields
+        ? JSON.parse(examRule.extendFields)
+        : [];
+      this.extendFields = extendFieldData.filter((item) => item.enable);
+
+      this.initModalForm = { ...requiredModalForm };
+      [...this.optionalFields, ...this.extendFields].forEach((item) => {
+        this.initModalForm[item.code] = "";
+      });
+      this.updateRules();
+    },
+    checkRequiredFieldValid(fieldName) {
+      return this.requiredFields.includes(fieldName);
+    },
+    getInitCreateTime() {
+      const curDate = getTimeDatestamp(Date.now());
+      const hour = 60 * 60 * 1000;
+      this.examSetTime = [curDate + 8 * hour, curDate + 10 * hour];
+      this.examSetDate = "";
+      console.log(this.examSetTime);
+    },
+    visibleChange() {
+      this.initData(this.instance);
+    },
+    updateRules() {
+      // const paperNumberRequired = this.curExam.examModel === "MODEL4";
+      const rules = { ...this.requiredRules };
+      [...this.optionalFields, ...this.extendFields].forEach((item) => {
+        rules[item.code] = [
+          // {
+          //   required: false,
+          //   message: `请输入${item.name}`,
+          //   trigger: "change",
+          // },
           {
-            message: "考场(考试教室)不能超过30个字",
+            message: `${item.name}不能超过30个字`,
             max: 30,
             trigger: "change",
           },
-        ],
-      };
+        ];
+      });
+      this.rules = rules;
     },
     cancel() {
       this.modalIsShow = false;
@@ -395,17 +450,29 @@ export default {
       this.modalForm.clazzId = "";
     },
     timeChange() {
-      if (!this.createDate || !this.createTime) {
-        this.modalForm.examStartTime = null;
-        this.modalForm.examEndTime = null;
+      if (!this.examSetDate || !this.examSetTime) {
+        this.modalForm.examStartTime = "";
+        this.modalForm.examEndTime = "";
         return;
       }
 
-      const curDate = getTimeDatestamp(this.createDate);
-      const timeDate = getTimeDatestamp(this.createTime[0]);
+      const curDate = getTimeDatestamp(this.examSetDate);
+      const timeDate = getTimeDatestamp(this.examSetTime[0]);
+
+      this.modalForm.examStartTime = curDate + this.examSetTime[0] - timeDate;
+      this.modalForm.examEndTime = curDate + this.examSetTime[1] - timeDate;
+    },
+    getModelData() {
+      const data = this.$objAssign(requiredModalForm, this.modalForm);
+      this.optionalFields.forEach((item) => {
+        data[item.code] = this.modalForm[item.code];
+      });
 
-      this.modalForm.examStartTime = curDate + this.createTime[0] - timeDate;
-      this.modalForm.examEndTime = curDate + this.createTime[1] - timeDate;
+      const extendFields = this.extendFields.map((item) => {
+        return { ...item, value: this.modalForm[item.code] };
+      });
+      data.extendFields = JSON.stringify(extendFields);
+      return data;
     },
     async submit() {
       const valid = await this.$refs.modalFormComp.validate().catch(() => {});
@@ -413,7 +480,7 @@ export default {
 
       if (this.isSubmit) return;
       this.isSubmit = true;
-      const data = await updateExamStudent(this.modalForm).catch(() => {});
+      const data = await updateExamStudent(this.getModelData()).catch(() => {});
       this.isSubmit = false;
 
       if (!data) return;

+ 18 - 2
src/modules/base/views/ExamStudentManage.vue

@@ -176,7 +176,7 @@
         <el-table-column
           prop="examPlace"
           label="考点(校区)"
-          min-width="100"
+          min-width="120"
         ></el-table-column>
         <el-table-column
           prop="examRoom"
@@ -238,7 +238,7 @@
         semesterId: filterSe.semesterId,
       }"
       :format="['xls', 'xlsx']"
-      :download-handle="() => downloadTemplate('examStudent')"
+      :download-handle="downloadHandle"
       :download-filename="dfilename"
       :auto-upload="false"
       @upload-success="uploadSuccess"
@@ -258,6 +258,7 @@ import {
   deleteExamStudent,
   exportExamStudent,
 } from "../api";
+import { businessTemplateDownload } from "@/modules/print/api";
 import ModifyExamStudent from "../components/ModifyExamStudent.vue";
 import ImportFile from "../../../components/ImportFile.vue";
 import { downloadByApi } from "@/plugins/download";
@@ -289,6 +290,7 @@ export default {
       multipleSelection: [],
       curRow: {},
       loading: false,
+      download: false,
       // import
       uploadUrl: "/api/admin/basic/exam_student/import",
       dfilename: "考生导入模板.xlsx",
@@ -326,6 +328,20 @@ export default {
     handleSelectionChange(val) {
       this.multipleSelection = val.map((item) => item.id);
     },
+    async downloadHandle() {
+      if (this.download) return;
+
+      this.download = true;
+      const res = await downloadByApi(() => {
+        return businessTemplateDownload();
+      }, `考生导入模板.xlsx`).catch((e) => {
+        this.$message.error(e || "下载失败,请重新尝试!");
+      });
+      this.download = false;
+
+      if (!res) return;
+      this.$message.success("下载成功!");
+    },
     toAdd() {
       this.curRow = {};
       this.$refs.ModifyExamStudent.open();

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

@@ -45,6 +45,9 @@
             end-placeholder="考试结束时间"
             placeholder="选择时间范围"
             value-format="timestamp"
+            :picker-options="{
+              format: 'HH:mm',
+            }"
             :disabled="timeDisabled"
             @change="timeChange"
           >

+ 4 - 1
src/modules/exam/components/createExamAndPrintTask/InfoPrintTask.vue

@@ -157,6 +157,7 @@
                 :picker-options="{
                   format: 'HH:mm',
                 }"
+                :default-value="defaultTime"
                 :editable="false"
                 style="width: 210px"
                 @change="timeChange(scope.row)"
@@ -307,6 +308,7 @@ export default {
       examStudentList: [],
       showStudent: false,
       curCreateTime: [],
+      defaultTime: "",
     };
   },
   computed: {
@@ -341,6 +343,7 @@ export default {
     const curDate = getTimeDatestamp(Date.now());
     const hour = 60 * 60 * 1000;
     this.curCreateTime = [curDate + 8 * hour, curDate + 10 * hour];
+    this.defaultTime = curDate;
   },
   methods: {
     ...mapMutations("exam", ["updateTaskInfo"]),
@@ -483,7 +486,7 @@ export default {
       this.printHouses = await listTaskPrintHouse();
     },
     timeChange(row) {
-      console.log(row.examSetDate, row.examSetTime);
+      // console.log(row.examSetDate, row.examSetTime);
       if (!row.examSetDate || !row.examSetTime) {
         row.examStartTime = null;
         row.examEndTime = null;