@@ -66,7 +66,7 @@ function App() { | |||
componentSize='large' | |||
> | |||
<AntdApp> | |||
<Router /> | |||
<Router /> | |||
</AntdApp> | |||
</ConfigProvider> | |||
) | |||
@@ -7,7 +7,7 @@ import Header from './header'; | |||
import { useUserStore } from '@/store/global/user'; | |||
import { useMenusStore } from "@/store/global/menu"; | |||
import { Menu } from '@/models'; | |||
import { components } from '@/router/config'; | |||
import { components, commonRoutes } from '@/router/config'; | |||
import { replaceRoutes, router } from '@/router/router'; | |||
import Result404 from './404'; | |||
@@ -41,32 +41,6 @@ const BasicLayout: React.FC = () => { | |||
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(() => { | |||
if (!refreshToken) { | |||
navigate('/login'); | |||
@@ -105,13 +79,11 @@ const BasicLayout: React.FC = () => { | |||
} | |||
} | |||
menuList.data.forEach(item => fixAndPushMenu(item)); | |||
setMenus(menuList.data) //([...formatedMenus, ...menuList.data]); | |||
console.log('components', components); | |||
setMenus(menuList.data); | |||
replaceRoutes('*', [ | |||
...routes.map(menu => ({ | |||
...[...routes, ...(commonRoutes as Menu[])].map(menu => ({ | |||
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}`, | |||
handle: { | |||
parentPaths: menu.parentPaths, | |||
@@ -128,16 +100,6 @@ const BasicLayout: React.FC = () => { | |||
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); | |||
setLoading(false); | |||
@@ -60,7 +60,7 @@ export interface UserDTO { | |||
} | |||
export interface Menu { | |||
id: number; | |||
id: number | string; | |||
permission?: string; | |||
parentId?: number; | |||
name?: string; | |||
@@ -75,6 +75,7 @@ interface Props { | |||
movable?: boolean; | |||
resizable?: boolean; | |||
grid?: boolean; | |||
imageUrl?: string; | |||
} | |||
interface Methods { | |||
@@ -122,9 +123,11 @@ export const ImageStencil = forwardRef<Methods, Props>( | |||
boundingBoxClassName, | |||
overlayClassName, | |||
draggableAreaClassName, | |||
...props | |||
}: Props, | |||
ref, | |||
) => { | |||
const { patternUrl } = props; | |||
const state = cropper.getState(); | |||
const transitions = cropper.getTransitions(); | |||
const interactions = cropper.getInteractions(); | |||
@@ -214,7 +217,7 @@ export const ImageStencil = forwardRef<Methods, Props>( | |||
width={width} | |||
height={height} | |||
preview={false} | |||
src="https://test.vogocm.com:9696/image/material/20230413162155A010.png" | |||
src={patternUrl} | |||
/> | |||
</DraggableArea> | |||
</BoundingBox> | |||
@@ -1,9 +1,13 @@ | |||
import React, { useState } from 'react'; | |||
import { useLocation } from 'react-router-dom'; | |||
import { CropperRef, Cropper } from 'react-advanced-cropper'; | |||
import 'react-advanced-cropper/dist/style.css' | |||
import { ImageStencil } from "./components/ImageStencil"; | |||
import cn from 'classnames'; | |||
import property from '../../../../../../mock/propertyById.json' | |||
export default () => { | |||
const { search } = useLocation() | |||
const [image] = useState( | |||
'https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A053.jpg', | |||
); | |||
@@ -13,17 +17,22 @@ export default () => { | |||
}; | |||
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 | |||
onClick={() => { | |||
navigate('/custom/product/sample/editor') | |||
navigate('/custom/product/sample/editor?id=10') | |||
}}>编辑</a> | |||
<a | |||
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', '')); | |||
let manifest: any; | |||
export const components = Object.keys(modules).reduce<Record<string, () => Promise<any>>>((prev, path: string) => { | |||
const formatPath = path.replace('../pages', ''); | |||
prev[formatPath] = async () => { | |||
@@ -30,3 +28,14 @@ export const components = Object.keys(modules).reduce<Record<string, () => Promi | |||
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 BasicLayout from '@/layout'; | |||
import Dashboard from '@/pages/dashboard'; | |||
import { App } from 'antd'; | |||
import { useEffect } from 'react'; | |||
import { antdUtils } from '@/utils/antd'; | |||
@@ -87,4 +86,3 @@ const Router = () => { | |||
}; | |||
export default Router; | |||