import type { RoleSummary, UserDetail, UserSummary } from '@lingxi/shared'; import type { Prisma, Role, UserStatus as PrismaUserStatus } from '@prisma/client'; /** 用户列表 / 详情需要的关联数据(部门含父级、角色) */ export type UserWithRelations = Prisma.UserGetPayload<{ include: { department: { include: { parent: true } }; roles: { include: { role: true } }; }; }>; export function iso(value: Date): string { return value.toISOString(); } export function isoOrNull(value: Date | null): string | null { return value === null ? null : value.toISOString(); } /** 手机号脱敏:138****2046;全号只在具备 user:manage 时由详情接口附带 */ export function maskPhone(phone: string): string { return `${phone.slice(0, 3)}****${phone.slice(7)}`; } export function toRoleSummary(role: Role): RoleSummary { return { id: role.id, code: role.code, name: role.name, isSystem: role.isSystem, ...(role.description.length > 0 ? { description: role.description } : {}), }; } export function toApiStatus(status: PrismaUserStatus): UserSummary['status'] { return status === 'ACTIVE' ? 'active' : 'disabled'; } function departmentFields( user: UserWithRelations, ): Pick { const leaf = user.department; const parent = leaf.parent; if (leaf.parentId !== null && parent !== null) { return { departmentId: parent.id, departmentName: parent.name, groupId: leaf.id, groupName: leaf.name, }; } return { departmentId: leaf.id, departmentName: leaf.name, groupId: null, groupName: null, }; } export function toUserSummary(user: UserWithRelations): UserSummary { return { id: user.id, name: user.name, phoneMasked: maskPhone(user.phone), account: user.account, ...departmentFields(user), roles: user.roles .filter((item) => item.role.status === 'ACTIVE') .map((item) => toRoleSummary(item.role)), status: toApiStatus(user.status), lastLoginAt: isoOrNull(user.lastLoginAt), createdAt: iso(user.createdAt), }; } /** 详情:phone 全号仅调用方具备 user:manage 时返回(契约铁律) */ export function toUserDetail(user: UserWithRelations, canSeePhone: boolean): UserDetail { return { ...toUserSummary(user), ...(canSeePhone ? { phone: user.phone } : {}), mustChangePassword: user.mustChangePassword, updatedAt: iso(user.updatedAt), lastLoginIp: user.lastLoginIp, disabledAt: isoOrNull(user.disabledAt), }; }