From e246aa751c6a8b36721e8acf70acc238188f49dc Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期一, 15 十二月 2025 11:12:25 +0800
Subject: [PATCH] #

---
 zy-acs-flow/src/map/http.js                                                               |    7 +
 zy-acs-flow/src/map/areaSettings/AreaBasicTab.jsx                                         |   71 +++++++++++++++++++----
 zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/AreaService.java          |    2 
 zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/MapController.java     |    3 
 zy-acs-flow/src/map/areaSettings/index.jsx                                                |   61 ++++++++++++++-----
 zy-acs-flow/src/map/MapPage.jsx                                                           |    9 ++-
 zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AreaServiceImpl.java |    4 +
 7 files changed, 119 insertions(+), 38 deletions(-)

diff --git a/zy-acs-flow/src/map/MapPage.jsx b/zy-acs-flow/src/map/MapPage.jsx
index 1b6ef7e..6012922 100644
--- a/zy-acs-flow/src/map/MapPage.jsx
+++ b/zy-acs-flow/src/map/MapPage.jsx
@@ -370,10 +370,13 @@
                                 setCurSprite(null);
                                 const started = Tool.startAreaDrawing({
                                     promptText: translate('page.map.prompt.areaName'),
-                                    onComplete: ({ name, start, end, color }) => {
+                                    onComplete: ({ name, start, end, color, graphics }) => {
                                         if (name) {
-                                            Http.saveAreaData(curZone, { name, start, end, color });
-                                            notify.success(translate('page.map.msg.areaCreated', { name }));
+                                            Http.saveAreaData(curZone, { name, start, end, color }).then((savedArea) => {
+                                                if (savedArea?.id && graphics?.data) {
+                                                    graphics.data.id = savedArea.id;
+                                                }
+                                            });
                                         }
                                     },
                                     onFinish: () => {
diff --git a/zy-acs-flow/src/map/areaSettings/AreaBasicTab.jsx b/zy-acs-flow/src/map/areaSettings/AreaBasicTab.jsx
index 639edc0..13efc82 100644
--- a/zy-acs-flow/src/map/areaSettings/AreaBasicTab.jsx
+++ b/zy-acs-flow/src/map/areaSettings/AreaBasicTab.jsx
@@ -1,17 +1,43 @@
 import React from 'react';
-import { Stack, TextField, Button, Typography, Box } from '@mui/material';
+import {
+    Stack,
+    TextField,
+    Button,
+    Typography,
+    Box,
+    Autocomplete,
+    Checkbox,
+} from '@mui/material';
+import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';
+import CheckBoxIcon from '@mui/icons-material/CheckBox';
 import { useTranslate } from 'react-admin';
 
 const AreaBasicTab = ({
     areaName,
     setAreaName,
-    agvList,
-    setAgvList,
+    agvOptions,
+    selectedAgvs,
+    setSelectedAgvs,
     barcodeList,
-    setBarcodeList,
     onSave,
 }) => {
     const translate = useTranslate();
+    const icon = <CheckBoxOutlineBlankIcon fontSize="small" />;
+    const checkedIcon = <CheckBoxIcon fontSize="small" />;
+
+    const getOptionLabel = (option) => {
+        if (typeof option === 'string') {
+            return option;
+        }
+        return option?.label ?? option?.name ?? option?.agvNo ?? option?.value ?? option?.id ?? '';
+    };
+
+    const getOptionId = (option) => {
+        if (typeof option === 'string') {
+            return option;
+        }
+        return option?.value ?? option?.id ?? option?.agvNo ?? option?.code ?? option?.name ?? '';
+    };
 
     return (
         <Stack spacing={2}>
@@ -31,13 +57,34 @@
                 <Typography variant="subtitle2" gutterBottom>
                     {translate('page.map.area.agv', { _: '娣诲姞AGV灏忚溅' })}
                 </Typography>
-                <TextField
-                    placeholder={translate('page.map.area.agv.placeholder', { _: '鐢ㄩ�楀彿鍒嗛殧锛歛gv01, agv02' })}
-                    fullWidth
-                    multiline
-                    minRows={3}
-                    value={agvList}
-                    onChange={(e) => setAgvList(e.target.value)}
+                <Autocomplete
+                    multiple
+                    disableCloseOnSelect
+                    options={agvOptions || []}
+                    value={selectedAgvs || []}
+                    getOptionLabel={getOptionLabel}
+                    isOptionEqualToValue={(option, value) => getOptionId(option) === getOptionId(value)}
+                    onChange={(event, newValue) => {
+                        setSelectedAgvs(newValue);
+                    }}
+                    renderOption={(props, option, { selected }) => (
+                        <li {...props}>
+                            <Checkbox
+                                icon={icon}
+                                checkedIcon={checkedIcon}
+                                style={{ marginRight: 8 }}
+                                checked={selected}
+                            />
+                            {getOptionLabel(option)}
+                        </li>
+                    )}
+                    renderInput={(params) => (
+                        <TextField
+                            {...params}
+                            placeholder={translate('page.map.area.agv.placeholder', { _: '閫夋嫨AGV' })}
+                        />
+                    )}
+                    ListboxProps={{ sx: { maxHeight: 280 } }}
                 />
             </Box>
 
@@ -52,7 +99,7 @@
                     minRows={6}
                     maxRows={10}
                     value={barcodeList}
-                    onChange={(e) => setBarcodeList(e.target.value)}
+                    InputProps={{ readOnly: true }}
                 />
             </Box>
         </Stack>
diff --git a/zy-acs-flow/src/map/areaSettings/index.jsx b/zy-acs-flow/src/map/areaSettings/index.jsx
index 11dd4a1..3871dfb 100644
--- a/zy-acs-flow/src/map/areaSettings/index.jsx
+++ b/zy-acs-flow/src/map/areaSettings/index.jsx
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, useMemo } from 'react';
 import { useTranslate } from "react-admin";
 import {
     Drawer,
@@ -19,6 +19,13 @@
 import AreaAdvancedTab from './AreaAdvancedTab';
 import { getAreaInfo } from '../http';
 
+const getAgvOptionId = (option) => {
+    if (typeof option === 'string') {
+        return option;
+    }
+    return option?.value ?? option?.id ?? option?.agvNo ?? option?.code ?? option?.name ?? '';
+};
+
 const AreaSettings = (props) => {
     const { open, onCancel, sprite, width = PAGE_DRAWER_WIDTH } = props;
     const theme = useTheme();
@@ -31,7 +38,7 @@
 
     const [activeTab, setActiveTab] = useState(0);
     const [areaName, setAreaName] = useState('');
-    const [agvList, setAgvList] = useState('');
+    const [selectedAgvs, setSelectedAgvs] = useState([]);
     const [barcodeList, setBarcodeList] = useState('');
     const [areaCode, setAreaCode] = useState('');
     const [maxQty, setMaxQty] = useState('');
@@ -48,29 +55,49 @@
     }
 
     useEffect(() => {
-        if (sprite?.data) {
-            console.log(sprite.data);
+        if (sprite?.data?.id) {
             fetchAreaInfo(sprite.data.id);
-
-            setAreaName(sprite.data.name || '');
-            setAreaCode(sprite.data.code || '');
-            setMaxQty(sprite.data.maxQty || '');
-            setSpeedLimit(sprite.data.speedLimit || '');
-            setShapeData(sprite.data.shape || '');
-            setPriority(sprite.data.priority || '');
-            setAgvList((sprite.data.agvs || []).join(', '));
-            setBarcodeList((sprite.data.barcodes || []).join('\n'));
         } else {
+            setCurAreaInfo(null);
             setAreaName('');
             setAreaCode('');
             setMaxQty('');
             setSpeedLimit('');
             setShapeData('');
             setPriority('');
-            setAgvList('');
+            setSelectedAgvs([]);
             setBarcodeList('');
         }
     }, [sprite]);
+
+    const agvOptions = useMemo(() => {
+        if (!curAreaInfo) {
+            return [];
+        }
+        return curAreaInfo.agvOptions || curAreaInfo.agvCandidates || curAreaInfo.agvList || [];
+    }, [curAreaInfo]);
+
+    useEffect(() => {
+        if (curAreaInfo) {
+            setAreaName(curAreaInfo.name || '');
+            setAreaCode(curAreaInfo.code || '');
+            setMaxQty(curAreaInfo.maxQty || '');
+            setSpeedLimit(curAreaInfo.speedLimit || '');
+            setShapeData(curAreaInfo.shape || '');
+            setPriority(curAreaInfo.priority || '');
+
+            const selected = curAreaInfo.selectedAgvs || curAreaInfo.agvs || [];
+            if (Array.isArray(selected) && Array.isArray(agvOptions) && agvOptions.length > 0) {
+                const optionMap = new Map(agvOptions.map(option => [getAgvOptionId(option), option]));
+                setSelectedAgvs(selected.map(item => optionMap.get(getAgvOptionId(item)) || item));
+            } else {
+                setSelectedAgvs(selected);
+            }
+
+            const barcodes = curAreaInfo.barcodes || curAreaInfo.barcodeList || [];
+            setBarcodeList(Array.isArray(barcodes) ? barcodes.join('\n') : (barcodes || ''));
+        }
+    }, [curAreaInfo, agvOptions]);
 
     const handleTabChange = (event, newValue) => {
         setActiveTab(newValue);
@@ -140,10 +167,10 @@
                                             <AreaBasicTab
                                                 areaName={areaName}
                                                 setAreaName={setAreaName}
-                                                agvList={agvList}
-                                                setAgvList={setAgvList}
+                                                agvOptions={agvOptions}
+                                                selectedAgvs={selectedAgvs}
+                                                setSelectedAgvs={setSelectedAgvs}
                                                 barcodeList={barcodeList}
-                                                setBarcodeList={setBarcodeList}
                                                 onSave={handleSaveBasic}
                                             />
                                         )}
diff --git a/zy-acs-flow/src/map/http.js b/zy-acs-flow/src/map/http.js
index 6180ac3..27de2c1 100644
--- a/zy-acs-flow/src/map/http.js
+++ b/zy-acs-flow/src/map/http.js
@@ -418,12 +418,15 @@
             zoneId: zoneId,
             ...areaData,
         });
-        const { code, msg } = res.data;
+        const { code, msg, data } = res.data;
         if (code !== 200) {
             notify.error(msg);
+            return null;
         }
+        return data;
     } catch (error) {
         notify.error(error.message);
         console.error(error.message);
     }
-}
\ No newline at end of file
+    return null;
+}
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/MapController.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/MapController.java
index b225fbb..4ab0eb5 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/MapController.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/controller/MapController.java
@@ -452,8 +452,7 @@
     @PostMapping("/area/save")
     @Transactional
     public R save(@RequestBody MapAreaParam param) {
-        areaService.saveMapArea(param, getLoginUserId());
-        return R.ok();
+        return R.ok().add(areaService.saveMapArea(param, getLoginUserId()));
     }
 
 }
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/AreaService.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/AreaService.java
index 2627aa6..11244f1 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/AreaService.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/AreaService.java
@@ -6,6 +6,6 @@
 
 public interface AreaService extends IService<Area> {
 
-    void saveMapArea(MapAreaParam param, Long loginUserId);
+    Area saveMapArea(MapAreaParam param, Long loginUserId);
 
 }
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AreaServiceImpl.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AreaServiceImpl.java
index ae20671..d82e44e 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AreaServiceImpl.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/manager/service/impl/AreaServiceImpl.java
@@ -22,7 +22,7 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void saveMapArea(MapAreaParam param, Long loginUserId) {
+    public Area saveMapArea(MapAreaParam param, Long loginUserId) {
         Date now = new Date();
 
         Area area = new Area();
@@ -53,6 +53,8 @@
         if (!this.save(area)) {
             log.error("failed to save area");
         }
+
+        return area;
     }
 
 }

--
Gitblit v1.9.1