From 4d97647ec29563c1cb0b0c01bafe9f8a70839977 Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期一, 15 十二月 2025 16:17:51 +0800
Subject: [PATCH] #
---
zy-acs-flow/src/map/http.js | 15 +++++
zy-acs-flow/src/map/areaSettings/AreaBasicTab.jsx | 30 +++++----
zy-acs-flow/src/map/areaSettings/index.jsx | 118 ++++++++++++++++++++++++---------------
3 files changed, 104 insertions(+), 59 deletions(-)
diff --git a/zy-acs-flow/src/map/areaSettings/AreaBasicTab.jsx b/zy-acs-flow/src/map/areaSettings/AreaBasicTab.jsx
index 13efc82..d6d6463 100644
--- a/zy-acs-flow/src/map/areaSettings/AreaBasicTab.jsx
+++ b/zy-acs-flow/src/map/areaSettings/AreaBasicTab.jsx
@@ -13,13 +13,14 @@
import { useTranslate } from 'react-admin';
const AreaBasicTab = ({
- areaName,
- setAreaName,
+ name,
+ setName,
agvOptions,
- selectedAgvs,
- setSelectedAgvs,
- barcodeList,
+ agvList,
+ setAgvList,
+ codeListText,
onSave,
+ disableSave,
}) => {
const translate = useTranslate();
const icon = <CheckBoxOutlineBlankIcon fontSize="small" />;
@@ -45,12 +46,9 @@
<TextField
label={translate('page.map.area.name', { _: '鍚嶇О' })}
fullWidth
- value={areaName}
- onChange={(e) => setAreaName(e.target.value)}
+ value={name}
+ onChange={(e) => setName(e.target.value)}
/>
- <Button variant="contained" onClick={onSave}>
- {translate('common.action.save', { _: '淇濆瓨' })}
- </Button>
</Stack>
<Box>
@@ -61,11 +59,11 @@
multiple
disableCloseOnSelect
options={agvOptions || []}
- value={selectedAgvs || []}
+ value={agvList || []}
getOptionLabel={getOptionLabel}
isOptionEqualToValue={(option, value) => getOptionId(option) === getOptionId(value)}
onChange={(event, newValue) => {
- setSelectedAgvs(newValue);
+ setAgvList(newValue);
}}
renderOption={(props, option, { selected }) => (
<li {...props}>
@@ -98,10 +96,16 @@
multiline
minRows={6}
maxRows={10}
- value={barcodeList}
+ value={codeListText}
InputProps={{ readOnly: true }}
/>
</Box>
+
+ <Box display="flex" justifyContent="flex-start">
+ <Button variant="contained" onClick={onSave} disabled={disableSave}>
+ {translate('common.action.save', { _: '淇濆瓨' })}
+ </Button>
+ </Box>
</Stack>
);
};
diff --git a/zy-acs-flow/src/map/areaSettings/index.jsx b/zy-acs-flow/src/map/areaSettings/index.jsx
index 3871dfb..1117f55 100644
--- a/zy-acs-flow/src/map/areaSettings/index.jsx
+++ b/zy-acs-flow/src/map/areaSettings/index.jsx
@@ -17,13 +17,26 @@
import { PAGE_DRAWER_WIDTH } from '@/config/setting';
import AreaBasicTab from './AreaBasicTab';
import AreaAdvancedTab from './AreaAdvancedTab';
-import { getAreaInfo } from '../http';
+import { getAreaInfo, fetchAgvListAll } from '../http';
const getAgvOptionId = (option) => {
if (typeof option === 'string') {
return option;
}
return option?.value ?? option?.id ?? option?.agvNo ?? option?.code ?? option?.name ?? '';
+};
+
+const areAgvSelectionsEqual = (aIds = [], bIds = []) => {
+ if (aIds.length !== bIds.length) {
+ return false;
+ }
+ const setA = new Set(aIds);
+ return bIds.every(id => setA.has(id));
+};
+
+const mapSelectionToOptions = (selection = [], options = []) => {
+ const optionMap = new Map(options.map(option => [getAgvOptionId(option), option]));
+ return selection.map(item => optionMap.get(getAgvOptionId(item)) || item);
};
const AreaSettings = (props) => {
@@ -37,15 +50,16 @@
}
const [activeTab, setActiveTab] = useState(0);
- const [areaName, setAreaName] = useState('');
- const [selectedAgvs, setSelectedAgvs] = useState([]);
- const [barcodeList, setBarcodeList] = useState('');
- const [areaCode, setAreaCode] = useState('');
- const [maxQty, setMaxQty] = useState('');
+ const [name, setName] = useState('');
+ const [agvList, setAgvList] = useState([]);
+ const [codeList, setCodeList] = useState([]);
+ const [code, setCode] = useState('');
+ const [maxCount, setMaxCount] = useState('');
const [speedLimit, setSpeedLimit] = useState('');
- const [shapeData, setShapeData] = useState('');
+ const [memo, setMemo] = useState('');
const [priority, setPriority] = useState('');
-
+ const [agvOptions, setAgvOptions] = useState([]);
+ const [initialBasic, setInitialBasic] = useState({ name: '', agvIds: [] });
const [curAreaInfo, setCurAreaInfo] = useState(null);
const fetchAreaInfo = (areaId) => {
@@ -59,43 +73,43 @@
fetchAreaInfo(sprite.data.id);
} else {
setCurAreaInfo(null);
- setAreaName('');
- setAreaCode('');
- setMaxQty('');
+ setName('');
+ setCode('');
+ setMaxCount('');
setSpeedLimit('');
- setShapeData('');
+ setMemo('');
setPriority('');
- setSelectedAgvs([]);
- setBarcodeList('');
+ setAgvList([]);
+ setCodeList([]);
+ setInitialBasic({ name: '', agvIds: [] });
}
}, [sprite]);
- const agvOptions = useMemo(() => {
- if (!curAreaInfo) {
- return [];
- }
- return curAreaInfo.agvOptions || curAreaInfo.agvCandidates || curAreaInfo.agvList || [];
- }, [curAreaInfo]);
+ useEffect(() => {
+ fetchAgvListAll().then((options) => {
+ setAgvOptions(options || []);
+ });
+ }, []);
useEffect(() => {
if (curAreaInfo) {
- setAreaName(curAreaInfo.name || '');
- setAreaCode(curAreaInfo.code || '');
- setMaxQty(curAreaInfo.maxQty || '');
- setSpeedLimit(curAreaInfo.speedLimit || '');
- setShapeData(curAreaInfo.shape || '');
- setPriority(curAreaInfo.priority || '');
+ setName(curAreaInfo.name || '');
+ setCode(curAreaInfo.code || '');
+ setMaxCount(curAreaInfo.maxCount ?? '');
+ setSpeedLimit(curAreaInfo.speedLimit ?? '');
+ setMemo(curAreaInfo.memo || '');
+ 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 selected = curAreaInfo.agvList || [];
+ const normalizedSelection = mapSelectionToOptions(selected, agvOptions);
+ setAgvList(normalizedSelection);
+ setInitialBasic({
+ name: curAreaInfo.name || '',
+ agvIds: normalizedSelection.map(getAgvOptionId)
+ });
- const barcodes = curAreaInfo.barcodes || curAreaInfo.barcodeList || [];
- setBarcodeList(Array.isArray(barcodes) ? barcodes.join('\n') : (barcodes || ''));
+ const codes = curAreaInfo.codeList || [];
+ setCodeList(Array.isArray(codes) ? codes : []);
}
}, [curAreaInfo, agvOptions]);
@@ -105,11 +119,22 @@
const handleSaveBasic = () => {
// placeholder for save logic
+ setInitialBasic({
+ name,
+ agvIds: agvList.map(getAgvOptionId),
+ });
};
const handleSaveAdvanced = () => {
// placeholder for save logic
};
+
+ const codeListText = (codeList || []).join('\n');
+ const basicDirty = name !== initialBasic.name
+ || !areAgvSelectionsEqual(
+ agvList.map(getAgvOptionId),
+ initialBasic.agvIds
+ );
return (
<>
@@ -165,25 +190,26 @@
<Box p={3}>
{activeTab === 0 && (
<AreaBasicTab
- areaName={areaName}
- setAreaName={setAreaName}
+ name={name}
+ setName={setName}
agvOptions={agvOptions}
- selectedAgvs={selectedAgvs}
- setSelectedAgvs={setSelectedAgvs}
- barcodeList={barcodeList}
+ agvList={agvList}
+ setAgvList={setAgvList}
+ codeListText={codeListText}
onSave={handleSaveBasic}
+ disableSave={!basicDirty}
/>
)}
{activeTab === 1 && (
<AreaAdvancedTab
- areaCode={areaCode}
- setAreaCode={setAreaCode}
- maxQty={maxQty}
- setMaxQty={setMaxQty}
+ areaCode={code}
+ setAreaCode={setCode}
+ maxQty={maxCount}
+ setMaxQty={setMaxCount}
speedLimit={speedLimit}
setSpeedLimit={setSpeedLimit}
- shapeData={shapeData}
- setShapeData={setShapeData}
+ shapeData={memo}
+ setShapeData={setMemo}
priority={priority}
setPriority={setPriority}
onSave={handleSaveAdvanced}
diff --git a/zy-acs-flow/src/map/http.js b/zy-acs-flow/src/map/http.js
index 27de2c1..11346d4 100644
--- a/zy-acs-flow/src/map/http.js
+++ b/zy-acs-flow/src/map/http.js
@@ -430,3 +430,18 @@
}
return null;
}
+
+export const fetchAgvListAll = async () => {
+ try {
+ const res = await request.get('/agv/list');
+ const { code, msg, data } = res.data;
+ if (code === 200) {
+ return data || [];
+ }
+ notify.error(msg);
+ } catch (error) {
+ notify.error(error.message);
+ console.error(error.message);
+ }
+ return [];
+}
--
Gitblit v1.9.1