diff --git a/src/constants/index.ts b/src/constants/index.ts new file mode 100644 index 0000000..1339fdd --- /dev/null +++ b/src/constants/index.ts @@ -0,0 +1,71 @@ +/** + * 通用常量定义 + * @description 定义项目中使用的所有常量 + */ + +// ==================== API 响应码常量 ==================== + +/** 成功响应码 */ +export const SUCCESS_CODE = 0; + +/** 失败响应码 */ +export const ERROR_CODE = 1; + +/** 未认证(需要登录) */ +export const UNAUTHORIZED_CODE = 401; + +/** 无权限 */ +export const FORBIDDEN_CODE = 403; + +/** 资源不存在 */ +export const NOT_FOUND_CODE = 404; + +/** 服务器错误 */ +export const SERVER_ERROR_CODE = 500; + +// ==================== 本地存储 Key 常量 ==================== + +/** Token 存储 Key */ +export const TOKEN_KEY = 'token'; + +/** 用户信息存储 Key */ +export const USERINFO_KEY = 'userInfo'; + +/** 用户登录状态 Key */ +export const USER_STATUS_KEY = 'userStatus'; + +/** 用户角色 Key */ +export const USER_ROLE_KEY = 'userRole'; + +/** 语言设置 Key(与现有项目保持一致) */ +export const LANG_KEY = 'arco-lang'; + +/** 主题设置 Key(与现有项目保持一致) */ +export const THEME_KEY = 'arco-theme'; + +// ==================== 用户角色常量 ==================== + +/** 管理员角色 */ +export const ROLE_ADMIN = 'ADMIN'; + +/** 普通用户角色 */ +export const ROLE_USER = 'USER'; + +// ==================== 用户状态常量 ==================== + +/** 用户状态 - 禁用 */ +export const USER_STATUS_DISABLED = 0; + +/** 用户状态 - 启用 */ +export const USER_STATUS_ENABLED = 1; + +// ==================== 默认分页配置 ==================== + +/** 默认页码 */ +export const DEFAULT_PAGE = 1; + +/** 默认每页条数 */ +export const DEFAULT_PAGE_SIZE = 10; + +/** 每页条数选项 */ +export const PAGE_SIZE_OPTIONS = [10, 20, 50, 100]; diff --git a/src/settings.json b/src/settings.json index 340491d..f77f8bd 100644 --- a/src/settings.json +++ b/src/settings.json @@ -3,6 +3,6 @@ "navbar": true, "menu": true, "footer": false, - "themeColor": "#4834D4", + "themeColor": "#005cb8", "menuWidth": 220 } diff --git a/src/types/api.ts b/src/types/api.ts new file mode 100644 index 0000000..b1f6d4b --- /dev/null +++ b/src/types/api.ts @@ -0,0 +1,111 @@ +/** + * API 通用类型定义 + * @description 定义后端 API 的通用数据结构类型 + */ + +// ==================== 通用响应类型 ==================== + +/** + * 统一响应格式 + * @template T - 响应数据类型 + */ +export interface R { + /** 响应码:'0'-成功,'1'-失败,其他-业务错误码(兼容后端返回字符串或数字) */ + code: string | number; + /** 响应消息 */ + msg: string; + /** 响应数据 */ + data: T; + /** 时间戳 */ + timestamp?: number; +} + +/** + * 分页响应格式 + * @template T - 列表数据项类型 + */ +export interface PageResp { + /** 数据列表 */ + list: T[]; + /** 总记录数 */ + total: number; + /** 每页条数 */ + size?: number; + /** 当前页码 */ + current?: number; + /** 总页数 */ + pages?: number; +} + +// ==================== 分页查询参数 ==================== + +/** + * 分页查询参数 + */ +export interface PageQuery { + /** 当前页码(从 1 开始)*/ + current?: number; + /** 每页条数 */ + size?: number; + /** 排序字段,格式:字段名,排序方向(如:createTime,desc) */ + sort?: string; +} + +// ==================== HTTP 错误响应 ==================== + +/** + * HTTP 错误响应 + */ +export interface HttpError { + /** HTTP 状态码 */ + status: number; + /** 错误消息 */ + message: string; + /** 错误详情 */ + error?: any; +} + +// ==================== 请求配置扩展 ==================== + +/** + * 自定义请求配置 + */ +export interface RequestConfig { + /** 是否显示加载提示 */ + showLoading?: boolean; + /** 是否显示成功提示 */ + showSuccessMsg?: boolean; + /** 是否显示错误提示 */ + showErrorMsg?: boolean; + /** 自定义成功提示消息 */ + successMsg?: string; + /** 自定义错误提示消息 */ + errorMsg?: string; + /** 是否需要认证(默认 true) */ + requireAuth?: boolean; +} + +// ==================== 类型守卫函数 ==================== + +/** + * 判断响应是否成功 + * @param response - 响应对象 + * @returns 是否成功 + */ +export function isSuccessResponse(response: R): boolean { + return response.code == 0; // 使用宽松相等,兼容字符串和数字 +} + +/** + * 判断是否为分页响应 + * @param data - 响应数据 + * @returns 是否为分页响应 + */ +export function isPageResponse(data: any): data is PageResp { + return ( + data !== null && + typeof data === 'object' && + Array.isArray(data.list) && + typeof data.total === 'number' + ); +} diff --git a/src/types/auth.ts b/src/types/auth.ts new file mode 100644 index 0000000..486e3a3 --- /dev/null +++ b/src/types/auth.ts @@ -0,0 +1,140 @@ +/** + * 认证相关类型定义 + * @description 定义登录、注册、用户信息等认证相关的数据类型 + */ + +// ==================== 登录相关 ==================== + +/** + * 登录请求参数 + */ +export interface LoginReq { + /** 账号(用户名/邮箱/手机号) */ + account: string; + /** 密码 */ + password: string; +} + +/** + * 登录响应数据 + */ +export interface LoginResp { + /** 访问令牌(需存储并在后续请求中携带) */ + token: string; + /** 用户ID */ + userId: number; + /** 用户名 */ + username: string; + /** 昵称 */ + nickname: string; + /** 角色(ADMIN-管理员, USER-普通用户) */ + role: string; + /** 头像地址 */ + avatar?: string; +} + +// ==================== 注册相关 ==================== + +/** + * 注册请求参数 + */ +export interface RegisterReq { + /** 用户名(4-20位字母、数字或下划线) */ + username: string; + /** 密码(8-20位,包含大小写字母和数字) */ + password: string; + /** 确认密码 */ + confirmPassword: string; + /** 邮箱 */ + email: string; + /** 手机号(11位) */ + phone: string; + /** 昵称 */ + nickname: string; +} + +// ==================== 用户信息相关 ==================== + +/** + * 用户信息响应 + */ +export interface UserInfoResp { + /** 用户ID */ + id: number; + /** 用户名 */ + username: string; + /** 昵称 */ + nickname: string; + /** 角色(ADMIN-管理员, USER-普通用户) */ + role: string; + /** 邮箱 */ + email?: string; + /** 手机号 */ + phone?: string; + /** 头像地址 */ + avatar?: string; + /** 状态(0-禁用, 1-启用) */ + status: number; + /** 创建时间 */ + createTime?: string; +} + +// ==================== 本地存储的用户信息 ==================== + +/** + * 本地存储的用户信息(简化版,用于 localStorage) + */ +export interface LocalUserInfo { + /** 用户ID */ + userId: number; + /** 用户名 */ + username: string; + /** 昵称 */ + nickname: string; + /** 角色 */ + role: string; + /** 头像地址 */ + avatar?: string; +} + +// ==================== 用户角色枚举 ==================== + +/** + * 用户角色枚举 + */ +export enum UserRole { + /** 管理员 */ + ADMIN = 'ADMIN', + /** 普通用户 */ + USER = 'USER', +} + +/** + * 用户状态枚举 + */ +export enum UserStatus { + /** 禁用 */ + DISABLED = 0, + /** 启用 */ + ENABLED = 1, +} + +// ==================== 类型守卫函数 ==================== + +/** + * 判断用户是否为管理员 + * @param role - 用户角色 + * @returns 是否为管理员 + */ +export function isAdmin(role: string): boolean { + return role === UserRole.ADMIN; +} + +/** + * 判断用户是否启用 + * @param status - 用户状态 + * @returns 是否启用 + */ +export function isUserEnabled(status: number): boolean { + return status === UserStatus.ENABLED; +} diff --git a/src/types/user.ts b/src/types/user.ts new file mode 100644 index 0000000..59a5342 --- /dev/null +++ b/src/types/user.ts @@ -0,0 +1,214 @@ +/** + * 用户管理相关类型定义 + * @description 定义用户管理(CRUD)相关的数据类型 + */ + +import type { PageQuery } from './api'; + +// ==================== 用户查询参数 ==================== + +/** + * 用户查询条件 + */ +export interface UserQuery extends PageQuery { + /** 用户名(模糊搜索) */ + username?: string; + /** 角色 */ + role?: string; + /** 昵称(模糊搜索) */ + nickname?: string; + /** 邮箱 */ + email?: string; + /** 手机号 */ + phone?: string; + /** 状态(0-禁用, 1-启用) */ + status?: number; +} + +// ==================== 用户响应数据 ==================== + +/** + * 用户响应数据 + */ +export interface UserResp { + /** 用户ID */ + id: number; + /** 用户名 */ + username: string; + /** 角色(ADMIN-管理员, USER-普通用户) */ + role: string; + /** 邮箱 */ + email?: string; + /** 手机号 */ + phone?: string; + /** 昵称 */ + nickname: string; + /** 头像地址 */ + avatar?: string; + /** 状态(0-禁用, 1-启用) */ + status: number; + /** 创建人ID */ + createUser?: number; + /** 创建人名称 */ + createUserString?: string; + /** 创建时间 */ + createTime?: string; + /** 更新时间 */ + updateTime?: string; +} + +// ==================== 用户请求参数 ==================== + +/** + * 用户请求参数(创建/更新用户) + */ +export interface UserReq { + /** 用户名(4-20位字母、数字或下划线) */ + username: string; + /** 角色(ADMIN 或 USER) */ + role: string; + /** 密码(8-20位,包含大小写字母和数字)- 可选,更新时不传则不修改密码 */ + password?: string; + /** 邮箱 */ + email?: string; + /** 手机号(11位) */ + phone?: string; + /** 昵称 */ + nickname: string; + /** 头像地址 */ + avatar?: string; + /** 状态(0-禁用, 1-启用) */ + status?: number; +} + +// ==================== 批量操作参数 ==================== + +/** + * 批量删除请求参数 + */ +export interface BatchDeleteReq { + /** 用户ID列表 */ + ids: number[]; +} + +/** + * 重置密码请求参数 + */ +export interface ResetPasswordReq { + /** 用户ID */ + userId: number; + /** 新密码 */ + newPassword: string; +} + +/** + * 修改个人信息请求参数 + */ +export interface UpdateProfileReq { + /** 昵称 */ + nickname?: string; + /** 邮箱 */ + email?: string; + /** 手机号 */ + phone?: string; + /** 头像地址 */ + avatar?: string; +} + +// ==================== 表单数据类型 ==================== + +/** + * 用户表单数据(用于前端表单组件) + */ +export interface UserFormData { + /** 用户ID(编辑时使用) */ + id?: number; + /** 用户名 */ + username: string; + /** 角色 */ + role: string; + /** 密码(创建时必填,更新时可选) */ + password?: string; + /** 确认密码(创建时必填,更新时可选) */ + confirmPassword?: string; + /** 邮箱 */ + email?: string; + /** 手机号 */ + phone?: string; + /** 昵称 */ + nickname: string; + /** 头像地址 */ + avatar?: string; + /** 状态 */ + status?: number; +} + +// ==================== 用户列表筛选条件 ==================== + +/** + * 用户列表筛选条件(用于前端筛选表单) + */ +export interface UserFilterForm { + /** 用户名 */ + username?: string; + /** 角色 */ + role?: string; + /** 昵称 */ + nickname?: string; + /** 状态 */ + status?: number; + /** 创建时间范围 */ + createTimeRange?: [string, string]; +} + +// ==================== 工具函数 ==================== + +/** + * 将用户响应数据转换为表单数据 + * @param user - 用户响应数据 + * @returns 表单数据 + */ +export function userRespToFormData(user: UserResp): UserFormData { + return { + id: user.id, + username: user.username, + role: user.role, + email: user.email, + phone: user.phone, + nickname: user.nickname, + avatar: user.avatar, + status: user.status, + }; +} + +/** + * 将表单数据转换为用户请求参数 + * @param formData - 表单数据 + * @returns 用户请求参数 + */ +export function formDataToUserReq(formData: UserFormData): UserReq { + const req: UserReq = { + username: formData.username, + role: formData.role, + nickname: formData.nickname, + }; + + // 可选字段 + if (formData.password) { + req.password = formData.password; + } + if (formData.email) { + req.email = formData.email; + } + if (formData.phone) { + req.phone = formData.phone; + } + if (formData.avatar) { + req.avatar = formData.avatar; + } + if (formData.status !== undefined) { + req.status = formData.status; + } + + return req; +}