/** * 用户管理数据源。 * TODO: 对接后端后,把下面 mock 实现替换为 http 调用(字段与返回形状保持不变)。 * 后端 User 实体字段:id/tenantCode/username/nickname/email/phone/status/orgCode/createdAt */ export type UserStatus = 'enabled' | 'disabled' | 'locked' export interface User { id: string tenantCode: string username: string nickname: string | null email: string | null phone: string | null status: UserStatus orgCode: string | null createdAt: number } export interface UserListQuery { page: number pageSize: number username?: string nickname?: string phone?: string status?: UserStatus | '' } export interface UserListResult { list: User[] total: number page: number pageSize: number } export interface UserUpsertData { username: string nickname?: string email?: string phone?: string status?: UserStatus orgCode?: string | null password?: string } /** 占位组织(后续接后端换真实组织数据)。 */ export const mockOrgs: { code: string; name: string }[] = [ { code: 'touyun', name: '投云总部' }, { code: 'rd', name: '研发部' }, { code: 'ops', name: '运维部' }, { code: 'sales', name: '销售部' }, ] const now = Date.now() const day = 24 * 60 * 60 * 1000 function mockUser(id: string, username: string, nickname: string, orgCode: string, status: UserStatus, daysAgo: number): User { return { id, tenantCode: 'touyun', username, nickname, email: `${username}@example.com`, phone: `1380000${String(1000 + Number(id)).slice(-4)}`, status, orgCode, createdAt: now - daysAgo * day, } } let mockUsers: User[] = [ mockUser('1', 'touyun', '超级管理员', 'touyun', 'enabled', 30), mockUser('2', 'zhangsan', '张三', 'rd', 'enabled', 20), mockUser('3', 'lisi', '李四', 'rd', 'disabled', 18), mockUser('4', 'wangwu', '王五', 'ops', 'locked', 15), mockUser('5', 'zhaoliu', '赵六', 'sales', 'enabled', 12), mockUser('6', 'sunqi', '孙七', 'ops', 'enabled', 9), mockUser('7', 'zhouba', '周八', 'rd', 'enabled', 7), mockUser('8', 'wujiu', '吴九', 'sales', 'disabled', 5), mockUser('9', 'zhengshi', '郑十', 'rd', 'enabled', 3), mockUser('10', 'chenyi', '陈一', 'sales', 'enabled', 1), ] function uuid(): string { return crypto.randomUUID() } export function orgName(code: string | null): string { if (!code) return '-' return mockOrgs.find((o) => o.code === code)?.name ?? code } export async function listUsers(query: UserListQuery): Promise { const { page, pageSize, username, nickname, phone, status } = query const filtered = mockUsers.filter((u) => { if (username && !u.username.includes(username)) return false if (nickname && !(u.nickname ?? '').includes(nickname)) return false if (phone && !(u.phone ?? '').includes(phone)) return false if (status && u.status !== status) return false return true }) const total = filtered.length const start = (page - 1) * pageSize return { list: filtered.slice(start, start + pageSize), total, page, pageSize } } export async function createUser(data: UserUpsertData): Promise { const user: User = { id: uuid(), tenantCode: 'touyun', username: data.username, nickname: data.nickname ?? null, email: data.email ?? null, phone: data.phone ?? null, status: data.status ?? 'enabled', orgCode: data.orgCode ?? null, createdAt: Date.now(), } mockUsers.unshift(user) return user } export async function updateUser(id: string, data: Partial): Promise { const user = mockUsers.find((u) => u.id === id) if (!user) throw new Error('用户不存在') Object.assign(user, data) return user } export async function deleteUser(id: string): Promise { mockUsers = mockUsers.filter((u) => u.id !== id) return null } export async function resetPassword(_id: string, _password: string): Promise { // mock:无真实密码存储,仅占位 return null }