diff --git a/mock/propertyById.json b/mock/propertyById.json
new file mode 100644
index 0000000..13f05d2
--- /dev/null
+++ b/mock/propertyById.json
@@ -0,0 +1,214 @@
+{
+ "id": 89,
+ "createTime": "2023-08-21 11:43:46",
+ "updateTime": "2023-08-21 11:43:46",
+ "spuCode": "1-28X7LF",
+ "categoryId": 1272,
+ "prototypeName": "TEST男装",
+ "costPrice": 10.000000,
+ "maxSyntheticNumber": 100,
+ "createId": 1,
+ "isDelete": 2,
+ "categoryName": "男士短裤",
+ "prototypeImgs": [
+ {
+ "id": 412,
+ "prototypeId": 89,
+ "imgId": 1991125,
+ "maskImgId": 1991130,
+ "imgName": "3.jpg",
+ "imgType": 2,
+ "imgWidth": 600.0,
+ "imgHeight": 600.0,
+ "imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A056.jpg",
+ "locations": [
+ {
+ "id": 394,
+ "prototypeImgId": 412,
+ "clipHeight": 139.2,
+ "clipWidth": 108.0,
+ "clipX": 230.4,
+ "clipY": 318.0,
+ "cropBoxJson": "{\"left\":317,\"top\":264.9999694824219,\"width\":90,\"height\":116.00003051757812}"
+ }
+ ]
+ },
+ {
+ "id": 413,
+ "prototypeId": 89,
+ "imgId": 1991122,
+ "maskImgId": 1991131,
+ "imgName": "1.jpg",
+ "imgType": 2,
+ "imgWidth": 600.0,
+ "imgHeight": 600.0,
+ "imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A053.jpg",
+ "locations": [
+ {
+ "id": 395,
+ "prototypeImgId": 413,
+ "clipHeight": 145.2,
+ "clipWidth": 116.4,
+ "clipX": 224.4,
+ "clipY": 314.4001,
+ "cropBoxJson": "{\"left\":312,\"top\":262.00006103515625,\"width\":97,\"height\":121}"
+ }
+ ]
+ },
+ {
+ "id": 414,
+ "prototypeId": 89,
+ "imgId": 1991127,
+ "imgName": "f60911abe38e82e9dd2aaa75f3292ed2.jpg",
+ "imgType": 2,
+ "imgWidth": 1000.0,
+ "imgHeight": 1000.0,
+ "imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A058.jpg",
+ "locations": [
+ {
+ "id": 396,
+ "prototypeImgId": 414,
+ "clipHeight": 234.0,
+ "clipWidth": 192.0,
+ "clipX": 190.0,
+ "clipY": 288.0,
+ "cropBoxJson": "{\"left\":220,\"top\":144,\"width\":96,\"height\":117}"
+ }
+ ]
+ },
+ {
+ "id": 415,
+ "prototypeId": 89,
+ "imgId": 1991123,
+ "imgName": "d247c5ec0ef78f302b803c6bf00658a2.jpg",
+ "imgType": 2,
+ "imgWidth": 1000.0,
+ "imgHeight": 1000.0,
+ "imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A054.jpg",
+ "locations": [
+ {
+ "id": 397,
+ "prototypeImgId": 415,
+ "clipHeight": 279.9999,
+ "clipWidth": 226.0,
+ "clipX": 380.0,
+ "clipY": 404.0001,
+ "cropBoxJson": "{\"left\":315,\"top\":202.00006103515625,\"width\":113,\"height\":139.99993896484375}"
+ }
+ ]
+ },
+ {
+ "id": 416,
+ "prototypeId": 89,
+ "imgId": 1991129,
+ "imgName": "b470dfa7876630bb2b6ba9ed294b58ca.jpg",
+ "imgType": 1,
+ "imgWidth": 1000.0,
+ "imgHeight": 1000.0,
+ "imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A060.jpg",
+ "locations": [
+ {
+ "id": 398,
+ "prototypeImgId": 416,
+ "clipHeight": 247.9999,
+ "clipWidth": 200.0,
+ "clipX": 414.0,
+ "clipY": 402.0001,
+ "cropBoxJson": "{\"left\":332,\"top\":201.00003051757812,\"width\":100,\"height\":123.99996948242188}"
+ }
+ ]
+ },
+ {
+ "id": 417,
+ "prototypeId": 89,
+ "imgId": 1991124,
+ "imgName": "e870596429cb1e46065fe25a71b29070.jpg",
+ "imgType": 1,
+ "imgWidth": 1000.0,
+ "imgHeight": 1000.0,
+ "imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A055.jpg",
+ "locations": [
+ {
+ "id": 399,
+ "prototypeImgId": 417,
+ "clipHeight": 282.0,
+ "clipWidth": 216.0,
+ "clipX": 408.0,
+ "clipY": 394.0,
+ "cropBoxJson": "{\"left\":329,\"top\":197,\"width\":108,\"height\":141}"
+ }
+ ]
+ },
+ {
+ "id": 418,
+ "prototypeId": 89,
+ "imgId": 1991128,
+ "imgName": "067b756a187026d1af97aa78b8d7d0ba.jpg",
+ "imgType": 1,
+ "imgWidth": 1000.0,
+ "imgHeight": 1000.0,
+ "imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A059.jpg",
+ "locations": [
+ {
+ "id": 400,
+ "prototypeImgId": 418,
+ "clipHeight": 300.0,
+ "clipWidth": 230.0001,
+ "clipX": 389.9999,
+ "clipY": 384.0,
+ "cropBoxJson": "{\"left\":319.99993896484375,\"top\":192,\"width\":115.00006103515625,\"height\":150}"
+ }
+ ]
+ },
+ {
+ "id": 419,
+ "prototypeId": 89,
+ "imgId": 1991126,
+ "imgName": "e944022ccb44a7fb14483da12f1cf8eb.jpg",
+ "imgType": 1,
+ "imgWidth": 1000.0,
+ "imgHeight": 1000.0,
+ "imgUrl": "https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A057.jpg",
+ "locations": [
+ {
+ "id": 401,
+ "prototypeImgId": 419,
+ "clipHeight": 299.9999,
+ "clipWidth": 206.0,
+ "clipX": 400.0,
+ "clipY": 392.0001,
+ "cropBoxJson": "{\"left\":325,\"top\":196.00006103515625,\"width\":103,\"height\":149.99993896484375}"
+ }
+ ]
+ }
+ ],
+ "materialClassifys": [
+ {
+ "id": 20,
+ "createTime": "2023-04-10 17:41:00",
+ "updateTime": "2023-04-10 17:41:06",
+ "parentId": 2,
+ "classifyName": "海贼王",
+ "createId": 2,
+ "isDelete": 2
+ },
+ {
+ "id": 21,
+ "createTime": "2023-04-10 17:41:07",
+ "updateTime": "2023-04-10 17:41:13",
+ "parentId": 2,
+ "classifyName": "火影忍者",
+ "createId": 2,
+ "isDelete": 2
+ },
+ {
+ "id": 22,
+ "createTime": "2023-04-10 17:41:16",
+ "updateTime": "2023-04-10 17:41:22",
+ "parentId": 2,
+ "classifyName": "死神",
+ "createId": 2,
+ "isDelete": 2
+ }
+ ]
+}
diff --git a/package.json b/package.json
index 38039e4..4c0eb3e 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "vogocm-web",
"private": true,
- "version": "0.0.0",
+ "version": "0.0.1",
"type": "module",
"scripts": {
"start": "vite",
@@ -31,6 +31,7 @@
"nprogress": "^0.2.0",
"rc-resize-observer": "^1.3.1",
"react": "^18.2.0",
+ "react-advanced-cropper": "^0.19.3",
"react-dom": "^18.2.0",
"react-router-dom": "latest",
"react-use": "^17.4.0",
diff --git a/src/layout/header/index.tsx b/src/layout/header/index.tsx
index 8524497..9878ff1 100644
--- a/src/layout/header/index.tsx
+++ b/src/layout/header/index.tsx
@@ -135,13 +135,13 @@ const Header = () => {
>
- {currentUser?.userName}
+ {currentUser?.username}
- {currentUser?.phoneNumber}
+ {currentUser?.mobile}
- {currentUser?.emailAddress}
+ {currentUser?.email}
@@ -153,8 +153,8 @@ const Header = () => {
}}
>
- {currentUser?.avatarUrl ? (
-
+ {currentUser?.avatar ? (
+
) : (
} />
)}
diff --git a/src/layout/index.tsx b/src/layout/index.tsx
index 566261c..6a5a348 100644
--- a/src/layout/index.tsx
+++ b/src/layout/index.tsx
@@ -80,7 +80,7 @@ const BasicLayout: React.FC = () => {
const formatedMenus = formatMenus(menus.filter(o => !o.parentId), menuGroup, routes);
setMenus(formatedMenus);
- console.log(components, 'components');
+ console.log('components', components);
replaceRoutes('*', [
...routes.map(menu => ({
path: `/*${menu.path}`,
@@ -100,9 +100,18 @@ const BasicLayout: React.FC = () => {
path: '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: '蒙版编辑',
+ },
}
]);
-
setLoading(false);
// replace一下当前路由,为了触发路由匹配
diff --git a/src/models/user.ts b/src/models/user.ts
index fbfefd3..346d003 100644
--- a/src/models/user.ts
+++ b/src/models/user.ts
@@ -73,16 +73,15 @@ export interface Menu {
export interface User {
id: number;
- userName: string;
- nickName: string;
- phoneNumber: string;
+ username: string;
+ nickname: string;
+ deptId:number;
+ postIds: number;
+ mobile: string;
email: string;
- createDate: string;
- updateDate: string;
- avatar?: any;
- menus: Menu[];
- routes: any[];
- flatMenus: Menu[];
- avatarPath: string;
- authList: string[];
+ sex: number;
+ createTime: string;
+ loginDate: string;
+ avatar?: string;
+ status: number;
}
diff --git a/src/pages/custom/product/sample/components/mask-picture-editor.tsx b/src/pages/custom/product/sample/components/mask-picture-editor.tsx
index a97f9fa..ddf9803 100644
--- a/src/pages/custom/product/sample/components/mask-picture-editor.tsx
+++ b/src/pages/custom/product/sample/components/mask-picture-editor.tsx
@@ -115,7 +115,7 @@ const MaskPictureEditor: React.FC
= (props) => {
url: item.maskImgUrl,
}] : []
return (
-
+
;
+
+type LineComponent = FC;
+
+interface HandlerClassNames extends Partial> {
+ default?: string;
+ disabled?: string;
+ hover?: string;
+}
+
+interface LineClassNames extends Partial> {
+ default?: string;
+ disabled?: string;
+ hover?: string;
+}
+
+interface DesiredCropperRef {
+ getState: () => CropperState | null;
+ getTransitions: () => CropperTransitions;
+ getInteractions: () => CropperInteractions;
+ hasInteractions: () => boolean;
+ resizeCoordinates: (anchor: ResizeAnchor, directions: Partial, parameters: unknown) => void;
+ resizeCoordinatesEnd: () => void;
+ moveCoordinates: (directions: Partial) => void;
+ moveCoordinatesEnd: () => void;
+}
+
+interface Props {
+ cropper: DesiredCropperRef;
+ coordinates?: Coordinates | ((state: CropperState | null) => Coordinates);
+ handlerComponent?: HandlerComponent;
+ handlers?: Partial>;
+ handlerClassNames?: HandlerClassNames;
+ handlerWrapperClassNames?: HandlerClassNames;
+ lines?: Partial>;
+ lineComponent?: LineComponent;
+ lineClassNames?: LineClassNames;
+ lineWrapperClassNames?: LineClassNames;
+ className?: string;
+ movingClassName?: string;
+ resizingClassName?: string;
+ gridClassName?: string;
+ previewClassName?: string;
+ boundingBoxClassName?: string;
+ overlayClassName?: string;
+ draggableAreaClassName?: string;
+ minAspectRatio?: number;
+ maxAspectRatio?: number;
+ aspectRatio?: RawAspectRatio;
+ movable?: boolean;
+ resizable?: boolean;
+ grid?: boolean;
+}
+
+interface Methods {
+ aspectRatio: RawAspectRatio;
+}
+
+export const ImageStencil = forwardRef(
+ (
+ {
+ cropper,
+ coordinates,
+ aspectRatio,
+ minAspectRatio,
+ maxAspectRatio,
+ handlerComponent = SimpleHandler,
+ handlers = {
+ eastNorth: true,
+ north: true,
+ westNorth: true,
+ west: true,
+ westSouth: true,
+ south: true,
+ eastSouth: true,
+ east: true,
+ },
+ handlerClassNames = {},
+ handlerWrapperClassNames = {},
+ lines = {
+ west: true,
+ north: true,
+ east: true,
+ south: true,
+ },
+ lineComponent = SimpleLine,
+ lineClassNames = {},
+ lineWrapperClassNames = {},
+ resizable = true,
+ movable = true,
+ grid,
+ gridClassName,
+ className,
+ movingClassName,
+ resizingClassName,
+ previewClassName,
+ boundingBoxClassName,
+ overlayClassName,
+ draggableAreaClassName,
+ }: Props,
+ ref,
+ ) => {
+ const state = cropper.getState();
+ const transitions = cropper.getTransitions();
+ const interactions = cropper.getInteractions();
+
+ useImperativeHandle(ref, () => ({
+ aspectRatio: createAspectRatio(
+ aspectRatio || {
+ minimum: minAspectRatio,
+ maximum: maxAspectRatio,
+ },
+ ),
+ }));
+
+ const onMove = (directions: MoveDirections) => {
+ if (cropper && movable) {
+ cropper.moveCoordinates(directions);
+ }
+ };
+
+ const onMoveEnd = () => {
+ if (cropper) {
+ cropper.moveCoordinatesEnd();
+ }
+ };
+
+ const onResize = (anchor: ResizeAnchor, directions: MoveDirections, options: ResizeOptions) => {
+ if (cropper && resizable) {
+ cropper.resizeCoordinates(anchor, directions, options);
+ }
+ };
+
+ const onResizeEnd = () => {
+ if (cropper) {
+ cropper.resizeCoordinatesEnd();
+ }
+ };
+
+ const { width, height, left, top } = coordinates
+ ? isFunction(coordinates)
+ ? coordinates(state)
+ : coordinates
+ : getStencilCoordinates(state);
+
+ return (
+ state && (
+
+
+
+
+
+
+
+ )
+ );
+ },
+);
+
+ImageStencil.displayName = 'ImageStencil';
diff --git a/src/pages/custom/product/sample/editor/index.tsx b/src/pages/custom/product/sample/editor/index.tsx
new file mode 100644
index 0000000..a5498b4
--- /dev/null
+++ b/src/pages/custom/product/sample/editor/index.tsx
@@ -0,0 +1,29 @@
+import React, { useState } from 'react';
+import { CropperRef, Cropper } from 'react-advanced-cropper';
+import 'react-advanced-cropper/dist/style.css'
+import { ImageStencil } from "./components/ImageStencil";
+
+export default () => {
+ const [image] = useState(
+ 'https://test.vogocm.com:9010/eshop/eshop_img/2023/8/21/20230821114346A053.jpg',
+ );
+
+ const onChange = (cropper: CropperRef) => {
+ console.log(cropper.getCoordinates(), cropper.getCanvas());
+ };
+
+ return (
+
+ )
+}
diff --git a/src/pages/custom/product/sample/index.tsx b/src/pages/custom/product/sample/index.tsx
index 32b7ce8..39f8d03 100644
--- a/src/pages/custom/product/sample/index.tsx
+++ b/src/pages/custom/product/sample/index.tsx
@@ -8,6 +8,7 @@ import SampleAttrEditor from './components/attr-editor'
import MaskPictureEditor from './components/mask-picture-editor';
import type { SampleAttribute } from './components/attr-editor'
import type { MaskPicture } from './components/mask-picture-editor';
+import { useNavigate } from 'react-router-dom';
interface DataType {
id: number;
@@ -79,7 +80,10 @@ const TablePage: React.FC = () => {
// setEditData(record);
setAttrEditorVisible(true);
}}>属性设置
- 编辑
+ {
+ navigate('/custom/product/sample/editor')
+ }}>编辑
删除
),
@@ -206,7 +210,7 @@ const TablePage: React.FC = () => {
const [attrEditorVisible, setAttrEditorVisible] = useState(false);
const [maskEditorVisible, setMaskEditorVisible] = useState(false);
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
-
+ const navigate = useNavigate();
const cancelHandle = () => {
setAttrEditorVisible(false);
};
diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx
index 2a20401..10cad63 100644
--- a/src/pages/login/index.tsx
+++ b/src/pages/login/index.tsx
@@ -14,6 +14,7 @@ import './index.css'
const Login = () => {
const navigate = useNavigate();
const { runAsync: listMenus } = useRequest(userService.listMenus, { manual: true });
+ const { runAsync: getProfile } = useRequest(userService.getProfile, { manual: true });
const { runAsync: login, loading } = useRequest(loginService.login, { manual: true });
const { runAsync: rerefshToken } = useRequest(loginService.rerefshToken, { manual: true });
const { setCurrentUser } = useUserStore();
@@ -28,9 +29,10 @@ const Login = () => {
// data.data.avatarUrl = 'https://test.vogocm.com:9010/eshop/eshop_img/2023/5/24/43853633d16749bfb291f81bebb73451_20230524150631A001.jpg';
setRefreshToken(data.refreshToken);
setToken(data.accessToken);
- const [ _, { data: menus } ] = await listMenus()
+ const [ _, { data: menus } ] = await listMenus();
+ const [err, {data: profile}] = await getProfile();
// const [ error, {data: tokenData}] = await rerefshToken(data.refreshToken)
- debugger
+ setCurrentUser(profile)
navigate('/');
};
diff --git a/src/request/index.ts b/src/request/index.ts
index db8eee7..f902f64 100644
--- a/src/request/index.ts
+++ b/src/request/index.ts
@@ -13,8 +13,8 @@ import { ResponseDTO } from '@/models';
const { apiUrl = '' } = useGlobSetting();
-
-const refreshTokenUrl = '/api/auth/refresh/token';
+const loginUrl = '/auth/login';
+const refreshTokenUrl = '/app-api/member/auth/refresh-token';
export type Response = Promise<[boolean, T, AxiosResponse]>;
@@ -70,9 +70,10 @@ class Request {
const {token} = useGlobalStore.getState();
- if (token) {
+ if (token && !axiosConfig.url?.endsWith(loginUrl)) {
axiosConfig.headers.Authorization = `Bearer ${token}`;
}
+ axiosConfig.headers['tenant-id'] = '1';
return Promise.resolve(axiosConfig);
}
@@ -99,6 +100,7 @@ class Request {
this.requestingCount += 1;
const {token} = useGlobalStore.getState();
config.headers.Authorization = `Bearer ${token}`;
+ config.headers['tenant-id'] = '1'
resolve(config);
}
}
diff --git a/src/request/service/user.ts b/src/request/service/user.ts
index 6aca3ed..8b6bc7d 100644
--- a/src/request/service/user.ts
+++ b/src/request/service/user.ts
@@ -1,8 +1,12 @@
import request from '@/request';
-import { Menu } from '@/models';
+import { Menu, User } from '@/models';
export default {
listMenus: () => {
return request.get