zhangjie hace 4 días
padre
commit
2f1c88e2bb

+ 0 - 1
src/api/types/base.ts

@@ -101,7 +101,6 @@ export interface ExamItem {
   code: string;
 }
 export interface SubjectItem {
-  id: number;
   name: string;
   code: string;
 }

+ 18 - 10
src/api/types/user.ts

@@ -1,4 +1,4 @@
-import { RoleType } from '@/constants/enumerate';
+import { RoleType, BatchAddRole, UserSource } from '@/constants/enumerate';
 
 export interface LoginData {
   account: string;
@@ -15,25 +15,33 @@ export interface UserItem {
   // 工号 (可选)
   empno: string;
   // 来源 (例如:内部用户)
-  source: string;
+  source: UserSource;
   // 角色 (例如:学校管理员, 扫描员)
   role: RoleType;
   // 状态 (启用/禁用)
   enable: boolean;
   // 关联账号
   relatedAccount: string;
+  // 学校
   schoolId: number;
+  // 最后登录IP
   lastLoginIp: string;
+  // 描述
   description: string;
 }
 export type UserListPageRes = PageResult<UserItem>;
 
 export interface UserListFilter {
-  name?: string; // 按名称搜索
-  loginName?: string; // 按登录名搜索
-  enable: boolean; // 按状态筛选
-  role?: RoleType; // 按角色筛选
-  source?: string; // 按来源筛选
+  // 登录名
+  loginName?: string;
+  // 姓名
+  name?: string;
+  // 状态
+  enable?: boolean;
+  // 角色
+  role?: RoleType;
+  // 来源
+  source?: UserSource;
 }
 export type UserListPageParam = PageParams<UserListFilter>;
 
@@ -49,12 +57,13 @@ export interface UserUpdateParam {
   enable: boolean;
   // 角色 (例如:学校管理员, 扫描员)
   role: RoleType;
+  // 密码
   password: string;
 }
 
 export interface ResetPasswordParam {
   ids: number[];
-  password: string; // 如果不传,后端可能会生成随机密码
+  password: string;
 }
 export interface EnableUserParam {
   ids: number[];
@@ -68,9 +77,8 @@ export interface UpdatePwdData {
 }
 
 export interface BatchCreateUserParam {
-  examId: number;
   // 角色
-  role: RoleType;
+  role: BatchAddRole;
   // 命名规则
   prefix: string;
   // 每分组账号数

+ 1 - 1
src/components/select-subject/index.vue

@@ -59,7 +59,7 @@
     if (!appStore.curExam?.id) return;
     const res = await subjectQuery(appStore.curExam?.id);
     optionList.value = res.map((item) => {
-      return { ...item, value: item.id, label: item.name };
+      return { ...item, value: item.code, label: item.name };
     });
   };
   search(); // Initial load

+ 8 - 0
src/constants/enumerate.ts

@@ -25,6 +25,14 @@ export const ROLE_TYPE = {
 
 export type RoleType = keyof typeof ROLE_TYPE;
 
+// 批量新增角色
+export const BATCH_ADD_ROLE = {
+  SUBJECT_HEADER: '科组长',
+  INSPECTOR: '复核员',
+  MARKER: '评卷员',
+};
+export type BatchAddRole = keyof typeof BATCH_ADD_ROLE;
+
 // 用户来源:"INTERNAL"|"EXTERNAL"
 export const USER_SOURCE = {
   INTERNAL: '内部用户',

+ 8 - 8
src/views/user/components/BatchCreateUserDialog.vue

@@ -21,12 +21,12 @@
       </el-form-item>
       <el-form-item label="角色" prop="role">
         <el-select v-model="formModel.role" placeholder="请选择角色">
-          <el-option label="学校管理员" value="school_admin" />
-          <el-option label="扫描员" value="scanner" />
-          <el-option label="普通用户" value="user" />
-          <el-option label="科组长" value="subject_leader" />
-          <el-option label="复核员" value="reviewer" />
-          <el-option label="评卷员" value="marker" />
+          <el-option
+            v-for="(val, key) in BATCH_ADD_ROLE"
+            :key="key"
+            :label="val"
+            :value="key"
+          />
         </el-select>
       </el-form-item>
       <el-form-item label="命名规则" prop="prefix">
@@ -91,6 +91,7 @@
   import { useAppStore } from '@/store';
   import useLoading from '@/hooks/loading';
   import useModal from '@/hooks/modal';
+  import { BATCH_ADD_ROLE } from '@/constants/enumerate';
 
   import type { SubjectItem } from '@/api/types/base';
   import type { BatchCreateUserParam } from '@/api/types/user';
@@ -143,8 +144,7 @@
 
   function getInitialFormModel(): BatchCreateUserParam {
     return {
-      examId: appStore.curExam?.id || 0,
-      role: '',
+      role: 'MARKER',
       prefix: '',
       number: undefined,
       random: false,

+ 8 - 8
src/views/user/components/SelectSubjectDialog.vue

@@ -13,16 +13,16 @@
     <el-form :model="searchModel" inline>
       <el-form-item label="科目">
         <el-select
-          v-model="searchModel.subjectId"
+          v-model="searchModel.subjectCode"
           placeholder="请选择科目"
           clearable
           filterable
         >
           <el-option
             v-for="item in subjectList"
-            :key="item.id"
+            :key="item.code"
             :label="item.name"
-            :value="item.id"
+            :value="item.code"
           />
         </el-select>
       </el-form-item>
@@ -34,7 +34,7 @@
     <el-table
       ref="tableRef"
       :data="dataList"
-      row-key="id"
+      row-key="code"
       :loading="loading"
       border
       stripe
@@ -91,7 +91,7 @@
   });
 
   interface SearchModel {
-    subjectId: number;
+    subjectCode: string;
   }
 
   /* modal */
@@ -139,7 +139,7 @@
   ];
 
   const { loading, setLoading } = useLoading();
-  const searchModel = reactive<SearchModel>({ subjectId: undefined });
+  const searchModel = reactive<SearchModel>({ subjectCode: undefined });
   const subjectList = ref<SubjectItem[]>([]);
   const dataList = ref<SubjectItem[]>([]);
   const selectedSubjects = ref<SubjectItem[]>([]);
@@ -163,11 +163,11 @@
   };
 
   const search = async () => {
-    if (!searchModel.subjectId) {
+    if (!searchModel.subjectCode) {
       dataList.value = subjectList.value;
     } else {
       dataList.value = subjectList.value.filter((item) => {
-        return item.id === searchModel.subjectId;
+        return item.code === searchModel.subjectCode;
       });
     }