소스 검색

feat: 学校学号配置

zhangjie 8 달 전
부모
커밋
baa1a845ce
4개의 변경된 파일308개의 추가작업 그리고 1개의 파일을 삭제
  1. 1 1
      package.json
  2. 14 0
      src/modules/admin/api.js
  3. 6 0
      src/modules/admin/components/ModifySchoolSet.vue
  4. 287 0
      src/modules/admin/components/school/SchoolSetStdno.vue

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "teachcloud-platform-web",
-  "version": "3.4.1",
+  "version": "3.4.2",
   "scripts": {
     "start": "vue-cli-service serve",
     "serve": "vue-cli-service serve",

+ 14 - 0
src/modules/admin/api.js

@@ -84,6 +84,18 @@ export const schoolSetMenuInfo = (schoolId) => {
 export const schoolSetMenuUpdate = (datas) => {
   return $post("/api/admin/set/menu/custom/save", datas);
 };
+
+// 学号配置
+export const schoolSetStdnoInfo = (schoolId) => {
+  return $postParam("/api/admin/set/student_number_config/select", {
+    schoolId,
+  });
+};
+export const schoolSetStdnoUpdate = (datas) => {
+  return $post("/api/admin/set/student_number_config/save", datas);
+};
+
+// 试卷规格配置
 export const sysPaperSizeList = () => {
   return $postParam("/api/admin/set/paper/sys/select", {});
 };
@@ -95,6 +107,8 @@ export const schoolSetPaperInfo = (schoolId) => {
 export const schoolSetPaperUpdate = (datas) => {
   return $post("/api/admin/set/paper/save", datas);
 };
+
+// 角色配置
 export const sysCustomRoleList = () => {
   return $postParam("/api/admin/set/role/custom/list", {});
 };

+ 6 - 0
src/modules/admin/components/ModifySchoolSet.vue

@@ -36,6 +36,7 @@ import SchoolSetPaper from "./school/SchoolSetPaper.vue";
 import SchoolSetRole from "./school/SchoolSetRole.vue";
 import SchoolSetSync from "./school/SchoolSetSync.vue";
 import SchoolSetTarget from "./school/SchoolSetTarget.vue";
+import SchoolSetStdno from "./school/SchoolSetStdno.vue";
 
 export default {
   name: "modify-school-set",
@@ -47,6 +48,7 @@ export default {
     SchoolSetRole,
     SchoolSetSync,
     SchoolSetTarget,
+    SchoolSetStdno,
   },
   props: {
     school: {
@@ -69,6 +71,10 @@ export default {
           name: "菜单管理",
           val: "menu",
         },
+        {
+          name: "学号配置",
+          val: "stdno",
+        },
         {
           name: "角色管理",
           val: "role",

+ 287 - 0
src/modules/admin/components/school/SchoolSetStdno.vue

@@ -0,0 +1,287 @@
+<template>
+  <div class="school-set-stdno">
+    <el-form
+      ref="modalFormComp"
+      :model="modalForm"
+      :rules="rules"
+      label-width="180px"
+    >
+      <el-form-item prop="digit" label="学号位数:">
+        <el-input-number
+          v-model="modalForm.digit"
+          :min="5"
+          :max="15"
+          :step="1"
+          step-strictly
+          :controls="false"
+          style="width: 200px"
+        ></el-input-number>
+        <span class="tips-info">(如:10)</span>
+      </el-form-item>
+      <el-form-item label="学号是否包含字母:">
+        <el-radio-group v-model="modalForm.containsLetter">
+          <el-radio :label="true">是</el-radio>
+          <el-radio :label="false">否</el-radio>
+        </el-radio-group>
+      </el-form-item>
+      <template v-if="modalForm.containsLetter">
+        <el-form-item prop="columns" label="字母所在列:">
+          <el-select
+            v-model="modalForm.columns"
+            placeholder="请选择"
+            multiple
+            style="width: 200px"
+            @change="columnChange"
+          >
+            <el-option
+              v-for="n in modalForm.digit"
+              :key="n"
+              :value="n"
+              :label="n"
+            ></el-option>
+          </el-select>
+          <div v-if="modalForm.relationList.length" style="margin-top: 10px">
+            <el-radio-group
+              v-model="curSelectColumn"
+              @change="selectColumnChange"
+            >
+              <el-radio-button
+                v-for="(item, index) in modalForm.relationList"
+                :key="index"
+                :label="item.columnIndex"
+                >第{{ item.columnIndex }}列</el-radio-button
+              >
+            </el-radio-group>
+          </div>
+        </el-form-item>
+        <template v-if="modalForm.columns.length">
+          <el-form-item prop="columnChar" label="使用字母:">
+            <el-input
+              v-model.trim="modalForm.columnChar"
+              plachholder="请输入"
+              style="width: 200px"
+              @change="columnCharChange"
+            ></el-input>
+            <p class="tips-info">说明:请输入大写字母,最多输入10个字母</p>
+          </el-form-item>
+          <el-form-item label="字母映射关系:">
+            <table
+              v-if="curSelectColumnLetters.length"
+              class="table table-tiny"
+              style="width: 200px"
+            >
+              <tr>
+                <th>使用字母</th>
+                <th>映射数字</th>
+              </tr>
+              <tr v-for="(item, index) in curSelectColumnLetters" :key="index">
+                <td>{{ item }}</td>
+                <td>{{ index }}</td>
+              </tr>
+            </table>
+          </el-form-item>
+        </template>
+      </template>
+      <el-form-item>
+        <el-button type="primary" :loading="loading" @click="confirm"
+          >保存</el-button
+        >
+      </el-form-item>
+    </el-form>
+  </div>
+</template>
+
+<script>
+import { deepCopy } from "@/plugins/utils";
+import { schoolSetStdnoInfo, schoolSetStdnoUpdate } from "../../api";
+
+export default {
+  name: "school-set-stdno",
+  props: {
+    school: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  data() {
+    return {
+      loading: false,
+      stdnoInfo: [],
+      modalForm: {
+        digit: 10,
+        containsLetter: false,
+        columns: [],
+        relationList: [],
+        columnChar: "",
+      },
+      curSelectColumn: -1,
+      curSelectColumnLetters: [],
+      rules: {
+        digit: [
+          {
+            required: true,
+            message: "请输入学号位数",
+            trigger: "change",
+          },
+        ],
+        columns: [
+          {
+            required: true,
+            validator: (rule, value, callback) => {
+              if (!value || !value.length) {
+                return callback(new Error(`请选择字母所在列`));
+              }
+
+              callback();
+            },
+            trigger: "change",
+          },
+        ],
+        columnChar: [
+          {
+            required: true,
+            validator: (rule, value, callback) => {
+              if (!/^[A-Z]{1,10}$/.test(value)) {
+                return callback(new Error(`只能输入大写字母,长度不超过10`));
+              }
+
+              const chars = Array.from(new Set((value || "").split(""))).join(
+                ""
+              );
+              if (chars !== value) {
+                return callback(new Error(`大写字母不可重复`));
+              }
+
+              callback();
+            },
+            trigger: "change",
+          },
+        ],
+      },
+    };
+  },
+  mounted() {
+    this.initData();
+  },
+  methods: {
+    async initData() {
+      const data = await schoolSetStdnoInfo(this.school.id);
+      this.stdnoInfo = data.result;
+      const config = data.result[0].value;
+      if (!config) {
+        this.modalForm = {
+          digit: 10,
+          containsLetter: false,
+          columns: [],
+          relationList: [],
+          columnChar: "",
+        };
+        return;
+      }
+
+      this.modalForm = {
+        digit: config.digit,
+        containsLetter: config.containsLetter,
+        columns: config.relationList.map((item) => item.columnIndex),
+        relationList: config.relationList,
+        columnChar: "",
+      };
+      if (this.modalForm.columns.length) {
+        this.curSelectColumn = this.modalForm.columns[0];
+        this.selectColumnChange();
+      }
+    },
+    toSwitchColumn(val) {
+      this.curSelectColumn = val.columnIndex;
+    },
+    columnChange() {
+      const relationList = this.modalForm.relationList || [];
+      const relationMap = {};
+      relationList.forEach((item) => {
+        relationMap[item.columnIndex] = item.letters;
+      });
+
+      this.modalForm.columns.sort((a, b) => a - b);
+
+      this.modalForm.relationList = this.modalForm.columns.map(
+        (columnIndex) => {
+          const letters = relationMap[columnIndex] || [];
+          return {
+            columnIndex,
+            letters,
+          };
+        }
+      );
+
+      if (
+        this.modalForm.columns.length &&
+        !this.modalForm.columns.includes(this.curSelectColumn)
+      ) {
+        this.curSelectColumn = this.modalForm.columns[0];
+        this.selectColumnChange();
+      }
+    },
+    selectColumnChange() {
+      const curRelation = this.modalForm.relationList.find(
+        (item) => item.columnIndex === this.curSelectColumn
+      );
+      this.modalForm.columnChar = curRelation
+        ? curRelation.letters.join("")
+        : "";
+      this.curSelectColumnLetters = curRelation ? curRelation.letters : [];
+    },
+    validateField(field) {
+      return new Promise((resolve, reject) => {
+        this.$refs.modalFormComp.validateField(field, (unvalid) => {
+          if (unvalid) {
+            reject(false);
+          } else {
+            resolve(true);
+          }
+        });
+      });
+    },
+    async columnCharChange() {
+      const res = await this.validateField("columnChar").catch(() => {});
+      if (!res) {
+        this.curSelectColumnLetters = [];
+        return;
+      }
+
+      const curRelation = this.modalForm.relationList.find(
+        (item) => item.columnIndex === this.curSelectColumn
+      );
+      if (!curRelation) return;
+      curRelation.letters = this.modalForm.columnChar.split("");
+      this.curSelectColumnLetters = curRelation.letters;
+    },
+    async confirm() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.loading) return;
+      this.loading = true;
+
+      const val = {
+        digit: this.modalForm.digit,
+        containsLetter: this.modalForm.containsLetter,
+        relationList: this.modalForm.containsLetter
+          ? this.modalForm.relationList
+          : [],
+      };
+
+      const datas = deepCopy(this.stdnoInfo);
+      datas[0].value = val;
+      const res = await schoolSetStdnoUpdate(datas).catch(() => {});
+      this.loading = false;
+
+      if (!res) return;
+
+      this.$message.success("修改成功!");
+      this.initData();
+    },
+  },
+};
+</script>