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