Browse Source

feat: 完善逻辑

chenhao 2 years ago
parent
commit
0b8754f480

+ 4 - 4
src/apis/struct.ts

@@ -13,11 +13,11 @@ export const getSubjectsListHttp = (data: FetchSubjectsListQuery) => {
 /**
  * @description 导入科目
  */
-export const importSubjectsHttp = (data: { examId: string; file: File }) => {
+export const importSubjectsHttp = (data: FormData) => {
   /** multipart/form-data */
   return request.post<unknown, null>("/api/paper/import-course", data, {
     headers: {
-      "content-type": "multipart/form-data",
+      "Content-Type": "multipart/form-data",
     },
   });
 };
@@ -26,10 +26,10 @@ export const importSubjectsHttp = (data: { examId: string; file: File }) => {
  * @description 导入试卷结构
  */
 
-export const importPaperStructHttp = (data: { examId: string; file: File }) => {
+export const importPaperStructHttp = (data: FormData) => {
   return request.post<unknown, null>("/api/paper/import-struct-subject", data, {
     headers: {
-      "content-type": "multipart/form-data",
+      "Content-Type": "multipart/form-data",
     },
   });
 };

BIN
src/assets/images/layout/web-logo.png


+ 1 - 0
src/assets/less/antd.modal.less

@@ -1,4 +1,5 @@
 .ant-modal {
+  width: 520px !important;
   .ant-modal-header {
     padding: 12.5px 24px;
   }

+ 5 - 6
src/pages/exam-manage/index.vue

@@ -125,10 +125,7 @@
 
 <script setup lang="ts" name="PageExam">
 import { reactive, ref, watch } from "vue";
-import {
-  PlusCircleOutlined,
-  CloudSyncOutlined,
-} from "@ant-design/icons-vue";
+import { PlusCircleOutlined, CloudSyncOutlined } from "@ant-design/icons-vue";
 import { getSchoolListHttp } from "@/apis/school";
 import {
   getExamListHttp,
@@ -223,6 +220,7 @@ watch(() => query.pageNumber, queryExamList);
 
 const onEdit = (record: ExamListInfo) => {
   examInfo.value = Object.assign(examInfo.value, { ...record });
+   toggleAddExamModal(true);
 };
 
 /** 新增考试 */
@@ -250,9 +248,10 @@ const resetExamInfo = () => {
 
 /** 同步考试数据 */
 const syncExamData = () => {
-  if (query.schoolId) {
-    syncExamDataHttp({ schoolId: query.schoolId }).then(queryExamList);
+  if (!query.schoolId) {
+    return message.error("请选择需要同步数据的学校");
   }
+  syncExamDataHttp({ schoolId: query.schoolId }).then(queryExamList);
 };
 
 querySchoolList();

+ 16 - 13
src/pages/subjects-manage/index.vue

@@ -114,7 +114,7 @@
       :title="`导入${importType === 'subject' ? '科目' : '试卷结构'}`"
       :footer="false"
       :maskClosable="false"
-      @close="clearFileList"
+      :after-close="clearFileList"
     >
       <a-upload
         :file-list="fileList"
@@ -271,14 +271,11 @@ watch(
 const importSubject = async () => {
   try {
     const formData = new FormData();
-    formData.append("schoolId", query.schoolId);
+    formData.append("examId", query.examId);
     fileList.value?.forEach((file: any) => {
       formData.append("file", file);
     });
-    await importSubjectsHttp({
-      examId: query.examId,
-      file: new File([], "a"),
-    }).then(querySubjectsList);
+    await importSubjectsHttp(formData).then(querySubjectsList);
   } catch (error) {
     console.error(error);
   }
@@ -287,10 +284,12 @@ const importSubject = async () => {
 /** 导入试卷结构 */
 const importPaperStruct = async () => {
   try {
-    await importPaperStructHttp({
-      examId: query.examId,
-      file: new File([], "a"),
-    }).then(querySubjectsList);
+    const formData = new FormData();
+    formData.append("examId", query.examId);
+    fileList.value?.forEach((file: any) => {
+      formData.append("file", file);
+    });
+    await importPaperStructHttp(formData).then(querySubjectsList);
   } catch (error) {
     console.error(error);
   }
@@ -348,14 +347,18 @@ const downloadTemplate = async () => {
 
 const showImportModalType = (type: "subject" | "struct") => {
   importType.value = type;
-  showImportModal.value = true
+  showImportModal.value = true;
 };
 
 const onImport = () => {
   if (importType.value === "subject") {
-    importSubject();
+    importSubject().then(() => {
+      showImportModal.value = false;
+    });
   } else {
-    importPaperStruct;
+    importPaperStruct().then(() => {
+      showImportModal.value = false;
+    });
   }
 };
 

+ 15 - 8
src/pages/user-manage/index.vue

@@ -103,7 +103,7 @@
       cancelText="取消"
       :maskClosable="false"
       @ok="onAddNewUser"
-      @close="resetUserInfo"
+      :after-close="resetUserInfo"
     >
       <a-form :labelCol="{ span: 6 }">
         <a-form-item label="学校" v-bind="validateInfos.schoolId">
@@ -150,7 +150,7 @@
       cancelText="取消"
       :maskClosable="false"
       @ok="onUpdateUserPwd"
-      @close="clearFileList"
+      :after-close="clearFileList"
     >
       <a-form :labelCol="{ span: 3 }">
         <a-form-item label="密码" v-bind="validatePwdInfos.passwd">
@@ -164,7 +164,7 @@
       title="导入用户"
       :footer="false"
       :maskClosable="false"
-      @close="resetPwdInfo"
+      :after-close="resetPwdInfo"
     >
       <a-upload
         :file-list="fileList"
@@ -201,7 +201,7 @@ import {
   editUserInfoHttp,
   resetUserPwdHttp,
   importUserHttp,
-  downloadImportUserHttp
+  downloadImportUserHttp,
 } from "@/apis/user";
 import Block from "@/components/block/index.vue";
 import { message } from "ant-design-vue";
@@ -239,8 +239,8 @@ const userRules = {
 
 const pwdRules = {
   passwd: [
-    { required: true, message: "请选择用户所属学校" },
-    { pattern: /s/, message: "请选择用户所属学校" },
+    { required: true, message: "请填写登录密码" },
+    { pattern: /^[a-zA-Z0-9]{6,18}$/, message: "密码只能由数字、字母组成,长度6-18个字符" },
   ],
 };
 
@@ -322,12 +322,18 @@ const updateUserStatus = (record: UserInfo) => {
 
 /** 编辑用户 */
 const onEdit = (record: UserInfo) => {
-  userInfo.value = { ...record, course: record.courseCodes.join(",") };
+  console.log(record);
+  Object.assign(userInfo.value, {
+    ...record,
+    course: record.courseCodes?.join(","),
+    role: `${record.roleId}` === "2" ? "SCHOOL_ADMIN" : "SECTION_LEADER",
+  });
+  toggleAddUserModal(true);
 };
 
 /** 重置密码 */
 const onResetPwd = (record: UserInfo) => {
-  resetPwd.value = { passwd: "", userId: `${record.id}` };
+  Object.assign(resetPwd.value, { passwd: "", userId: `${record.id}` });
   showResetPwdModal.value = true;
 };
 
@@ -338,6 +344,7 @@ const onAddNewUser = () => {
       editUserInfoHttp(userInfo.value).then(() => {
         message.success(`${userInfo.value.id ? "修改" : "添加"}成功`);
         toggleAddUserModal(false);
+        queryUserList();
       });
     }
   });

+ 12 - 2
src/plugins/request.ts

@@ -10,7 +10,7 @@ const request = axios.create({
   withCredentials: true,
   timeout: 20000,
   method: "post",
-  transformRequest: [(data) => new URLSearchParams(data)],
+  transformRequest: [],
 });
 
 request.interceptors.request.use(
@@ -22,12 +22,17 @@ request.interceptors.request.use(
         config
       );
     }
-    config.headers = config.headers || {}
+    config.headers = config.headers || {};
     if (!config.noAuth) {
       const { token, timestamp } = signToken(config.url, config.method);
       config.headers["Authorization"] = token;
       config.headers["time"] = timestamp;
     }
+    config.headers["Content-Type"] =
+      config.headers["Content-Type"] || "application/x-www-form-urlencoded";
+    if (!config.headers["Content-Type"]?.toString().includes("multipart")) {
+      config.transformRequest = (d) => new URLSearchParams(d);
+    }
     filterConfigEmpty(config);
     return config;
   },
@@ -44,6 +49,11 @@ request.interceptors.response.use(
     if (response.config.download) {
       return response;
     }
+    if (response.data.hasError) {
+      const errMsg = response.data?.errMsg?.join("\n");
+      message.error(errMsg);
+      return Promise.reject(response.data);
+    }
     return response.data;
   },
   (error: AxiosError<any>) => {