import { createApiClient } from "../lib/apiClient"; import { normalizeRoleFromApi, type PagedResultDto, type RoleDto, type RoleGetListInput } from "../types/role"; const api = createApiClient({ getToken: () => { try { return localStorage.getItem("access_token") ?? localStorage.getItem("token") ?? null; } catch { return null; } }, }); const PATH = "/rbac-role"; export type RbacRoleUpsertInput = { roleName: string; roleCode: string; remark?: string | null; dataScope?: number | null; state: boolean; orderNum?: number | null; /** 访问权限编码(与表单一致) */ accessPermissionCodes?: string[] | null; /** 与 `accessPermissionCodes` 同源,提交时合并为 `accessPermissions` */ accessPermissions?: string[] | null; }; function mergeUpsertAccessPermissions(input: RbacRoleUpsertInput): string[] { const merged = [...(input.accessPermissionCodes ?? []), ...(input.accessPermissions ?? [])]; const seen = new Set(); const out: string[] = []; for (const x of merged) { if (typeof x !== "string") continue; const t = x.trim(); if (!t || seen.has(t)) continue; seen.add(t); out.push(t); } return out; } /** 创建/更新请求体:`accessPermissions` 为 JSON 数组字符串 */ function buildRbacRoleRequestBody(input: RbacRoleUpsertInput): Record { const codes = mergeUpsertAccessPermissions(input); return { roleName: input.roleName, roleCode: input.roleCode, remark: input.remark ?? null, dataScope: input.dataScope ?? 0, state: input.state, orderNum: input.orderNum ?? null, accessPermissions: codes.length > 0 ? JSON.stringify(codes) : null, }; } /** * 角色分页列表(与创建/更新同一套 `/rbac-role` 数据源) */ export async function getRbacRoles( input: RoleGetListInput, signal?: AbortSignal, ): Promise> { const raw = await api.requestJson>>({ path: PATH, method: "GET", query: { SkipCount: input.skipCount, MaxResultCount: input.maxResultCount, RoleName: input.roleName, RoleCode: input.roleCode, State: input.state, }, signal, }); const itemsRaw = raw.items ?? (raw as { Items?: unknown[] }).Items ?? []; const items = (Array.isArray(itemsRaw) ? itemsRaw : []).map((x) => normalizeRoleFromApi(x as Record), ); const total = typeof raw.totalCount === "number" ? raw.totalCount : typeof (raw as { TotalCount?: number }).TotalCount === "number" ? (raw as { TotalCount: number }).TotalCount : items.length; return { totalCount: total, items }; } export async function createRbacRole(input: RbacRoleUpsertInput): Promise { const raw = await api.requestJson({ path: PATH, method: "POST", body: buildRbacRoleRequestBody(input), }); return normalizeRoleFromApi(raw); } export async function updateRbacRole(id: string, input: RbacRoleUpsertInput): Promise { const raw = await api.requestJson({ path: `${PATH}/${encodeURIComponent(id)}`, method: "PUT", body: buildRbacRoleRequestBody(input), }); return normalizeRoleFromApi(raw); } function extractMenuIdsFromRoleDetail(raw: unknown): string[] { if (!raw || typeof raw !== "object") return []; const r = raw as Record; // 常见命名:menuIds / MenuIds const direct = Array.isArray(r.menuIds) ? r.menuIds : Array.isArray((r as any).MenuIds) ? (r as any).MenuIds : undefined; if (direct) return (direct as unknown[]).map(String); // 包一层:{ data: { menuIds } } const data = (r as any).data ?? (r as any).Data; if (data && typeof data === "object") { const dd = data as Record; const fromData = Array.isArray(dd.menuIds) ? dd.menuIds : Array.isArray(dd.MenuIds) ? dd.MenuIds : undefined; if (fromData) return (fromData as unknown[]).map(String); } // 可能是 roleMenus: [{ menuId: '...' }] 之类 const roleMenus = Array.isArray((r as any).roleMenus) ? (r as any).roleMenus : Array.isArray((r as any).RoleMenus) ? (r as any).RoleMenus : undefined; if (Array.isArray(roleMenus)) { const ids: string[] = []; for (const x of roleMenus) { if (!x || typeof x !== "object") continue; const rr = x as Record; const mid = rr.menuId ?? rr.MenuId ?? rr.id ?? rr.Id; if (mid) ids.push(String(mid)); } return ids; } return []; } /** * Swagger(常见约定):DELETE /api/app/rbac-role,Body 为 ID 数组 */ export async function deleteRbacRoles(ids: string[]): Promise { if (!ids.length) return; await api.requestJson({ path: PATH, method: "DELETE", body: ids, }); } export async function deleteRbacRole(id: string): Promise { await deleteRbacRoles([id]); } /** * Swagger: GET /api/app/rbac-role/{id} * 用于“查看当前角色菜单权限”,尽量从返回对象里提取 menuIds 字段。 */ export async function getRbacRoleMenuIds(roleId: string, signal?: AbortSignal): Promise { const raw = await api.requestJson({ path: `${PATH}/${encodeURIComponent(roleId)}`, method: "GET", signal, }); return extractMenuIdsFromRoleDetail(raw); }