1
1
This commit is contained in:
553
src/App.tsx
553
src/App.tsx
@ -3,36 +3,36 @@ import { bitable, CurrencyCode, FieldType, ICurrencyField, ICurrencyFieldMeta }
|
||||
import { Card, Modal, Checkbox, message } from 'antd';
|
||||
import './App.css';
|
||||
|
||||
// 选项类型定义
|
||||
interface OptionGroupDef {
|
||||
title: string;
|
||||
options: string[];
|
||||
required: boolean;
|
||||
level?: number;
|
||||
parentOption?: string;
|
||||
condition?: (checkedList: string[]) => boolean;
|
||||
resetOn?: string[];
|
||||
multiple?: boolean; // 新增:是否支持多选,默认为 false(单选)
|
||||
// 客户配置类型定义
|
||||
interface CustomerOptionGroup {
|
||||
title: string; // 客户名称
|
||||
options: CustomerTagGroup[]; // 客户专属标签组
|
||||
isDefault?: boolean; // 是否为默认客户
|
||||
}
|
||||
|
||||
// 选项分组配置
|
||||
const OPTION_GROUPS: OptionGroupDef[] = [
|
||||
// 第一层:品牌选择
|
||||
{
|
||||
title: '品牌',
|
||||
options: ['PDS', 'LWH', 'PLT', 'RBE'],
|
||||
required: true,
|
||||
level: 1
|
||||
},
|
||||
// 客户标签组类型定义
|
||||
interface CustomerTagGroup {
|
||||
title: string; // 标签组标题
|
||||
options: string[]; // 标签选项
|
||||
required: boolean; // 是否必填
|
||||
level?: number; // 层级
|
||||
parentOption?: string; // 父选项
|
||||
condition?: (checkedList: string[]) => boolean; // 显示条件
|
||||
resetOn?: string[]; // 重置条件
|
||||
multiple?: boolean; // 是否支持多选
|
||||
}
|
||||
|
||||
// PDS和LWH共用的标签树
|
||||
// 客户配置 - 按客户分组管理标签
|
||||
const CUSTOMER_CONFIG: CustomerOptionGroup[] = [
|
||||
// PDS 客户配置
|
||||
{
|
||||
title: 'PDS',
|
||||
options: [
|
||||
{
|
||||
title: '单据类型',
|
||||
options: ['首单', '翻单'],
|
||||
required: true,
|
||||
level: 2,
|
||||
condition: (checkedList) => checkedList.includes('PDS') || checkedList.includes('LWH'),
|
||||
resetOn: ['PLT', 'RBE']
|
||||
level: 2
|
||||
},
|
||||
{
|
||||
title: '是否要打板',
|
||||
@ -40,45 +40,8 @@ const OPTION_GROUPS: OptionGroupDef[] = [
|
||||
required: false,
|
||||
level: 3,
|
||||
parentOption: '首单',
|
||||
condition: (checkedList) => (checkedList.includes('PDS')) && checkedList.includes('首单'),
|
||||
resetOn: ['翻单', 'PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
title: '打板类型(多选)',
|
||||
options: ['复版', 'PP版','不用打版'],
|
||||
required: false,
|
||||
level: 3,
|
||||
parentOption: '首单',
|
||||
multiple: true,
|
||||
condition: (checkedList) => (checkedList.includes('LWH')) && checkedList.includes('首单'),
|
||||
resetOn: ['翻单', 'PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
title: '翻单变动',
|
||||
options: ['无变动不需要修改', '有变动需要修改'],
|
||||
required: false,
|
||||
level: 3,
|
||||
parentOption: '翻单',
|
||||
condition: (checkedList) => (checkedList.includes('PDS') || checkedList.includes('LWH')) && checkedList.includes('翻单'),
|
||||
resetOn: ['首单', 'PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
title: '特殊订单',
|
||||
options: ['换料寄面料样', '换料重新打板', '加色', '改尺寸重新打板'],
|
||||
required: false,
|
||||
level: 4,
|
||||
parentOption: '有变动需要修改',
|
||||
condition: (checkedList) => (checkedList.includes('PDS') || checkedList.includes('LWH')) && checkedList.includes('有变动需要修改'),
|
||||
resetOn: ['首单', '无变动不需要修改', 'PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
title: '特殊订单',
|
||||
options: ['批大货布'],
|
||||
required: false,
|
||||
level: 4,
|
||||
parentOption: '无变动不需要修改',
|
||||
condition: (checkedList) => (checkedList.includes('LWH')) && checkedList.includes('无变动不需要修改'),
|
||||
resetOn: ['首单', '有变动需要修改', 'PLT', 'RBE']
|
||||
condition: (checkedList) => checkedList.includes('首单'),
|
||||
resetOn: ['翻单']
|
||||
},
|
||||
{
|
||||
title: '批色样',
|
||||
@ -86,8 +49,8 @@ const OPTION_GROUPS: OptionGroupDef[] = [
|
||||
required: true,
|
||||
level: 5,
|
||||
parentOption: '加色',
|
||||
condition: (checkedList) => (checkedList.includes('PDS') || checkedList.includes('LWH')) && checkedList.includes('加色'),
|
||||
resetOn: ['首单', '无变动不需要修改', '需要打板', '不需要打板', 'PLT', 'RBE']
|
||||
condition: (checkedList) => checkedList.includes('加色'),
|
||||
resetOn: ['首单', '无变动不需要修改', '需要打板', '不需要打板']
|
||||
},
|
||||
{
|
||||
title: '批色样',
|
||||
@ -95,38 +58,33 @@ const OPTION_GROUPS: OptionGroupDef[] = [
|
||||
required: true,
|
||||
level: 4,
|
||||
parentOption: '不需要打板',
|
||||
condition: (checkedList) => (checkedList.includes('PDS') || checkedList.includes('LWH')) && checkedList.includes('首单') && checkedList.includes('不需要打板'),
|
||||
resetOn: ['翻单', '有变动需要修改', '无变动不需要修改', 'PLT', 'RBE']
|
||||
condition: (checkedList) => checkedList.includes('首单') && checkedList.includes('不需要打板'),
|
||||
resetOn: ['翻单', '有变动需要修改', '无变动不需要修改']
|
||||
},
|
||||
{
|
||||
title: '品类',
|
||||
options: ['牛仔', '时装'],
|
||||
required: true,
|
||||
condition: (checkedList) => checkedList.includes('PDS') || checkedList.includes('LWH')
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: '复杂度',
|
||||
options: ['简单款', '基础款', '复杂款'],
|
||||
required: true,
|
||||
condition: (checkedList) => checkedList.includes('PDS') || checkedList.includes('LWH')
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: '二次工艺',
|
||||
options: ['绣花', '印花'],
|
||||
required: false,
|
||||
condition: (checkedList) => checkedList.includes('PDS') || checkedList.includes('LWH')
|
||||
required: false
|
||||
},
|
||||
{
|
||||
title: '是否需要批船样',
|
||||
options: ['不需要批船样', '需要批船样'],
|
||||
required: true,
|
||||
condition: (checkedList) => checkedList.includes('PDS') || checkedList.includes('LWH')
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: '运输方式',
|
||||
options: ['美国', '澳大利亚', '英国'],
|
||||
required: false,
|
||||
condition: (checkedList) => checkedList.includes('PDS') || checkedList.includes('LWH'),
|
||||
resetOn: ['PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
@ -144,7 +102,7 @@ const OPTION_GROUPS: OptionGroupDef[] = [
|
||||
required: false,
|
||||
level: 2,
|
||||
parentOption: '英国',
|
||||
condition: (checkedList) => (checkedList.includes('PDS') || checkedList.includes('LWH')) && checkedList.includes('英国'),
|
||||
condition: (checkedList) => checkedList.includes('英国'),
|
||||
resetOn: ['美国', '澳大利亚', 'PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
@ -157,7 +115,7 @@ const OPTION_GROUPS: OptionGroupDef[] = [
|
||||
required: true,
|
||||
level: 2,
|
||||
parentOption: '美国',
|
||||
condition: (checkedList) => (checkedList.includes('PDS') || checkedList.includes('LWH')) && checkedList.includes('美国'),
|
||||
condition: (checkedList) => checkedList.includes('美国'),
|
||||
resetOn: ['英国', '澳大利亚', 'PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
@ -169,7 +127,7 @@ const OPTION_GROUPS: OptionGroupDef[] = [
|
||||
required: true,
|
||||
level: 2,
|
||||
parentOption: '澳大利亚',
|
||||
condition: (checkedList) => (checkedList.includes('PDS') || checkedList.includes('LWH')) && checkedList.includes('澳大利亚'),
|
||||
condition: (checkedList) => checkedList.includes('澳大利亚'),
|
||||
resetOn: ['美国', '英国', 'PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
@ -179,12 +137,321 @@ const OPTION_GROUPS: OptionGroupDef[] = [
|
||||
'特殊面料(真丝、皮革、功能性面料)',
|
||||
'易损面料(薄纱、蕾丝)'
|
||||
],
|
||||
required: false,
|
||||
condition: (checkedList) => checkedList.includes('PDS') || checkedList.includes('LWH')
|
||||
required: false
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// HELLOMOLLY和RBE品牌的标签树仍然为空
|
||||
// 后续可根据需要添加专用标签
|
||||
// LWH 客户配置
|
||||
{
|
||||
title: 'LWH',
|
||||
options: [
|
||||
{
|
||||
title: '单据类型',
|
||||
options: ['首单', '翻单'],
|
||||
required: true,
|
||||
level: 2
|
||||
},
|
||||
{
|
||||
title: '打板类型(多选)',
|
||||
options: ['复版', 'PP版','不用打版'],
|
||||
required: false,
|
||||
level: 3,
|
||||
parentOption: '首单',
|
||||
multiple: true,
|
||||
condition: (checkedList) => checkedList.includes('首单'),
|
||||
resetOn: ['翻单']
|
||||
},
|
||||
{
|
||||
title: '翻单变动',
|
||||
options: ['无变动不需要修改', '有变动需要修改'],
|
||||
required: false,
|
||||
level: 3,
|
||||
parentOption: '翻单',
|
||||
condition: (checkedList) => checkedList.includes('翻单'),
|
||||
resetOn: ['首单']
|
||||
},
|
||||
{
|
||||
title: '特殊订单',
|
||||
options: ['换料寄面料样', '换料重新打板', '加色', '改尺寸重新打板','改尺寸不打版'],
|
||||
required: false,
|
||||
level: 4,
|
||||
parentOption: '有变动需要修改',
|
||||
condition: (checkedList) => checkedList.includes('有变动需要修改'),
|
||||
resetOn: ['首单', '无变动不需要修改']
|
||||
},
|
||||
{
|
||||
title: '特殊订单',
|
||||
options: ['批大货布'],
|
||||
required: false,
|
||||
level: 4,
|
||||
parentOption: '无变动不需要修改',
|
||||
condition: (checkedList) => checkedList.includes('无变动不需要修改'),
|
||||
resetOn: ['首单', '有变动需要修改']
|
||||
},
|
||||
{
|
||||
title: '批色样',
|
||||
options: ['寄成衣','寄色样'],
|
||||
required: true,
|
||||
level: 5,
|
||||
parentOption: '加色',
|
||||
condition: (checkedList) => checkedList.includes('加色'),
|
||||
resetOn: ['首单', '无变动不需要修改', '需要打板', '不需要打板']
|
||||
},
|
||||
{
|
||||
title: '品类',
|
||||
options: ['牛仔', '时装'],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: '复杂度',
|
||||
options: ['简单款', '基础款', '复杂款'],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: '二次工艺',
|
||||
options: ['绣花', '印花'],
|
||||
required: false
|
||||
},
|
||||
{
|
||||
title: '是否需要批船样',
|
||||
options: ['不需要批船样', '需要批船样'],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: '运输方式',
|
||||
options: ['美国', '澳大利亚', '英国'],
|
||||
required: false,
|
||||
resetOn: ['PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
title: '英国运输方式',
|
||||
options: [
|
||||
'英国-海运',
|
||||
'英国-空运 (直飞)',
|
||||
'英国-空运 (转机)',
|
||||
'英国-铁路(中欧班列)',
|
||||
'英国-卡航',
|
||||
'英国-卡空',
|
||||
'英国-卡车联运',
|
||||
'英国-海空联运'
|
||||
],
|
||||
required: false,
|
||||
level: 2,
|
||||
parentOption: '英国',
|
||||
condition: (checkedList) => checkedList.includes('英国'),
|
||||
resetOn: ['美国', '澳大利亚', 'PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
title: '美国运输方式',
|
||||
options: [
|
||||
'美国-海运慢船',
|
||||
'美国-海运快船',
|
||||
'美国-空运(直飞)'
|
||||
],
|
||||
required: true,
|
||||
level: 2,
|
||||
parentOption: '美国',
|
||||
condition: (checkedList) => checkedList.includes('美国'),
|
||||
resetOn: ['英国', '澳大利亚', 'PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
title: '澳大利亚运输方式',
|
||||
options: [
|
||||
'澳大利亚-海运',
|
||||
'澳大利亚-空运(直飞)'
|
||||
],
|
||||
required: true,
|
||||
level: 2,
|
||||
parentOption: '澳大利亚',
|
||||
condition: (checkedList) => checkedList.includes('澳大利亚'),
|
||||
resetOn: ['美国', '英国', 'PLT', 'RBE']
|
||||
},
|
||||
{
|
||||
title: '面料特性',
|
||||
options: [
|
||||
'普通面料(纯棉、常规化纤)',
|
||||
'特殊面料(真丝、皮革、功能性面料)',
|
||||
'易损面料(薄纱、蕾丝)'
|
||||
],
|
||||
required: false
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// PLT 客户配置
|
||||
{
|
||||
title: 'PLT',
|
||||
options: [
|
||||
{
|
||||
title: '单据类型',
|
||||
options: ['首单', '翻单'],
|
||||
required: true,
|
||||
level: 2
|
||||
},
|
||||
{
|
||||
title: '打板类型(多选)',
|
||||
options: ['复版', '拍照版','不用打版'],
|
||||
required: false,
|
||||
level: 3,
|
||||
parentOption: '首单',
|
||||
multiple: true,
|
||||
condition: (checkedList) => checkedList.includes('首单'),
|
||||
resetOn: ['翻单']
|
||||
},
|
||||
{
|
||||
title: '寄样方式',
|
||||
options: ['寄裤筒', '寄成衣'],
|
||||
required: false,
|
||||
level: 4,
|
||||
parentOption: '不用打版',
|
||||
condition: (checkedList) => checkedList.includes('首单') && checkedList.includes('不用打版'),
|
||||
resetOn: ['翻单']
|
||||
},
|
||||
{
|
||||
title: '翻单变动',
|
||||
options: ['无变动不需要修改', '有变动需要修改'],
|
||||
required: false,
|
||||
level: 3,
|
||||
parentOption: '翻单',
|
||||
condition: (checkedList) => checkedList.includes('翻单'),
|
||||
resetOn: ['首单']
|
||||
},
|
||||
{
|
||||
title: '特殊订单',
|
||||
options: ['换料寄面料样', '换料重新打板', '改尺寸重新打板','改尺寸不打版'],
|
||||
required: false,
|
||||
level: 4,
|
||||
parentOption: '有变动需要修改',
|
||||
condition: (checkedList) => checkedList.includes('有变动需要修改'),
|
||||
resetOn: ['首单', '无变动不需要修改']
|
||||
},
|
||||
{
|
||||
title: '打版类型',
|
||||
options: ['复版','拍照版'],
|
||||
required: false,
|
||||
level: 5,
|
||||
parentOption: '换料重新打板',
|
||||
condition: (checkedList) => checkedList.includes('换料重新打板'),
|
||||
resetOn: ['首单', '无变动不需要修改','换料重新打板']
|
||||
},
|
||||
{
|
||||
title: '打版类型',
|
||||
options: ['复版','拍照版'],
|
||||
required: false,
|
||||
level: 5,
|
||||
parentOption: '改尺寸重新打板',
|
||||
condition: (checkedList) => checkedList.includes('改尺寸重新打板'),
|
||||
resetOn: ['首单', '无变动不需要修改','换料重新打板']
|
||||
},
|
||||
{
|
||||
title: '特殊订单',
|
||||
options: ['批大货布'],
|
||||
required: false,
|
||||
level: 4,
|
||||
parentOption: '无变动不需要修改',
|
||||
condition: (checkedList) => checkedList.includes('无变动不需要修改'),
|
||||
resetOn: ['首单', '有变动需要修改']
|
||||
},
|
||||
{
|
||||
title: '品类',
|
||||
options: ['牛仔', '时装'],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: '复杂度',
|
||||
options: ['简单款', '基础款', '复杂款'],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: '二次工艺',
|
||||
options: ['绣花', '印花'],
|
||||
required: false
|
||||
},
|
||||
{
|
||||
title: '是否需要批船样',
|
||||
options: ['不需要批船样', '需要批船样'],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: '运输方式',
|
||||
options: ['美国', '澳大利亚', '英国'],
|
||||
required: false,
|
||||
resetOn: ['RBE']
|
||||
},
|
||||
{
|
||||
title: '英国运输方式',
|
||||
options: [
|
||||
'英国-海运',
|
||||
'英国-空运 (直飞)',
|
||||
'英国-空运 (转机)',
|
||||
'英国-铁路(中欧班列)',
|
||||
'英国-卡航',
|
||||
'英国-卡空',
|
||||
'英国-卡车联运',
|
||||
'英国-海空联运'
|
||||
],
|
||||
required: false,
|
||||
level: 2,
|
||||
parentOption: '英国',
|
||||
condition: (checkedList) => checkedList.includes('英国'),
|
||||
resetOn: ['美国', '澳大利亚', 'RBE']
|
||||
},
|
||||
{
|
||||
title: '美国运输方式',
|
||||
options: [
|
||||
'美国-海运慢船',
|
||||
'美国-海运快船',
|
||||
'美国-空运(直飞)'
|
||||
],
|
||||
required: true,
|
||||
level: 2,
|
||||
parentOption: '美国',
|
||||
condition: (checkedList) => checkedList.includes('美国'),
|
||||
resetOn: ['英国', '澳大利亚', 'RBE']
|
||||
},
|
||||
{
|
||||
title: '澳大利亚运输方式',
|
||||
options: [
|
||||
'澳大利亚-海运',
|
||||
'澳大利亚-空运(直飞)'
|
||||
],
|
||||
required: true,
|
||||
level: 2,
|
||||
parentOption: '澳大利亚',
|
||||
condition: (checkedList) => checkedList.includes('澳大利亚'),
|
||||
resetOn: ['美国', '英国', 'RBE']
|
||||
},
|
||||
{
|
||||
title: '面料特性',
|
||||
options: [
|
||||
'普通面料(纯棉、常规化纤)',
|
||||
'特殊面料(真丝、皮革、功能性面料)',
|
||||
'易损面料(薄纱、蕾丝)'
|
||||
],
|
||||
required: false
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// RBE 客户配置 - 简化示例
|
||||
{
|
||||
title: 'RBE',
|
||||
options: [
|
||||
{
|
||||
title: '特殊订单类型',
|
||||
options: ['紧急订单', '常规订单'],
|
||||
required: true,
|
||||
level: 2
|
||||
},
|
||||
{
|
||||
title: '运输优先级',
|
||||
options: ['标准运输', '加急运输', '特快运输'],
|
||||
required: true,
|
||||
level: 3
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const FABRIC_TEST_OPTIONS = ['需要面料测试', '不需要面料测试'];
|
||||
@ -205,8 +472,9 @@ const createOptionSets = (checkedList: string[]) => {
|
||||
|
||||
// 优化:使用memo包装OptionGroup组件
|
||||
interface OptionGroupProps {
|
||||
group: OptionGroupDef;
|
||||
group: CustomerTagGroup;
|
||||
checkedList: string[];
|
||||
customer: string;
|
||||
onChange: (newList: string[]) => void;
|
||||
lockedOptions?: string[];
|
||||
level?: number;
|
||||
@ -215,6 +483,7 @@ interface OptionGroupProps {
|
||||
const OptionGroup = memo<OptionGroupProps>(({
|
||||
group,
|
||||
checkedList,
|
||||
customer,
|
||||
onChange,
|
||||
lockedOptions = [],
|
||||
level = 1
|
||||
@ -281,11 +550,45 @@ const OptionGroup = memo<OptionGroupProps>(({
|
||||
);
|
||||
});
|
||||
|
||||
// 客户选择器组件 - 添加变更时清空选项的功能
|
||||
const CustomerSelector = memo(({ customers, selectedCustomer, onChange, onCustomerChange }) => {
|
||||
return (
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
<div style={{ fontWeight: 'bold', marginBottom: 8 }}>选择客户:</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
|
||||
{customers.map(customer => (
|
||||
<button
|
||||
key={customer.title}
|
||||
onClick={() => {
|
||||
if (customer.title !== selectedCustomer) {
|
||||
onCustomerChange(customer.title);
|
||||
}
|
||||
onChange(customer.title);
|
||||
}}
|
||||
style={{
|
||||
padding: '8px 16px',
|
||||
borderRadius: 4,
|
||||
border: selectedCustomer === customer.title ? '2px solid #1677ff' : '1px solid #d9d9d9',
|
||||
backgroundColor: selectedCustomer === customer.title ? '#e6f7ff' : '#fff',
|
||||
cursor: 'pointer',
|
||||
fontWeight: selectedCustomer === customer.title ? 'bold' : 'normal'
|
||||
}}
|
||||
>
|
||||
{customer.title}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
// 优化:使用memo包装OrderConfigSelector组件
|
||||
interface OrderConfigSelectorProps {
|
||||
selectedRecordId: string | null;
|
||||
checkedList: string[];
|
||||
setCheckedList: (list: string[]) => void;
|
||||
selectedCustomer: string;
|
||||
setSelectedCustomer: (customer: string) => void;
|
||||
onSubmit: (options: string[]) => void;
|
||||
onCancel: () => void;
|
||||
loading: boolean;
|
||||
@ -295,32 +598,54 @@ const OrderConfigSelector = memo<OrderConfigSelectorProps>(({
|
||||
selectedRecordId,
|
||||
checkedList,
|
||||
setCheckedList,
|
||||
selectedCustomer,
|
||||
setSelectedCustomer,
|
||||
onSubmit,
|
||||
onCancel,
|
||||
loading
|
||||
}) => {
|
||||
// 查找当前选中客户的配置
|
||||
const customerConfig = useMemo(() =>
|
||||
CUSTOMER_CONFIG.find(c => c.title === selectedCustomer) || CUSTOMER_CONFIG[0],
|
||||
[selectedCustomer]
|
||||
);
|
||||
|
||||
// 优化:使用useMemo缓存可见的选项组
|
||||
const visibleGroups = useMemo(() => {
|
||||
return OPTION_GROUPS.filter(group => {
|
||||
if (!group.condition) return true;
|
||||
if (!customerConfig) return [];
|
||||
|
||||
// 筛选出可见的选项组
|
||||
return customerConfig.options.filter(group => {
|
||||
// 如果没有定义显示条件,默认为可见
|
||||
if (!group.condition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 有显示条件的,检查条件是否满足
|
||||
return group.condition(checkedList);
|
||||
});
|
||||
}, [checkedList]);
|
||||
}, [checkedList, customerConfig]);
|
||||
|
||||
// 当客户变更时清空选项
|
||||
const handleCustomerChange = useCallback((newCustomer: string) => {
|
||||
console.log(`客户变更为: ${newCustomer},清空当前选项`);
|
||||
setCheckedList([]);
|
||||
}, [setCheckedList]);
|
||||
|
||||
// 优化:使用useCallback缓存事件处理函数
|
||||
const handleCheckedListChange = useCallback((newList: string[]) => {
|
||||
const addedOptions = newList.filter(opt => !checkedList.includes(opt));
|
||||
|
||||
if (addedOptions.length > 0) {
|
||||
const resetGroups = OPTION_GROUPS.filter(group =>
|
||||
const resetGroups = customerConfig?.options.filter(group =>
|
||||
group.resetOn?.some(resetOpt => addedOptions.includes(resetOpt))
|
||||
);
|
||||
) || [];
|
||||
|
||||
if (resetGroups.length > 0) {
|
||||
const resetGroupsSet = new Set(resetGroups);
|
||||
const filteredOptions = newList.filter(opt => {
|
||||
const group = OPTION_GROUPS.find(g => g.options.includes(opt));
|
||||
return !resetGroupsSet.has(group as OptionGroupDef);
|
||||
const group = customerConfig?.options.find(g => g.options.includes(opt));
|
||||
return !(group && resetGroupsSet.has(group));
|
||||
});
|
||||
setCheckedList(filteredOptions);
|
||||
return;
|
||||
@ -328,12 +653,18 @@ const OrderConfigSelector = memo<OrderConfigSelectorProps>(({
|
||||
}
|
||||
|
||||
setCheckedList(newList);
|
||||
}, [checkedList, setCheckedList]);
|
||||
}, [checkedList, setCheckedList, customerConfig]);
|
||||
|
||||
// 优化:使用useCallback缓存验证函数
|
||||
const validateRequired = useCallback(() => {
|
||||
for (const group of OPTION_GROUPS) {
|
||||
if (group.required && group.condition?.(checkedList) !== false) {
|
||||
if (!customerConfig) {
|
||||
message.error('请选择客户');
|
||||
return false;
|
||||
}
|
||||
|
||||
// 验证可见的必填项
|
||||
for (const group of visibleGroups) {
|
||||
if (group.required) {
|
||||
const has = checkedList.some(v => group.options.includes(v));
|
||||
if (!has) {
|
||||
message.error(`请至少选择一项【${group.title}】`);
|
||||
@ -352,7 +683,7 @@ const OrderConfigSelector = memo<OrderConfigSelectorProps>(({
|
||||
}
|
||||
|
||||
return true;
|
||||
}, [checkedList]);
|
||||
}, [checkedList, customerConfig, visibleGroups]);
|
||||
|
||||
const needFabricTestDialog = useCallback(() => {
|
||||
return !(checkedList.includes('翻单') && checkedList.includes('无变动不需要修改'));
|
||||
@ -416,16 +747,30 @@ const OrderConfigSelector = memo<OrderConfigSelectorProps>(({
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
confirmLoading={loading}
|
||||
width={768}
|
||||
>
|
||||
<CustomerSelector
|
||||
customers={CUSTOMER_CONFIG}
|
||||
selectedCustomer={selectedCustomer}
|
||||
onChange={setSelectedCustomer}
|
||||
onCustomerChange={handleCustomerChange}
|
||||
/>
|
||||
|
||||
{/* 只有选择了客户才显示标签组 */}
|
||||
{selectedCustomer && customerConfig && (
|
||||
<div>
|
||||
{visibleGroups.map(group => (
|
||||
<OptionGroup
|
||||
key={group.title}
|
||||
group={group}
|
||||
checkedList={checkedList}
|
||||
customer={selectedCustomer}
|
||||
onChange={handleCheckedListChange}
|
||||
level={group.level}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
@ -460,6 +805,9 @@ const App: React.FC = () => {
|
||||
recordId: string | null;
|
||||
}>({ tableId: null, recordId: null });
|
||||
|
||||
// 新增:当前选中的客户
|
||||
const [selectedCustomer, setSelectedCustomer] = useState<string | null>(null);
|
||||
|
||||
// 优化:缓存字段选项映射,避免重复查找
|
||||
const [fieldOptionsMap, setFieldOptionsMap] = useState<Map<string, {id: string, name: string}>>(new Map());
|
||||
|
||||
@ -467,6 +815,7 @@ const App: React.FC = () => {
|
||||
const resetOptions = useCallback(() => {
|
||||
setSelectedRecordId(null);
|
||||
setCheckedList([]);
|
||||
setSelectedCustomer(null); // 重置时也重置客户选择
|
||||
}, []);
|
||||
|
||||
const saveOptions = useCallback(async () => {
|
||||
@ -475,6 +824,11 @@ const App: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!selectedCustomer) {
|
||||
message.error('请选择客户');
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
const FIELD_ID_TO_SAVE = 'fldTtRHwlo';
|
||||
|
||||
@ -551,7 +905,7 @@ const App: React.FC = () => {
|
||||
resetOptions();
|
||||
setCurrentSelection({ tableId: null, recordId: null });
|
||||
}
|
||||
}, [selectedRecordId, currentSelection.tableId, checkedList, fieldOptionsMap, resetOptions]);
|
||||
}, [selectedRecordId, currentSelection.tableId, checkedList, fieldOptionsMap, resetOptions, selectedCustomer]);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = bitable.base.onSelectionChange(async (event: any) => {
|
||||
@ -584,6 +938,13 @@ const App: React.FC = () => {
|
||||
} else {
|
||||
setCheckedList([]);
|
||||
}
|
||||
|
||||
// 尝试从选中的选项中推断客户
|
||||
const firstOption = checkedList[0];
|
||||
const customer = CUSTOMER_CONFIG.find(c => c.options.some(g => g.options.includes(firstOption)));
|
||||
if (customer) {
|
||||
setSelectedCustomer(customer.title);
|
||||
}
|
||||
}
|
||||
} catch (e: any) {
|
||||
message.error('获取选中记录失败: ' + (e.message || e));
|
||||
@ -602,6 +963,8 @@ const App: React.FC = () => {
|
||||
selectedRecordId={selectedRecordId}
|
||||
checkedList={checkedList}
|
||||
setCheckedList={setCheckedList}
|
||||
selectedCustomer={selectedCustomer || ''}
|
||||
setSelectedCustomer={setSelectedCustomer}
|
||||
onSubmit={saveOptions}
|
||||
onCancel={resetOptions}
|
||||
loading={loading}
|
||||
|
Reference in New Issue
Block a user