From e47cf31c07c3c93570f768abb781234db31aadc4 Mon Sep 17 00:00:00 2001 From: dayjoy Date: Sun, 20 Oct 2024 14:32:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- template/README.md | 11 ++++--- template/script/GenerateMetaPlugin.js | 9 +++++- template/src/App.tsx | 2 +- template/src/global.d.ts | 2 ++ template/src/pages/demo/Demo.tsx | 3 +- template/src/pages/test/Test.js | 8 ++---- template/src/pages/yyy/xxx/Xxx.js | 25 ++++++++++++++++ template/src/pages/yyy/xxx/meta.json | 8 ++++++ template/src/pages/yyy/xxx/xxxAPI.ts | 26 +++++++++++++++++ template/src/utils/withPage.tsx | 41 +++++++++++++++++++++++++++ 10 files changed, 123 insertions(+), 12 deletions(-) create mode 100644 template/src/pages/yyy/xxx/Xxx.js create mode 100644 template/src/pages/yyy/xxx/meta.json create mode 100644 template/src/pages/yyy/xxx/xxxAPI.ts create mode 100644 template/src/utils/withPage.tsx diff --git a/template/README.md b/template/README.md index bd82114..6a2c10c 100644 --- a/template/README.md +++ b/template/README.md @@ -26,23 +26,26 @@ ```ts interface Meta { - displayName?: string; // 展示在菜单上的名字 + displayName?: string; // 展示在菜单上的名字, 可以用 {{language_id}} 包起来,用于国际化显示 icon?: string; // 展示在菜单上的图标 headMenu?: // 是否展示在头部菜单 或 所属头部菜单的名字 | boolean | { key: string; - label: string; + label: string; // 可以用 {{language_id}} 包起来,用于国际化显示 icon?: string; + order?: number; // 菜单序号,数字越小越靠前 }; sideMenu?: // 是否展示在侧边菜单 或 所属侧边菜单的名字 | boolean | { key: string; - label: string; + label: string; // 可以用 {{language_id}} 包起来,用于国际化显示 icon?: string; + order?: number; // 菜单序号,数字越小越靠前 }; - order?: number; // 菜单排列序号,数字越小越靠前 + order?: number; // 菜单序号,数字越小越靠前 + route?: string; // 当前页面路由名字,支持 ':id' 等路由参数,不同则默认等于目录名 } ``` diff --git a/template/script/GenerateMetaPlugin.js b/template/script/GenerateMetaPlugin.js index 8a85fce..050f2c2 100644 --- a/template/script/GenerateMetaPlugin.js +++ b/template/script/GenerateMetaPlugin.js @@ -10,6 +10,7 @@ function buildNestedStructure(filePaths) { const parts = filePath.split('/').slice(2, -1); // 去掉 'src/pages' 'meta.json' let current = root; + let parentFullRoute = ''; parts.forEach((part, index) => { const find = current.find((item) => item._path === part); @@ -25,9 +26,15 @@ function buildNestedStructure(filePaths) { if (index === parts.length - 1) { const content = fs.readFileSync(filePath, 'utf-8'); - Object.assign(current, JSON.parse(content), { + const contentJSON = JSON.parse(content); + Object.assign(current, contentJSON, { _fullpath: parts.join('/'), + _fullroute: parentFullRoute + ? `${parentFullRoute}/${contentJSON.route || part}` + : contentJSON.route || part, }); + } else { + parentFullRoute = current._fullroute || parentFullRoute; } current = current._children; }); diff --git a/template/src/App.tsx b/template/src/App.tsx index 5000e1b..4a15962 100644 --- a/template/src/App.tsx +++ b/template/src/App.tsx @@ -22,7 +22,7 @@ const parseMeta2Routes = (meta: Meta[]) => { () => import(`@/pages/${item._fullpath}/${toPascalCase(item._path)}`), ); const route: RouteObject = { - path: item._fullpath, + path: item._fullroute, element: , }; routes.push(route); diff --git a/template/src/global.d.ts b/template/src/global.d.ts index b8e2a5c..af87e1e 100644 --- a/template/src/global.d.ts +++ b/template/src/global.d.ts @@ -23,6 +23,8 @@ interface Meta { order?: number; // 菜单序号,数字越小越靠前 }; order?: number; // 菜单序号,数字越小越靠前 + route?: string; // 当前页面路由名字,支持 ':id' 等路由参数,不同则默认等于目录名 + _fullroute?: string; // 完整路由,最终路由 _path: string; // 目录名 _fullpath?: string; // 完整目录结构 _children: Meta[]; diff --git a/template/src/pages/demo/Demo.tsx b/template/src/pages/demo/Demo.tsx index 32a6ea4..970ad42 100644 --- a/template/src/pages/demo/Demo.tsx +++ b/template/src/pages/demo/Demo.tsx @@ -1,6 +1,7 @@ import { useAppDispatch, useAppSelector } from '@/app/hooks'; import { User } from '@/pages/demo/demoAPI'; import { fetchUsers, selectDemo } from '@/pages/demo/demoSlice'; +import withPage from '@/utils/withPage'; import { EditTableColumnsType, Table } from '@df/toco-ui'; import { useEffect } from 'react'; @@ -43,4 +44,4 @@ const Demo = () => { ); }; -export default Demo; +export default withPage(Demo); diff --git a/template/src/pages/test/Test.js b/template/src/pages/test/Test.js index 58509dd..25a855a 100644 --- a/template/src/pages/test/Test.js +++ b/template/src/pages/test/Test.js @@ -1,21 +1,19 @@ import { useAppSelector } from '@/app/hooks'; +import withPage from '@/utils/withPage'; import { useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; import * as tocoServices from './testAPI'; const Test = (props) => { const tocoStore = useAppSelector((state) => state); - const navigate = useNavigate(); useEffect(() => { // 一些常用变量或方法 - console.log('navigate', navigate); console.log('props', props); console.log('store', tocoStore); console.log('services', tocoServices); console.log('refs', tocoRefs); console.log('modals', tocoModals); - }, [navigate, props, tocoStore]); + }, [props, tocoStore]); return (
@@ -30,4 +28,4 @@ const Test = (props) => { ); }; -export default Test; +export default withPage(Test); diff --git a/template/src/pages/yyy/xxx/Xxx.js b/template/src/pages/yyy/xxx/Xxx.js new file mode 100644 index 0000000..613c2c6 --- /dev/null +++ b/template/src/pages/yyy/xxx/Xxx.js @@ -0,0 +1,25 @@ +import { useAppSelector } from '@/app/hooks'; +import withPage from '@/utils/withPage'; +import { useEffect } from 'react'; +import * as tocoServices from './xxxAPI'; + +const Xxx = (props) => { + const tocoStore = useAppSelector((state) => state); + + useEffect(() => { + // 一些常用变量或方法 + console.log('props', props); + console.log('services', tocoServices); + console.log('refs', tocoRefs); + console.log('modals', tocoModals); + console.log('store', tocoStore); + }, [props, tocoStore]); + + return ( +
+

xxx

+
+ ); +}; + +export default withPage(Xxx); diff --git a/template/src/pages/yyy/xxx/meta.json b/template/src/pages/yyy/xxx/meta.json new file mode 100644 index 0000000..6b33f54 --- /dev/null +++ b/template/src/pages/yyy/xxx/meta.json @@ -0,0 +1,8 @@ +{ + "displayName": "xxx", + "icon": "RobotOutlined", + "headMenu": false, + "sideMenu": false, + "order": 0, + "route": "xx/:oo" +} \ No newline at end of file diff --git a/template/src/pages/yyy/xxx/xxxAPI.ts b/template/src/pages/yyy/xxx/xxxAPI.ts new file mode 100644 index 0000000..27f1a4e --- /dev/null +++ b/template/src/pages/yyy/xxx/xxxAPI.ts @@ -0,0 +1,26 @@ +import axiosInstance from '@/app/request'; +import { AxiosResponse } from 'axios'; + +export interface User { + name: { + first: string; + last: string; + }; + phone: string; + gender: 'female' | 'male'; +} + +export const getUsers = async (): Promise => { + const response: AxiosResponse<{ + info: any; + results: User[]; + }> = await axiosInstance.get( + `https://randomuser.me/api/?results=8&seed=toco`, + { + params: { + errorHandler: false, + }, + }, + ); + return response.data?.results || []; +}; diff --git a/template/src/utils/withPage.tsx b/template/src/utils/withPage.tsx new file mode 100644 index 0000000..8a6b2e7 --- /dev/null +++ b/template/src/utils/withPage.tsx @@ -0,0 +1,41 @@ +import { useMemo } from 'react'; +import { + useLocation, + useNavigate, + useParams, + useSearchParams, +} from 'react-router-dom'; + +const withPage = (BaseComponent: React.ComponentType) => { + const WithPageComponent = (props: any) => { + const navigate = useNavigate(); + const params = useParams(); + const location = useLocation(); + const [searchParamsOri] = useSearchParams(); + const searchParams = useMemo(() => { + const params = {}; + for (const [key, value] of searchParamsOri.entries()) { + params[key] = value; + } + return params; + }, [searchParamsOri]); + + return ( + <> + + + ); + }; + WithPageComponent.displayName = + BaseComponent.displayName ?? 'WithPageComponent'; + + return WithPageComponent; +}; + +export default withPage;