From b3cd0b749e427c5c8e4dba8e9f01c6cff51d07d7 Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期一, 19 一月 2026 12:47:44 +0800
Subject: [PATCH] #
---
zy-acs-flow/src/page/code/CodeEdit.jsx | 196 +++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 191 insertions(+), 5 deletions(-)
diff --git a/zy-acs-flow/src/page/code/CodeEdit.jsx b/zy-acs-flow/src/page/code/CodeEdit.jsx
index 9741cd5..ec0ab8b 100644
--- a/zy-acs-flow/src/page/code/CodeEdit.jsx
+++ b/zy-acs-flow/src/page/code/CodeEdit.jsx
@@ -1,4 +1,4 @@
-import React, { useState, useRef, useEffect, useMemo } from "react";
+import React, { useEffect, useMemo } from "react";
import {
Edit,
SimpleForm,
@@ -21,8 +21,8 @@
DeleteButton,
} from 'react-admin';
import { useWatch, useFormContext } from "react-hook-form";
-import { Stack, Grid, Box, Typography } from '@mui/material';
-import * as Common from '@/utils/common';
+import { Stack, Grid, Box, Typography, ToggleButton, ToggleButtonGroup } from '@mui/material';
+import { alpha } from '@mui/material/styles';
import { EDIT_MODE } from '@/config/setting';
import EditBaseAside from "../components/EditBaseAside";
import CustomerTopToolBar from "../components/EditTopToolBar";
@@ -39,6 +39,178 @@
</Toolbar>
)
}
+
+const DIR_RULE_ANGLES = [0, 90, 180, 270];
+const DEFAULT_DIR_RULES = DIR_RULE_ANGLES.map(angle => ({ angle, enabled: true }));
+
+const normalizeDirRuleValue = (value) => {
+ let parsed = [];
+
+ if (Array.isArray(value)) {
+ parsed = value;
+ } else if (typeof value === 'string' && value.trim()) {
+ try {
+ parsed = JSON.parse(value);
+ } catch (error) {
+ parsed = [];
+ }
+ } else if (value && typeof value === 'object') {
+ parsed = [value];
+ }
+
+ const angleMap = new Map();
+
+ parsed.forEach(item => {
+ const angle = typeof item?.angle === 'number' ? item.angle : Number(item?.angle);
+ if (!Number.isFinite(angle)) {
+ return;
+ }
+ const enabled = !(
+ item?.enabled === false ||
+ item?.enabled === 'false' ||
+ item?.enabled === 0 ||
+ item?.enabled === '0'
+ );
+ angleMap.set(angle, { angle, enabled });
+ });
+
+ let disabledCaptured = false;
+
+ return DIR_RULE_ANGLES.map(angle => {
+ const matched = angleMap.get(angle);
+ if (matched && matched.enabled === false) {
+ if (disabledCaptured) {
+ return { angle, enabled: true };
+ }
+ disabledCaptured = true;
+ return { angle, enabled: false };
+ }
+
+ return { angle, enabled: true };
+ });
+};
+
+const DirectionRuleInput = () => {
+ const translate = useTranslate();
+ const record = useRecordContext();
+ const { register, setValue } = useFormContext();
+ const dirRuleValue = useWatch({ name: 'dirRule' });
+
+ useEffect(() => {
+ register('dirRule');
+ }, [register]);
+
+ const initialDirRuleString = useMemo(() => {
+ const source = record?.dirRule ?? DEFAULT_DIR_RULES;
+ return JSON.stringify(normalizeDirRuleValue(source));
+ }, [record]);
+
+ useEffect(() => {
+ if (dirRuleValue === undefined || dirRuleValue === null || dirRuleValue === '') {
+ setValue('dirRule', initialDirRuleString, { shouldDirty: false, shouldTouch: false });
+ return;
+ }
+
+ const normalizedString = JSON.stringify(normalizeDirRuleValue(dirRuleValue));
+ if (dirRuleValue !== normalizedString) {
+ setValue('dirRule', normalizedString, { shouldDirty: false, shouldTouch: false });
+ }
+ }, [dirRuleValue, initialDirRuleString, setValue]);
+
+ const rules = useMemo(
+ () => normalizeDirRuleValue(dirRuleValue ?? initialDirRuleString),
+ [dirRuleValue, initialDirRuleString]
+ );
+
+ const disabledAngle = useMemo(() => {
+ const disabled = rules.find(rule => !rule.enabled);
+ return typeof disabled?.angle === 'number' ? disabled.angle : null;
+ }, [rules]);
+
+ const handleToggle = (_, newDisabledAngle) => {
+ if (newDisabledAngle === null) {
+ const resetRules = rules.map(rule => ({ ...rule, enabled: true }));
+ setValue('dirRule', JSON.stringify(resetRules), { shouldDirty: true, shouldTouch: true });
+ return;
+ }
+
+ const parsedAngle = typeof newDisabledAngle === 'number' ? newDisabledAngle : Number(newDisabledAngle);
+ if (Number.isNaN(parsedAngle)) {
+ return;
+ }
+
+ const nextRules = rules.map(rule =>
+ rule.angle === parsedAngle ? { ...rule, enabled: false } : { ...rule, enabled: true }
+ );
+
+ setValue('dirRule', JSON.stringify(nextRules), { shouldDirty: true, shouldTouch: true });
+ };
+
+ return (
+ <Box>
+ <Typography variant="subtitle2" sx={{ fontWeight: 500, mb: 1 }}>
+ {translate('table.field.code.dirRule')}
+ </Typography>
+ <Typography variant="caption" color="text.secondary" sx={{ display: 'block', mb: 1 }}>
+ {translate('page.code.dirRule.helper')}
+ </Typography>
+ <ToggleButtonGroup
+ fullWidth
+ exclusive
+ value={disabledAngle}
+ onChange={handleToggle}
+ color="primary"
+ >
+ {rules.map(rule => {
+ const isDisabled = !rule.enabled;
+ const disabledStyles = {
+ color: (theme) => theme.palette.error.main,
+ borderColor: (theme) => theme.palette.error.main,
+ bgcolor: (theme) => alpha(theme.palette.error.main, 0.08),
+ '&:hover': {
+ bgcolor: (theme) => alpha(theme.palette.error.main, 0.16),
+ },
+ };
+ return (
+ <ToggleButton
+ key={rule.angle}
+ value={rule.angle}
+ sx={{
+ textTransform: 'none',
+ flex: 1,
+ flexDirection: 'column',
+ gap: 0.5,
+ py: 1.5,
+ ...(isDisabled ? disabledStyles : {}),
+ '&.Mui-selected': disabledStyles,
+ '& .dirRuleStatus': {
+ color: isDisabled ? 'error.main' : 'text.secondary',
+ },
+ '& .dirRuleAngle': {
+ fontWeight: 600,
+ },
+ '&.Mui-selected .dirRuleStatus': {
+ color: (theme) => theme.palette.error.main,
+ },
+ }}
+ >
+ <Typography className="dirRuleAngle" variant="body2">
+ {rule.angle}掳
+ </Typography>
+ <Typography
+ variant="caption"
+ className="dirRuleStatus"
+ sx={{ fontWeight: 600, letterSpacing: 0.2, textTransform: 'uppercase' }}
+ >
+ {translate(isDisabled ? 'page.code.dirRule.status.disabled' : 'page.code.dirRule.status.enabled')}
+ </Typography>
+ </ToggleButton>
+ );
+ })}
+ </ToggleButtonGroup>
+ </Box>
+ );
+};
const CodeEdit = () => {
const translate = useTranslate();
@@ -98,13 +270,27 @@
source="y"
/>
</Stack>
- <Stack direction='row' gap={2}>
+ {/* <Stack direction='row' gap={2}>
+ <SelectInput
+ label="table.field.code.spin"
+ source="spin"
+ choices={[
+ { id: 0, name: 'page.code.enums.spin.na' },
+ { id: 1, name: 'page.code.enums.spin.cw' },
+ { id: 2, name: 'page.code.enums.spin.ccw' },
+ ]}
+ validate={required()}
+ />
<TextInput
label="table.field.code.scale"
source="scale"
parse={v => v}
/>
- </Stack>
+ </Stack> */}
+
+ <Box mt={2}>
+ <DirectionRuleInput />
+ </Box>
</Grid>
<Grid item xs={12} md={4}>
--
Gitblit v1.9.1