refactor: 重构项目接口与API调用体系,统一类型管理

1.  合并拆分的API类型定义到统一的api/interface.ts文件
2.  删除旧的api/client.ts与api/types.ts文件
3.  重构所有页面与组件的API调用方式,统一使用api/index.ts导出的接口
4.  调整组件文件结构,将分散的组件按模块整理
5.  统一类型导入路径,移除冗余的类型重复定义
This commit is contained in:
2026-07-02 14:57:06 +08:00
parent e160476ecf
commit 3451d373bc
54 changed files with 1106 additions and 930 deletions

View File

@@ -0,0 +1,136 @@
import { useMemo } from "react";
import { Tree } from "@arco-design/web-react";
import type { Permission, PermissionModuleConfig, PermissionTreeNode, PermissionTreePickerProps } from "../interface";
const systemPermissionModules: PermissionModuleConfig[] = [
{ prefix: "permission", title: "权限管理", subject: "权限" },
{ prefix: "role", title: "角色管理", subject: "角色" },
{ prefix: "admin-user", title: "人员管理", subject: "人员" },
{ prefix: "user", title: "用户管理", subject: "用户" },
{ prefix: "log", title: "日志管理", subject: "日志" },
];
const businessPermissionModules: PermissionModuleConfig[] = [
{ prefix: "drama", title: "短剧管理", subject: "短剧" },
{ prefix: "episode", title: "剧集管理", subject: "剧集" },
{ prefix: "media", title: "媒体管理", subject: "媒体" },
{ prefix: "payment", title: "支付管理", subject: "支付" },
];
const actionNames: Record<string, string> = {
read: "查看",
create: "创建",
update: "更新",
delete: "删除",
manage: "管理",
};
function permissionKey(id: number) {
return `permission:${id}`;
}
function permissionIdFromKey(key: string) {
const id = Number(key.replace("permission:", ""));
return Number.isInteger(id) ? id : null;
}
function getPermissionPrefix(code: string) {
return code.split(":")[0];
}
function getPermissionAction(code: string) {
return code.split(":")[1] || code;
}
function getPermissionTitle(permission: Permission, module?: PermissionModuleConfig) {
return permission.name || (module ? `${actionNames[getPermissionAction(permission.code)]}${module.subject}` : permission.code);
}
function buildPermissionModuleNode(permissions: Permission[], module: PermissionModuleConfig): PermissionTreeNode | null {
const children = permissions
.filter((permission) => getPermissionPrefix(permission.code) === module.prefix)
.map((permission) => ({
key: permissionKey(permission.id),
title: getPermissionTitle(permission, module),
}));
if (!children.length) {
return null;
}
return {
key: `module:${module.prefix}`,
title: module.title,
children,
};
}
function buildPermissionTree(permissions: Permission[]): PermissionTreeNode[] {
const knownPrefixes = new Set([
...systemPermissionModules.map((module) => module.prefix),
...businessPermissionModules.map((module) => module.prefix),
]);
const systemChildren = systemPermissionModules
.map((module) => buildPermissionModuleNode(permissions, module))
.filter((node): node is PermissionTreeNode => Boolean(node));
const businessChildren = businessPermissionModules
.map((module) => buildPermissionModuleNode(permissions, module))
.filter((node): node is PermissionTreeNode => Boolean(node));
const otherPermissions = permissions
.filter((permission) => !knownPrefixes.has(getPermissionPrefix(permission.code)))
.map((permission) => ({
key: permissionKey(permission.id),
title: permission.name,
}));
if (otherPermissions.length) {
businessChildren.push({
key: "module:other",
title: "其他权限",
children: otherPermissions,
});
}
return [
{ key: "group:system", title: "系统权限", children: systemChildren },
{ key: "group:business", title: "业务权限", children: businessChildren },
];
}
function collectExpandedKeys(nodes: PermissionTreeNode[]) {
const keys: string[] = [];
const visit = (items: PermissionTreeNode[]) => {
items.forEach((item) => {
if (item.children?.length) {
keys.push(item.key);
visit(item.children);
}
});
};
visit(nodes);
return keys;
}
export function PermissionTreePicker({ permissions, value, onChange }: PermissionTreePickerProps) {
const treeData = useMemo(() => buildPermissionTree(permissions), [permissions]);
const expandedKeys = useMemo(() => collectExpandedKeys(treeData), [treeData]);
const checkedKeys = value.map((id) => permissionKey(id));
return (
<div className="mb-[15px] h-[360px] overflow-auto rounded-md border border-line bg-panel px-4 py-3">
<Tree
blockNode
checkable
checkedStrategy="child"
checkedKeys={checkedKeys}
defaultExpandedKeys={expandedKeys}
selectable={false}
showLine
treeData={treeData}
onCheck={(keys) => {
onChange(keys.map((key) => permissionIdFromKey(key)).filter((id): id is number => id !== null));
}}
/>
</div>
);
}