#
vincentlu
9 天以前 3060671bbaa7fe72dd47b7c7b30e385cfdf11802
#
1个文件已修改
283 ■■■■ 已修改文件
zy-acs-flow/src/page/sta/StaPanel.jsx 283 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-flow/src/page/sta/StaPanel.jsx
@@ -1,31 +1,90 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { Box, Card, CardContent, Grid, Typography, Tooltip } from '@mui/material';
import React, { useState, useEffect } from "react";
import {
    Box,
    Card,
    CardContent,
    Grid,
    Typography,
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableRow,
    Divider,
    CircularProgress,
    Stack,
} from '@mui/material';
import {
    useTranslate,
    useRecordContext,
    useDataProvider,
} from 'react-admin';
import { format } from 'date-fns';
import PanelTypography from "../components/PanelTypography";
import * as Common from '@/utils/common'
const STATUS_FIELDS = [
    { key: 'autoing', labelKey: 'table.field.sta.autoing' },
    { key: 'loading', labelKey: 'table.field.sta.loading' },
    { key: 'inEnable', labelKey: 'table.field.sta.inEnable' },
    { key: 'outEnable', labelKey: 'table.field.sta.outEnable' },
];
const StaPanel = () => {
    const record = useRecordContext();
    if (!record) return null;
    const translate = useTranslate();
    const dataProvider = useDataProvider();
    const [reserves, setReserves] = useState([]);
    const [isReservesLoading, setIsReservesLoading] = useState(false);
    useEffect(() => {
        if (!record?.id) {
            setReserves([]);
            setIsReservesLoading(false);
            return;
        }
        let isMounted = true;
        setIsReservesLoading(true);
        dataProvider.getList('staReserve', {
            pagination: { page: 1, perPage: 10 },
            sort: { field: 'updateTime', order: 'DESC' },
            filter: { staId: record.id },
        })
            .then(({ data }) => {
                if (!isMounted) return;
                setReserves(data || []);
            })
            .catch(() => {
                if (!isMounted) return;
                setReserves([]);
            })
            .finally(() => {
                if (!isMounted) return;
                setIsReservesLoading(false);
            });
        return () => {
            isMounted = false;
        };
    }, [record?.id, dataProvider]);
    if (!record) return null;
    return (
        <>
            <Card sx={{ width: { xs: 300, sm: 500, md: 600, lg: 800 }, margin: 'auto' }}>
            <Card sx={{ width: { xs: 320, sm: 560, md: 680, lg: 900 }, margin: 'auto', mt: .5, mb: .5 }}>
                <CardContent>
                    <Grid container spacing={2}>
                        <Grid item xs={12} sx={{ display: 'flex', justifyContent: 'space-between' }}>
                            <Typography variant="h6" gutterBottom align="left" sx={{
                                maxWidth: { xs: '100px', sm: '180px', md: '260px', lg: '360px' },
                                maxWidth: { xs: '140px', sm: '220px', md: '300px', lg: '360px' },
                                whiteSpace: 'nowrap',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis',
                            }}>
                                {Common.camelToPascalWithSpaces(translate('table.field.sta.staNo'))}: {record.staNo}
                            </Typography>
                            {/*  inherit, primary, secondary, textPrimary, textSecondary, error */}
                            <Typography variant="h6" gutterBottom align="right" >
                                ID: {record.id}
                            </Typography>
@@ -34,96 +93,222 @@
                    <Grid container spacing={2}>
                        <Grid item xs={12} container alignContent="flex-end">
                            <Typography variant="caption" color="textSecondary" sx={{ wordWrap: 'break-word', wordBreak: 'break-all' }}>
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo}
                                {Common.camelToPascalWithSpaces(translate('common.field.memo'))}:{record.memo || '-'}
                            </Typography>
                        </Grid>
                    </Grid>
                    <Box height={20}>&nbsp;</Box>
                    <Box height={16}>&nbsp;</Box>
                    <Grid container spacing={2}>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.uuid"
                                title="table.field.sta.uuid"
                                property={record.uuid}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.zoneId"
                                title="table.field.sta.zoneId"
                                property={record.zoneId$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.staNo"
                                property={record.staNo}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.name"
                                property={record.name}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.staType"
                                title="table.field.sta.staType"
                                property={record.staType$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.code"
                                title="table.field.sta.code"
                                property={record.code$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.offset"
                                title="table.field.sta.capacity"
                                property={record.capacity}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.offset"
                                property={record.offset}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.autoing"
                                property={record.autoing}
                                title="table.field.sta.rsvInCnt"
                                property={record.rsvInCnt}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.loading"
                                property={record.loading}
                                title="table.field.sta.rsvOutCnt"
                                property={record.rsvOutCnt}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.inEnable"
                                property={record.inEnable}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.outEnable"
                                property={record.outEnable}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.zpallet"
                                property={record.zpallet}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.staSts"
                                title="table.field.sta.staSts"
                                property={record.staSts$}
                            />
                        </Grid>
                        <Grid item xs={6}>
                            <PanelTypography
                                title="table.field.sta.zpallet"
                                property={record.zpallet}
                            />
                        </Grid>
                    </Grid>
                    <Divider sx={{ my: 2 }} />
                    <Typography variant="subtitle2" color="textSecondary" gutterBottom>
                        {translate('common.field.status')} / {translate('table.field.sta.staNo')}
                    </Typography>
                    <Grid container spacing={2}>
                        {STATUS_FIELDS.map(({ key, labelKey }) => (
                            <Grid item xs={6} sm={3} key={key}>
                                <StatusIndicator labelKey={labelKey} value={record[key]} />
                            </Grid>
                        ))}
                    </Grid>
                    <Divider sx={{ my: 2 }} />
                    <Box>
                        <Typography variant="subtitle1" gutterBottom>
                            {translate('menu.staReserve')}
                        </Typography>
                        <Table size="small">
                            <TableHead>
                                <TableRow>
                                    <TableCell>{translate('table.field.staReserve.name')}</TableCell>
                                    <TableCell>{translate('table.field.staReserve.type')}</TableCell>
                                    <TableCellRight>{translate('table.field.staReserve.qty')}</TableCellRight>
                                    <TableCell>{translate('table.field.staReserve.state')}</TableCell>
                                    <TableCell>{translate('table.field.staReserve.agvId')}</TableCell>
                                    <TableCell>{translate('table.field.staReserve.waitingAt')}</TableCell>
                                    <TableCell>{translate('table.field.staReserve.confirmedAt')}</TableCell>
                                </TableRow>
                            </TableHead>
                            <TableBody>
                                {isReservesLoading && (
                                    <TableRow>
                                        <TableCell colSpan={7}>
                                            <Box display="flex" alignItems="center" gap={1}>
                                                <CircularProgress size={16} />
                                                <Typography variant="body2" color="textSecondary">
                                                    {translate('common.loading', { _: 'Loading...' })}
                                                </Typography>
                                            </Box>
                                        </TableCell>
                                    </TableRow>
                                )}
                                {!isReservesLoading && reserves.length === 0 && (
                                    <TableRow>
                                        <TableCell colSpan={7}>
                                            <Typography variant="body2" color="textSecondary">
                                                No reservations
                                            </Typography>
                                        </TableCell>
                                    </TableRow>
                                )}
                                {reserves.map((reserve) => (
                                    <TableRow key={reserve.id}>
                                        <TableCell>{reserve.name || '-'}</TableCell>
                                        <TableCell>{reserve.type || '-'}</TableCell>
                                        <TableCellRight>{reserve.qty ?? '-'}</TableCellRight>
                                        <TableCell>{reserve.state || '-'}</TableCell>
                                        <TableCell>{reserve.agvId$ || reserve.agvId || '-'}</TableCell>
                                        <TableCell>{formatDateTime(reserve.waitingAt)}</TableCell>
                                        <TableCell>{formatDateTime(reserve.confirmedAt)}</TableCell>
                                    </TableRow>
                                ))}
                            </TableBody>
                        </Table>
                    </Box>
                </CardContent>
            </Card >
        </>
    );
};
const StatusIndicator = ({ labelKey, value }) => {
    const translate = useTranslate();
    const color = getIndicatorColor(value);
    return (
        <Stack spacing={0.5}>
            <Typography variant="caption" color="textSecondary">
                {Common.camelToPascalWithSpaces(translate(labelKey))}
            </Typography>
            <Box display="flex" alignItems="center" gap={1}>
                <Box sx={{
                    width: 14,
                    height: 14,
                    borderRadius: '50%',
                    backgroundColor: color,
                    boxShadow: `0 0 6px ${color}`,
                    border: '1px solid rgba(0,0,0,0.12)'
                }} />
                <Typography variant="body2">
                    {formatIndicatorValue(value)}
                </Typography>
            </Box>
        </Stack>
    );
};
const getIndicatorColor = (value) => {
    if (isTruthy(value)) {
        return '#2e7d32';
    }
    if (isFalsy(value)) {
        return '#9e9e9e';
    }
    return '#ff9800';
};
const isTruthy = (value) => {
    if (typeof value === 'boolean') return value;
    if (typeof value === 'number') return value > 0;
    if (typeof value === 'string') {
        const normalized = value.toLowerCase();
        return ['1', 'true', 'y', 'yes', 'open', 'enable'].includes(normalized);
    }
    return false;
};
const isFalsy = (value) => {
    if (typeof value === 'boolean') return !value;
    if (typeof value === 'number') return value === 0;
    if (typeof value === 'string') {
        const normalized = value.toLowerCase();
        return ['0', 'false', 'n', 'no', 'close', 'disable'].includes(normalized);
    }
    return false;
};
const formatIndicatorValue = (value) => {
    if (value === null || value === undefined || value === '') {
        return '-';
    }
    return String(value);
};
const formatDateTime = (value) => {
    if (!value) return '-';
    try {
        const date = new Date(value);
        if (Number.isNaN(date.getTime())) {
            return value;
        }
        return format(date, 'MM-dd HH:mm');
    } catch (error) {
        return value;
    }
};
const TableCellRight = (props) => <TableCell align="right" {...props} />;
export default StaPanel;