Browse Source

feat: dict option

zhangjie 1 week ago
parent
commit
2b84186aa0

+ 3 - 2
src/api/types/exam.ts

@@ -1,3 +1,4 @@
+import { ExamType, MarkingMode } from '@/constants/enumerate';
 import { PageResult, PageParams } from './common';
 
 export interface ExamBaseItem {
@@ -5,7 +6,7 @@ export interface ExamBaseItem {
   // 考试名称
   name: string;
   // 类型
-  type: string;
+  type: ExamType;
   // 扫描图片类型
   scanImageType: number;
   // 考试日期
@@ -15,7 +16,7 @@ export interface ExamBaseItem {
   // 评卷结束日期
   markingEndDate: string;
   // 评卷模式
-  markingMode: 'TRACK' | 'COMMON' | 'NONE';
+  markingMode: MarkingMode;
   // 强制标记
   forceMark: boolean;
   // 禁止其他人查看考生信息

+ 4 - 3
src/api/types/log.ts

@@ -1,3 +1,4 @@
+import { LogType } from '@/constants/enumerate';
 import { PageResult, PageParams } from './common';
 
 // 日志
@@ -21,10 +22,10 @@ export type LogListPageRes = PageResult<LogItem>;
 
 export interface LogListFilter {
   // 登录名
-  loginName: string;
+  loginName?: string;
   // 用户类型
-  userType: string;
+  userType?: string;
   // 操作类型
-  operationType: string;
+  operationType?: LogType;
 }
 export type LogListPageParam = PageParams<LogListFilter>;

+ 9 - 9
src/api/types/user.ts

@@ -1,3 +1,5 @@
+import { RoleType } from '@/constants/enumerate';
+
 export interface LoginData {
   account: string;
   password: string;
@@ -9,19 +11,17 @@ export interface UserItem {
   name: string; // 名称
   employeeId?: string; // 工号 (可选)
   source: string; // 来源 (例如:内部用户)
-  role: string; // 角色 (例如:学校管理员, 扫描员)
-  status: 'enabled' | 'disabled'; // 状态 (启用/禁用)
+  role: RoleType; // 角色 (例如:学校管理员, 扫描员)
+  enable: boolean; // 状态 (启用/禁用)
   wechatLinked?: boolean; // 关联微信 (可选, 可能为显示字段)
-  // 根据实际需要添加更多字段
 }
 export type UserListPageRes = PageResult<UserItem>;
 
 export interface UserListFilter {
   name?: string; // 按名称搜索
   loginName?: string; // 按登录名搜索
-  status?: 'enabled' | 'disabled'; // 按状态筛选
-  role?: string; // 按角色筛选
-  // 根据实际需要添加更多筛选字段
+  enable: boolean; // 按状态筛选
+  role?: RoleType; // 按角色筛选
 }
 export type UserListPageParam = PageParams<UserListFilter>;
 
@@ -30,8 +30,8 @@ export interface UserUpdateParam {
   loginName: string;
   name: string;
   employeeId: string;
-  status: 'enabled' | 'disabled';
-  role: string;
+  enable: boolean;
+  role: RoleType;
   password: string;
 }
 
@@ -52,7 +52,7 @@ export interface UpdatePwdData {
 
 export interface BatchCreateUserParam {
   examId: number;
-  role: string;
+  role: RoleType;
   namingRule: string;
   accountsPerGroup: number;
   randomPassword: boolean;

+ 40 - 8
src/constants/enumerate.ts

@@ -1,10 +1,10 @@
-export const SYS_ADMIN_NAME = 'sysadmin';
+export const SYS_ADMIN_NAME = 'admin';
 
 export const DEFAULT_LABEL = '--';
 
 // 通用 -------------->
 // 启用/禁用
-export const ABLE_TYPE = {
+export const ENABLE_TYPE = {
   false: '禁用',
   true: '启用',
 };
@@ -12,14 +12,46 @@ export const ABLE_TYPE = {
 // 基础 -------------->
 // 角色
 export const ROLE_TYPE = {
+  SCANNER: '扫描员',
+  COORDINATOR: '科组长',
+  REVIEWER: '复核员',
+  EVALUATOR: '评卷员',
   ADMIN: '学校管理员',
-  TEACHING: '教学点管理员',
+  SCHOOL: '学校查询员',
+  COLLEGE: '学院查询员',
 };
 
-export const TASK_STATUS = {
-  RUNNING: '进行中',
-  SUCCESS: '成功',
-  FAILURE: '失败',
+export type RoleType = keyof typeof ROLE_TYPE;
+
+// 考试类型
+export const EXAM_TYPE = {
+  SCAN: '扫描图片类型',
+  MULTIMEDIA: '多媒体类型',
 };
+export type ExamType = keyof typeof EXAM_TYPE;
 
-export type RoleType = keyof typeof ROLE_TYPE;
+// 评卷模式:普通、轨迹、不限
+export const MARKING_MODE = {
+  COMMON: '普通',
+  TRACK: '轨迹',
+  UNLIMITED: '不限',
+};
+export type MarkingMode = keyof typeof MARKING_MODE;
+
+// 分数间隔:五分一段、十分一段
+export const SCORE_INTERVAL = {
+  FIVE: '五分一段',
+  TEN: '十分一段',
+};
+export type ScoreInterval = keyof typeof SCORE_INTERVAL;
+
+// 日志操作类型:查询、新增、更新、删除、导入、导出
+export const LOG_TYPE = {
+  QUERY: '查询',
+  ADD: '新增',
+  UPDATE: '更新',
+  DELETE: '删除',
+  IMPORT: '导入',
+  EXPORT: '导出',
+};
+export type LogType = keyof typeof LOG_TYPE;

+ 0 - 31
src/hooks/dict-option.ts

@@ -1,31 +0,0 @@
-import { ref } from 'vue';
-import {
-  DEFAULT_LABEL,
-  ABLE_TYPE,
-  ROLE_TYPE,
-  TASK_STATUS,
-} from '@/constants/enumerate';
-import { dictToOption } from '@/utils/utils';
-import { Options } from '@/types/global';
-
-const dicts = {
-  ABLE_TYPE,
-  ROLE_TYPE,
-  TASK_STATUS,
-};
-
-type DictTypeType = keyof typeof dicts;
-
-export default function useDictOption(dictType: DictTypeType) {
-  const optionList = ref<Options[]>(dictToOption(dicts[dictType] || {}));
-
-  function getLabel(val: string): string {
-    // @ts-ignore
-    return dicts[dictType] ? dicts[dictType][val] : DEFAULT_LABEL;
-  }
-
-  return {
-    optionList,
-    getLabel,
-  };
-}

+ 23 - 11
src/utils/filter.ts

@@ -1,16 +1,28 @@
-import { DEFAULT_LABEL } from '@/constants/enumerate';
+import {
+  DEFAULT_LABEL,
+  ENABLE_TYPE,
+  ROLE_TYPE,
+  EXAM_TYPE,
+  MARKING_MODE,
+  LOG_TYPE,
+} from '@/constants/enumerate';
 import { formatDate } from './utils';
 
+// 字典过滤器
+export const dictFilter = {
+  enable: (val: boolean) =>
+    ENABLE_TYPE[val as keyof typeof ENABLE_TYPE] || DEFAULT_LABEL,
+  role: (val: string) =>
+    ROLE_TYPE[val as keyof typeof ROLE_TYPE] || DEFAULT_LABEL,
+  examType: (val: string) =>
+    EXAM_TYPE[val as keyof typeof EXAM_TYPE] || DEFAULT_LABEL,
+  markingMode: (val: string) =>
+    MARKING_MODE[val as keyof typeof MARKING_MODE] || DEFAULT_LABEL,
+  logType: (val: string) =>
+    LOG_TYPE[val as keyof typeof LOG_TYPE] || DEFAULT_LABEL,
+};
+
+// 时间戳过滤器
 export function timestampFilter(val: number | null): string {
   return val ? formatDate('YYYY-MM-DD HH:mm:ss', new Date(val)) : DEFAULT_LABEL;
 }
-
-interface CourseNameCode {
-  courseName: string;
-  courseCode: string;
-}
-export function courseNameCodeFilter(val: CourseNameCode) {
-  return `${val.courseName || DEFAULT_LABEL}(${
-    val.courseCode || DEFAULT_LABEL
-  })`;
-}

+ 15 - 6
src/views/exam/ExamEdit.vue

@@ -32,8 +32,12 @@
                   placeholder="请选择类型"
                   style="width: 200px"
                 >
-                  <el-option label="扫描图片" value="扫描图片" />
-                  <el-option label="其他类型" value="其他类型" />
+                  <el-option
+                    v-for="(val, key) in EXAM_TYPE"
+                    :key="key"
+                    :label="val"
+                    :value="key"
+                  />
                 </el-select>
               </el-form-item>
             </el-col>
@@ -100,9 +104,12 @@
                   placeholder="请选择"
                   style="width: 200px"
                 >
-                  <el-option label="不限" value="NONE" />
-                  <el-option label="轨迹" value="TRACK" />
-                  <el-option label="普通" value="COMMON" />
+                  <el-option
+                    v-for="(val, key) in MARKING_MODE"
+                    :key="key"
+                    :label="val"
+                    :value="key"
+                  />
                 </el-select>
               </el-form-item>
             </el-col>
@@ -322,6 +329,8 @@
   import { getExamDetail, updateExam } from '@/api/exam';
   import type { ExamUpdateParam, ExamAdvancedConfig } from '@/api/types/exam';
   import useLoading from '@/hooks/loading';
+  import { MARKING_MODE, EXAM_TYPE } from '@/constants/enumerate';
+
   import ExamAdvancedDialog from './ExamAdvancedDialog.vue';
 
   defineOptions({
@@ -341,7 +350,7 @@
   // 表单数据
   const initialFormState: Partial<ExamUpdateParam> = {
     name: '',
-    type: '',
+    type: 'SCAN',
     scanImageType: 1,
     examDate: '',
     markingStartDate: '',

+ 1 - 1
src/views/exam/IssuePaperTypeDialog.vue

@@ -53,7 +53,7 @@
 
 <script setup lang="ts">
   import { ref } from 'vue';
-  import { ElMessage, ElMessageBox } from 'element-plus';
+  import { ElMessage } from 'element-plus';
   import type { IssuePaperTypeItem } from '@/api/types/issue-paper';
   import {
     getIssuePaperTypeList,

+ 1 - 1
src/views/exam/RejectTypeDialog.vue

@@ -57,7 +57,7 @@
 
 <script setup lang="ts">
   import { ref } from 'vue';
-  import { ElMessage, ElMessageBox } from 'element-plus';
+  import { ElMessage } from 'element-plus';
   import type { RejectTypeItem } from '@/api/types/reject';
   import { getRejectTypeList, deleteRejectType } from '@/api/reject';
   import useModal from '@/hooks/modal';

+ 12 - 14
src/views/log/LogManage.vue

@@ -29,22 +29,19 @@
           clearable
           style="width: 120px"
         >
-          <el-option label="请选择" value="" />
-          <el-option label="登录" value="登录" />
-          <el-option label="登出" value="登出" />
-          <el-option label="查询" value="查询" />
-          <el-option label="新增" value="新增" />
-          <el-option label="修改" value="修改" />
-          <el-option label="删除" value="删除" />
-          <el-option label="导入" value="导入" />
-          <el-option label="导出" value="导出" />
+          <el-option
+            v-for="(val, key) in LOG_TYPE"
+            :key="key"
+            :label="val"
+            :value="key"
+          />
         </el-select>
       </el-form-item>
+      <el-form-item>
+        <el-button type="primary" @click="toPage(1)">查询</el-button>
+        <el-button @click="exportData">导出</el-button>
+      </el-form-item>
     </el-form>
-    <el-space wrap>
-      <el-button type="primary" @click="toPage(1)">查询</el-button>
-      <el-button @click="exportData">导出</el-button>
-    </el-space>
   </div>
   <div class="part-box">
     <el-table class="page-table" :data="dataList" :loading="loading">
@@ -73,6 +70,7 @@
   import { getLogList } from '@/api/log';
   import { LogItem, LogListFilter } from '@/api/types/log';
   import useTable from '@/hooks/table';
+  import { LOG_TYPE } from '@/constants/enumerate';
 
   defineOptions({
     name: 'LogManage',
@@ -81,7 +79,7 @@
   const searchModel = reactive<LogListFilter>({
     loginName: '',
     userType: '',
-    operationType: '',
+    operationType: undefined,
   });
 
   const { dataList, pagination, loading, toPage, pageSizeChange } =

+ 12 - 8
src/views/user/ModifyUser.vue

@@ -39,16 +39,18 @@
       </el-form-item>
       <el-form-item label="状态" prop="status">
         <el-select v-model="formModel.status" placeholder="请选择状态">
-          <el-option label="启用" value="enabled" />
-          <el-option label="禁用" value="disabled" />
+          <el-option label="启用" :value="true" />
+          <el-option label="禁用" :value="false" />
         </el-select>
       </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
+            v-for="(val, key) in ROLE_TYPE"
+            :key="key"
+            :label="val"
+            :value="key"
+          />
         </el-select>
       </el-form-item>
     </el-form>
@@ -71,6 +73,8 @@
   import { updateUser } from '@/api/user';
   import useModal from '@/hooks/modal';
   import useLoading from '@/hooks/loading';
+  import { ROLE_TYPE } from '@/constants/enumerate';
+
   import { objAssign, objModifyAssign } from '@/utils/utils';
 
   defineOptions({
@@ -99,8 +103,8 @@
     name: '',
     employeeId: '',
     password: '',
-    status: 'enabled',
-    role: 'user', // 默认角色
+    enable: true,
+    role: 'EVALUATOR', // 默认角色
   };
 
   const formModel = reactive<UserUpdateParam>({ ...initialFormState });

+ 19 - 10
src/views/user/UserManage.vue

@@ -17,13 +17,13 @@
       </el-form-item>
       <el-form-item label="状态">
         <el-select
-          v-model="searchModel.status"
+          v-model="searchModel.enable"
           placeholder="请选择状态"
           clearable
           style="width: 100px"
         >
-          <el-option label="启用" value="enabled" />
-          <el-option label="禁用" value="disabled" />
+          <el-option label="启用" :value="true" />
+          <el-option label="禁用" :value="false" />
         </el-select>
       </el-form-item>
       <el-form-item label="角色">
@@ -33,9 +33,12 @@
           clearable
           style="width: 200px"
         >
-          <el-option label="学校管理员" value="school_admin" />
-          <el-option label="扫描员" value="scanner" />
-          <el-option label="普通用户" value="user" />
+          <el-option
+            v-for="(val, key) in ROLE_TYPE"
+            :key="key"
+            :label="val"
+            :value="key"
+          />
         </el-select>
       </el-form-item>
       <el-form-item>
@@ -118,10 +121,10 @@
           {{ formatRole(row.role) }}
         </template>
       </el-table-column>
-      <el-table-column prop="status" label="状态">
+      <el-table-column prop="enable" label="状态">
         <template #default="{ row }">
-          <el-tag :type="row.status === 'enabled' ? 'success' : 'danger'">
-            {{ row.status === 'enabled' ? '启用' : '禁用' }}
+          <el-tag :type="row.enable ? 'success' : 'danger'">
+            {{ row.enable ? '启用' : '禁用' }}
           </el-tag>
         </template>
       </el-table-column>
@@ -184,6 +187,7 @@
   import type { UserItem, UserListFilter } from '@/api/types/user';
   import useTable from '@/hooks/table';
   import { modalConfirm } from '@/utils/ui';
+  import { ROLE_TYPE } from '@/constants/enumerate';
 
   import ModifyUser from './ModifyUser.vue'; // 引入弹窗组件
   import BatchCreateUserDialog from './components/BatchCreateUserDialog.vue';
@@ -192,7 +196,12 @@
     name: 'UserManage',
   });
 
-  const searchModel = reactive<UserListFilter>({});
+  const searchModel = reactive<UserListFilter>({
+    name: '',
+    loginName: '',
+    enable: undefined,
+    role: undefined,
+  });
 
   const {
     dataList,