| | |
| | | import MemoInput from "../../components/MemoInput"; |
| | | import StatusSelectInput from "../../components/StatusSelectInput"; |
| | | import DictionarySelect from "../../components/DictionarySelect"; |
| | | import AreasSortInput from "../../components/AreasSortInput"; |
| | | |
| | | const FormToolbar = () => { |
| | | const { getValues } = useFormContext(); |
| | |
| | | mutationMode={EDIT_MODE} |
| | | actions={<CustomerTopToolBar />} |
| | | aside={<EditBaseAside />} |
| | | transform={(data) => { |
| | | // 保存前转换:将 areas 从纯ID数组转换为 [{id, sort}] 格式 |
| | | // 从隐藏字段 areasSort 获取排序信息 |
| | | const areas = data.areas || []; |
| | | const areasSort = data.areasSort || []; |
| | | |
| | | if (areas.length > 0) { |
| | | if (typeof areas[0] === 'number') { |
| | | // 如果是纯ID数组,使用 areasSort 中的排序信息 |
| | | if (areasSort.length > 0 && typeof areasSort[0] === 'object') { |
| | | // 使用 areasSort 中的排序信息,但只保留 areas 中存在的ID |
| | | const areaIds = new Set(areas); |
| | | const sortedAreas = areasSort |
| | | .filter(item => areaIds.has(item.id)) |
| | | .sort((a, b) => (a.sort || 0) - (b.sort || 0)); |
| | | |
| | | // 如果 areasSort 中有所有ID的排序信息,使用它 |
| | | if (sortedAreas.length === areas.length) { |
| | | data.areas = sortedAreas; |
| | | } else { |
| | | // 否则,为缺失的ID添加默认排序 |
| | | const existingIds = new Set(sortedAreas.map(item => item.id)); |
| | | const missingIds = areas.filter(id => !existingIds.has(id)); |
| | | const maxSort = sortedAreas.length > 0 |
| | | ? Math.max(...sortedAreas.map(item => item.sort || 1)) |
| | | : 0; |
| | | const newItems = missingIds.map((id, index) => ({ |
| | | id: id, |
| | | sort: maxSort + index + 1, |
| | | })); |
| | | data.areas = [...sortedAreas, ...newItems]; |
| | | } |
| | | } else { |
| | | // 如果没有排序信息,使用默认排序 |
| | | data.areas = areas.map((id, index) => ({ |
| | | id: id, |
| | | sort: index + 1, |
| | | })); |
| | | } |
| | | } |
| | | // 删除临时字段 |
| | | delete data.areasSort; |
| | | } |
| | | return data; |
| | | }} |
| | | > |
| | | <SimpleForm |
| | | shouldUnregister |
| | |
| | | /> |
| | | </Stack> |
| | | <Stack direction='row' gap={2}> |
| | | <ReferenceArrayInput source="areas" reference="warehouseAreas"> |
| | | <ReferenceArrayInput |
| | | source="areas" |
| | | reference="warehouseAreas" |
| | | sort={{ field: 'sort', order: 'ASC' }} |
| | | format={(value) => { |
| | | // 从后端接收时:将 [{id, sort}] 转换为 [id, id, ...] |
| | | if (!value || !Array.isArray(value)) return []; |
| | | if (value.length === 0) return []; |
| | | // 如果是对象数组,提取id |
| | | if (typeof value[0] === 'object' && value[0] !== null && value[0].id !== undefined) { |
| | | return value.map(item => item.id); |
| | | } |
| | | // 如果已经是纯ID数组,直接返回 |
| | | return value; |
| | | }} |
| | | parse={(value) => { |
| | | // 保存时:保持原值,由 AreasSortInput 处理转换 |
| | | return value; |
| | | }} |
| | | > |
| | | <SelectArrayInput |
| | | label="table.field.basContainer.areas" |
| | | optionText="name" |
| | |
| | | /> |
| | | </ReferenceArrayInput> |
| | | </Stack> |
| | | {/* 下方显示已选库区和排序编辑 */} |
| | | <AreasSortInput source="areas" /> |
| | | {/* 隐藏字段:存储排序信息 */} |
| | | <TextInput source="areasSort" style={{ display: 'none' }} /> |
| | | |
| | | </Grid> |
| | | <Grid item xs={12} md={4}> |