From 7f70cb15d035f0c233b9e62b9e43aa985317c908 Mon Sep 17 00:00:00 2001 From: luxiaotao1123 <t1341870251@163.com> Date: 星期一, 04 十一月 2024 10:22:45 +0800 Subject: [PATCH] # --- zy-acs-flow/src/map/insight/agv/AgvMain.jsx | 284 +++++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 207 insertions(+), 77 deletions(-) diff --git a/zy-acs-flow/src/map/insight/agv/AgvMain.jsx b/zy-acs-flow/src/map/insight/agv/AgvMain.jsx index ada1503..c5aaf5b 100644 --- a/zy-acs-flow/src/map/insight/agv/AgvMain.jsx +++ b/zy-acs-flow/src/map/insight/agv/AgvMain.jsx @@ -1,5 +1,6 @@ import React, { useRef, useEffect, useState } from 'react'; -import { useTranslate } from 'react-admin'; +import * as THREE from 'three'; +import { useTranslate, useDataProvider, useRedirect } from 'react-admin'; import { Box, CircularProgress, @@ -9,101 +10,117 @@ Button, Divider, Stack, + useTheme, } from '@mui/material'; -import ShelfThree from './AgvThree'; -import { getAgvInfo } from '../../http'; +import { useNotification } from '../../Notification'; +import AgvThree from './AgvThree'; +import { handleRestoreAgvAll } from '../../http'; +import BoolValueIcon from '../BoolValueIcon'; +import ConfirmButton from '../../../page/components/ConfirmButton'; import { grey } from '@mui/material/colors'; -let shelfThree; - -const startThree = (dom) => { - shelfThree = new ShelfThree(dom); - shelfThree.startup(); -} - -const endThree = () => { - if (shelfThree) { - shelfThree.destroy(); - shelfThree = null; - } -} - -const renderThree = (info, curAgvNo) => { - if (info && shelfThree) { - shelfThree.generateMesh((loader, addObject) => { - const promises = []; - promises.push(new Promise((resolve) => { - loader.load('model/agv.fbx', (mesh) => { - mesh.position.set(0, singleHeight * (lev - 1), 0); - mesh.scale.set(5, 5, 5); - mesh.name = item.locNo; - mesh.traverse((child) => { - if (child.isMesh) { - switch (child.name) { - case '璐ф灦': - child.material.color.set(0x4680BF); - break; - case '鎵樼洏': - child.visible = item.locStsEl === 'STOCK' || item.locStsEl === 'PAKOUT'; - child.material.color.set(0xBEBEBE); - break; - case '涓嶈鍒�': - child.visible = item.locStsEl === 'STOCK' || item.locStsEl === 'PAKOUT'; - child.material.color.set(0xE8B67E); - break; - default: - break; - } - child.castShadow = true; - child.receiveShadow = true; - } - }); - addObject(mesh); - resolve(); - }) - })); - - Promise.all(promises).then(() => { - shelfThree.setNewSelectedMesh(curLocNo); - shelfThree.rePerspective(singleHeight * info.length, 500); - }).catch(error => { - console.error(error); - }); - }) - } -} - const AgvMain = (props) => { - const { data, curAgvNo, setCurAgvNo } = props; + const { curAgvNo, curAgvInfo: info, fetchAgvInfo } = props; + const theme = useTheme(); const translate = useTranslate(); + const dataProvider = useDataProvider(); + const redirect = useRedirect(); + const notify = useNotification(); const containerRef = useRef(); const [loading, setLoading] = useState(true); - const [info, setInfo] = useState(null); - useEffect(() => { - if (data) { - getAgvInfo(data.no, (response) => { - setInfo(response); - setCurAgvNo(data.no); + const threeRef = useRef(null); + + const startThree = (dom) => { + if (threeRef.current) { + threeRef.current.destroy(); + } + threeRef.current = new AgvThree(dom); + threeRef.current.startup(); + } + + const endThree = () => { + if (threeRef.current) { + threeRef.current.destroy(); + threeRef.current = null; + } + } + + const renderThree = (curAgvNo) => { + if (curAgvNo && threeRef.current) { + threeRef.current.generateMesh((loader, addObject) => { + const loadModel = (path) => { + return new Promise((resolve, reject) => { + loader.load(path, (mesh) => { + resolve(mesh); + }, undefined, (error) => { + reject(error); + }); + }); + }; + + Promise.all([ + loadModel('model/agv/body.fbx'), + loadModel('model/agv/loader.fbx'), + loadModel('model/agv/fork.fbx'), + ]).then(([bodyMesh, loaderMesh, forkMesh]) => { + const scaleVal = 1; + bodyMesh.scale.set(scaleVal, scaleVal, scaleVal); + loaderMesh.scale.set(scaleVal, scaleVal, scaleVal); + forkMesh.scale.set(scaleVal, scaleVal, scaleVal); + + bodyMesh.position.set(55, 0, 0);; + loaderMesh.position.set(55, 150, 0);; + forkMesh.position.set(55, 165, 0);; + + const agvGroup = new THREE.Group(); + agvGroup.add(bodyMesh); + agvGroup.add(loaderMesh); + agvGroup.add(forkMesh); + + agvGroup.name = curAgvNo; + + addObject(agvGroup); + + threeRef.current?.rePerspective(350, 450); + + }).catch((error) => { + console.error(error); + }); }); } - }, [data]); + } useEffect(() => { if (info) { - endThree(); setLoading(true); setTimeout(() => { startThree(containerRef.current); - shelfThree.handleClick = (objName) => { - setCurAgvNo(objName); - }; - renderThree(info, curAgvNo); + renderThree(curAgvNo); setLoading(false); - }, 300) + }, 200); } return endThree; }, [info]); + + const handleRestoreAll = () => { + handleRestoreAgvAll({ agvNo: info.agvNo }); + } + + const updateStatus = () => { + dataProvider.update('agv', { + id: info.agvId, + data: { + status: info.status === 0 ? 1 : 0 + } + }).then(({ data }) => { + fetchAgvInfo(curAgvNo); + notify.success(translate('common.response.success')); + }).catch((error) => { + notify.success(translate('common.response.fail')); + console.error(`Error: ${error.message}`); + }); + } return ( <Box display="flex" height="100%"> @@ -126,9 +143,122 @@ )} </Box> <Box width="50%" height="100%" overflow="auto" pl={1}> + <Paper elevation={1} style={{ + height: "100%", + padding: '16px', + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between', + }}> + <Box sx={{ + height: "70%", + overflowY: 'auto' + }}> + <Grid container spacing={1.5} style={{ marginTop: '0px' }}> + <Grid item xs={12}> + <KeyValuePair label={translate('table.field.agv.uuid')} value={info?.agvNo} /> + </Grid> + <Grid item xs={12}> + <KeyValuePair label={translate('table.field.agvDetail.online')} value={info?.online} bool /> + </Grid> + <Grid item xs={12}> + <KeyValuePair label={translate('table.field.agvDetail.pos')} value={info?.pos} bool /> + </Grid> + <Grid item xs={12}> + <KeyValuePair label={translate('common.field.status')} value={info?.agvStatus} /> + </Grid> + <Grid item xs={12}> + <KeyValuePair label={translate('table.field.agvDetail.vol')} value={info?.vol} /> + </Grid> + <Grid item xs={12}> + <KeyValuePair label={translate('table.field.agvDetail.soc')} value={info?.soc} /> + </Grid> + <Grid item xs={12}> + <KeyValuePair label={translate('table.field.agvDetail.agvAngle')} value={info?.direction} /> + </Grid> + <Grid item xs={12}> + <KeyValuePair label={translate('table.field.agvDetail.backpack')} value={info?.backpack.filter(item => item.loaded === true).length} /> + </Grid> + <Grid item xs={12}> + <KeyValuePair label={translate('table.field.agvDetail.task')} value={info?.taskIds?.join(',')} /> + </Grid> + </Grid> + </Box> + + <Box sx={{ + height: "30%", + display: 'flex', + flexDirection: 'column', + justifyContent: 'flex-end' + }}> + <Grid container spacing={2} style={{ marginTop: '0px' }}> + <Grid item xs={12}> + <Stack spacing={2} mt={2}> + <Button + color="primary" + variant="contained" + onClick={() => { + redirect(`/agv/${info?.agvId}/show`); + }} + > + {translate('page.map.settings.map.more.title')} + </Button> + {info && ( + info.status === 1 + ? <Button variant="contained" color="error" fullWidth onClick={() => { + updateStatus(); + }}> + {translate('page.map.action.disable')} + </Button> + : <Button variant="contained" fullWidth onClick={() => { + updateStatus(); + }}> + {translate('page.map.action.enable')} + </Button> + )} + <ConfirmButton + label="page.map.action.restoreALl" + color="inherit" + // variant="contained" + onConfirm={() => { + handleRestoreAll(); + }} + /> + </Stack> + </Grid> + </Grid> + </Box> + </Paper> </Box> </Box> ); } -export default AgvMain; \ No newline at end of file +const KeyValuePair = ({ label, value, bool }) => { + return ( + <> + <Stack direction="row" alignItems="center" spacing={1} sx={{ mb: 1 }}> + <Typography + variant="body2" + sx={{ minWidth: '80px', fontWeight: 'bold', color: 'text.secondary', textAlign: 'left' }} + > + {label}: + </Typography> + {bool + ? <BoolValueIcon + value={value} + /> + : <Typography + variant="body2" + sx={{ flexGrow: 1, color: 'text.primary', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }} + > + {value} + </Typography> + } + </Stack> + <Divider /> + </> + ) +}; + +export default AgvMain; -- Gitblit v1.9.1