#
vincentlu
3 天以前 878ba960dd6ea01fc9c434d49ea902efc2cb8f24
zy-acs-flow/src/map/insight/code/CodeMain.jsx
@@ -8,6 +8,7 @@
    Grid,
    Chip,
    Button,
    Divider,
    Skeleton,
    useTheme,
} from '@mui/material';
@@ -63,8 +64,6 @@
    const ruleList = useMemo(() => normalizeDirRule(info?.dirRule), [info?.dirRule]);
    const spatialItems = [
        { label: translate('table.field.code.x'), value: formatNumber(info?.x, 0), hideWhenEmpty: true },
        { label: translate('table.field.code.y'), value: formatNumber(info?.y, 0), hideWhenEmpty: true },
        {
            label: translate('page.map.insight.code.fields.mapPosition', { _: '地图坐标' }),
            render: () => (
@@ -135,18 +134,18 @@
                                    />
                                )}
                                <FieldGrid items={spatialItems} loading={loading} />
                                <Button
                                    variant="contained"
                                    color="primary"
                                    startIcon={<OpenInNewIcon />}
                                    onClick={handleOpenDetail}
                                    disabled={!info?.id}
                                    sx={{ alignSelf: 'flex-start', textTransform: 'none', px: 3 }}
                                >
                                    {translate('page.map.insight.code.actions.openDetail', { _: '编辑' })}
                                </Button>
                            </Stack>
                        </Paper>
                        <Button
                            variant="contained"
                            color="primary"
                            startIcon={<OpenInNewIcon />}
                            onClick={handleOpenDetail}
                            disabled={!info?.id}
                            sx={{ alignSelf: 'flex-start', textTransform: 'none', px: 3 }}
                        >
                            {translate('page.map.insight.code.actions.openDetail', { _: '编辑' })}
                        </Button>
                    </Stack>
                </Grid>
                <Grid item xs={12} md={7}>
@@ -170,7 +169,7 @@
                                />
                            </InfoPanel>
                            <InfoPanel title={translate('page.map.insight.code.relations.routes', { _: '关联路线' })}>
                                <RelationsChips
                                <RelationsList
                                    items={routeRelations}
                                    emptyLabel={translate('page.map.insight.code.relations.empty', { _: '暂无关联信息' })}
                                />
@@ -229,6 +228,43 @@
                    label={`+${items.length - MAX_RELATION_ITEMS}`}
                    size="small"
                />
            )}
        </Stack>
    );
};
const RelationsList = ({ items, emptyLabel }) => {
    if (!items?.length) {
        return (
            <Typography variant="body2" color="text.disabled">
                {emptyLabel}
            </Typography>
        );
    }
    return (
        <Stack spacing={1}>
            {items.slice(0, MAX_RELATION_ITEMS).map((item, index) => (
                <Box
                    key={`${getRelationKey(item)}-${index}`}
                    sx={{
                        px: 1.25,
                        py: 0.75,
                        borderRadius: 999,
                        border: '1px solid',
                        borderColor: 'divider',
                        backgroundColor: 'background.default',
                    }}
                >
                    <Typography variant="body2" sx={{ lineHeight: 1.2 }}>
                        {getRelationLabel(item)}
                    </Typography>
                </Box>
            ))}
            {items.length > MAX_RELATION_ITEMS && (
                <Typography variant="caption" color="text.secondary">
                    +{items.length - MAX_RELATION_ITEMS}
                </Typography>
            )}
        </Stack>
    );
@@ -430,8 +466,9 @@
                }
            />
        </Box>
        <Divider />
        {loading ? (
            <Skeleton variant="rounded" height={220} />
            <Skeleton variant="rounded" height={188} />
        ) : (
            <DirectionRuleCompass rules={rules} translate={translate} />
        )}
@@ -441,87 +478,88 @@
const DirectionRuleCompass = ({ rules, translate }) => {
    const theme = useTheme();
    const enabledCount = rules.filter(rule => rule.enabled).length;
    const placement = {
        0: { gridColumn: 2, gridRow: 1 },
        90: { gridColumn: 3, gridRow: 2 },
        180: { gridColumn: 2, gridRow: 3 },
        270: { gridColumn: 1, gridRow: 2 },
    };
    const topRule = rules.find(rule => rule.angle === 0);
    const rightRule = rules.find(rule => rule.angle === 90);
    const bottomRule = rules.find(rule => rule.angle === 180);
    const leftRule = rules.find(rule => rule.angle === 270);
    return (
        <Stack spacing={0.85} alignItems="center">
            <DirectionRuleCard rule={topRule} translate={translate} />
            <Stack direction="row" spacing={0.6} alignItems="center" justifyContent="center">
                <DirectionRuleCard rule={leftRule} translate={translate} />
                <Box
                    sx={{
                        width: 52,
                        height: 42,
                        borderRadius: 2.5,
                        border: '1px dashed',
                        borderColor: 'divider',
                        backgroundColor: alpha(theme.palette.primary.main, 0.04),
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'center',
                        textAlign: 'center',
                        flexShrink: 0,
                    }}
                >
                    <Typography variant="h5" sx={{ lineHeight: 1, fontWeight: 700, fontSize: '0.98rem' }}>
                        {enabledCount}/{rules.length}
                    </Typography>
                </Box>
                <DirectionRuleCard rule={rightRule} translate={translate} />
            </Stack>
            <DirectionRuleCard rule={bottomRule} translate={translate} />
        </Stack>
    );
};
const DirectionRuleCard = ({ rule, translate }) => {
    const theme = useTheme();
    if (!rule) {
        return null;
    }
    const statusText = translate(
        rule.enabled ? 'page.code.dirRule.status.enabled' : 'page.code.dirRule.status.disabled'
    );
    return (
        <Box
            sx={{
                display: 'grid',
                gridTemplateColumns: 'repeat(3, minmax(0, 1fr))',
                gridTemplateRows: 'repeat(3, minmax(58px, auto))',
                gap: 1,
                alignItems: 'stretch',
                width: 68,
                height: 42,
                borderRadius: 2.5,
                border: '1px solid',
                borderColor: rule.enabled ? 'success.light' : 'error.light',
                backgroundColor: rule.enabled
                    ? alpha(theme.palette.success.main, 0.08)
                    : alpha(theme.palette.error.main, 0.08),
                px: 0.5,
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                textAlign: 'center',
                flexShrink: 0,
            }}
        >
            <Box
                sx={{
                    gridColumn: 2,
                    gridRow: 2,
                    borderRadius: 3,
                    border: '1px dashed',
                    borderColor: 'divider',
                    backgroundColor: alpha(theme.palette.primary.main, 0.04),
                    px: 1,
                    py: 0.75,
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    textAlign: 'center',
                }}
            >
                <Typography variant="h6" sx={{ lineHeight: 1.1, fontWeight: 700 }}>
                    {enabledCount}/{rules.length}
            <Stack spacing={0.1}>
                <Typography variant="subtitle2" sx={{ fontWeight: 700, lineHeight: 1, fontSize: '0.88rem' }}>
                    {rule.angle}°
                </Typography>
            </Box>
            {rules.map(rule => {
                const position = placement[rule.angle] || { gridColumn: 'auto', gridRow: 'auto' };
                const statusText = translate(
                    rule.enabled ? 'page.code.dirRule.status.enabled' : 'page.code.dirRule.status.disabled'
                );
                return (
                    <Box
                        key={rule.angle}
                        sx={{
                            ...position,
                            borderRadius: 3,
                            border: '1px solid',
                            borderColor: rule.enabled ? 'success.light' : 'error.light',
                            backgroundColor: rule.enabled
                                ? alpha(theme.palette.success.main, 0.08)
                                : alpha(theme.palette.error.main, 0.08),
                            px: 1,
                            py: 0.75,
                            minHeight: 60,
                            display: 'flex',
                            alignItems: 'center',
                            justifyContent: 'center',
                            textAlign: 'center',
                        }}
                    >
                        <Stack spacing={0.35}>
                            <Typography variant="subtitle2" sx={{ fontWeight: 700, lineHeight: 1 }}>
                                {rule.angle}°
                            </Typography>
                            <Typography
                                variant="caption"
                                sx={{
                                    lineHeight: 1.1,
                                    color: rule.enabled ? 'success.dark' : 'error.dark',
                                    fontWeight: 600,
                                }}
                            >
                                {statusText}
                            </Typography>
                        </Stack>
                    </Box>
                );
            })}
                <Typography
                    variant="caption"
                    sx={{
                        lineHeight: 1.05,
                        fontSize: '0.64rem',
                        color: rule.enabled ? 'success.dark' : 'error.dark',
                        fontWeight: 600,
                    }}
                >
                    {statusText}
                </Typography>
            </Stack>
        </Box>
    );
};