@@ -66,7 +66,7 @@ function App() { | |||||
componentSize='large' | componentSize='large' | ||||
> | > | ||||
<AntdApp> | <AntdApp> | ||||
<Router /> | |||||
<Router /> | |||||
</AntdApp> | </AntdApp> | ||||
</ConfigProvider> | </ConfigProvider> | ||||
) | ) | ||||
@@ -7,7 +7,7 @@ import Header from './header'; | |||||
import { useUserStore } from '@/store/global/user'; | import { useUserStore } from '@/store/global/user'; | ||||
import { useMenusStore } from "@/store/global/menu"; | import { useMenusStore } from "@/store/global/menu"; | ||||
import { Menu } from '@/models'; | import { Menu } from '@/models'; | ||||
import { components } from '@/router/config'; | |||||
import { components, commonRoutes } from '@/router/config'; | |||||
import { replaceRoutes, router } from '@/router/router'; | import { replaceRoutes, router } from '@/router/router'; | ||||
import Result404 from './404'; | import Result404 from './404'; | ||||
@@ -41,32 +41,6 @@ const BasicLayout: React.FC = () => { | |||||
const { data: menuList, run: listMenus} = useRequest(authService.listMenus, { manual: true }); | const { data: menuList, run: listMenus} = useRequest(authService.listMenus, { manual: true }); | ||||
const formatMenus = ( | |||||
menus: Menu[], | |||||
menuGroup: Record<string, Menu[]>, | |||||
routes: Menu[], | |||||
parentMenu?: Menu | |||||
): Menu[] => { | |||||
return menus.map(menu => { | |||||
const children = menuGroup[menu.id]; | |||||
const parentPaths = parentMenu?.parentPaths || []; | |||||
const path = (parentMenu ? `${parentPaths.at(-1)}${menu.path}` : menu.path) || ''; | |||||
routes.push({ ...menu, path, parentPaths }); | |||||
return { | |||||
...menu, | |||||
path, | |||||
parentPaths, | |||||
children: children?.length ? formatMenus(children, menuGroup, routes, { | |||||
...menu, | |||||
parentPaths: [...parentPaths, path || ''].filter(o => o), | |||||
}) : undefined, | |||||
}; | |||||
}); | |||||
} | |||||
useEffect(() => { | useEffect(() => { | ||||
if (!refreshToken) { | if (!refreshToken) { | ||||
navigate('/login'); | navigate('/login'); | ||||
@@ -105,13 +79,11 @@ const BasicLayout: React.FC = () => { | |||||
} | } | ||||
} | } | ||||
menuList.data.forEach(item => fixAndPushMenu(item)); | menuList.data.forEach(item => fixAndPushMenu(item)); | ||||
setMenus(menuList.data) //([...formatedMenus, ...menuList.data]); | |||||
console.log('components', components); | |||||
setMenus(menuList.data); | |||||
replaceRoutes('*', [ | replaceRoutes('*', [ | ||||
...routes.map(menu => ({ | |||||
...[...routes, ...(commonRoutes as Menu[])].map(menu => ({ | |||||
path: `/*${menu.path}`, | path: `/*${menu.path}`, | ||||
Component: menu.component ? lazy(components[menu.component]) : null, | |||||
Component: menu.component && menu.component in components? lazy(components[menu.component]) : Result404, | |||||
id: `/*${menu.path}`, | id: `/*${menu.path}`, | ||||
handle: { | handle: { | ||||
parentPaths: menu.parentPaths, | parentPaths: menu.parentPaths, | ||||
@@ -128,16 +100,6 @@ const BasicLayout: React.FC = () => { | |||||
name: '404', | name: '404', | ||||
}, | }, | ||||
}, | }, | ||||
{ | |||||
path: `/*/custom/product/sample/editor`, | |||||
Component: lazy(components['/custom/product/sample/editor/index.tsx']), | |||||
id: `/*/custom/product/sample/editor`, | |||||
handle: { | |||||
parentPaths: ['/custom', '/custom/product', '/custom/product/sample'], | |||||
path: '/*/custom/product/sample/editor', | |||||
name: '蒙板编辑', | |||||
}, | |||||
} | |||||
]); | ]); | ||||
setCurrentUser(currentUserProfile!!.data); | setCurrentUser(currentUserProfile!!.data); | ||||
setLoading(false); | setLoading(false); | ||||
@@ -60,7 +60,7 @@ export interface UserDTO { | |||||
} | } | ||||
export interface Menu { | export interface Menu { | ||||
id: number; | |||||
id: number | string; | |||||
permission?: string; | permission?: string; | ||||
parentId?: number; | parentId?: number; | ||||
name?: string; | name?: string; | ||||
@@ -75,6 +75,7 @@ interface Props { | |||||
movable?: boolean; | movable?: boolean; | ||||
resizable?: boolean; | resizable?: boolean; | ||||
grid?: boolean; | grid?: boolean; | ||||
imageUrl?: string; | |||||
} | } | ||||
interface Methods { | interface Methods { | ||||
@@ -122,9 +123,11 @@ export const ImageStencil = forwardRef<Methods, Props>( | |||||
boundingBoxClassName, | boundingBoxClassName, | ||||
overlayClassName, | overlayClassName, | ||||
draggableAreaClassName, | draggableAreaClassName, | ||||
...props | |||||
}: Props, | }: Props, | ||||
ref, | ref, | ||||
) => { | ) => { | ||||
const { patternUrl } = props; | |||||
const state = cropper.getState(); | const state = cropper.getState(); | ||||
const transitions = cropper.getTransitions(); | const transitions = cropper.getTransitions(); | ||||
const interactions = cropper.getInteractions(); | const interactions = cropper.getInteractions(); | ||||
@@ -214,7 +217,7 @@ export const ImageStencil = forwardRef<Methods, Props>( | |||||
width={width} | width={width} | ||||
height={height} | height={height} | ||||
preview={false} | preview={false} | ||||
src="https://test.vogocm.com:9696/image/material/20230413162155A010.png" | |||||
src={patternUrl} | |||||
/> | /> | ||||
</DraggableArea> | </DraggableArea> | ||||
</BoundingBox> | </BoundingBox> | ||||
@@ -1,9 +1,13 @@ | |||||
import React, { useState } from 'react'; | import React, { useState } from 'react'; | ||||
import { useLocation } from 'react-router-dom'; | |||||
import { CropperRef, Cropper } from 'react-advanced-cropper'; | import { CropperRef, Cropper } from 'react-advanced-cropper'; | ||||
import 'react-advanced-cropper/dist/style.css' | import 'react-advanced-cropper/dist/style.css' | ||||
import { ImageStencil } from "./components/ImageStencil"; | import { ImageStencil } from "./components/ImageStencil"; | ||||
import cn from 'classnames'; | |||||
import property from '../../../../../../mock/propertyById.json' | |||||
export default () => { | export default () => { | ||||
const { search } = useLocation() | |||||
const [image] = useState( | const [image] = useState( | ||||
'https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A053.jpg', | 'https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A053.jpg', | ||||
); | ); | ||||
@@ -13,17 +17,22 @@ export default () => { | |||||
}; | }; | ||||
return ( | return ( | ||||
<Cropper | |||||
src={image} | |||||
className={'cropper'} | |||||
onChange={onChange} | |||||
stencilComponent={ImageStencil} | |||||
defaultCoordinates={{ | |||||
left: 100, | |||||
top: 100, | |||||
width: 400, | |||||
height: 400, | |||||
}} | |||||
/> | |||||
<div> | |||||
<Cropper | |||||
src={image} | |||||
className={cn('cropper', `w-[${600}px]`, `h-[${600}px]`)} | |||||
onChange={onChange} | |||||
stencilProps={{ | |||||
patternUrl: 'https://test.vogocm.com:9696/image/material/20230413162155A010.png' | |||||
}} | |||||
stencilComponent={ImageStencil} | |||||
defaultCoordinates={{ | |||||
left: 300, | |||||
top: 300, | |||||
width: 100, | |||||
height: 100, | |||||
}} | |||||
/> | |||||
</div> | |||||
) | ) | ||||
} | } |
@@ -153,7 +153,7 @@ const TablePage: React.FC = () => { | |||||
}}>属性设置</a> | }}>属性设置</a> | ||||
<a | <a | ||||
onClick={() => { | onClick={() => { | ||||
navigate('/custom/product/sample/editor') | |||||
navigate('/custom/product/sample/editor?id=10') | |||||
}}>编辑</a> | }}>编辑</a> | ||||
<a | <a | ||||
onClick={() => { | onClick={() => { | ||||
@@ -2,8 +2,6 @@ export const modules = import.meta.glob('../pages/**/index.tsx'); | |||||
export const componentPaths = Object.keys(modules).map((path: string) => path.replace('../pages', '')); | export const componentPaths = Object.keys(modules).map((path: string) => path.replace('../pages', '')); | ||||
let manifest: any; | |||||
export const components = Object.keys(modules).reduce<Record<string, () => Promise<any>>>((prev, path: string) => { | export const components = Object.keys(modules).reduce<Record<string, () => Promise<any>>>((prev, path: string) => { | ||||
const formatPath = path.replace('../pages', ''); | const formatPath = path.replace('../pages', ''); | ||||
prev[formatPath] = async () => { | prev[formatPath] = async () => { | ||||
@@ -30,3 +28,14 @@ export const components = Object.keys(modules).reduce<Record<string, () => Promi | |||||
return prev; | return prev; | ||||
}, {}); | }, {}); | ||||
export const commonRoutes = [ | |||||
{ | |||||
component: "/custom/product/sample/editor/index.tsx", | |||||
id: '/custom/product/sample/editor', | |||||
keepAlive: true, | |||||
name: "蒙板编辑", | |||||
parentId: 2, | |||||
parentPaths: ['/custom', '/custom/product', '/custom/product/sample'], | |||||
path: "/custom/product/sample/editor", | |||||
} | |||||
] |
@@ -2,7 +2,6 @@ import { RouteObject, RouterProvider, createBrowserRouter, Navigate } from 'reac | |||||
import Login from '@/pages/login'; | import Login from '@/pages/login'; | ||||
import BasicLayout from '@/layout'; | import BasicLayout from '@/layout'; | ||||
import Dashboard from '@/pages/dashboard'; | |||||
import { App } from 'antd'; | import { App } from 'antd'; | ||||
import { useEffect } from 'react'; | import { useEffect } from 'react'; | ||||
import { antdUtils } from '@/utils/antd'; | import { antdUtils } from '@/utils/antd'; | ||||
@@ -87,4 +86,3 @@ const Router = () => { | |||||
}; | }; | ||||
export default Router; | export default Router; | ||||