@gadmin2n/cli 0.0.81 → 0.0.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.yalc/@gadmin2n/schematics/LICENSE +21 -0
- package/.yalc/@gadmin2n/schematics/README.md +9 -0
- package/.yalc/@gadmin2n/schematics/dist/collection.json +122 -0
- package/.yalc/@gadmin2n/schematics/dist/index.d.ts +2 -0
- package/.yalc/@gadmin2n/schematics/dist/index.js +18 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/application.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/application.factory.js +92 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/.dockerignore +33 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/Dockerfile +63 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/Jenkinsfile +70 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/config/.types.d.ts +143 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/default-schema.prisma +46 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/config/prisma/page.prisma +116 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/readme.md +49 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/server/.env +31 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/server/.env.local +1 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/server/.prettierignore +1 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/server/README.md +55 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/server/gadmin-cli.json +17 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/server/migrate-between-pg-schemas.js +1232 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/server/package.json +141 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/server/prisma/.generator.prisma +34 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/server/start-prod.sh +130 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/server/test/jest-e2e.json +9 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/server/tsconfig.build.json +4 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/README.MD +48 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/index.html +19 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/package.json +81 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/postcss.config.cjs +6 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/public/favicon.ico +0 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/public/images/flags/en.svg +1 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/public/images/flags/zh_CN.svg +11 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/App.tsx +111 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/BulkActions.tsx +236 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/ListPageHeader.tsx +56 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/RowActions.tsx +292 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/SearchBar.tsx +294 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/VanillaJSONEditor/index.css +10 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/VanillaJSONEditor/index.jsx +53 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/AgentContext.tsx +201 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/AgentPanel.tsx +497 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/agentPanel/ElementInspector.tsx +282 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/auditLog/components/eventList/index.tsx +62 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/auditLog/components/logButton/index.tsx +96 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/auditLog/components/logList/index.tsx +73 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/auditLog/components/modalDiffViewer/index.tsx +104 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/auditLog/index.tsx +2 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/contexts/business/index.tsx +65 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/contexts/color-mode/index.tsx +58 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/custom-avatar.tsx +38 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/header.tsx +121 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/layout.tsx +32 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/logo.tsx +19 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/sider.tsx +383 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/layout/title.tsx +61 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/offLayoutArea/index.tsx +5 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/pagination-total.tsx +21 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/tags/role-tag.tsx +44 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/components/text.tsx +74 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/config/routeRegistry.tsx +175 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/form.tsx +421 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/index.tsx +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/list.tsx +465 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/helpers/show.tsx +182 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/hooks/useDynamicResources.tsx +211 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/index.tsx +20 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/en/common.json +128 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/locales/zh_CN/common.json +130 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/meta.json +4 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/components/action-cell.css +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/components/action-cell.tsx +134 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/create.tsx +113 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/edit.tsx +122 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/index.tsx +6 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/list.tsx +213 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/audit/show.tsx +61 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/AssignRolesModal.tsx +168 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/CreatePageModal.tsx +42 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/EditPageModal.tsx +42 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/PageDetailDrawer.tsx +101 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/Components/PageFormModal.tsx +731 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/create.tsx +113 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/edit.tsx +122 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/index.tsx +6 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/list.tsx +1113 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/page/show.tsx +61 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/pageResource/create.tsx +113 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/pageResource/edit.tsx +122 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/pageResource/index.tsx +6 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/pageResource/list.tsx +243 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/pageResource/show.tsx +61 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/permission-readme/index.tsx +1088 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/CreateModal.tsx +25 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/EditModal.tsx +28 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/ResourceDetailDrawer.tsx +160 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/Components/modal.tsx +202 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/create.tsx +113 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/edit.tsx +122 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/index.tsx +6 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/list.tsx +184 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/resource/show.tsx +61 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/CreateModal.tsx +30 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/EditModal.tsx +47 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/RoleDetailDrawer.tsx +56 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/Components/modal.tsx +302 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/create.tsx +113 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/edit.tsx +122 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/index.tsx +6 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/list.tsx +382 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/role/show.tsx +61 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/rolePages/create.tsx +113 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/rolePages/edit.tsx +122 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/rolePages/index.tsx +6 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/rolePages/list.tsx +243 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/rolePages/show.tsx +61 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/roleResource/create.tsx +113 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/roleResource/edit.tsx +122 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/roleResource/index.tsx +6 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/roleResource/list.tsx +243 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/roleResource/show.tsx +61 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/create-modal.tsx +17 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/edit-modal.tsx +19 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/form-modal.tsx +188 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/role-tag.tsx +48 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/components/show-drawer.tsx +140 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/create.tsx +113 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/edit.tsx +122 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/index.tsx +6 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/list.tsx +342 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/routes/user/show.tsx +61 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/antd.css +132 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/fc.css +58 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/index.css +128 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/show-drawer.module.css +18 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/styles/show-page.module.css +21 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/utilities/utils.tsx +5 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/files/gadmin2-game-angle-demo/web/src/vite-env.d.ts +1 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/application/schema.json +99 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/class/class.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/class/class.factory.js +42 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/class/files/js/__name__.js +1 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/class/files/js/__name__.spec.js +7 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/class/schema.json +45 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/client-app/angular/angular.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/client-app/angular/angular.factory.js +98 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/client-app/angular/schema.json +24 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/configuration/configuration.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/configuration/configuration.factory.js +24 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/configuration/files/js/nest-cli.json +6 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/configuration/files/ts/nest-cli.json +5 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/controller/controller.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/controller/controller.factory.js +118 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/controller/files/js/__name__.controller.js +4 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/controller/files/js/__name__.controller.spec.js +18 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/controller/schema.json +51 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/decorator/decorator.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/decorator/decorator.factory.js +33 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/decorator/files/js/__name__.decorator.js +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/decorator/schema.json +36 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/defaults.d.ts +16 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/defaults.js +19 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/filter/files/js/__name__.filter.js +6 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/filter/files/js/__name__.filter.spec.js +7 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/filter/filter.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/filter/filter.factory.js +34 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/filter/schema.json +41 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/gateway/files/js/__name__.gateway.js +9 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/gateway/files/js/__name__.gateway.spec.js +18 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/gateway/gateway.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/gateway/gateway.factory.js +62 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/gateway/schema.json +41 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/guard/files/js/__name__.guard.js +8 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/guard/files/js/__name__.guard.spec.js +7 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/guard/guard.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/guard/guard.factory.js +34 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/guard/schema.json +41 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/interceptor/files/js/__name__.interceptor.js +8 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/interceptor/files/js/__name__.interceptor.spec.js +7 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/interceptor/interceptor.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/interceptor/interceptor.factory.js +116 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/interceptor/schema.json +50 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/interface/interface.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/interface/interface.factory.js +32 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/interface/schema.json +32 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/library/files/js/.babelrc +4 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/library/files/js/jsconfig.json +9 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/library/files/js/src/__name__.module.js +8 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/library/files/js/src/__name__.service.js +4 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/library/files/js/src/__name__.service.spec.js +18 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/library/files/js/src/index.js +2 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/library/files/ts/tsconfig.lib.json +9 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/library/library.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/library/library.factory.js +190 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/library/schema.json +37 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/middleware/files/js/__name__.middleware.js +8 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/middleware/files/js/__name__.middleware.spec.js +7 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/middleware/middleware.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/middleware/middleware.factory.js +34 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/middleware/schema.json +41 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/module/files/js/__name__.module.js +4 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/module/module.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/module/module.factory.js +58 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/module/schema.json +46 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/pipe/files/js/__name__.pipe.js +8 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/pipe/files/js/__name__.pipe.spec.js +7 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/pipe/pipe.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/pipe/pipe.factory.js +34 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/pipe/schema.json +41 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/prisma-resource/prisma-resource.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/prisma-resource/prisma-resource.factory.js +131 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/prisma-resource/schema.json +91 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/provider/files/js/__name__.js +4 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/provider/files/js/__name__.spec.js +18 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/provider/provider.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/provider/provider.factory.js +67 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/provider/schema.json +45 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/resolver/files/js/__name__.resolver.js +4 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/resolver/files/js/__name__.resolver.spec.js +18 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/resolver/resolver.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/resolver/resolver.factory.js +62 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/resolver/schema.json +41 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/resource/files/ts/__name__.graphql +24 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/resource/resource.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/resource/resource.factory.js +131 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/resource/schema.json +90 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/service/files/js/__name__.service.js +4 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/service/files/js/__name__.service.spec.js +18 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/service/schema.json +41 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/service/service.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/service/service.factory.js +63 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/js/.babelrc +4 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/js/index.js +2 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/js/jsconfig.json +10 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/js/src/app.controller.js +15 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/js/src/app.controller.spec.js +22 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/js/src/app.module.js +10 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/js/src/app.service.js +8 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/js/src/main.js +8 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/js/test/app.e2e-spec.js +23 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/js/test/jest-e2e.json +5 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/ts/test/jest-e2e.json +9 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/files/ts/tsconfig.app.json +9 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/schema.json +32 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/sub-app.factory.d.ts +3 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/sub-app.factory.js +245 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/workspace/js/.babelrc +4 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/workspace/js/index.js +2 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/workspace/js/jsconfig.json +10 -0
- package/.yalc/@gadmin2n/schematics/dist/lib/sub-app/workspace/ts/tsconfig.app.json +9 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/change.d.ts +46 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/change.js +95 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/dependencies.utils.d.ts +15 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/dependencies.utils.js +42 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/export-from.declarator.d.ts +10 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/export-from.declarator.js +39 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/formatting.d.ts +1 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/formatting.js +12 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/index.d.ts +9 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/index.js +25 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/json-file.util.d.ts +15 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/json-file.util.js +68 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/metadata.manager.d.ts +13 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/metadata.manager.js +162 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/module-import.declarator.d.ts +10 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/module-import.declarator.js +39 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/module-metadata.declarator.d.ts +4 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/module-metadata.declarator.js +12 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/module.declarator.d.ts +23 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/module.declarator.js +32 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/module.finder.d.ts +13 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/module.finder.js +24 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/name.parser.d.ts +12 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/name.parser.js +17 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/path.solver.d.ts +4 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/path.solver.js +14 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/source-root.helpers.d.ts +8 -0
- package/.yalc/@gadmin2n/schematics/dist/utils/source-root.helpers.js +35 -0
- package/.yalc/@gadmin2n/schematics/package.json +78 -0
- package/.yalc/@gadmin2n/schematics/yalc.sig +1 -0
- package/package.json +2 -2
- package/yalc.lock +10 -0
|
@@ -0,0 +1,1088 @@
|
|
|
1
|
+
import { Alert, Card, Collapse, Divider, Table, Tabs, Typography } from "antd";
|
|
2
|
+
|
|
3
|
+
const { Title, Paragraph, Text } = Typography;
|
|
4
|
+
|
|
5
|
+
// ─── 核心概念 ────────────────────────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
const coreConceptColumns = [
|
|
8
|
+
{ title: "概念", dataIndex: "concept", key: "concept", width: 160 },
|
|
9
|
+
{ title: "数据库表", dataIndex: "table", key: "table", width: 140 },
|
|
10
|
+
{ title: "说明", dataIndex: "description", key: "description" },
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
const coreConceptData = [
|
|
14
|
+
{
|
|
15
|
+
key: "page",
|
|
16
|
+
concept: "Page(页面/菜单)",
|
|
17
|
+
table: "t_page",
|
|
18
|
+
description:
|
|
19
|
+
"定义系统中的所有菜单项,支持树形结构(parentId)。每个 Page 有唯一的 code,对应前端路由注册表中的 key。",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
key: "resource",
|
|
23
|
+
concept: "Resource(资源)",
|
|
24
|
+
table: "t_resource",
|
|
25
|
+
description:
|
|
26
|
+
"定义后端 API 资源,每个资源对应一组 CRUD 权限(readAny, createAny, updateAny, deleteAny)。",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
key: "role",
|
|
30
|
+
concept: "Role(角色)",
|
|
31
|
+
table: "t_role",
|
|
32
|
+
description:
|
|
33
|
+
"角色是权限分配的基本单位。一个用户拥有一个角色,角色决定了可见菜单和 API 权限。",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
key: "role_pages",
|
|
37
|
+
concept: "RolePages(角色-页面)",
|
|
38
|
+
table: "t_role_pages",
|
|
39
|
+
description: "角色与页面的关联表,决定角色可以看到哪些菜单项。",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
key: "role_resource",
|
|
43
|
+
concept: "RoleResource(角色-资源)",
|
|
44
|
+
table: "t_role_resource",
|
|
45
|
+
description:
|
|
46
|
+
"角色与资源的关联表,定义角色对每个资源的具体权限(读/写/改/删)。",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
key: "page_resource",
|
|
50
|
+
concept: "PageResource(页面-资源)",
|
|
51
|
+
table: "t_page_resource",
|
|
52
|
+
description:
|
|
53
|
+
"页面与资源的关联表,记录每个页面需要哪些 API 资源。用于批量为角色分配权限。",
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
// ─── t_page 字段说明 ─────────────────────────────────────────────────────────
|
|
58
|
+
|
|
59
|
+
const pageFieldColumns = [
|
|
60
|
+
{ title: "字段", dataIndex: "field", key: "field", width: 180 },
|
|
61
|
+
{ title: "说明", dataIndex: "description", key: "description" },
|
|
62
|
+
{ title: "示例", dataIndex: "example", key: "example", width: 260 },
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
const pageFieldData = [
|
|
66
|
+
{
|
|
67
|
+
key: "code",
|
|
68
|
+
field: "code",
|
|
69
|
+
description:
|
|
70
|
+
"页面唯一标识,原生页面必须与 routeRegistry 的 key 一致",
|
|
71
|
+
example: "software_dashboard",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
key: "zhName",
|
|
75
|
+
field: "zhName / enName",
|
|
76
|
+
description: "菜单显示的中英文名称",
|
|
77
|
+
example: "软件看板 / Software Dashboard",
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
key: "path",
|
|
81
|
+
field: "path",
|
|
82
|
+
description:
|
|
83
|
+
"URL 完整路径。原生页面会被 routeRegistry 覆盖,iframe/外部链接页面以此作为菜单跳转路径",
|
|
84
|
+
example: "/office/software-dashboard",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
key: "parentId",
|
|
88
|
+
field: "parentId",
|
|
89
|
+
description: "父菜单 ID,用于构建树形菜单结构",
|
|
90
|
+
example: "office 页面的 ID",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
key: "sortOrder",
|
|
94
|
+
field: "sortOrder",
|
|
95
|
+
description: "同级菜单的排序权重,数字越小越靠前",
|
|
96
|
+
example: "10",
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
key: "iframeUrl",
|
|
100
|
+
field: "iframeUrl",
|
|
101
|
+
description:
|
|
102
|
+
"iframe 嵌入地址。设置后页面以 iframe 方式渲染,支持 {{locale}} 模板变量",
|
|
103
|
+
example: "https://analytics.example.com?lang={{locale}}",
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
key: "externalRedirectUrl",
|
|
107
|
+
field: "externalRedirectUrl",
|
|
108
|
+
description:
|
|
109
|
+
"外部跳转地址。设置后点击菜单在新窗口打开目标 URL,支持 {{locale}} 模板变量",
|
|
110
|
+
example: "https://wiki.example.com/page",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
key: "isVirtual",
|
|
114
|
+
field: "isVirtual",
|
|
115
|
+
description: "虚拟页面标记,设为 true 时不在侧边栏显示菜单项",
|
|
116
|
+
example: "false",
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
|
|
120
|
+
// ─── 常见问题 ────────────────────────────────────────────────────────────────
|
|
121
|
+
|
|
122
|
+
const faqItems = [
|
|
123
|
+
{
|
|
124
|
+
key: "1",
|
|
125
|
+
label: "菜单不显示?",
|
|
126
|
+
children: (
|
|
127
|
+
<ol>
|
|
128
|
+
<li>
|
|
129
|
+
检查 <Text code>routeRegistry.tsx</Text> 中是否注册了路由,且 key 与
|
|
130
|
+
t_page 的 code 一致
|
|
131
|
+
</li>
|
|
132
|
+
<li>
|
|
133
|
+
检查 <Text code>t_page</Text>{" "}
|
|
134
|
+
表中是否创建了记录(进入 Page Management 查看)
|
|
135
|
+
</li>
|
|
136
|
+
<li>检查当前用户的角色是否分配了该页面(进入 Role Management 查看)</li>
|
|
137
|
+
<li>
|
|
138
|
+
检查 <Text code>parentId</Text>{" "}
|
|
139
|
+
是否正确——父级页面也需要分配给角色,否则整个子树不可见
|
|
140
|
+
</li>
|
|
141
|
+
</ol>
|
|
142
|
+
),
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
key: "2",
|
|
146
|
+
label: "页面显示空白?",
|
|
147
|
+
children: (
|
|
148
|
+
<ol>
|
|
149
|
+
<li>
|
|
150
|
+
检查 <Text code>routeRegistry.tsx</Text> 中的{" "}
|
|
151
|
+
<Text code>component</Text> 是否正确导入
|
|
152
|
+
</li>
|
|
153
|
+
<li>
|
|
154
|
+
确认页面组件文件已正确导出(export 名称是否与 import 一致)
|
|
155
|
+
</li>
|
|
156
|
+
<li>
|
|
157
|
+
打开浏览器 DevTools Console 查看是否有 JS 加载错误
|
|
158
|
+
</li>
|
|
159
|
+
</ol>
|
|
160
|
+
),
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
key: "3",
|
|
164
|
+
label: "API 返回 403?",
|
|
165
|
+
children: (
|
|
166
|
+
<Paragraph>
|
|
167
|
+
后端权限由 <Text code>t_role_resource</Text> 控制。进入 Role
|
|
168
|
+
Management,检查角色是否分配了对应资源的权限(readAny / createAny /
|
|
169
|
+
updateAny / deleteAny)。注意:前端菜单可见不代表有 API
|
|
170
|
+
权限,两者独立配置。
|
|
171
|
+
</Paragraph>
|
|
172
|
+
),
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
key: "4",
|
|
176
|
+
label: "iframe 页面加载失败?",
|
|
177
|
+
children: (
|
|
178
|
+
<ol>
|
|
179
|
+
<li>
|
|
180
|
+
检查目标网站是否允许被 iframe 嵌入(X-Frame-Options /
|
|
181
|
+
Content-Security-Policy 头)
|
|
182
|
+
</li>
|
|
183
|
+
<li>
|
|
184
|
+
确认 <Text code>iframeUrl</Text> 与{" "}
|
|
185
|
+
<Text code>externalRedirectUrl</Text> 未同时填写(两者互斥)
|
|
186
|
+
</li>
|
|
187
|
+
<li>
|
|
188
|
+
如果目标网站禁止 iframe 嵌入,改用 <Text code>externalRedirectUrl</Text>{" "}
|
|
189
|
+
以新窗口方式打开
|
|
190
|
+
</li>
|
|
191
|
+
</ol>
|
|
192
|
+
),
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
key: "5",
|
|
196
|
+
label: "如何添加子菜单?",
|
|
197
|
+
children: (
|
|
198
|
+
<Paragraph>
|
|
199
|
+
在 <Text code>t_page</Text> 中创建记录时将{" "}
|
|
200
|
+
<Text code>parentId</Text> 设为父菜单的 ID。如果是原生页面,在{" "}
|
|
201
|
+
<Text code>routeRegistry.tsx</Text> 中也需要将路由放入父路由的{" "}
|
|
202
|
+
<Text code>children</Text> 对象中。
|
|
203
|
+
</Paragraph>
|
|
204
|
+
),
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
key: "6",
|
|
208
|
+
label: "{{locale}} 模板变量怎么用?",
|
|
209
|
+
children: (
|
|
210
|
+
<Paragraph>
|
|
211
|
+
在 <Text code>iframeUrl</Text> 或{" "}
|
|
212
|
+
<Text code>externalRedirectUrl</Text> 中使用{" "}
|
|
213
|
+
<Text code>{"{{locale}}"}</Text>,系统会在运行时自动替换为当前语言(
|
|
214
|
+
<Text code>en</Text> 或 <Text code>zh</Text>)。例如:
|
|
215
|
+
<Text code>
|
|
216
|
+
https://example.com/docs?lang={"{{locale}}"}
|
|
217
|
+
</Text>
|
|
218
|
+
</Paragraph>
|
|
219
|
+
),
|
|
220
|
+
},
|
|
221
|
+
];
|
|
222
|
+
|
|
223
|
+
// ─── 原生页面注册步骤 ────────────────────────────────────────────────────────
|
|
224
|
+
|
|
225
|
+
const nativeStepColumns = [
|
|
226
|
+
{ title: "步骤", dataIndex: "step", key: "step", width: 80 },
|
|
227
|
+
{ title: "操作", dataIndex: "action", key: "action", width: 200 },
|
|
228
|
+
{ title: "说明", dataIndex: "detail", key: "detail" },
|
|
229
|
+
];
|
|
230
|
+
|
|
231
|
+
const nativeStepData = [
|
|
232
|
+
{
|
|
233
|
+
key: "1",
|
|
234
|
+
step: "1",
|
|
235
|
+
action: "创建页面组件",
|
|
236
|
+
detail:
|
|
237
|
+
"在 src/routes/ 下创建页面组件文件,如 src/routes/office/my-feature/index.tsx,导出页面组件。",
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
key: "2",
|
|
241
|
+
step: "2",
|
|
242
|
+
action: "在 routeRegistry 注册路由",
|
|
243
|
+
detail:
|
|
244
|
+
"在 src/config/routeRegistry.tsx 中添加路由条目。key 即为 page code,配置 path(相对路径)和 component(lazy import)。如有子路由放入 children。",
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
key: "3",
|
|
248
|
+
step: "3",
|
|
249
|
+
action: "在 Page Management 创建记录",
|
|
250
|
+
detail:
|
|
251
|
+
"进入 /admin/permission/page-list,新建页面。code 必须与 routeRegistry 中的 key 完全一致,设置 parentId 为父菜单 ID。",
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
key: "4",
|
|
255
|
+
step: "4",
|
|
256
|
+
action: "关联资源(可选)",
|
|
257
|
+
detail:
|
|
258
|
+
"如果页面需要 API 权限控制,在页面记录中关联对应的 Resource,用于后续批量分配权限。",
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
key: "5",
|
|
262
|
+
step: "5",
|
|
263
|
+
action: "为角色分配页面",
|
|
264
|
+
detail:
|
|
265
|
+
"进入 /admin/permission/role-list,编辑目标角色,勾选新添加的页面。",
|
|
266
|
+
},
|
|
267
|
+
];
|
|
268
|
+
|
|
269
|
+
// ─── 对比表 ──────────────────────────────────────────────────────────────────
|
|
270
|
+
|
|
271
|
+
const comparisonColumns = [
|
|
272
|
+
{ title: "", dataIndex: "item", key: "item", width: 160 },
|
|
273
|
+
{ title: "原生页面", dataIndex: "native", key: "native" },
|
|
274
|
+
{ title: "外部链接", dataIndex: "external", key: "external" },
|
|
275
|
+
{ title: "iframe 嵌入", dataIndex: "iframe", key: "iframe" },
|
|
276
|
+
{ title: "动态菜单", dataIndex: "dynamic", key: "dynamic" },
|
|
277
|
+
];
|
|
278
|
+
|
|
279
|
+
const comparisonData = [
|
|
280
|
+
{
|
|
281
|
+
key: "scene",
|
|
282
|
+
item: "适用场景",
|
|
283
|
+
native: "内部开发的完整功能页面",
|
|
284
|
+
external: "跳转到外部系统(Wiki、文档等)",
|
|
285
|
+
iframe: "在应用内嵌入外部页面(报表等)",
|
|
286
|
+
dynamic: "同一组件多实例(如工作室列表)",
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
key: "registry",
|
|
290
|
+
item: "需要修改前端页面",
|
|
291
|
+
native: "是(config/routeRegistry.tsx)",
|
|
292
|
+
external: "否",
|
|
293
|
+
iframe: "否",
|
|
294
|
+
dynamic: "是(config/dynamicMenus.ts 配置)",
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
key: "component",
|
|
298
|
+
item: "需要写页面组件",
|
|
299
|
+
native: "是",
|
|
300
|
+
external: "否",
|
|
301
|
+
iframe: "否",
|
|
302
|
+
dynamic: "是(共享组件)",
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
key: "tpage",
|
|
306
|
+
item: "需要 t_page 记录",
|
|
307
|
+
native: "是(code = routeRegistry key)",
|
|
308
|
+
external: "是(填 externalRedirectUrl)",
|
|
309
|
+
iframe: "是(填 iframeUrl)",
|
|
310
|
+
dynamic: "是(父级目录)",
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
key: "url",
|
|
314
|
+
item: "关键 t_page 字段",
|
|
315
|
+
native: "code, path, parentId",
|
|
316
|
+
external: "externalRedirectUrl",
|
|
317
|
+
iframe: "iframeUrl",
|
|
318
|
+
dynamic: "code(如 invested / native)",
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
key: "behavior",
|
|
322
|
+
item: "用户体验",
|
|
323
|
+
native: "应用内完整渲染",
|
|
324
|
+
external: "新窗口打开 + 自动返回",
|
|
325
|
+
iframe: "应用框架内嵌入",
|
|
326
|
+
dynamic: "应用内完整渲染",
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
key: "template",
|
|
330
|
+
item: "支持 {{locale}}",
|
|
331
|
+
native: "—",
|
|
332
|
+
external: "是",
|
|
333
|
+
iframe: "是",
|
|
334
|
+
dynamic: "—",
|
|
335
|
+
},
|
|
336
|
+
];
|
|
337
|
+
|
|
338
|
+
// ─── 组件 ────────────────────────────────────────────────────────────────────
|
|
339
|
+
|
|
340
|
+
export const PermissionReadmePage = () => {
|
|
341
|
+
return (
|
|
342
|
+
<div style={{ padding: "24px 0" }}>
|
|
343
|
+
<Typography>
|
|
344
|
+
<Title level={2}>菜单管理说明</Title>
|
|
345
|
+
<Paragraph>
|
|
346
|
+
本页面介绍系统的菜单、路由与权限管理机制,帮助管理员理解如何添加和配置不同类型的菜单项。
|
|
347
|
+
</Paragraph>
|
|
348
|
+
</Typography>
|
|
349
|
+
|
|
350
|
+
{/* ── 架构概览 ──────────────────────────────────────────────── */}
|
|
351
|
+
<Card title="菜单系统架构" style={{ marginBottom: 24 }}>
|
|
352
|
+
<Paragraph>
|
|
353
|
+
系统的菜单管理涉及<Text strong>前端路由注册</Text>和
|
|
354
|
+
<Text strong>数据库页面配置</Text>两个部分的协作。
|
|
355
|
+
未匹配到 routeRegistry 的路由会进入{" "}
|
|
356
|
+
<Text code>WildcardPage</Text> 通配组件,
|
|
357
|
+
由它根据 t_page 的配置决定渲染 iframe、打开外部链接或显示 404。
|
|
358
|
+
</Paragraph>
|
|
359
|
+
<Alert
|
|
360
|
+
type="info"
|
|
361
|
+
showIcon
|
|
362
|
+
message="数据流"
|
|
363
|
+
description={
|
|
364
|
+
<div>
|
|
365
|
+
<Text code>routeRegistry.tsx</Text>(前端路由定义:Route Path、React组件) +{" "}
|
|
366
|
+
<Text code>t_page</Text>(数据库菜单配置) →{" "}
|
|
367
|
+
<Text code>侧边栏菜单渲染</Text> + <Text code>路由匹配</Text>
|
|
368
|
+
<br />
|
|
369
|
+
<br />
|
|
370
|
+
路由匹配优先级:<Text code>routeRegistry</Text> 原生路由 >{" "}
|
|
371
|
+
<Text code>WildcardPage (/*)</Text> 通配路由
|
|
372
|
+
<br />
|
|
373
|
+
<br />
|
|
374
|
+
WildcardPage 处理:查询 t_page → 有{" "}
|
|
375
|
+
<Text code>iframeUrl</Text> → 渲染 iframe | 有{" "}
|
|
376
|
+
<Text code>externalRedirectUrl</Text> → 新窗口打开 | 否则 → 404
|
|
377
|
+
</div>
|
|
378
|
+
}
|
|
379
|
+
style={{ marginBottom: 16 }}
|
|
380
|
+
/>
|
|
381
|
+
</Card>
|
|
382
|
+
|
|
383
|
+
{/* ── 核心概念 ──────────────────────────────────────────────── */}
|
|
384
|
+
<Card title="核心概念" style={{ marginBottom: 24 }}>
|
|
385
|
+
<Table
|
|
386
|
+
columns={coreConceptColumns}
|
|
387
|
+
dataSource={coreConceptData}
|
|
388
|
+
pagination={false}
|
|
389
|
+
size="small"
|
|
390
|
+
bordered
|
|
391
|
+
/>
|
|
392
|
+
<Divider />
|
|
393
|
+
<Title level={5}>t_page 关键字段</Title>
|
|
394
|
+
<Table
|
|
395
|
+
columns={pageFieldColumns}
|
|
396
|
+
dataSource={pageFieldData}
|
|
397
|
+
pagination={false}
|
|
398
|
+
size="small"
|
|
399
|
+
bordered
|
|
400
|
+
/>
|
|
401
|
+
</Card>
|
|
402
|
+
|
|
403
|
+
{/* ── 四种注册方式 ──────────────────────────────────────────── */}
|
|
404
|
+
<Card title="菜单注册方式" style={{ marginBottom: 24 }}>
|
|
405
|
+
<Alert
|
|
406
|
+
type="info"
|
|
407
|
+
showIcon
|
|
408
|
+
message="四种方式对比"
|
|
409
|
+
style={{ marginBottom: 16 }}
|
|
410
|
+
description={
|
|
411
|
+
<Table
|
|
412
|
+
columns={comparisonColumns}
|
|
413
|
+
dataSource={comparisonData}
|
|
414
|
+
pagination={false}
|
|
415
|
+
size="small"
|
|
416
|
+
bordered
|
|
417
|
+
scroll={{ x: 800 }}
|
|
418
|
+
/>
|
|
419
|
+
}
|
|
420
|
+
/>
|
|
421
|
+
|
|
422
|
+
<Tabs
|
|
423
|
+
items={[
|
|
424
|
+
{
|
|
425
|
+
key: "native",
|
|
426
|
+
label: "原生页面",
|
|
427
|
+
children: (
|
|
428
|
+
<>
|
|
429
|
+
<Paragraph>
|
|
430
|
+
原生页面是最常见的方式——编写 React 组件,在{" "}
|
|
431
|
+
<Text code>routeRegistry.tsx</Text> 中注册路由,再在 t_page
|
|
432
|
+
中创建对应记录。
|
|
433
|
+
</Paragraph>
|
|
434
|
+
<Alert
|
|
435
|
+
type="warning"
|
|
436
|
+
showIcon
|
|
437
|
+
message="关键约束"
|
|
438
|
+
description={
|
|
439
|
+
<>
|
|
440
|
+
routeRegistry 中的 key(如{" "}
|
|
441
|
+
<Text code>software_dashboard</Text>)必须与 t_page 的{" "}
|
|
442
|
+
<Text code>code</Text>{" "}
|
|
443
|
+
字段完全一致,否则菜单无法正常显示。
|
|
444
|
+
</>
|
|
445
|
+
}
|
|
446
|
+
style={{ marginBottom: 16 }}
|
|
447
|
+
/>
|
|
448
|
+
<Title level={5}>注册步骤</Title>
|
|
449
|
+
<Table
|
|
450
|
+
columns={nativeStepColumns}
|
|
451
|
+
dataSource={nativeStepData}
|
|
452
|
+
pagination={false}
|
|
453
|
+
size="small"
|
|
454
|
+
bordered
|
|
455
|
+
/>
|
|
456
|
+
<Divider />
|
|
457
|
+
<Title level={5}>routeRegistry 示例</Title>
|
|
458
|
+
<pre
|
|
459
|
+
style={{
|
|
460
|
+
background: "#f5f5f5",
|
|
461
|
+
padding: 16,
|
|
462
|
+
borderRadius: 6,
|
|
463
|
+
overflow: "auto",
|
|
464
|
+
fontSize: 13,
|
|
465
|
+
lineHeight: 1.6,
|
|
466
|
+
}}
|
|
467
|
+
>{`// src/config/routeRegistry.tsx
|
|
468
|
+
office: {
|
|
469
|
+
path: "/office",
|
|
470
|
+
children: {
|
|
471
|
+
// key "my_feature" 即为 t_page 中的 code
|
|
472
|
+
my_feature: {
|
|
473
|
+
path: "my-feature-dashboard",
|
|
474
|
+
component: lazy(() => import("@/routes/office/my-feature")),
|
|
475
|
+
},
|
|
476
|
+
},
|
|
477
|
+
},`}</pre>
|
|
478
|
+
|
|
479
|
+
<Divider />
|
|
480
|
+
<Title level={5}>
|
|
481
|
+
下划线前缀(_ 开头)的子路由
|
|
482
|
+
</Title>
|
|
483
|
+
<Paragraph>
|
|
484
|
+
routeRegistry 中以 <Text code>_</Text>{" "}
|
|
485
|
+
开头的 key 是<Text strong>内部子路由</Text>,
|
|
486
|
+
<Text strong>无需在 t_page 中注册</Text>。
|
|
487
|
+
它们由父级页面的 code
|
|
488
|
+
统一管理权限,属于同一个页面模块的不同视图。
|
|
489
|
+
</Paragraph>
|
|
490
|
+
|
|
491
|
+
<Title level={5}>
|
|
492
|
+
CRUD 子路由
|
|
493
|
+
</Title>
|
|
494
|
+
<Paragraph>
|
|
495
|
+
最常见的 <Text code>_</Text> 前缀子路由,
|
|
496
|
+
用于同一模块的列表/新建/编辑/详情视图,不出现在侧边栏中:
|
|
497
|
+
</Paragraph>
|
|
498
|
+
<Table
|
|
499
|
+
columns={[
|
|
500
|
+
{ title: "Key", dataIndex: "key", key: "key", width: 100 },
|
|
501
|
+
{ title: "典型 path", dataIndex: "path", key: "path", width: 140 },
|
|
502
|
+
{ title: "用途", dataIndex: "usage", key: "usage" },
|
|
503
|
+
]}
|
|
504
|
+
dataSource={[
|
|
505
|
+
{
|
|
506
|
+
key: "_list",
|
|
507
|
+
path: '""(index: true)',
|
|
508
|
+
usage:
|
|
509
|
+
"列表页,作为父路由的默认子路由(index route),访问父路径时自动渲染",
|
|
510
|
+
},
|
|
511
|
+
{
|
|
512
|
+
key: "_create",
|
|
513
|
+
path: '"create"',
|
|
514
|
+
usage: "新建页,如 /admin/staff/create",
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
key: "_edit",
|
|
518
|
+
path: '"edit/:id"',
|
|
519
|
+
usage: "编辑页,如 /admin/staff/edit/123",
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
key: "_show",
|
|
523
|
+
path: '"show/:id"',
|
|
524
|
+
usage: "详情页,如 /admin/staff/show/123",
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
key: "_index",
|
|
528
|
+
path: '""(index: true)',
|
|
529
|
+
usage: "与 _list 类似,用于非 CRUD 场景的默认子路由",
|
|
530
|
+
},
|
|
531
|
+
]}
|
|
532
|
+
pagination={false}
|
|
533
|
+
size="small"
|
|
534
|
+
bordered
|
|
535
|
+
/>
|
|
536
|
+
|
|
537
|
+
<Divider />
|
|
538
|
+
<Title level={5}>
|
|
539
|
+
动态参数路由 + Sidebar-only 菜单条目
|
|
540
|
+
</Title>
|
|
541
|
+
<Paragraph>
|
|
542
|
+
当多个菜单项共享同一个页面组件、只通过 URL
|
|
543
|
+
参数区分内容时,使用{" "}
|
|
544
|
+
<Text strong>动态参数路由 + Sidebar-only 条目</Text>的组合模式:
|
|
545
|
+
</Paragraph>
|
|
546
|
+
<ul>
|
|
547
|
+
<li>
|
|
548
|
+
动态参数路由(如 <Text code>_tab</Text> / <Text code>_region</Text>) - 负责实际渲染,<Text strong>不注册 t_page</Text>
|
|
549
|
+
</li>
|
|
550
|
+
<li>
|
|
551
|
+
Sidebar-only 条目(如{" "}
|
|
552
|
+
<Text code>apac</Text>、<Text code>security_event</Text>
|
|
553
|
+
)— 只有 path、没有 component,
|
|
554
|
+
<Text strong>需要注册 t_page</Text>,
|
|
555
|
+
出现在侧边栏菜单中。用户点击后 URL
|
|
556
|
+
匹配到动态参数路由,由共享组件渲染。
|
|
557
|
+
</li>
|
|
558
|
+
</ul>
|
|
559
|
+
<pre
|
|
560
|
+
style={{
|
|
561
|
+
background: "#f5f5f5",
|
|
562
|
+
padding: 16,
|
|
563
|
+
borderRadius: 6,
|
|
564
|
+
overflow: "auto",
|
|
565
|
+
fontSize: 13,
|
|
566
|
+
lineHeight: 1.6,
|
|
567
|
+
}}
|
|
568
|
+
>{`// 示例:RTO 看板按区域分子菜单
|
|
569
|
+
// t_page 需注册:overview, apac, amer, emea
|
|
570
|
+
// _index 和 _region 无需注册
|
|
571
|
+
|
|
572
|
+
overview: {
|
|
573
|
+
path: "rto-dashboard",
|
|
574
|
+
children: {
|
|
575
|
+
_index: { // 默认视图,无需注册 t_page
|
|
576
|
+
path: "",
|
|
577
|
+
index: true,
|
|
578
|
+
component: lazy(() => import("@/routes/office/rto")),
|
|
579
|
+
},
|
|
580
|
+
_region: { // 动态参数路由,无需注册 t_page
|
|
581
|
+
path: ":region", // 匹配 /office/rto-dashboard/apac 等
|
|
582
|
+
component: lazy(() => import("@/routes/office/rto")),
|
|
583
|
+
},
|
|
584
|
+
// Sidebar-only 条目:需注册 t_page,出现在侧边栏菜单
|
|
585
|
+
apac: { path: "apac" }, // 无 component,点击后由 _region 渲染
|
|
586
|
+
amer: { path: "amer" },
|
|
587
|
+
emea: { path: "emea" },
|
|
588
|
+
},
|
|
589
|
+
},`}</pre>
|
|
590
|
+
|
|
591
|
+
<Alert
|
|
592
|
+
type="info"
|
|
593
|
+
showIcon
|
|
594
|
+
message="命名约定总结"
|
|
595
|
+
description={
|
|
596
|
+
<ul style={{ margin: 0, paddingLeft: 20 }}>
|
|
597
|
+
<li>
|
|
598
|
+
<Text strong>不以 _ 开头</Text>的 key →
|
|
599
|
+
页面 code,需在 t_page 中注册。有 component
|
|
600
|
+
的是原生页面,无 component 的是 sidebar-only 菜单条目
|
|
601
|
+
</li>
|
|
602
|
+
<li>
|
|
603
|
+
<Text strong>以 _ 开头</Text>的 key →
|
|
604
|
+
内部子路由,不注册 t_page,不出现在侧边栏,权限跟随父级页面
|
|
605
|
+
</li>
|
|
606
|
+
</ul>
|
|
607
|
+
}
|
|
608
|
+
style={{ marginTop: 16, marginBottom: 16 }}
|
|
609
|
+
/>
|
|
610
|
+
|
|
611
|
+
<Title level={5}>CRUD 模块完整示例</Title>
|
|
612
|
+
<pre
|
|
613
|
+
style={{
|
|
614
|
+
background: "#f5f5f5",
|
|
615
|
+
padding: 16,
|
|
616
|
+
borderRadius: 6,
|
|
617
|
+
overflow: "auto",
|
|
618
|
+
fontSize: 13,
|
|
619
|
+
lineHeight: 1.6,
|
|
620
|
+
}}
|
|
621
|
+
>{`// 只需在 t_page 中注册 "staff"(code="staff"),
|
|
622
|
+
// 下面 4 个 _ 开头的子路由无需注册,自动跟随 staff 的权限。
|
|
623
|
+
staff: {
|
|
624
|
+
path: "staff",
|
|
625
|
+
children: {
|
|
626
|
+
_list: {
|
|
627
|
+
path: "",
|
|
628
|
+
index: true, // 访问 /admin/staff 时渲染列表页
|
|
629
|
+
component: lazy(() => import("@/routes/administration/staff")
|
|
630
|
+
.then((m) => ({ default: m.StaffListPage }))),
|
|
631
|
+
},
|
|
632
|
+
_create: {
|
|
633
|
+
path: "create", // /admin/staff/create
|
|
634
|
+
component: lazy(() => import("@/routes/administration/staff")
|
|
635
|
+
.then((m) => ({ default: m.StaffCreatePage }))),
|
|
636
|
+
},
|
|
637
|
+
_edit: {
|
|
638
|
+
path: "edit/:id", // /admin/staff/edit/123
|
|
639
|
+
component: lazy(() => import("@/routes/administration/staff")
|
|
640
|
+
.then((m) => ({ default: m.StaffEditPage }))),
|
|
641
|
+
},
|
|
642
|
+
_show: {
|
|
643
|
+
path: "show/:id", // /admin/staff/show/123
|
|
644
|
+
component: lazy(() => import("@/routes/administration/staff")
|
|
645
|
+
.then((m) => ({ default: m.StaffShowPage }))),
|
|
646
|
+
},
|
|
647
|
+
},
|
|
648
|
+
},`}</pre>
|
|
649
|
+
</>
|
|
650
|
+
),
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
key: "external",
|
|
654
|
+
label: "外部链接",
|
|
655
|
+
children: (
|
|
656
|
+
<>
|
|
657
|
+
<Paragraph>
|
|
658
|
+
外部链接方式<Text strong>无需编写任何前端代码</Text>
|
|
659
|
+
,只需在 Page Management 中创建一条 t_page 记录,并填写{" "}
|
|
660
|
+
<Text code>externalRedirectUrl</Text> 字段即可。
|
|
661
|
+
点击菜单时系统会在新窗口打开目标 URL,并自动返回前一个页面。
|
|
662
|
+
</Paragraph>
|
|
663
|
+
<Title level={5}>注册步骤</Title>
|
|
664
|
+
<ol>
|
|
665
|
+
<li>
|
|
666
|
+
进入 <Text code>/admin/permission/page-list</Text>
|
|
667
|
+
,新建页面记录
|
|
668
|
+
</li>
|
|
669
|
+
<li>
|
|
670
|
+
填写 <Text code>code</Text>、
|
|
671
|
+
<Text code>zhName</Text>、<Text code>path</Text>(任意唯一路径即可)、
|
|
672
|
+
<Text code>parentId</Text>
|
|
673
|
+
</li>
|
|
674
|
+
<li>
|
|
675
|
+
在 <Text code>External Redirect URL</Text> 字段填入目标地址
|
|
676
|
+
</li>
|
|
677
|
+
<li>为角色分配该页面</li>
|
|
678
|
+
</ol>
|
|
679
|
+
<Alert
|
|
680
|
+
type="info"
|
|
681
|
+
showIcon
|
|
682
|
+
message="模板变量"
|
|
683
|
+
description={
|
|
684
|
+
<>
|
|
685
|
+
URL 中可使用{" "}
|
|
686
|
+
<Text code>{"{{locale}}"}</Text>{" "}
|
|
687
|
+
模板变量,运行时会替换为当前语言(en / zh)。例如:
|
|
688
|
+
<br />
|
|
689
|
+
<Text code>
|
|
690
|
+
https://wiki.example.com/page?lang={"{{locale}}"}
|
|
691
|
+
</Text>
|
|
692
|
+
</>
|
|
693
|
+
}
|
|
694
|
+
style={{ marginTop: 16 }}
|
|
695
|
+
/>
|
|
696
|
+
<Divider />
|
|
697
|
+
<Title level={5}>工作流程</Title>
|
|
698
|
+
<pre
|
|
699
|
+
style={{
|
|
700
|
+
background: "#f5f5f5",
|
|
701
|
+
padding: 16,
|
|
702
|
+
borderRadius: 6,
|
|
703
|
+
overflow: "auto",
|
|
704
|
+
fontSize: 13,
|
|
705
|
+
lineHeight: 1.6,
|
|
706
|
+
}}
|
|
707
|
+
>{`用户点击菜单
|
|
708
|
+
→ 前端路由跳转到 page.path
|
|
709
|
+
→ 未匹配到 routeRegistry,进入 WildcardPage
|
|
710
|
+
→ WildcardPage 查询 t_page,发现 externalRedirectUrl
|
|
711
|
+
→ window.open(url, "_blank") 新窗口打开
|
|
712
|
+
→ window.history.back() 自动返回`}</pre>
|
|
713
|
+
</>
|
|
714
|
+
),
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
key: "iframe",
|
|
718
|
+
label: "iframe 嵌入",
|
|
719
|
+
children: (
|
|
720
|
+
<>
|
|
721
|
+
<Paragraph>
|
|
722
|
+
iframe 方式同样<Text strong>无需编写前端代码</Text>
|
|
723
|
+
,在 Page Management 中填写{" "}
|
|
724
|
+
<Text code>iframeUrl</Text>{" "}
|
|
725
|
+
字段即可。页面会在应用框架(侧边栏、顶栏)内以
|
|
726
|
+
iframe 全屏嵌入目标网页。
|
|
727
|
+
</Paragraph>
|
|
728
|
+
<Title level={5}>注册步骤</Title>
|
|
729
|
+
<ol>
|
|
730
|
+
<li>
|
|
731
|
+
进入 <Text code>/admin/permission/page-list</Text>
|
|
732
|
+
,新建页面记录
|
|
733
|
+
</li>
|
|
734
|
+
<li>
|
|
735
|
+
填写 <Text code>code</Text>、
|
|
736
|
+
<Text code>zhName</Text>、<Text code>path</Text>(任意唯一路径即可)、
|
|
737
|
+
<Text code>parentId</Text>
|
|
738
|
+
</li>
|
|
739
|
+
<li>
|
|
740
|
+
在 <Text code>Iframe URL</Text> 字段填入目标地址
|
|
741
|
+
</li>
|
|
742
|
+
<li>为角色分配该页面</li>
|
|
743
|
+
</ol>
|
|
744
|
+
<Alert
|
|
745
|
+
type="warning"
|
|
746
|
+
showIcon
|
|
747
|
+
message="注意事项"
|
|
748
|
+
description={
|
|
749
|
+
<ul style={{ margin: 0, paddingLeft: 20 }}>
|
|
750
|
+
<li>
|
|
751
|
+
<Text code>iframeUrl</Text> 和{" "}
|
|
752
|
+
<Text code>externalRedirectUrl</Text>{" "}
|
|
753
|
+
不能同时填写,两者互斥
|
|
754
|
+
</li>
|
|
755
|
+
<li>
|
|
756
|
+
目标网站必须允许被 iframe 嵌入(未设置{" "}
|
|
757
|
+
<Text code>X-Frame-Options: DENY</Text> 或{" "}
|
|
758
|
+
<Text code>Content-Security-Policy: frame-ancestors 'none'</Text>
|
|
759
|
+
)
|
|
760
|
+
</li>
|
|
761
|
+
<li>
|
|
762
|
+
如果目标网站禁止 iframe,请改用外部链接方式
|
|
763
|
+
</li>
|
|
764
|
+
<li>
|
|
765
|
+
同样支持{" "}
|
|
766
|
+
<Text code>{"{{locale}}"}</Text> 模板变量
|
|
767
|
+
</li>
|
|
768
|
+
</ul>
|
|
769
|
+
}
|
|
770
|
+
style={{ marginTop: 16 }}
|
|
771
|
+
/>
|
|
772
|
+
</>
|
|
773
|
+
),
|
|
774
|
+
},
|
|
775
|
+
{
|
|
776
|
+
key: "dynamic",
|
|
777
|
+
label: "动态菜单",
|
|
778
|
+
children: (
|
|
779
|
+
<>
|
|
780
|
+
<Paragraph>
|
|
781
|
+
动态菜单适用于<Text strong>同一个页面组件需要生成多个菜单项</Text>
|
|
782
|
+
的场景。通过{" "}
|
|
783
|
+
<Text code>src/config/dynamicMenus.ts</Text>{" "}
|
|
784
|
+
的配置驱动方案,开发者只需添加一条配置即可新增动态菜单组。
|
|
785
|
+
</Paragraph>
|
|
786
|
+
|
|
787
|
+
<Title level={5}>配置方式</Title>
|
|
788
|
+
<Paragraph>
|
|
789
|
+
在{" "}
|
|
790
|
+
<Text code>src/config/dynamicMenus.ts</Text>{" "}
|
|
791
|
+
中的{" "}
|
|
792
|
+
<Text code>dynamicMenuGroups</Text>{" "}
|
|
793
|
+
数组中添加一条配置:
|
|
794
|
+
</Paragraph>
|
|
795
|
+
<pre
|
|
796
|
+
style={{
|
|
797
|
+
background: "#f5f5f5",
|
|
798
|
+
padding: 16,
|
|
799
|
+
borderRadius: 6,
|
|
800
|
+
overflow: "auto",
|
|
801
|
+
fontSize: 13,
|
|
802
|
+
lineHeight: 1.6,
|
|
803
|
+
}}
|
|
804
|
+
>{`// src/config/dynamicMenus.ts
|
|
805
|
+
interface DynamicMenuGroup {
|
|
806
|
+
parentCode: string; // 父级 page code(需在 t_page 注册)
|
|
807
|
+
routePrefix: string; // 路由前缀,如 "/rd/invested"
|
|
808
|
+
items: string[]; // 子项列表,每项生成一个菜单项和路由
|
|
809
|
+
component: LazyExoticComponent<ComponentType<any>>; // 共享组件
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
// 示例:RD 工作室
|
|
813
|
+
{
|
|
814
|
+
parentCode: "invested",
|
|
815
|
+
routePrefix: "/rd/invested",
|
|
816
|
+
items: studioMap.investedStudios,
|
|
817
|
+
component: lazy(() => import("@/routes/rd/rdec")),
|
|
818
|
+
}`}</pre>
|
|
819
|
+
|
|
820
|
+
<Alert
|
|
821
|
+
type="info"
|
|
822
|
+
showIcon
|
|
823
|
+
message="权限控制"
|
|
824
|
+
description={
|
|
825
|
+
<>
|
|
826
|
+
动态菜单的权限以{" "}
|
|
827
|
+
<Text code>parentCode</Text>{" "}
|
|
828
|
+
为单位控制。例如为角色分配{" "}
|
|
829
|
+
<Text code>invested</Text>{" "}
|
|
830
|
+
页面后,该角色可以看到该组下所有子菜单项。无需为每个子项单独配置权限。
|
|
831
|
+
</>
|
|
832
|
+
}
|
|
833
|
+
style={{ marginTop: 16 }}
|
|
834
|
+
/>
|
|
835
|
+
|
|
836
|
+
<Divider />
|
|
837
|
+
<Title level={5}>添加新动态菜单组的步骤</Title>
|
|
838
|
+
<ol>
|
|
839
|
+
<li>
|
|
840
|
+
在 <Text code>t_page</Text> 中注册父级页面(设置{" "}
|
|
841
|
+
<Text code>code</Text>、<Text code>parentId</Text>)
|
|
842
|
+
</li>
|
|
843
|
+
<li>
|
|
844
|
+
在 <Text code>src/config/dynamicMenus.ts</Text> 的{" "}
|
|
845
|
+
<Text code>dynamicMenuGroups</Text> 数组中添加一条配置
|
|
846
|
+
</li>
|
|
847
|
+
<li>
|
|
848
|
+
路由和菜单项会自动生成,无需修改{" "}
|
|
849
|
+
<Text code>routeRegistry.tsx</Text>、
|
|
850
|
+
<Text code>App.tsx</Text> 或{" "}
|
|
851
|
+
<Text code>useDynamicResources.tsx</Text>
|
|
852
|
+
</li>
|
|
853
|
+
</ol>
|
|
854
|
+
|
|
855
|
+
<Divider />
|
|
856
|
+
<Title level={5}>现有示例:RD 工作室</Title>
|
|
857
|
+
<Paragraph>
|
|
858
|
+
当前系统中 RD 模块的 invested(投资工作室)和 native(自研工作室)使用动态菜单:
|
|
859
|
+
</Paragraph>
|
|
860
|
+
<ul>
|
|
861
|
+
<li>
|
|
862
|
+
工作室列表定义在{" "}
|
|
863
|
+
<Text code>src/config/studio.ts</Text> 的{" "}
|
|
864
|
+
<Text code>studioMap</Text> 中
|
|
865
|
+
</li>
|
|
866
|
+
<li>
|
|
867
|
+
所有工作室路由共享同一个{" "}
|
|
868
|
+
<Text code>RDEC</Text> 组件,组件内从 URL 提取工作室名称
|
|
869
|
+
</li>
|
|
870
|
+
<li>
|
|
871
|
+
添加新工作室只需在{" "}
|
|
872
|
+
<Text code>studio.ts</Text> 的{" "}
|
|
873
|
+
<Text code>StudioEnum</Text> 和{" "}
|
|
874
|
+
<Text code>studioMap</Text> 中添加条目即可
|
|
875
|
+
</li>
|
|
876
|
+
</ul>
|
|
877
|
+
</>
|
|
878
|
+
),
|
|
879
|
+
},
|
|
880
|
+
]}
|
|
881
|
+
/>
|
|
882
|
+
</Card>
|
|
883
|
+
|
|
884
|
+
{/* ── 权限层级关系 ────────────────────────────────────────────── */}
|
|
885
|
+
<Card title="权限层级关系" style={{ marginBottom: 24 }}>
|
|
886
|
+
<Title level={5}>实体关系总览</Title>
|
|
887
|
+
<pre
|
|
888
|
+
style={{
|
|
889
|
+
background: "#f5f5f5",
|
|
890
|
+
padding: 16,
|
|
891
|
+
borderRadius: 6,
|
|
892
|
+
overflow: "auto",
|
|
893
|
+
fontSize: 13,
|
|
894
|
+
lineHeight: 1.8,
|
|
895
|
+
}}
|
|
896
|
+
>{`User (t_admin_user_role)
|
|
897
|
+
└─ roles: ["PRODUCT", "SYSTEM_ADMIN"] ← 用户可拥有多个角色(JSON 数组)
|
|
898
|
+
│
|
|
899
|
+
▼
|
|
900
|
+
Role (t_role)
|
|
901
|
+
├─ RolePages (t_role_pages) ← 控制菜单可见性(前端)
|
|
902
|
+
│ └─ Page (t_page)
|
|
903
|
+
│ └─ PageResource (t_page_resource) ← 页面声明需要的资源权限
|
|
904
|
+
│
|
|
905
|
+
└─ RoleResource (t_role_resource) ← 控制 API 访问权限(后端)
|
|
906
|
+
└─ Resource (t_resource)
|
|
907
|
+
└─ actions: ["readAny", "createAny", "updateAny", "deleteAny"]`}</pre>
|
|
908
|
+
|
|
909
|
+
<Divider />
|
|
910
|
+
<Title level={5}>双层权限防御</Title>
|
|
911
|
+
<Paragraph>
|
|
912
|
+
系统在前端和后端分别进行权限检查,两层独立运作:
|
|
913
|
+
</Paragraph>
|
|
914
|
+
|
|
915
|
+
<Table
|
|
916
|
+
columns={[
|
|
917
|
+
{ title: "", dataIndex: "item", key: "item", width: 140 },
|
|
918
|
+
{ title: "前端:菜单可见性", dataIndex: "frontend", key: "frontend" },
|
|
919
|
+
{ title: "后端:API 访问权限", dataIndex: "backend", key: "backend" },
|
|
920
|
+
]}
|
|
921
|
+
dataSource={[
|
|
922
|
+
{
|
|
923
|
+
key: "table",
|
|
924
|
+
item: "关联表",
|
|
925
|
+
frontend: "t_role_pages(角色 → 页面)",
|
|
926
|
+
backend: "t_role_resource(角色 → 资源)",
|
|
927
|
+
},
|
|
928
|
+
{
|
|
929
|
+
key: "what",
|
|
930
|
+
item: "控制什么",
|
|
931
|
+
frontend: "侧边栏菜单项是否显示",
|
|
932
|
+
backend: "API 请求是否允许执行",
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
key: "fail",
|
|
936
|
+
item: "无权限表现",
|
|
937
|
+
frontend: "菜单不可见",
|
|
938
|
+
backend: "返回 HTTP 403",
|
|
939
|
+
},
|
|
940
|
+
{
|
|
941
|
+
key: "check",
|
|
942
|
+
item: "检查机制",
|
|
943
|
+
frontend: "useUserPageAccess() Hook 过滤菜单树",
|
|
944
|
+
backend: "AuthGuard → RolesGuard → @UseRoles() 装饰器",
|
|
945
|
+
},
|
|
946
|
+
]}
|
|
947
|
+
pagination={false}
|
|
948
|
+
size="small"
|
|
949
|
+
bordered
|
|
950
|
+
/>
|
|
951
|
+
|
|
952
|
+
<Divider />
|
|
953
|
+
<Title level={5}>权限检查完整流程</Title>
|
|
954
|
+
<pre
|
|
955
|
+
style={{
|
|
956
|
+
background: "#f5f5f5",
|
|
957
|
+
padding: 16,
|
|
958
|
+
borderRadius: 6,
|
|
959
|
+
overflow: "auto",
|
|
960
|
+
fontSize: 13,
|
|
961
|
+
lineHeight: 1.8,
|
|
962
|
+
}}
|
|
963
|
+
>{`┌─ 前端菜单加载 ─────────────────────────────────────────────────────┐
|
|
964
|
+
│ │
|
|
965
|
+
│ 1. GET /userinfo → 获取用户角色列表 (如 ["PRODUCT"]) │
|
|
966
|
+
│ 2. POST /role/findMany → 查询角色 ID │
|
|
967
|
+
│ 3. POST /rolePages/findMany → 查询角色关联的页面 ID │
|
|
968
|
+
│ 4. POST /page/findMany → 获取所有页面定义 │
|
|
969
|
+
│ 5. 构建可访问页面集合(包含分配页面 + 递归添加祖先页面) │
|
|
970
|
+
│ 6. 生成侧边栏菜单树 │
|
|
971
|
+
│ │
|
|
972
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
973
|
+
|
|
974
|
+
┌─ 后端 API 权限检查 ────────────────────────────────────────────────┐
|
|
975
|
+
│ │
|
|
976
|
+
│ 请求到达 → AuthGuard(验证身份,提取 userid) │
|
|
977
|
+
│ → RolesGuard(查询 t_admin_user_role,获取角色列表) │
|
|
978
|
+
│ → @UseRoles({ resource: "xxx", action: "read" }) │
|
|
979
|
+
│ → RolesBuilder 检查该角色对该资源是否有对应权限 │
|
|
980
|
+
│ → 通过 ✓ 执行 / 拒绝 ✗ 返回 403 │
|
|
981
|
+
│ │
|
|
982
|
+
└─────────────────────────────────────────────────────────────────────┘`}</pre>
|
|
983
|
+
|
|
984
|
+
<Divider />
|
|
985
|
+
<Title level={5}>PageResource 的作用</Title>
|
|
986
|
+
<Paragraph>
|
|
987
|
+
<Text code>t_page_resource</Text> 定义了每个页面需要哪些 API
|
|
988
|
+
资源及权限。当管理员在 Role Management
|
|
989
|
+
中为角色勾选页面时,系统会<Text strong>自动从 PageResource
|
|
990
|
+
中提取资源权限</Text>,同步写入{" "}
|
|
991
|
+
<Text code>t_role_resource</Text>。
|
|
992
|
+
</Paragraph>
|
|
993
|
+
<pre
|
|
994
|
+
style={{
|
|
995
|
+
background: "#f5f5f5",
|
|
996
|
+
padding: 16,
|
|
997
|
+
borderRadius: 6,
|
|
998
|
+
overflow: "auto",
|
|
999
|
+
fontSize: 13,
|
|
1000
|
+
lineHeight: 1.8,
|
|
1001
|
+
}}
|
|
1002
|
+
>{`管理员勾选页面 A(关联了 Resource X [readAny] 和 Resource Y [readAny, createAny])
|
|
1003
|
+
↓
|
|
1004
|
+
系统自动执行:
|
|
1005
|
+
1. 写入 t_role_pages:角色 → 页面 A
|
|
1006
|
+
2. 查询 t_page_resource:页面 A 需要 X(readAny)、Y(readAny, createAny)
|
|
1007
|
+
3. 合并写入 t_role_resource:角色 → X(readAny)、Y(readAny, createAny)
|
|
1008
|
+
|
|
1009
|
+
管理员取消勾选页面 A:
|
|
1010
|
+
1. 删除 t_role_pages 中的关联
|
|
1011
|
+
2. 如果 Resource X/Y 不被其他页面引用,同步删除 t_role_resource 中的关联`}</pre>
|
|
1012
|
+
|
|
1013
|
+
<Divider />
|
|
1014
|
+
<Title level={5}>API 权限类型</Title>
|
|
1015
|
+
<Table
|
|
1016
|
+
columns={[
|
|
1017
|
+
{ title: "权限", dataIndex: "action", key: "action", width: 140 },
|
|
1018
|
+
{ title: "含义", dataIndex: "meaning", key: "meaning" },
|
|
1019
|
+
{ title: "对应 HTTP 操作", dataIndex: "http", key: "http", width: 200 },
|
|
1020
|
+
]}
|
|
1021
|
+
dataSource={[
|
|
1022
|
+
{
|
|
1023
|
+
key: "read",
|
|
1024
|
+
action: "readAny",
|
|
1025
|
+
meaning: "读取任意记录",
|
|
1026
|
+
http: "GET / POST findMany",
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
key: "create",
|
|
1030
|
+
action: "createAny",
|
|
1031
|
+
meaning: "创建新记录",
|
|
1032
|
+
http: "POST createOne",
|
|
1033
|
+
},
|
|
1034
|
+
{
|
|
1035
|
+
key: "update",
|
|
1036
|
+
action: "updateAny",
|
|
1037
|
+
meaning: "修改任意记录",
|
|
1038
|
+
http: "PATCH / PUT updateOne",
|
|
1039
|
+
},
|
|
1040
|
+
{
|
|
1041
|
+
key: "delete",
|
|
1042
|
+
action: "deleteAny",
|
|
1043
|
+
meaning: "删除任意记录",
|
|
1044
|
+
http: "DELETE deleteOne",
|
|
1045
|
+
},
|
|
1046
|
+
]}
|
|
1047
|
+
pagination={false}
|
|
1048
|
+
size="small"
|
|
1049
|
+
bordered
|
|
1050
|
+
/>
|
|
1051
|
+
|
|
1052
|
+
<Divider />
|
|
1053
|
+
<Title level={5}>通用资源(Common Resource)</Title>
|
|
1054
|
+
<Paragraph>
|
|
1055
|
+
<Text code>t_resource</Text> 中标记为{" "}
|
|
1056
|
+
<Text code>isCommonResource = true</Text>{" "}
|
|
1057
|
+
的资源会自动为所有角色授予{" "}
|
|
1058
|
+
<Text code>readAny</Text>{" "}
|
|
1059
|
+
权限,无需在页面或角色中单独配置。适用于全局公共数据(如枚举列表、配置项等)。
|
|
1060
|
+
</Paragraph>
|
|
1061
|
+
|
|
1062
|
+
<Divider />
|
|
1063
|
+
<Title level={5}>系统管理员</Title>
|
|
1064
|
+
<Alert
|
|
1065
|
+
type="info"
|
|
1066
|
+
showIcon
|
|
1067
|
+
message="硬编码管理员"
|
|
1068
|
+
description={
|
|
1069
|
+
<>
|
|
1070
|
+
以下用户在后端硬编码为 SYSTEM_ADMIN 角色,即使不在{" "}
|
|
1071
|
+
<Text code>t_admin_user_role</Text>{" "}
|
|
1072
|
+
表中也会自动获得管理员权限:
|
|
1073
|
+
<Text code>kavenma</Text>、<Text code>jasonlan</Text>、
|
|
1074
|
+
<Text code>gc_lvhenan</Text>。
|
|
1075
|
+
</>
|
|
1076
|
+
}
|
|
1077
|
+
/>
|
|
1078
|
+
</Card>
|
|
1079
|
+
|
|
1080
|
+
{/* ── 常见问题 ──────────────────────────────────────────────── */}
|
|
1081
|
+
<Card title="常见问题">
|
|
1082
|
+
<Collapse items={faqItems} />
|
|
1083
|
+
</Card>
|
|
1084
|
+
</div>
|
|
1085
|
+
);
|
|
1086
|
+
};
|
|
1087
|
+
|
|
1088
|
+
export default PermissionReadmePage;
|