From a673254db9bdc9e540b0b67b4ef63c0deb64916a Mon Sep 17 00:00:00 2001 From: luxiaotao1123 <t1341870251@163.com> Date: 星期二, 15 十月 2024 13:59:23 +0800 Subject: [PATCH] # --- zy-acs-flow/src/map/http.js | 2 zy-acs-flow/src/i18n/en.js | 1 zy-acs-flow/src/map/header/MapSearch.jsx | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++ zy-acs-flow/src/map/tool.js | 29 +++++++ zy-acs-flow/src/i18n/zh.js | 1 5 files changed, 237 insertions(+), 2 deletions(-) diff --git a/zy-acs-flow/src/i18n/en.js b/zy-acs-flow/src/i18n/en.js index 8fbcbcb..4d8fb5f 100644 --- a/zy-acs-flow/src/i18n/en.js +++ b/zy-acs-flow/src/i18n/en.js @@ -75,6 +75,7 @@ tip: 'Tip', desc: 'Are you sure you want to proceed?', }, + placeholder: 'Please enter your search content', }, }, filters: { diff --git a/zy-acs-flow/src/i18n/zh.js b/zy-acs-flow/src/i18n/zh.js index fb9a6b6..3a7ea00 100644 --- a/zy-acs-flow/src/i18n/zh.js +++ b/zy-acs-flow/src/i18n/zh.js @@ -74,6 +74,7 @@ tip: '鎻愮ず', desc: '鎮ㄧ‘瀹氳鎵ц姝ゆ搷浣滃悧锛�', }, + placeholder: '璇疯緭鍏ユ悳绱㈠唴瀹�', }, }, filters: { diff --git a/zy-acs-flow/src/map/header/MapSearch.jsx b/zy-acs-flow/src/map/header/MapSearch.jsx new file mode 100644 index 0000000..f5e5e16 --- /dev/null +++ b/zy-acs-flow/src/map/header/MapSearch.jsx @@ -0,0 +1,206 @@ +import React, { useState, useEffect } from 'react'; +import { + Select, + MenuItem, + Autocomplete, + TextField, + InputAdornment, + IconButton, + useTheme, +} from '@mui/material'; +import { useTranslate } from 'react-admin'; +import CloseIcon from '@mui/icons-material/Close'; +import { MAP_MODE, DEVICE_TYPE } from "../constants"; +import * as Tool from "../tool"; + +const renderTitle = (title, uuid) => ( + <> + <span style={{ fontWeight: 'bold' }}>{title}</span> + <span style={{ float: 'right', opacity: 0.3 }}>{uuid}</span> + </> +); + +const deviceTypeSelectOptionsFn = (translate) => { + const deviceTypes = [ + { + key: DEVICE_TYPE.SHELF, + id: 'page.map.devices.shelf', + }, + { + key: DEVICE_TYPE.STATION, + id: 'page.map.devices.station', + }, + { + key: DEVICE_TYPE.AGV, + id: 'page.map.devices.agv', + }, + { + key: DEVICE_TYPE.POINT, + id: 'page.map.devices.point', + }, + // Add other sensor types if needed + ]; + + return deviceTypes.map(({ key, id }) => ({ + value: key, + label: translate(id), + })); +}; + +const getAllDeviceList = (curDeviceType) => { + const children = Tool.getMapContainer()?.children || []; + return children.reduce((list, child) => { + if (child?.data) { + const { data } = child; + if (data.type === curDeviceType && data.no) { + list.push({ + value: data.no, + label: renderTitle(data.no, data.uuid), + }); + } + } + return list; + }, []); +}; + +const MapSearch = (props) => { + const { + setCurSprite, + setSpriteSettings, + mode, + setMode, + } = props; + + const theme = useTheme(); + const themeMode = theme.palette.mode; + const translate = useTranslate(); + + // type + const deviceTypeOptions = deviceTypeSelectOptionsFn(translate); + const [curDeviceType, setCurDeviceType] = useState( + deviceTypeOptions[0]?.value || '' + ); + // list + const [deviceList, setDeviceList] = useState([]); + const [filterDeviceList, setFilterDeviceList] = useState([]); + const [inputValue, setInputValue] = useState(''); + const [selectedOption, setSelectedOption] = useState(null); + + const resetSearch = () => { + const deviceListAll = getAllDeviceList(curDeviceType); + setDeviceList(deviceListAll); + setFilterDeviceList(deviceListAll); + setInputValue(''); + setSelectedOption(null); + }; + + useEffect(() => { + if (!Tool.getMapContainer()) return; + setTimeout(() => { + resetSearch(); + }, 200); + }, [curDeviceType, props.curZone]); + + useEffect(() => { + if (!Tool.getMapContainer()) return; + if (inputValue !== '' && deviceList.length > 0) { + setFilterDeviceList( + deviceList.filter((item) => item.value.includes(inputValue)) + ); + } else { + setFilterDeviceList(deviceList); + } + }, [inputValue]); + + const onSecondSelect = (option) => { + if (!option) return; + const uuid = option.label.props.children[1]?.props?.children; + const selectSprite = Tool.findSpriteByUuid(uuid); + if (selectSprite) { + Tool.focusSprite(selectSprite); + } + switch (mode) { + case MAP_MODE.OBSERVER_MODE: + setCurSprite(selectSprite); + break; + case MAP_MODE.MOVABLE_MODE: + setMode(MAP_MODE.SETTINGS_MODE); + setTimeout(() => { + setSpriteSettings(selectSprite); + }, 200); + break; + case MAP_MODE.SETTINGS_MODE: + setSpriteSettings(selectSprite); + break; + default: + break; + } + }; + + return ( + <> + <Select + className="map-header-select" + variant="filled" + style={{ width: 160, marginRight: 8 }} + size="medium" + value={curDeviceType} + onChange={(event) => setCurDeviceType(event.target.value)} + > + {deviceTypeOptions.map((option) => ( + <MenuItem key={option.value} value={option.value}> + <span style={{ fontWeight: 'bold' }}>{option.label}</span> + </MenuItem> + ))} + </Select> + <Autocomplete + className="map-header-select" + style={{ width: 360 }} + size="medium" + options={filterDeviceList} + getOptionLabel={(option) => option.value} + renderOption={(props, option) => ( + <li {...props}>{option.label}</li> + )} + renderInput={(params) => ( + <TextField + {...params} + variant="filled" + placeholder={translate('common.msg.placeholder')} + InputProps={{ + ...params.InputProps, + endAdornment: ( + <> + {params.InputProps.endAdornment} + {inputValue && ( + <InputAdornment position="end"> + <IconButton + onClick={() => { + setInputValue(''); + setSelectedOption(null); + }} + > + <CloseIcon /> + </IconButton> + </InputAdornment> + )} + </> + ), + }} + /> + )} + value={selectedOption} + onChange={(event, newValue) => { + setSelectedOption(newValue); + onSecondSelect(newValue); + }} + inputValue={inputValue} + onInputChange={(event, newInputValue) => { + setInputValue(newInputValue); + }} + /> + </> + ); +}; + +export default MapSearch; diff --git a/zy-acs-flow/src/map/http.js b/zy-acs-flow/src/map/http.js index 109bd7a..c317224 100644 --- a/zy-acs-flow/src/map/http.js +++ b/zy-acs-flow/src/map/http.js @@ -45,7 +45,7 @@ switch (item.type) { case DEVICE_TYPE.POINT: sprite.tint = 0xCACDCF; - sprite.scale.set(0.5, 0.5); + sprite.scale.set(0.65, 0.65); break default: break diff --git a/zy-acs-flow/src/map/tool.js b/zy-acs-flow/src/map/tool.js index 32a0124..8eab20d 100644 --- a/zy-acs-flow/src/map/tool.js +++ b/zy-acs-flow/src/map/tool.js @@ -129,6 +129,10 @@ } } +export const findSpriteByUuid = (uuid) => { + return mapContainer?.children?.find(child => child?.data?.uuid === uuid); +} + export const markSprite = (sprite) => { sprite.alpha = 0.5; } @@ -261,6 +265,29 @@ function onClick(event) { setSpriteSettings(sprite); } +} + +export const focusSprite = (sprite) => { + if (!sprite || !app || !mapContainer) { + return; + } + + mapContainer.scale.set(1); + mapContainer.position.set(0, 0); + + let bounds = sprite.getBounds(); + let focusPoint = { + x: bounds.x + bounds.width / 2, + y: bounds.y + bounds.height / 2 + }; + + let targetPos = { + x: app.renderer.width / 3 - focusPoint.x * mapContainer.scale.x, + y: app.renderer.height / 3 - focusPoint.y * mapContainer.scale.y + }; + + new TWEEDLE.Tween(mapContainer.position).easing(TWEEDLE.Easing.Quadratic.Out) + .to(targetPos, 500).start(); } export const clearMapData = () => { @@ -452,7 +479,7 @@ // dynamic graphic ---------------- export const generateDynamicGraphic = (curZone, data) => { - console.log("ws", curZone, data); + // console.log("ws", curZone, data); for (const agvVo of data.agvVos) { showAgvSprite(curZone, agvVo) -- Gitblit v1.9.1