import React, { useRef, useEffect, useState } from 'react';
|
import { useTranslate, useDataProvider, useRedirect } from 'react-admin';
|
import {
|
Box,
|
CircularProgress,
|
Grid,
|
Typography,
|
Paper,
|
Button,
|
Divider,
|
Stack,
|
} from '@mui/material';
|
import ShelfThree from './ShelfThree';
|
import { getLocGroup } from '../../http';
|
import { grey } from '@mui/material/colors';
|
import ConfirmButton from '../../../page/components/ConfirmButton';
|
|
const ShelfMain = (props) => {
|
const { row, bay, curLocNo, curShelfInfo: info, setCurLocNo } = props;
|
const translate = useTranslate();
|
const dataProvider = useDataProvider();
|
const redirect = useRedirect();
|
const containerRef = useRef();
|
|
const [selectedLoc, setSelectedLoc] = useState(null); // loc obj
|
const [loading, setLoading] = useState(true);
|
|
const shelfThreeRef = useRef(null);
|
|
const startThree = (dom) => {
|
if (shelfThreeRef.current) {
|
shelfThreeRef.current.destroy();
|
}
|
shelfThreeRef.current = new ShelfThree(dom);
|
shelfThreeRef.current.startup();
|
};
|
|
const endThree = () => {
|
if (shelfThreeRef.current) {
|
shelfThreeRef.current.destroy();
|
shelfThreeRef.current = null;
|
}
|
};
|
|
const renderThree = (info, curLocNo) => {
|
if (info && shelfThreeRef.current) {
|
shelfThreeRef.current.generateMesh((loader, addObject) => {
|
const promises = [];
|
const singleHeight = 123;
|
for (const item of info) {
|
const { lev } = item;
|
promises.push(new Promise((resolve) => {
|
loader.load('model/shelf.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.name = item.locNo;
|
child.castShadow = true;
|
child.receiveShadow = true;
|
}
|
});
|
addObject(mesh);
|
resolve();
|
});
|
}));
|
}
|
|
Promise.all(promises).then(() => {
|
if (shelfThreeRef.current) {
|
if (typeof shelfThreeRef.current.setNewSelectedMesh === 'function') {
|
shelfThreeRef.current.setNewSelectedMesh(curLocNo);
|
}
|
if (typeof shelfThreeRef.current.rePerspective === 'function') {
|
shelfThreeRef.current.rePerspective(singleHeight * info.length, 500);
|
}
|
}
|
}).catch(error => {
|
console.error(error);
|
});
|
});
|
}
|
};
|
|
useEffect(() => {
|
if (info) {
|
setSelectedLoc(info[0]);
|
setLoading(true);
|
setTimeout(() => {
|
startThree(containerRef.current);
|
shelfThreeRef.current.handleClick = (objName) => {
|
setCurLocNo(objName);
|
setSelectedLoc(info.find(loc => objName === loc.locNo));
|
};
|
renderThree(info, curLocNo);
|
setLoading(false);
|
}, 200);
|
}
|
return endThree;
|
}, [info]);
|
|
const updateStatus = () => {
|
dataProvider.update('loc', {
|
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%">
|
<Box
|
position="relative"
|
width="50%"
|
height="100%"
|
ref={containerRef}
|
style={{ backgroundColor: '#7a7a7a' }}
|
>
|
{loading && (
|
<Box
|
position="absolute"
|
top="50%"
|
left="50%"
|
style={{ transform: 'translate(-50%, -50%)' }}
|
>
|
<CircularProgress sx={{ color: grey[50] }} />
|
</Box>
|
)}
|
</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.loc.locNo')} value={selectedLoc?.locNo || 'N/A'} />
|
</Grid>
|
<Grid item xs={12}>
|
<KeyValuePair label={translate('table.field.loc.row')} value={selectedLoc?.row || 'N/A'} />
|
</Grid>
|
<Grid item xs={12}>
|
<KeyValuePair label={translate('table.field.loc.bay')} value={selectedLoc?.bay || 'N/A'} />
|
</Grid>
|
<Grid item xs={12}>
|
<KeyValuePair label={translate('table.field.loc.lev')} value={selectedLoc?.lev || 'N/A'} />
|
</Grid>
|
<Grid item xs={12}>
|
<KeyValuePair label={translate('table.field.loc.offset')} value={selectedLoc?.offset || 'N/A'} />
|
</Grid>
|
<Grid item xs={12}>
|
<KeyValuePair label={translate('table.field.loc.locSts')} value={selectedLoc?.locSts$ || 'N/A'} />
|
</Grid>
|
<Grid item xs={12}>
|
<KeyValuePair label={translate('table.field.loc.zoneId')} value={selectedLoc?.zoneId$ || 'N/A'} />
|
</Grid>
|
<Grid item xs={12}>
|
<KeyValuePair label={translate('table.field.loc.code')} value={selectedLoc?.code$ || 'N/A'} />
|
</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={() => {
|
const searchQuery = encodeURIComponent(JSON.stringify({ row, bay }));
|
redirect(`/loc?filter=${searchQuery}`);
|
}}
|
>
|
{translate('page.map.settings.map.more.title')}
|
</Button>
|
<Button
|
color="primary" // inherit
|
variant="contained"
|
onClick={() => {
|
redirect('edit', 'loc', selectedLoc?.id);
|
}}
|
>
|
{translate('page.map.insight.shelf.updateStatus')}
|
</Button>
|
{/* <ConfirmButton
|
label="page.map.insight.shelf.updateStatus"
|
color="primary" // inherit
|
variant="contained"
|
onConfirm={() => {
|
redirect('edit', 'loc', selectedLoc?.id);
|
}}
|
/> */}
|
<Button variant="contained" color="error" disabled={selectedLoc?.locStsEl !== 'STOCK'} fullWidth>
|
{translate('page.map.insight.shelf.outbound')}
|
</Button>
|
</Stack>
|
</Grid>
|
</Grid>
|
</Box>
|
</Paper>
|
</Box>
|
</Box>
|
);
|
};
|
|
const KeyValuePair = ({ label, value }) => (
|
<>
|
<Stack direction="row" alignItems="center" spacing={1} sx={{ mb: 1 }}>
|
<Typography
|
variant="body2"
|
sx={{ width: '80px', fontWeight: 'bold', color: 'text.secondary', textAlign: 'left' }}
|
>
|
{label}:
|
</Typography>
|
<Typography
|
variant="body2"
|
sx={{ flexGrow: 1, color: 'text.primary', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}
|
>
|
{value}
|
</Typography>
|
</Stack>
|
<Divider />
|
</>
|
);
|
|
export default ShelfMain;
|