Browse Source

考试和考生管理

zhangjie 1 year ago
parent
commit
e7094e77d0

+ 107 - 0
src/components/SecSelect.vue

@@ -0,0 +1,107 @@
+<template>
+  <div :class="['sec-select', { inline: inline }]">
+    <el-form-item v-if="filterProps.includes('semesterId')" label="学期:">
+      <semester-select
+        v-model.trim="filter.semesterId"
+        placeholder="学期"
+        default-select
+        :clearable="!defaultSelectExam"
+        @default-selected="semesterDefaultSelect"
+      ></semester-select>
+    </el-form-item>
+    <el-form-item v-if="filterProps.includes('examId')" label="考试:">
+      <exam-select
+        v-model="filter.examId"
+        :semester-id="filter.semesterId"
+        :clearable="!defaultSelectExam"
+        :default-select="defaultSelectExam"
+        @default-selected="examDefaultSelect"
+      ></exam-select>
+    </el-form-item>
+    <el-form-item
+      v-if="filterProps.includes('courseCode')"
+      label="课程(代码):"
+      label-width="110px"
+    >
+      <course-select
+        v-model.trim="filter.courseCode"
+        :filter-data="{ semesterId: filter.semesterId, examId: filter.examId }"
+        placeholder="课程(代码)"
+        clearable
+      ></course-select>
+    </el-form-item>
+  </div>
+</template>
+
+<script>
+const fullProps = ["semesterId", "examId", "courseCode"];
+export default {
+  name: "sec-select",
+  props: {
+    value: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    inline: {
+      type: Boolean,
+      default: true,
+    },
+    defaultSelectExam: { type: Boolean, default: false },
+  },
+  data() {
+    return {
+      filter: {},
+      filterProps: [],
+    };
+  },
+  watch: {
+    filter: {
+      deep: true,
+      handler() {
+        this.emitChange();
+      },
+    },
+  },
+  created() {
+    this.initData();
+    this.filter = this.$objAssign(this.filter, this.value);
+  },
+  methods: {
+    initData() {
+      this.filterProps = fullProps.filter((field) =>
+        Object.prototype.hasOwnProperty.call(this.value, field)
+      );
+      let filter = {};
+      this.filterProps.forEach((field) => {
+        filter[field] = "";
+      });
+      this.filter = filter;
+    },
+    getFilterData() {
+      return Object.assign({}, this.value, this.filter);
+    },
+    emitChange() {
+      const data = this.getFilterData();
+      this.$emit("input", data);
+      this.$emit("change", data);
+    },
+    semesterDefaultSelect() {
+      if (this.defaultSelectExam) return;
+      this.emitChange();
+      this.$emit("semester-default", this.getFilterData());
+    },
+    examDefaultSelect() {
+      this.emitChange();
+      this.$emit("exam-default", this.getFilterData());
+    },
+  },
+};
+</script>
+
+<style scoped>
+.sec-select.inline {
+  display: inline;
+}
+</style>

+ 12 - 9
src/components/base/CourseSelect.vue

@@ -30,12 +30,7 @@ export default {
     clearable: { type: Boolean, default: true },
     filterData: {
       type: Object,
-      default() {
-        return {
-          paperArchivesId: "",
-          semesterId: "",
-        };
-      },
+      default: null,
     },
   },
   data() {
@@ -64,9 +59,17 @@ export default {
   },
   methods: {
     async search() {
-      const res = await commonCourseQuery({
-        ...this.filterData,
-      });
+      this.optionList = [];
+
+      if (
+        this.filterData &&
+        (!this.filterData.semesterId || !this.filterData.examId)
+      )
+        return;
+
+      const datas = this.filterData || {};
+
+      const res = await commonCourseQuery(datas);
       this.optionList = res;
     },
     select() {

+ 87 - 0
src/components/base/ExamSelect.vue

@@ -0,0 +1,87 @@
+<template>
+  <el-select
+    v-model="selected"
+    class="exam-select"
+    :placeholder="placeholder"
+    filterable
+    :clearable="clearable"
+    :disabled="disabled"
+    @change="select"
+  >
+    <el-option
+      v-for="item in optionList"
+      :key="item.id"
+      :value="item.id"
+      :label="item.name"
+    >
+    </el-option>
+  </el-select>
+</template>
+
+<script>
+import { commonExamQuery } from "../../modules/base/api";
+
+export default {
+  name: "exam-select",
+  props: {
+    disabled: { type: Boolean, default: false },
+    placeholder: { type: String, default: "考试" },
+    value: { type: [Number, String], default: "" },
+    clearable: { type: Boolean, default: true },
+    semesterId: { type: String, default: "" },
+    defaultSelect: { type: Boolean, default: false },
+  },
+  data() {
+    return {
+      optionList: [],
+      selected: "",
+    };
+  },
+  watch: {
+    value: {
+      immediate: true,
+      handler(val) {
+        this.selected = val;
+      },
+    },
+    semesterId(val, oldval) {
+      if (val !== oldval) {
+        this.search();
+        this.$emit("input", "");
+        this.$emit("change", {});
+      }
+    },
+  },
+  created() {
+    this.search();
+  },
+  methods: {
+    async search() {
+      this.optionList = [];
+      if (!this.semesterId) return;
+
+      let data = {
+        semesterId: this.semesterId,
+      };
+      const res = await commonExamQuery(data);
+      this.optionList = res;
+      if (this.defaultSelect && !this.value) this.selectDefault();
+    },
+    select() {
+      this.$emit("input", this.selected);
+      this.$emit(
+        "change",
+        this.optionList.find((item) => item.id === this.selected)
+      );
+    },
+    selectDefault() {
+      const defaultData = this.optionList[0];
+      if (defaultData) {
+        this.selected = defaultData.id;
+        this.$emit("input", this.selected);
+        this.$emit("default-selected", defaultData);
+      }
+    },
+  },
+};
+</script>

+ 11 - 9
src/modules/base/api.js

@@ -24,10 +24,7 @@ export const commonTeachClazzQuery = ({
 export const commonArchivesQuery = (data) => {
   return $postParam("/api/admin/common/archives/query", data);
 };
-// 档案类型
-export const commonArchivesTypeQuery = () => {
-  return $postParam("/api/admin/common/archives_type/query", {});
-};
+
 // 档案类型
 export const commonArchivesManageUserQuery = () => {
   return $postParam("/api/admin/common/manager_user/query", {});
@@ -36,11 +33,16 @@ export const commonArchivesManageUserQuery = () => {
 export const commonArchivesOrgQuery = (data) => {
   return $postParam("/api/admin/common/manager_org/query", data);
 };
+
 // 学期
 export const commonSemesterQuery = () => {
   return $postParam("/api/admin/common/semester/query", {});
 };
-// 学期
+// 考试
+export const commonExamQuery = (data) => {
+  return $postParam("/api/admin/common/exam/query", data);
+};
+// 扫描任务
 export const commonScanTaskQuery = (data) => {
   return $postParam("/api/admin/common/scan_task/query", data);
 };
@@ -169,16 +171,16 @@ export const deleteSemester = (ids) => {
 export const updateSemester = (datas) => {
   return $post("/api/admin/basic/semester/save", datas);
 };
-// record-type-manage
-export const ArchivesTypeListQuery = (datas) => {
+// exam-manage
+export const examListQuery = (datas) => {
   return $postParam("/api/admin/paper/archives_type/page", datas);
 };
-export const deleteArchivesType = (ids) => {
+export const deleteExam = (ids) => {
   return $postParam("/api/admin/paper/archives_type/delete", {
     ids: ids.join(),
   });
 };
-export const updateArchivesType = (datas) => {
+export const updateExam = (datas) => {
   return $post("/api/admin/paper/archives_type/save", datas);
 };
 

+ 25 - 10
src/modules/base/components/ModifyArchivesType.vue → src/modules/base/components/ModifyExam.vue

@@ -1,6 +1,6 @@
 <template>
   <el-dialog
-    class="modify-record-type"
+    class="modify-exam"
     :visible.sync="modalIsShow"
     :title="title"
     top="10vh"
@@ -14,15 +14,22 @@
       ref="modalFormComp"
       :model="modalForm"
       :rules="rules"
-      @submit.native.prevent
+      label-width="100px"
     >
-      <el-form-item prop="name" label="类型名称:" label-width="100px">
+      <el-form-item prop="name" label="考试名称:">
         <el-input
           v-model.trim="modalForm.name"
-          placeholder="请输入类型名称"
+          placeholder="请输入考试名称"
           clearable
         ></el-input>
       </el-form-item>
+      <el-form-item prop="semesterId" label="所属学期:">
+        <semester-select
+          v-model="modalForm.semesterId"
+          placeholder="请选择所属学期"
+          :clearable="false"
+        ></semester-select>
+      </el-form-item>
     </el-form>
     <div slot="footer">
       <el-button type="primary" :disabled="isSubmit" @click="submit"
@@ -34,15 +41,16 @@
 </template>
 
 <script>
-import { updateArchivesType } from "../api";
+import { updateExam } from "../api";
 
 const initModalForm = {
   id: null,
+  semesterId: "",
   name: "",
 };
 
 export default {
-  name: "modify-record-type",
+  name: "modify-exam",
   props: {
     instance: {
       type: Object,
@@ -56,7 +64,7 @@ export default {
       return !!this.instance.id;
     },
     title() {
-      return (this.isEdit ? "编辑" : "新增") + "档案类型";
+      return (this.isEdit ? "编辑" : "新增") + "考试";
     },
   },
   data() {
@@ -68,15 +76,22 @@ export default {
         name: [
           {
             required: true,
-            message: "请输入类型名称",
+            message: "请输入考试名称",
             trigger: "change",
           },
           {
-            message: "类型名称不能超过100字符",
+            message: "考试名称不能超过100字符",
             max: 100,
             trigger: "change",
           },
         ],
+        semesterId: [
+          {
+            required: true,
+            message: "请选择所属学期",
+            trigger: "change",
+          },
+        ],
       },
     };
   },
@@ -104,7 +119,7 @@ export default {
       if (this.isSubmit) return;
       this.isSubmit = true;
       let datas = { ...this.modalForm };
-      const data = await updateArchivesType(datas).catch(() => {});
+      const data = await updateExam(datas).catch(() => {});
       this.isSubmit = false;
 
       if (!data) return;

+ 4 - 4
src/modules/base/router.js

@@ -7,7 +7,7 @@ import SystemSetting from "./views/SystemSetting.vue";
 // dict
 import StudentManage from "./views/StudentManage.vue";
 import SemesterManage from "./views/SemesterManage.vue";
-import ArchivesTypeManage from "./views/ArchivesTypeManage.vue";
+import ExamManage from "./views/ExamManage.vue";
 
 export default [
   {
@@ -41,8 +41,8 @@ export default [
     component: SemesterManage,
   },
   {
-    path: "/base/archives-type-manage",
-    name: "ArchivesTypeManage",
-    component: ArchivesTypeManage,
+    path: "/base/exam-manage",
+    name: "ExamManage",
+    component: ExamManage,
   },
 ];

+ 14 - 13
src/modules/base/views/ArchivesTypeManage.vue → src/modules/base/views/ExamManage.vue

@@ -15,7 +15,7 @@
           type="primary"
           icon="el-icon-circle-plus-outline"
           @click="toAdd"
-          >新增类型</el-button
+          >新增考试</el-button
         >
       </div>
     </div>
@@ -27,7 +27,8 @@
           width="70"
           :index="indexMethod"
         ></el-table-column>
-        <el-table-column prop="name" label="类型名称"></el-table-column>
+        <el-table-column prop="name" label="考试名称"></el-table-column>
+        <el-table-column prop="semesterName" label="所属学期"></el-table-column>
         <el-table-column class-name="action-column" label="操作" width="160px">
           <template slot-scope="scope">
             <el-button
@@ -60,21 +61,21 @@
       </div>
     </div>
 
-    <modify-archives-type
+    <modify-exam
+      ref="ModifyExam"
       :instance="curRow"
       @modified="getList"
-      ref="ModifyArchivesType"
-    ></modify-archives-type>
+    ></modify-exam>
   </div>
 </template>
 
 <script>
-import { ArchivesTypeListQuery, deleteArchivesType } from "../api";
-import ModifyArchivesType from "../components/ModifyArchivesType.vue";
+import { examListQuery, deleteExam } from "../api";
+import ModifyExam from "../components/ModifyExam.vue";
 
 export default {
   name: "record-type-manage",
-  components: { ModifyArchivesType },
+  components: { ModifyExam },
   data() {
     return {
       filter: {},
@@ -97,7 +98,7 @@ export default {
         pageNumber: this.current,
         pageSize: this.size,
       };
-      const data = await ArchivesTypeListQuery(datas);
+      const data = await examListQuery(datas);
       this.dataList = data.records;
       this.total = data.total;
     },
@@ -107,15 +108,15 @@ export default {
     },
     toAdd() {
       this.curRow = {};
-      this.$refs.ModifyArchivesType.open();
+      this.$refs.ModifyExam.open();
     },
     toEdit(row) {
       this.curRow = row;
-      this.$refs.ModifyArchivesType.open();
+      this.$refs.ModifyExam.open();
     },
     async toDelete(row) {
       const result = await this.$confirm(
-        `确定要删除类型【${row.name}】吗?`,
+        `确定要删除考试【${row.name}】吗?`,
         "提示",
         {
           type: "warning",
@@ -123,7 +124,7 @@ export default {
       ).catch(() => {});
       if (result !== "confirm") return;
 
-      await deleteArchivesType([row.id]);
+      await deleteExam([row.id]);
       this.$message.success("删除成功!");
       this.deletePageLastItem();
     },

+ 13 - 30
src/modules/base/views/StudentManage.vue

@@ -2,28 +2,11 @@
   <div class="student-manage">
     <div class="part-box part-box-filter part-box-flex">
       <el-form ref="FilterForm" label-position="left" label-width="90px" inline>
-        <el-form-item label="学院:">
-          <college-select
-            v-model="filter.collegeId"
-            placeholder="学院"
-          ></college-select>
-        </el-form-item>
-        <el-form-item label="专业:">
-          <major-select
-            v-model="filter.majorName"
-            :college-id="filter.collegeId"
-            cascader
-            placeholder="专业"
-          ></major-select>
-        </el-form-item>
-        <el-form-item label="班级:">
-          <class-select
-            v-model="filter.clazzName"
-            :major-name="filter.majorName"
-            cascader
-            placeholder="班级"
-          ></class-select>
-        </el-form-item>
+        <sec-select
+          v-model="filter"
+          defaultSelectExam
+          @exam-default="toPage(1)"
+        ></sec-select>
         <el-form-item label="姓名/学号:">
           <el-input
             style="width: 142px"
@@ -55,7 +38,7 @@
           type="success"
           icon="el-icon-upload"
           @click="toImportStudent"
-          >导入生</el-button
+          >导入生</el-button
         >
         <el-button
           v-if="checkPrivilege('button', 'import')"
@@ -68,7 +51,7 @@
           type="primary"
           icon="el-icon-circle-plus-outline"
           @click="toAdd"
-          >新增生</el-button
+          >新增生</el-button
         >
       </div>
     </div>
@@ -136,7 +119,7 @@
     <import-file
       v-if="checkPrivilege('button', 'import')"
       ref="ImportFile"
-      title="导入生"
+      title="导入生"
       :upload-url="uploadUrl"
       :format="['xls', 'xlsx']"
       :download-url="downloadUrl"
@@ -166,9 +149,9 @@ export default {
     return {
       filter: {
         queryParams: "",
-        collegeId: "",
-        majorName: "",
-        clazzName: "",
+        semesterId: "",
+        examId: "",
+        courseCode: "",
       },
       queriedFilter: {},
       current: 1,
@@ -179,7 +162,7 @@ export default {
       // import
       uploadUrl: "/api/admin/basic/student/data_import",
       downloadUrl: "/temps/studentTemplate.xlsx",
-      dfilename: "生导入模板.xlsx",
+      dfilename: "生导入模板.xlsx",
     };
   },
   computed: {
@@ -233,7 +216,7 @@ export default {
         .catch(() => {});
     },
     toDelete(row) {
-      this.$confirm(`确定要删除生【${row.studentName}】吗?`, "提示", {
+      this.$confirm(`确定要删除生【${row.studentName}】吗?`, "提示", {
         type: "warning",
       })
         .then(async () => {

+ 5 - 2
src/plugins/globalVuePlugins.js

@@ -16,9 +16,11 @@ import OrgSelect from "../components/base/OrgSelect.vue";
 import TeachClazzSelect from "../components/base/TeachClazzSelect.vue";
 import ArchivesSelect from "../components/base/ArchivesSelect.vue";
 import ArchivesOrgSelect from "../components/base/ArchivesOrgSelect.vue";
-import ArchivesTypeSelect from "../components/base/ArchivesTypeSelect.vue";
 import ArchivesManageUserSelect from "../components/base/ArchivesManageUserSelect.vue";
 
+import ExamSelect from "../components/base/ExamSelect.vue";
+import SecSelect from "../components/SecSelect.vue";
+
 const components = {
   ViewFooter,
   MoreText,
@@ -33,8 +35,9 @@ const components = {
   TeachClazzSelect,
   ArchivesSelect,
   ArchivesOrgSelect,
-  ArchivesTypeSelect,
   ArchivesManageUserSelect,
+  ExamSelect,
+  SecSelect,
 };
 
 export default {