/** 用户角色字段映射(任务 48):行 role/is_admin → 角色域 → 可编辑值/锁定原因,镜像 Java 约束。 */ import { roleKind } from '../../types/admin.ts' /** 后台角色域(与 AdminUserItemVo.role / is_admin 对齐)。 */ export type RoleDomain = 'super_admin' | 'admin' | 'normal' /** 用户角色下拉可选值;super_admin 只能由系统持有,不入下拉。 */ export type EditableRole = 'admin' | 'normal' export interface UserRoleOption { value: EditableRole label: string } /** 编辑/创建表单角色下拉候选(镜像后端 admin|normal 白名单)。 */ export const USER_ROLE_OPTIONS: readonly UserRoleOption[] = [ { value: 'admin', label: '管理员' }, { value: 'normal', label: '普通用户' }, ] const ROLE_DOMAIN_LABELS: Record = { super_admin: '超级管理员', admin: '管理员', normal: '普通用户', } /** 行字段 → 角色域:优先 role;为空时按 is_admin 布尔推断(1=管理员);未知归 normal。 */ export function roleDomainOf(row: { role?: string | null; isAdmin?: boolean }): RoleDomain { const kind = roleKind(row?.role) if (kind === 'super_admin' || kind === 'admin' || kind === 'normal') return kind return row?.isAdmin ? 'admin' : 'normal' } /** 行 → 可编辑角色值:超级管理员返回 null(不可编辑),其余返回 admin/normal。 */ export function selectRoleOf(row: { role?: string | null; isAdmin?: boolean }): EditableRole | null { const domain = roleDomainOf(row) return domain === 'super_admin' ? null : domain } /** 角色域展示文案。 */ export function roleDomainLabel(domain: RoleDomain): string { return ROLE_DOMAIN_LABELS[domain] || '' } /** * 角色下拉锁定原因:目标为超管、或操作者非超管(镜像后端:admin 编辑时强制不调角色、 * super_admin 不可改)。无锁定时返回 undefined。 */ export function userRoleLockMessage( operatorRole: string | null | undefined, target: { role?: string | null; isAdmin?: boolean }, ): string | undefined { if (roleDomainOf(target) === 'super_admin') return '不能修改超级管理员' if (roleKind(operatorRole) !== 'super_admin') return '仅超级管理员可调整角色' return undefined }