浏览代码

feat: 命题任务相关

zhangjie 1 年之前
父节点
当前提交
91acd418a4

+ 141 - 171
src/modules/exam/components/createExamAndPrintTask/InfoPrintTask.vue

@@ -8,37 +8,6 @@
         考试需要命题老师提交完整的考务数据,每个卷袋表示一个考场,人数字段为应考人数,备份数量为该考场试卷题卡备用数量
       </p>
     </template>
-    <el-form ref="modalFormComp" label-position="top">
-      <el-form-item v-if="!IS_REBUILD" label="考试时间:" required>
-        <el-date-picker
-          v-model="createDate"
-          type="date"
-          value-format="timestamp"
-          placeholder="考试日期"
-          style="width: 150px"
-          :editable="false"
-          @change="timeChange"
-        >
-        </el-date-picker>
-        <el-time-picker
-          is-range
-          v-model="createTime"
-          range-separator="至"
-          start-placeholder="考试开始时间"
-          end-placeholder="考试结束时间"
-          placeholder="选择时间范围"
-          value-format="timestamp"
-          :editable="false"
-          @change="timeChange"
-        >
-        </el-time-picker>
-      </el-form-item>
-      <el-form-item
-        label="考试对象:"
-        required
-        style="margin-bottom: 0"
-      ></el-form-item>
-    </el-form>
     <div v-if="IS_MODEL2 || IS_REBUILD" class="part-box">
       <div class="box-justify mb-1">
         <div></div>
@@ -102,7 +71,7 @@
             </el-select>
           </td>
           <td>
-            {{ model2ClassList.map((item) => item.clazzName).join(",") }}
+            {{ modalForm.teachClazzName }}
           </td>
           <td>
             <el-button
@@ -130,25 +99,6 @@
           </p>
         </div>
         <div>
-          <el-button
-            v-if="checkPrivilege('button', 'ExamTaskStudentObjectImport')"
-            type="success"
-            icon="el-icon-download"
-            @click="downloadTemplate('examTaskStudent')"
-            >模板下载</el-button
-          >
-          <upload-button
-            v-if="checkPrivilege('button', 'ExamTaskStudentObjectImport')"
-            btn-icon="el-icon-circle-plus-outline"
-            btn-content="批量导入"
-            btn-type="success"
-            :upload-url="uploadUrl"
-            :format="['xls', 'xlsx']"
-            accept=".xls,.xlsx"
-            @valid-error="validError"
-            @upload-success="uploadSuccess"
-          >
-          </upload-button>
           <el-button
             v-if="checkPrivilege('button', 'ExamTaskStudentObject')"
             type="primary"
@@ -179,6 +129,42 @@
             ></el-input-number>
           </template>
         </el-table-column>
+        <el-table-column label="考试时间" width="240">
+          <template slot-scope="scope">
+            <template v-if="!scope.row.canEditTime">
+              {{ scope.row.examDate }} {{ scope.row.examTime }}
+            </template>
+            <template v-else>
+              <el-date-picker
+                v-model="scope.row.examSetDate"
+                type="date"
+                value-format="timestamp"
+                placeholder="考试日期"
+                style="width: 130px"
+                :clearable="false"
+                :editable="false"
+                @change="timeChange(scope.row)"
+              >
+              </el-date-picker>
+              <el-time-picker
+                is-range
+                v-model="scope.row.examSetTime"
+                range-separator="至"
+                start-placeholder="考试开始时间"
+                end-placeholder="考试结束时间"
+                placeholder="选择时间范围"
+                value-format="timestamp"
+                :picker-options="{
+                  format: 'HH:mm',
+                }"
+                :editable="false"
+                style="width: 210px"
+                @change="timeChange(scope.row)"
+              >
+              </el-time-picker>
+            </template>
+          </template>
+        </el-table-column>
         <el-table-column prop="examPlace" label="校区(考点)" width="140">
           <template slot-scope="scope">
             <el-input
@@ -263,7 +249,7 @@
         teachingRoomId: infoExamTask.teachingRoomId,
       }"
       :show-student="showStudent"
-      :selected-ids="IS_MODEL2 || IS_REBUILD ? model2ClassIds : null"
+      :selected-ids="IS_MODEL2 || IS_REBUILD ? model2ClassList : null"
       @modified="examStudentModified"
     ></modify-exam-task-student>
     <!-- PreviewTaskStudent -->
@@ -277,18 +263,14 @@
 </template>
 
 <script>
-import { calcSum, getTimeDatestamp } from "@/plugins/utils";
+import { mapState, mapMutations } from "vuex";
+import { calcSum, getExamDateTime, getTimeDatestamp } from "@/plugins/utils";
 import { examRuleDetail } from "../../../base/api";
 import { listTaskPrintHouse } from "../../api";
 import ModifyExamTaskStudent from "./ModifyExamTaskStudent.vue";
 import PreviewTaskStudent from "./PreviewTaskStudent.vue";
-import { mapState, mapMutations } from "vuex";
-import UploadButton from "@/components/UploadButton";
-import templateDownload from "@/mixins/templateDownload";
 
 const initModalForm = {
-  examStartTime: "",
-  examEndTime: "",
   paperNumber: "",
   courseName: "",
   courseCode: "",
@@ -296,14 +278,12 @@ const initModalForm = {
   totalSubjects: 1,
   printHouseId: "",
   backupCount: null,
-  classId: "",
   teachClazzName: "",
 };
 
 export default {
   name: "info-print-task",
-  components: { ModifyExamTaskStudent, PreviewTaskStudent, UploadButton },
-  mixins: [templateDownload],
+  components: { ModifyExamTaskStudent, PreviewTaskStudent },
   data() {
     return {
       modalForm: {
@@ -311,7 +291,6 @@ export default {
       },
       tableData: [],
       model2ClassList: [],
-      model2ClassIds: [],
       model2Students: [],
       curRow: {},
       printHouses: [],
@@ -327,14 +306,7 @@ export default {
       disabledStudentIds: [],
       examStudentList: [],
       showStudent: false,
-      // date-picker
       curCreateTime: [],
-      createDate: "",
-      createTime: [],
-      // import
-      uploadUrl: "/api/admin/exam/task/exam_task_exam_student_import",
-      dfilename: "学生导入模板.xlsx",
-      studentUploaded: false,
     };
   },
   computed: {
@@ -369,7 +341,6 @@ export default {
     const curDate = getTimeDatestamp(Date.now());
     const hour = 60 * 60 * 1000;
     this.curCreateTime = [curDate + 8 * hour, curDate + 10 * hour];
-    this.createTime = [...this.curCreateTime];
   },
   methods: {
     ...mapMutations("exam", ["updateTaskInfo"]),
@@ -386,19 +357,10 @@ export default {
       if (this.IS_MODEL2 || this.IS_REBUILD) {
         this.modalForm.backupCount = this.infoExamPrintPlan.backupCount;
         this.model2ClassList = [];
-        this.model2ClassIds = [];
         this.model2Students = [];
         return;
       }
 
-      const { examStartTime, examEndTime } = this.infoPrintTask;
-      if (examStartTime && examEndTime) {
-        this.createTime = [examStartTime, examEndTime];
-        this.createDate = getTimeDatestamp(examStartTime);
-        this.modalForm.examStartTime = this.createTime[0];
-        this.modalForm.examEndTime = this.createTime[1];
-      }
-
       this.tableData = [];
       this.updatePackageInfos();
       this.updateData();
@@ -417,21 +379,7 @@ export default {
       }
       return { backupCount, minBackupCount: backupCount };
     },
-    checkTime() {
-      if (!this.modalForm.examStartTime || !this.modalForm.examEndTime) {
-        this.$message.error("请选择考试时间!");
-        return false;
-      }
-
-      if (this.modalForm.examStartTime >= this.modalForm.examEndTime) {
-        this.$message.error("考试开始时间必须小于考试结束时间!");
-        return false;
-      }
-      return true;
-    },
     checkData() {
-      if (!this.IS_REBUILD && !this.checkTime()) return Promise.reject();
-
       if (this.IS_MODEL2 || this.IS_REBUILD) {
         if (!this.modalForm.totalSubjects) {
           this.$message.error("请输入印刷份数!");
@@ -462,6 +410,9 @@ export default {
           }
         });
 
+        if (!row.examStartTime || !row.examEndTime) {
+          errorFields.push("考试时间");
+        }
         if (!row.backupCount) {
           errorFields.push("备份数量");
         }
@@ -496,8 +447,8 @@ export default {
         });
 
         nrow.extendFields = JSON.stringify(extendFields);
-        nrow.examStartTime = this.modalForm.examStartTime;
-        nrow.examEndTime = this.modalForm.examEndTime;
+        nrow.examTaskStudentObjectParamList =
+          row.examTaskStudentObjectParamList.map((item) => item.id);
         return nrow;
       });
 
@@ -531,18 +482,22 @@ export default {
     async getPrintHouses() {
       this.printHouses = await listTaskPrintHouse();
     },
-    timeChange() {
-      if (!this.createDate || !this.createTime) {
-        this.modalForm.examStartTime = null;
-        this.modalForm.examEndTime = null;
+    timeChange(row) {
+      console.log(row.examSetDate, row.examSetTime);
+      if (!row.examSetDate || !row.examSetTime) {
+        row.examStartTime = null;
+        row.examEndTime = null;
+        row.examDate = "";
+        row.examTime = "";
         return;
       }
 
-      const curDate = getTimeDatestamp(this.createDate);
-      const timeDate = getTimeDatestamp(this.createTime[0]);
+      const curDate = getTimeDatestamp(row.examSetDate);
+      const timeDate = getTimeDatestamp(row.examSetTime[0]);
 
-      this.modalForm.examStartTime = curDate + this.createTime[0] - timeDate;
-      this.modalForm.examEndTime = curDate + this.createTime[1] - timeDate;
+      row.examStartTime = curDate + row.examSetTime[0] - timeDate;
+      row.examEndTime = curDate + row.examSetTime[1] - timeDate;
+      Object.assign(row, getExamDateTime(row.examStartTime, row.examEndTime));
     },
     backupCountChange() {
       this.updatePackageInfos();
@@ -568,22 +523,26 @@ export default {
       this.$refs.ModifyExamTaskStudent.open();
     },
     getTabelStudentIds() {
-      let ids = [];
-      this.tableData.forEach((item) => {
-        item.examTaskStudentObjectParamList.forEach((elem) => {
-          ids.push(elem.id);
-        });
-      });
-      return ids;
+      return this.tableData
+        .map((item) => {
+          return item.examTaskStudentObjectParamList.map((elem) => elem.id);
+        })
+        .flat();
     },
     getInitTableRow() {
       let modalFormData = { ...this.modalForm };
       delete modalFormData.printHouseId;
       let data = {
         id: this.$randomCode(),
+        groupName: "",
         examPlace: "",
         examRoom: "",
-        classId: "",
+        examStartTime: "",
+        examEndTime: "",
+        examDate: "",
+        examTime: "",
+        examSetDate: "",
+        examSetTime: [0, 0],
         className: "",
         studentCount: "",
         printHouseId: "",
@@ -593,6 +552,8 @@ export default {
         minBackupCount: 0,
         isSelectStudent: true,
         examTaskStudentObjectParamList: [],
+        classNames: [],
+        canEditTime: false,
         ...modalFormData,
       };
       let extendFieldModal = {};
@@ -604,17 +565,8 @@ export default {
     },
     examStudentModified({ selectedStudents, isSelectStudent }) {
       if (this.IS_MODEL2 || this.IS_REBUILD) {
-        this.model2ClassList = selectedStudents.map((item) => {
-          return {
-            clazzId: item.clazzId,
-            clazzName: item.clazzName,
-          };
-        });
-        this.model2ClassIds = this.model2ClassList.map((item) => item.clazzId);
-        this.modalForm.classId = this.model2ClassIds.join();
-        this.modalForm.teachClazzName = this.model2ClassList
-          .map((item) => item.clazzName)
-          .join();
+        this.model2ClassList = selectedStudents.map((item) => item.label);
+        this.modalForm.teachClazzName = this.model2ClassList.join();
         this.model2Students = selectedStudents
           .map((item) => item.children)
           .flat()
@@ -630,23 +582,79 @@ export default {
         this.tableData = [];
         this.studentUploaded = false;
       }
-      let examTaskStudentObjectParamList = [];
+
+      this.updateTableData(selectedStudents);
+
+      this.updatePackageInfos();
+    },
+    updateTableData(selectedStudents) {
+      const groupMap = {};
       selectedStudents.forEach((item) => {
         item.children.forEach((student) => {
-          examTaskStudentObjectParamList.push({ ...student, enable: true });
+          const { examRoom, examPlace, examStartTime, examEndTime } = student;
+          const groupName = `${examRoom}_${examPlace}_${examStartTime}_${examEndTime}`;
+          if (!groupMap[groupName]) {
+            groupMap[groupName] = {
+              examTaskStudentObjectParamList: [],
+              classNames: [],
+              examRoom,
+              examPlace,
+              examStartTime,
+              examEndTime,
+              groupName,
+            };
+          }
+          groupMap[groupName].examTaskStudentObjectParamList.push({
+            ...student,
+            enable: true,
+          });
+          if (!groupMap[groupName].classNames.includes(item.label)) {
+            groupMap[groupName].classNames.push(item.label);
+          }
         });
       });
-      let tableRow = this.$objAssign(this.getInitTableRow(), {
-        classId: selectedStudents.map((item) => item.clazzId).join(),
-        className: selectedStudents.map((item) => item.clazzName).join(),
-        studentCount: examTaskStudentObjectParamList.length,
-        examTaskStudentObjectParamList,
-        isSelectStudent,
-        ...this.getBackupCount(examTaskStudentObjectParamList.length),
+
+      const tableGroupNames = this.tableData.map((item) => {
+        const { examRoom, examPlace, examStartTime, examEndTime } = item;
+        return `${examRoom}_${examPlace}_${examStartTime}_${examEndTime}`;
       });
-      this.tableData.push(tableRow);
 
-      this.updatePackageInfos();
+      Object.keys(groupMap).forEach((groupName) => {
+        const data = groupMap[groupName];
+        const ind = tableGroupNames.indexOf(groupName);
+        if (ind !== -1) {
+          this.tableData[ind].examTaskStudentObjectParamList.push(
+            ...data.examTaskStudentObjectParamList
+          );
+          const classNameSet = new Set([
+            ...this.tableData[ind].classNames,
+            ...data.classNames,
+          ]);
+          const studentCount =
+            this.tableData[ind].examTaskStudentObjectParamList.length;
+          this.tableData[ind].studentCount = studentCount;
+          this.tableData[ind].classNames = Array.from(classNameSet);
+          this.tableData[ind].className = this.tableData[ind].classNames.join();
+
+          Object.assign(this.tableData[ind], this.getBackupCount(studentCount));
+          return;
+        }
+
+        const times =
+          data.examStartTime && data.examEndTime
+            ? getExamDateTime(data.examStartTime, data.examEndTime)
+            : { examSetDate: "", examSetTime: [...this.curCreateTime] };
+
+        const tableRow = this.$objAssign(this.getInitTableRow(), {
+          ...data,
+          ...times,
+          ...this.getBackupCount(data.examTaskStudentObjectParamList.length),
+          className: data.classNames.join(),
+          studentCount: data.examTaskStudentObjectParamList.length,
+          canEditTime: !data.examStartTime || !data.examEndTime,
+        });
+        this.tableData.push(tableRow);
+      });
     },
     toDelete(index) {
       this.tableData.splice(index, 1);
@@ -677,44 +685,6 @@ export default {
         studentCount,
       });
     },
-    // import
-    validError(errorData) {
-      this.$message.error(errorData.message);
-    },
-    uploadSuccess(res) {
-      this.studentUploaded = true;
-      this.$message.success("导入成功!");
-
-      this.tableData = res.data.map((item) => {
-        const initRow = this.getInitTableRow();
-        let examTaskStudentObjectParamList = [];
-        item.examTaskStudentObjectResultList.forEach((elem) => {
-          elem.studentInfoList.forEach((std) => {
-            examTaskStudentObjectParamList.push({
-              ...std,
-              studentClazzType: elem.studentClazzType,
-              id: `${elem.clazzId}_${std.studentId}`,
-            });
-          });
-        });
-        let tableRow = this.$objAssign(initRow, {
-          classId: item.examTaskStudentObjectResultList
-            .map((item) => item.clazzId)
-            .join(),
-          className: item.examTaskStudentObjectResultList
-            .map((item) => item.clazzName)
-            .join(),
-          examRoom: item.examRoom,
-          examPlace: item.examPlace,
-          studentCount: examTaskStudentObjectParamList.length,
-          examTaskStudentObjectParamList,
-          ...this.getBackupCount(examTaskStudentObjectParamList.length),
-        });
-
-        return tableRow;
-      });
-      this.updatePackageInfos();
-    },
     // model2 select class
     toSelectClass() {
       if (!this.infoExamTask.courseId) {

+ 18 - 22
src/modules/exam/components/createExamAndPrintTask/ModifyExamTaskStudent.vue

@@ -187,7 +187,7 @@ export default {
       this.$refs.UserTree.setCheckedKeys([]);
       this.selectedUsers = [];
       this.userTree = this.getUserTree();
-      // this.updateUserTreeDisableInfo(this.disabledIds);
+      this.updateUserTreeDisableInfo(this.disabledIds);
 
       if (this.selectedIds && this.selectedIds.length) {
         this.$nextTick(() => {
@@ -232,22 +232,17 @@ export default {
       const disabledStdIds = this.disabledIds.map((item) => item.split("_")[1]);
       return data.map((item) => {
         let nitem = {
-          id: item.clazzId,
-          label: item.clazzName,
-          clazzId: item.clazzId,
-          clazzName: item.clazzName,
-          studentClazzType: item.studentClazzType,
+          id: item.teachClassName,
+          label: item.teachClassName,
           children: [],
         };
 
         nitem.children = item.studentInfoList.map((elem) => {
           return {
             ...elem,
-            disabled: disabledStdIds.includes(elem.studentId),
-            isUser: true,
-            id: `${item.clazzId}_${elem.studentId}`,
             label: elem.studentName,
-            studentClazzType: item.studentClazzType,
+            isUser: true,
+            disabled: disabledStdIds.includes(elem.studentId),
           };
         });
         nitem.disabled = !nitem.children.some((elem) => !elem.disabled);
@@ -274,8 +269,6 @@ export default {
         );
         return;
       }
-      const disabledIds = [...selectedKeys, ...this.disabledIds];
-      const disabledStdIds = disabledIds.map((item) => item.split("_")[1]);
 
       let selectedUsers = [];
       this.userTree.forEach((item) => {
@@ -288,13 +281,6 @@ export default {
             children,
           });
         }
-        // 同一个学生只允许选择一次
-        item.children.forEach((elem) => {
-          elem.disabled =
-            !selectedKeys.includes(elem.id) &&
-            disabledStdIds.includes(elem.studentId);
-        });
-        item.disabled = !item.children.some((elem) => !elem.disabled);
       });
       this.selectedUsers = selectedUsers;
     },
@@ -342,12 +328,22 @@ export default {
       this.setTreeSelectedKeys();
     },
     updateUserTreeDisableInfo(disabledIds) {
-      if (!this.showStudent) return;
-      const disabledStdIds = disabledIds.map((item) => item.split("_")[1]);
+      if (!this.showStudent) {
+        const disabledClassIds = [];
+        this.dataTree.forEach((item) => {
+          if (item.children.some((elem) => disabledIds.includes(elem.id))) {
+            disabledClassIds.push(item.id);
+          }
+        });
+        this.userTree.forEach((item) => {
+          item.disabled = disabledClassIds.includes(item.id);
+        });
+        return;
+      }
 
       this.userTree.forEach((item) => {
         item.children.forEach((elem) => {
-          elem.disabled = disabledStdIds.includes(elem.studentId);
+          elem.disabled = disabledIds.includes(elem.id);
         });
         item.disabled = !item.children.some((elem) => !elem.disabled);
       });