refactor: 重命名 CRUD 组件为 Crud 并简化字典标签类型

- CURD 组件 PageModal、PageSearch、PageContent、usePage 重命名为 CrudModal、CrudSearch、CrudTable、useCrudPage
- 字典项标签类型改用 primary/success/warning/danger/info,保留历史单字母值兼容读取
- 字典项页面拆分为独立子组件,移除 GithubCorner 组件
- 新增 icon 工具与 screen 样式
- 新增路由缓存、路由跳转、大屏与表格 CRUD 示例页
This commit is contained in:
Ray.Hao
2026-09-25 21:10:54 +08:00
parent 3ccbdb7c06
commit 89d45da839
224 changed files with 7926 additions and 3052 deletions

View File

@@ -1,6 +1,9 @@
import type { App } from "vue";
import { createRouter, createWebHashHistory, type RouteRecordRaw } from "vue-router";
/**
* 布局组件,供各路由复用(懒加载)
*/
export const Layout = () => import("@/layouts/index.vue");
// 静态路由
@@ -78,6 +81,12 @@ export const constantRoutes: RouteRecordRaw[] = [
component: () => import("@/views/demo/route/detail.vue"),
meta: { title: "详情页缓存", icon: "user", hidden: true, keepAlive: true },
},
{
path: "/route-example/edit/:id(\\d+)",
name: "RouteExampleEdit",
component: () => import("@/views/demo/route/navigate/edit.vue"),
meta: { title: "跳转编辑页", icon: "user", hidden: true },
},
],
},
];
@@ -92,7 +101,9 @@ const router = createRouter({
scrollBehavior: () => ({ left: 0, top: 0 }),
});
// 全局注册 router
/**
* 全局注册 router
*/
export function setupRouter(app: App<Element>) {
app.use(router);
}

View File

@@ -1,16 +1,17 @@
/**
* 视图组件注册表
*
* 维护「菜单 component 字符串 → src/views 视图文件」的映射,路由注册与菜单表单共用。
* 表单的「页面路径」选项树也由此派生:跳过错误页与页面内部组件,index.vue 归并到目录。
*/
// 视图组件注册表
// 维护「菜单 component 字符串 → src/views 视图文件」的映射,路由注册与菜单表单共用
// 表单的「页面路径」选项树也由此派生:跳过错误页与页面内部组件,index.vue 归并到目录
/** 全部视图模块,键形如 /src/views/system/user/index.vue */
/**
* 全部视图模块,键形如 /src/views/system/user/index.vue
*/
export const viewModules = import.meta.glob("/src/views/**/*.vue");
const VIEW_PREFIX = "/src/views/";
/** 视图文件路径集合,元素形如 system/user/index */
/**
* 视图文件路径集合,元素形如 system/user/index
*/
export const viewPaths = new Set(
Object.keys(viewModules).map((key) => key.slice(VIEW_PREFIX.length).replace(/\.vue$/, ""))
);
@@ -46,7 +47,9 @@ export function isViewComponent(componentPath?: string): boolean {
return viewPaths.has(path) || viewPaths.has(`${path}/index`);
}
/** 选项树节点 */
/**
* 选项树节点
*/
export interface PageComponentNode {
/** 表单取值:真实文件路径,目录无 index.vue 时不可选 */
value?: string;
@@ -55,12 +58,18 @@ export interface PageComponentNode {
disabled?: boolean;
}
/**
* 判断路径是否可以作为页面组件选择项
*/
function isSelectable(path: string): boolean {
const segments = path.split("/");
if (segments.includes("components")) return false;
return segments[0] !== "error" && path !== "redirect";
}
/**
* 把页面路径列表构造成组件树
*/
function buildTree(): PageComponentNode[] {
const tree: PageComponentNode[] = [];
@@ -109,12 +118,17 @@ function markDisabled(nodes: PageComponentNode[]): void {
});
}
/**
* 按名称排序树节点
*/
function sortTree(nodes: PageComponentNode[]): void {
nodes.sort((a, b) => a.label.localeCompare(b.label));
nodes.forEach((node) => node.children && sortTree(node.children));
}
/** 页面组件选项树 */
/**
* 页面组件选项树
*/
export const pageComponentTree = buildTree();
/**