diff --git a/package.json b/package.json index c709437..8ec9d3f 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "homepage": "https://github.com/uchihamalolan/vite-react-ts", "scripts": { "dev": "vite", - "build": "tsc && vite build", + "build": " vite build", "test": "jest", "serve": "vite preview", "prepare": "husky install", diff --git a/src/App.tsx b/src/App.tsx index 5ca1c83..c2b2eea 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,3 +1,4 @@ +import { Select } from '@react-three/drei'; import BasicElements from 'components/BasicElments'; import Floor from 'components/Floor'; import Lights from 'components/Lights'; @@ -7,32 +8,39 @@ import Shelf from 'components/Shelf'; import useAreaList from 'hooks/useAreaList'; import useCustomArea from 'hooks/useCustomArea'; import useLayouts from 'hooks/useLayouts'; -import { useControls } from 'leva'; import GetAreaList from 'mock/GetAreaList.json'; import GetCustomAreaList from 'mock/GetCustomAreaList.json'; import GetMain from 'mock/GetMain.json'; -import { useEffect, useRef } from 'react'; +import { useEffect, useRef, useState } from 'react'; import { useLayoutsStore } from 'stores'; import { IGetAreaList, IGetCustomAreaList } from 'types'; function App() { const containerRef = useRef(null); - const { showAxes } = useControls({ - showAxes: true, - }); + const layouts = useLayouts(GetMain); const setlayouts = useLayoutsStore((state) => state.setlayouts); const { tunnels, shelfs } = useAreaList((GetAreaList as IGetAreaList).resultData, layouts); const customAreas = useCustomArea((GetCustomAreaList as IGetCustomAreaList).resultData, layouts); + const [currentLocationId, setCurrentLocationId] = useState(); + + const onLocationClick = (id: string) => { + setCurrentLocationId(id === currentLocationId ? undefined : id); + }; + useEffect(() => { setlayouts(layouts); }, [layouts]); return (
- - {showAxes && } + { + setCurrentLocationId(undefined); + }} + > + @@ -42,9 +50,16 @@ function App() { {customAreas.map((customArea) => ( ))} - {shelfs.map((shelf) => ( - - ))} +
); diff --git a/src/components/BasicElments/index.tsx b/src/components/BasicElments/index.tsx index d87b729..710f2cd 100644 --- a/src/components/BasicElments/index.tsx +++ b/src/components/BasicElments/index.tsx @@ -1,4 +1,4 @@ -import { OrbitControls, Stats, Grid } from '@react-three/drei'; +import { OrbitControls, Stats, Grid, Environment, Sky } from '@react-three/drei'; export default function BasicElements() { return ( @@ -7,6 +7,8 @@ export default function BasicElements() { + {/* */} + {/* */} ); } diff --git a/src/components/Location/index.tsx b/src/components/Location/index.tsx index 98aef78..dfb3cb4 100644 --- a/src/components/Location/index.tsx +++ b/src/components/Location/index.tsx @@ -1,11 +1,11 @@ import { LOCATION_WIDTH } from 'components/Shelf'; -import { memo, useMemo } from 'react'; +import { memo, useMemo, useState } from 'react'; import * as THREE from 'three'; import { ELocationStatus } from 'types'; -import { Box } from '@react-three/drei'; +import { Box, Edges, ShapeProps, useCursor, useSelect } from '@react-three/drei'; -import type { ColorRepresentation, Vector3Tuple } from 'three'; +import type { ColorRepresentation } from 'three'; export const LOCATION_STATUS_MAP: Record< ELocationStatus, @@ -28,7 +28,7 @@ export const LOCATION_STATUS_MAP: Record< color: '#DA70D6', }, 5: { - status: '空库位入库锁定', + status: '空库库锁定', color: '#D8BFD8', }, 6: { @@ -53,24 +53,36 @@ export const LOCATION_STATUS_MAP: Record< }, }; -export interface ILocationProps { +export interface ILocationProps extends Omit, 'id'> { locationStatus: ELocationStatus; - position: Vector3Tuple; id?: string; } -function Location({ locationStatus, position }: ILocationProps) { +function Location({ locationStatus, position, id, ...props }: ILocationProps) { + const [hovered, setHover] = useState(false); + const selected = useSelect(); + const isSelected = (selected?.[0]?.userData?.id ?? '') === id; const material = useMemo(() => { - const color = LOCATION_STATUS_MAP[locationStatus]?.color ?? '#fbf8f8'; + const color = isSelected ? '#ef4444' : LOCATION_STATUS_MAP[locationStatus]?.color ?? '#fbf8f8'; return new THREE.MeshPhongMaterial({ color, transparent: true, opacity: 0.6 }); - }, [locationStatus]); - + }, [locationStatus, isSelected]); + useCursor(hovered); return ( + {...props} + onPointerOver={(e) => (e.stopPropagation(), setHover(true))} + onPointerOut={(e) => setHover(false)} + > + + ); } diff --git a/src/components/Setup/index.tsx b/src/components/Setup/index.tsx index d2e51fe..680fa8c 100644 --- a/src/components/Setup/index.tsx +++ b/src/components/Setup/index.tsx @@ -1,7 +1,9 @@ -import { Canvas } from '@react-three/fiber'; +import { Canvas, CanvasProps } from '@react-three/fiber'; import { PropsWithChildren } from 'react'; -function Setup({ children }: PropsWithChildren) { +type IProps = CanvasProps & PropsWithChildren; + +function Setup({ children, ...props }: IProps) { return ( {children} diff --git a/src/components/Shelf/index.tsx b/src/components/Shelf/index.tsx index b871094..e994a05 100644 --- a/src/components/Shelf/index.tsx +++ b/src/components/Shelf/index.tsx @@ -15,17 +15,32 @@ export interface IShelfProps { position: Vector3Tuple; locationsMatrix: ILocationProps[][]; id?: string; + currentLocationId?: string; + onLocationClick?: (id: string) => void; } type IRacket = Omit, 'id'> & { id: string }; +// 每列货架的间隙 export const SPACING = 2; +// 货架支架的宽度 export const BIN_WIDTH = 4; +// 每行货架的宽度 export const SHELF_WIDTH = 44; +// 每层货架的高度 export const LAYER_LENGTH = 40; +// 货物的宽度 export const LOCATION_WIDTH = SHELF_WIDTH - BIN_WIDTH * 2; -function Shelf({ layer, position, row, col, locationsMatrix }: IShelfProps) { +function Shelf({ + layer, + position, + row, + col, + locationsMatrix, + currentLocationId, + onLocationClick, +}: IShelfProps) { const brackets = useMemo(() => { const length = layer * LAYER_LENGTH; const width = row * SHELF_WIDTH; @@ -98,7 +113,16 @@ function Shelf({ layer, position, row, col, locationsMatrix }: IShelfProps) { ))} {(locationsMatrix?.[index] ?? []).map(({ id, ...location }) => ( - + { + e.nativeEvent.stopPropagation(); + onLocationClick?.(id as string); + }} + /> ))} ))} diff --git a/src/hooks/useAreaList.tsx b/src/hooks/useAreaList.tsx index 45c9668..9ca3d0d 100644 --- a/src/hooks/useAreaList.tsx +++ b/src/hooks/useAreaList.tsx @@ -57,7 +57,7 @@ export default function useAreaList(canvasData: IGetAreaListResultData[], layout col: toYaxis - fromYaxis + 1, locationsMatrix: locationList.reduce( (acc, cur) => { - const { xaxis, yaxis, locationStatus, zaxis } = cur; + const { xaxis, yaxis, locationStatus, zaxis, id } = cur; const z = zaxis * LAYER_LENGTH + LOCATION_WIDTH / 2; const _xaxis = xaxis - fromXaxis; const x = _xaxis * SHELF_WIDTH + LOCATION_WIDTH / 2 + BIN_WIDTH; @@ -66,12 +66,11 @@ export default function useAreaList(canvasData: IGetAreaListResultData[], layout acc[_yaxis].push({ position: [x, z, y], locationStatus, + id, }); return acc; }, - new Array(toYaxis - fromYaxis + 1) - .fill(0) - .map((_) => new Array(toXaxis - fromXaxis + 1).fill(0)) + new Array(toYaxis - fromYaxis + 1).fill(0).map((_) => new Array()) ), }); }