占位数据源 src/api/user.ts(字段对齐后端 User),页面跑通 CRUD 模式,后续接后端只换数据源。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
140 lines
4.0 KiB
TypeScript
140 lines
4.0 KiB
TypeScript
/**
|
||
* 用户管理数据源。
|
||
* 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<UserListResult> {
|
||
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<User> {
|
||
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<UserUpsertData>): Promise<User> {
|
||
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<null> {
|
||
mockUsers = mockUsers.filter((u) => u.id !== id)
|
||
return null
|
||
}
|
||
|
||
export async function resetPassword(_id: string, _password: string): Promise<null> {
|
||
// mock:无真实密码存储,仅占位
|
||
return null
|
||
}
|