From 1e99f0d8260b8343437015032c4faa113b5124f3 Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期三, 17 十二月 2025 13:40:31 +0800
Subject: [PATCH] #

---
 zy-acs-flow/src/i18n/en.js       |    1 
 zy-acs-flow/src/map/tool.js      |    2 
 zy-acs-flow/src/i18n/zh.js       |    1 
 zy-acs-flow/src/map/AreaList.jsx |  138 ++++++++++++++++++++++++++++++++++++++++++++++
 zy-acs-flow/src/map/MapPage.jsx  |   19 ++++++
 5 files changed, 160 insertions(+), 1 deletions(-)

diff --git a/zy-acs-flow/src/i18n/en.js b/zy-acs-flow/src/i18n/en.js
index c99369a..509406d 100644
--- a/zy-acs-flow/src/i18n/en.js
+++ b/zy-acs-flow/src/i18n/en.js
@@ -676,6 +676,7 @@
                 oneClickPatrol: 'One-click Patrol',
                 cancelPatrol: 'Cancel Patrol',
                 addArea: 'Add Area',
+                areaList: 'Area List',
             },
             mode: {
                 observer: 'OBSERVER',
diff --git a/zy-acs-flow/src/i18n/zh.js b/zy-acs-flow/src/i18n/zh.js
index bdf056c..00d03ba 100644
--- a/zy-acs-flow/src/i18n/zh.js
+++ b/zy-acs-flow/src/i18n/zh.js
@@ -676,6 +676,7 @@
                 oneClickPatrol: '涓�閿贰閫�',
                 cancelPatrol: '鍙栨秷宸¢��',
                 addArea: '娣诲姞鍖哄煙',
+                areaList: '鍖哄煙鍒楄〃',
             },
             mode: {
                 observer: '瑙傚療妯″紡',
diff --git a/zy-acs-flow/src/map/AreaList.jsx b/zy-acs-flow/src/map/AreaList.jsx
new file mode 100644
index 0000000..e759dfa
--- /dev/null
+++ b/zy-acs-flow/src/map/AreaList.jsx
@@ -0,0 +1,138 @@
+import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
+import { useTranslate } from "react-admin";
+import { Drawer, Box, Typography, Grid, IconButton, Stack, useTheme } from '@mui/material';
+import CloseIcon from '@mui/icons-material/Close';
+import * as Common from '@/utils/common';
+import { PAGE_DRAWER_WIDTH } from '@/config/setting';
+import * as Tool from './tool';
+
+import shelf from '/map/shelf.svg';
+import charge from '/map/charge.svg';
+import station from '/map/station.svg';
+import direction from '/map/direction.svg';
+
+const items = [
+    { src: shelf, label: 'page.map.devices.shelf', type: 'SHELF', scale: 1 },
+    { src: charge, label: 'page.map.devices.charge', type: 'CHARGE', scale: .7 },
+    { src: station, label: 'page.map.devices.station', type: 'STATION', scale: 1 },
+    { src: direction, label: 'page.map.devices.direction', type: 'DIRECTION', scale: 1 },
+];
+
+const AreaList = (props) => {
+    const {
+        title,
+        open,
+        onCancel,
+        closeCallback,
+        width = PAGE_DRAWER_WIDTH,
+        children
+    } = props;
+    const theme = useTheme();
+    const themeMode = theme.palette.mode;
+    const translate = useTranslate();
+
+    const [dragging, setDragging] = useState(false);
+    const [dragSprite, setDragSprite] = useState(null);
+    const [dragSpriteType, setDragSpriteType] = useState(null);
+
+    const handleClose = () => {
+        onCancel();
+        if (closeCallback) {
+            closeCallback();
+        }
+    }
+
+    const onDragStart = (e, type) => {
+        setDragging(true);
+        const sprite = Tool.generateSprite(type);
+        setDragSprite(sprite);
+        setDragSpriteType(type);
+    };
+
+    useEffect(() => {
+        const handleMouseMove = (e) => {
+            if (dragging) {
+                props.onDrop(dragSprite, dragSpriteType, e.clientX, e.clientY);
+                setDragging(false);
+                setDragSpriteType(null);
+            }
+        };
+        window.addEventListener('mousemove', handleMouseMove);
+        return () => window.removeEventListener('mousemove', handleMouseMove);
+    }, [dragging, props.onDrop, props.onCancel]);
+
+
+    return (
+        <Drawer
+            variant="persistent"
+            open={open}
+            anchor="right"
+            onClose={handleClose}
+            sx={{ zIndex: 100, opacity: .8 }}
+        >
+            {open && (
+                <Box pt={12} width={{ xs: '100vW', sm: width }} height={'calc(100vh - 200px);'} mt={{ xs: 2, sm: 1 }} sx={{
+                }}>
+                    <Stack direction="row" p={2}>
+                        <Typography variant="h6" flex="1">
+                            {title || translate('page.map.devices.title')}
+                        </Typography>
+                        <IconButton onClick={handleClose} size="small">
+                            <CloseIcon />
+                        </IconButton>
+                    </Stack>
+                    <Box p={3}>
+                        <Grid container spacing={0} sx={{
+                            borderTop: themeMode === 'light' ? '1px solid #f0f0f0' : '1px solid #303030',
+                            borderLeft: themeMode === 'light' ? '1px solid #f0f0f0' : '1px solid #303030',
+                        }}>
+                            {items.map((item, index) => {
+                                return (
+                                    <Grid
+                                        key={index}
+                                        item
+                                        xs={4}
+                                        onDragStart={(e) => onDragStart(e, item.type)}
+                                        draggable="true"
+                                    >
+                                        <Box
+                                            sx={{
+                                                height: '100px',
+                                                display: 'flex',
+                                                flexDirection: 'column',
+                                                justifyContent: 'center',
+                                                alignItems: 'center',
+                                                p: 2,
+                                                cursor: 'pointer',
+                                                borderRight: themeMode === 'light' ? '1px solid #f0f0f0' : '1px solid #303030',
+                                                borderBottom: themeMode === 'light' ? '1px solid #f0f0f0' : '1px solid #303030',
+                                                borderColor: 'divider',
+                                                '&:hover': {
+                                                    boxShadow: themeMode === 'light' ? '0px 5px 5px rgba(0, 0, 0, 0.15)' : '0px 5px 5px rgba(63, 63, 63, 0.8)',
+                                                    transition: 'all 0.3s ease !important',
+                                                },
+                                            }}
+                                        >
+                                            <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '70%' }}>
+                                                <img src={item.src} alt={item.label} width="50px" style={{
+                                                    transform: `scale(${item.scale || 1})`,
+                                                }} />
+                                            </Box>
+                                            <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '30%' }}>
+                                                <Typography variant="body2" sx={{ mt: 2.5, textAlign: 'center' }}>
+                                                    {translate(item.label)}
+                                                </Typography>
+                                            </Box>
+                                        </Box>
+                                    </Grid>
+                                )
+                            })}
+                        </Grid>
+                    </Box>
+                </Box>
+            )}
+        </Drawer>
+    )
+}
+
+export default AreaList;
\ No newline at end of file
diff --git a/zy-acs-flow/src/map/MapPage.jsx b/zy-acs-flow/src/map/MapPage.jsx
index 610badc..0de9c8a 100644
--- a/zy-acs-flow/src/map/MapPage.jsx
+++ b/zy-acs-flow/src/map/MapPage.jsx
@@ -14,6 +14,7 @@
 import { NotificationProvider, useNotification } from './Notification';
 import Insight from "./insight";
 import Device from "./Device";
+import AreaList from "./AreaList";
 import Settings from "./settings";
 import Batch from "./batch";
 import AreaSettings from "./areaSettings";
@@ -52,6 +53,7 @@
     const [settingsVisible, setSettingsVisible] = useState(false);
     const [batchSelectionVisible, setBatchSelectionVisible] = useState(false);
     const [areaSettingsVisible, setAreaSettingsVisible] = useState(false);
+    const [areaListVisible, setAreaListVisible] = useState(false);
     const [areaDrawing, setAreaDrawing] = useState(false);
 
     const [curSprite, setCurSprite] = useState(null);
@@ -139,6 +141,7 @@
         setBatchSelectionVisible(false);
         setAreaSettingsVisible(false);
         setAreaDrawing(false);
+        setAreaListVisible(false);
         Tool.cancelAreaDrawing();
         Tool.hideAreas(curZone, setShowAreas);
 
@@ -365,6 +368,13 @@
                 {mode === MAP_MODE.AREA_MODE && (
                     <>
                         <Button
+                            variant="outlined"
+                            onClick={() => setAreaListVisible(!areaListVisible)}
+                            sx={{ mr: 2 }}
+                        >
+                            {translate('page.map.action.areaList')}
+                        </Button>
+                        <Button
                             variant={areaDrawing ? "outlined" : "contained"}
                             color="primary"
                             sx={{}}
@@ -562,6 +572,15 @@
                 width={570}
             />
 
+            <AreaList
+                open={areaListVisible}
+                onCancel={() => {
+                    setAreaListVisible(false);
+                }}
+                onDrop={onDrop}
+                width={400}
+            />
+
         </Box>
     );
 }
diff --git a/zy-acs-flow/src/map/tool.js b/zy-acs-flow/src/map/tool.js
index e239915..2bd45c6 100644
--- a/zy-acs-flow/src/map/tool.js
+++ b/zy-acs-flow/src/map/tool.js
@@ -1001,7 +1001,7 @@
     if (setCurSprite) {
         draft.zIndex = DEVICE_Z_INDEX.AREA;
     }
-    draft.lineStyle(.5 / Math.abs(mapContainer.scale.x || 1), AREA_BORDER_COLOR, 0.9);
+    draft.lineStyle(1 / Math.abs(mapContainer.scale.x || 1), AREA_BORDER_COLOR, 0.9);
     draft.beginFill(areaColor, 0.18);
     draft.drawRect(
         Math.min(from.x, to.x),

--
Gitblit v1.9.1