2025-07-09 19:30:27 +08:00

995 lines
30 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useEffect, useMemo, useCallback, memo } from 'react';
import { bitable, CurrencyCode, FieldType, ICurrencyField, ICurrencyFieldMeta } from '@lark-base-open/js-sdk';
import { Card, Modal, Checkbox, message } from 'antd';
import './App.css';
// 客户配置类型定义
interface CustomerOptionGroup {
title: string; // 客户名称
options: CustomerTagGroup[]; // 客户专属标签组
isDefault?: boolean; // 是否为默认客户
}
// 客户标签组类型定义
interface CustomerTagGroup {
title: string; // 标签组标题
options: string[]; // 标签选项
required: boolean; // 是否必填
level?: number; // 层级
parentOption?: string; // 父选项
condition?: (checkedList: string[]) => boolean; // 显示条件
resetOn?: string[]; // 重置条件
multiple?: boolean; // 是否支持多选
}
// 客户配置 - 按客户分组管理标签
const CUSTOMER_CONFIG: CustomerOptionGroup[] = [
// PDS 客户配置
{
title: 'PDS',
options: [
{
title: '单据类型',
options: ['首单', '翻单'],
required: true,
level: 2
},
{
title: '是否要打板',
options: ['需要打板', '不需要打板'],
required: false,
level: 3,
parentOption: '首单',
condition: (checkedList) => checkedList.includes('首单'),
resetOn: ['翻单']
},
{
title: '批色样',
options: ['要批色样', '不要批色样'],
required: true,
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: 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
}
]
},
// 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 = ['需要面料测试', '不需要面料测试'];
// 优化预计算选项集合避免重复includes操作
const createOptionSets = (checkedList: string[]) => {
const checkedSet = new Set(checkedList);
return {
checkedSet,
hasFirstOrder: checkedSet.has('首单'),
hasReorder: checkedSet.has('翻单'),
hasNoChange: checkedSet.has('无变动不需要修改'),
hasChange: checkedSet.has('有变动需要修改'),
hasAddColor: checkedSet.has('加色'),
hasNoPlate: checkedSet.has('不需要打板')
};
};
// 优化使用memo包装OptionGroup组件
interface OptionGroupProps {
group: CustomerTagGroup;
checkedList: string[];
customer: string;
onChange: (newList: string[]) => void;
lockedOptions?: string[];
level?: number;
}
const OptionGroup = memo<OptionGroupProps>(({
group,
checkedList,
customer,
onChange,
lockedOptions = [],
level = 1
}) => {
// 使用配置中的 multiple 属性,默认为 false单选
const isMulti = group.multiple || false;
// 优化使用useMemo缓存计算结果
const groupChecked = useMemo(() =>
checkedList.filter(v => group.options.includes(v)),
[checkedList, group.options]
);
const indentStyle = useMemo(() => ({
marginLeft: level > 1 ? (level - 1) * 24 : 0,
marginTop: level > 1 ? 8 : 0,
borderLeft: level > 1 ? `${level > 2 ? 'dashed' : 'solid'} 2px #eee` : 'none',
paddingLeft: level > 1 ? 12 : 0
}), [level]);
const titleColor = useMemo(() => {
switch(level) {
case 1: return '#000';
case 2: return '#888';
case 3: return '#b36d00';
default: return '#888';
}
}, [level]);
const options = useMemo(() =>
group.options.map(opt => ({
label: opt,
value: opt,
disabled: lockedOptions.includes(opt)
})),
[group.options, lockedOptions]
);
const handleChange = useCallback((list: string[]) => {
const others = checkedList.filter(v => !group.options.includes(v));
let newList;
if (isMulti) {
// 多选模式:保留所有选中项
newList = [...others, ...list];
} else {
// 单选模式:只保留最后选中的一项
newList = [...others, list.slice(-1)[0]].filter(Boolean);
}
onChange(newList);
}, [checkedList, group.options, isMulti, onChange]);
return (
<div key={group.title} style={{ ...indentStyle, marginBottom: 12 }}>
<div style={{ fontWeight: 'bold', marginBottom: 4, color: titleColor }}>
{group.title}
{group.required && <span style={{ color: 'red', marginLeft: 4 }}>*</span>}
</div>
<Checkbox.Group
options={options}
value={groupChecked}
onChange={handleChange}
/>
</div>
);
});
// 客户选择器组件 - 添加变更时清空选项的功能
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;
}
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(() => {
if (!customerConfig) return [];
// 筛选出可见的选项组
return customerConfig.options.filter(group => {
// 如果没有定义显示条件,默认为可见
if (!group.condition) {
return true;
}
// 有显示条件的,检查条件是否满足
return group.condition(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 = 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 = customerConfig?.options.find(g => g.options.includes(opt));
return !(group && resetGroupsSet.has(group));
});
setCheckedList(filteredOptions);
return;
}
}
setCheckedList(newList);
}, [checkedList, setCheckedList, customerConfig]);
// 优化使用useCallback缓存验证函数
const validateRequired = useCallback(() => {
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}`);
return false;
}
}
}
// 特殊验证:如果选择了"不需要打板",必须选择是否批色样
if (checkedList.includes('首单') && checkedList.includes('不需要打板')) {
const hasColorSample = checkedList.some(v => v === '要批色样' || v === '不要批色样');
if (!hasColorSample) {
message.error('请选择是否要批色样');
return false;
}
}
return true;
}, [checkedList, customerConfig, visibleGroups]);
const needFabricTestDialog = useCallback(() => {
return !(checkedList.includes('翻单') && checkedList.includes('无变动不需要修改'));
}, [checkedList]);
const [showFabricTestModal, setShowFabricTestModal] = useState(false);
const [fabricTestSelection, setFabricTestSelection] = useState<string[]>([]);
const [isSubmitting, setIsSubmitting] = useState(false);
const [finalOptions, setFinalOptions] = useState<string[]>([]);
const handleSubmit = useCallback(() => {
if (!validateRequired()) return;
setFinalOptions([...checkedList]);
if (needFabricTestDialog()) {
setFabricTestSelection([]);
setShowFabricTestModal(true);
} else {
onSubmit([...checkedList]);
}
}, [validateRequired, checkedList, needFabricTestDialog, onSubmit]);
const handleFabricTestSubmit = useCallback(() => {
if (fabricTestSelection.length === 0) {
message.error('请选择是否需要面料测试');
return;
}
setIsSubmitting(true);
onSubmit([...finalOptions, ...fabricTestSelection]);
setShowFabricTestModal(false);
}, [fabricTestSelection, finalOptions, onSubmit]);
const handleCancel = useCallback(() => {
onCancel();
setCheckedList([]);
}, [onCancel, setCheckedList]);
const handleFabricTestChange = useCallback((values: string[]) => {
if (values.length > 0) {
setFabricTestSelection([values[values.length - 1]]);
} else {
setFabricTestSelection([]);
}
}, []);
useEffect(() => {
if (!showFabricTestModal && isSubmitting) {
setIsSubmitting(false);
}
}, [showFabricTestModal, isSubmitting]);
return (
<>
<Modal
title="订单配置"
open={!!selectedRecordId}
onOk={handleSubmit}
onCancel={handleCancel}
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
title="面料测试"
open={showFabricTestModal}
onOk={handleFabricTestSubmit}
onCancel={() => setShowFabricTestModal(false)}
okText="确定"
cancelText="取消"
confirmLoading={isSubmitting}
>
<div>
<p>:</p>
<Checkbox.Group
options={FABRIC_TEST_OPTIONS}
value={fabricTestSelection}
onChange={handleFabricTestChange}
/>
</div>
</Modal>
</>
);
});
// 优化:主应用组件
const App: React.FC = () => {
const [selectedRecordId, setSelectedRecordId] = useState<string | null>(null);
const [checkedList, setCheckedList] = useState<string[]>([]);
const [loading, setLoading] = useState(false);
const [currentSelection, setCurrentSelection] = useState<{
tableId: string | null;
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());
// 优化使用useCallback缓存函数
const resetOptions = useCallback(() => {
setSelectedRecordId(null);
setCheckedList([]);
setSelectedCustomer(null); // 重置时也重置客户选择
}, []);
const saveOptions = useCallback(async () => {
if (!selectedRecordId || !currentSelection.tableId) {
message.warning('没有有效的选中记录或表格信息');
return;
}
if (!selectedCustomer) {
message.error('请选择客户');
return;
}
setLoading(true);
const FIELD_ID_TO_SAVE = 'fldTtRHwlo';
try {
const table = await bitable.base.getTableById(currentSelection.tableId);
if (!table) {
message.error('无法获取表格对象');
return;
}
const field = await table.getFieldById(FIELD_ID_TO_SAVE);
if (!field) {
message.error('无法获取字段对象');
return;
}
// 优化:只在字段选项映射为空时才重新获取
let optionsMap = fieldOptionsMap;
if (optionsMap.size === 0) {
const fieldMeta = await field.getMeta();
console.log('字段元数据:', fieldMeta);
// 检查字段类型是否为多选或单选字段
let fieldOptions = [];
if (fieldMeta.type === FieldType.MultiSelect || fieldMeta.type === FieldType.SingleSelect) {
fieldOptions = (fieldMeta.property as any).options || [];
}
optionsMap = new Map(fieldOptions.map(opt => [opt.name, opt]));
setFieldOptionsMap(optionsMap);
}
let dataToSave = null;
if (checkedList.length > 0) {
console.log('字段中的所有选项:', Array.from(optionsMap.keys()));
console.log('要保存的选项:', checkedList);
// 优化使用Map查找O(1)时间复杂度
dataToSave = checkedList.map(optionText => {
const matchedOption = optionsMap.get(optionText);
if (!matchedOption) {
console.warn(`未找到选项 "${optionText}" 对应的ID`);
console.log('可能的匹配选项:', Array.from(optionsMap.keys()).filter(key =>
key.includes(optionText) || optionText.includes(key)
));
return null;
}
console.log(`找到匹配: "${optionText}" -> ID: ${matchedOption.id}`);
return {
id: matchedOption.id,
text: matchedOption.name
};
}).filter(Boolean);
}
console.log('准备保存的数据:', dataToSave);
await field.setValue(selectedRecordId, dataToSave);
const savedValue = await field.getValue(selectedRecordId);
console.log('保存后的字段值:', savedValue);
if (savedValue) {
console.log('数据成功写入单元格');
message.success('已保存选项');
} else {
throw new Error('数据写入后未能读取到值');
}
} catch (e: any) {
console.error('保存失败:', e);
message.error(`保存失败: ${e.message || '未知错误'}`);
} finally {
setLoading(false);
resetOptions();
setCurrentSelection({ tableId: null, recordId: null });
}
}, [selectedRecordId, currentSelection.tableId, checkedList, fieldOptionsMap, resetOptions, selectedCustomer]);
useEffect(() => {
const unsubscribe = bitable.base.onSelectionChange(async (event: any) => {
try {
const { data } = event;
if (data && data.tableId && data.recordId) {
const isNewCell = (
data.tableId !== currentSelection.tableId ||
data.recordId !== currentSelection.recordId
);
if (isNewCell) {
resetOptions();
setCurrentSelection({
tableId: data.tableId,
recordId: data.recordId
});
// 优化:切换单元格时清空字段选项缓存
setFieldOptionsMap(new Map());
}
const table = await bitable.base.getTableById(data.tableId);
const cellValue = await table.getCellValue('fldTtRHwlo', data.recordId);
setSelectedRecordId(data.recordId);
if (typeof cellValue === 'string' && cellValue.trim() !== '') {
setCheckedList(cellValue.split(',').map(item => item.trim()));
} else if (Array.isArray(cellValue)) {
setCheckedList(cellValue.map(item => String(item)));
} 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));
}
});
return unsubscribe;
}, [currentSelection, resetOptions]);
return (
<div style={{ padding: '16px' }}>
<Card>
<div></div>
</Card>
<OrderConfigSelector
selectedRecordId={selectedRecordId}
checkedList={checkedList}
setCheckedList={setCheckedList}
selectedCustomer={selectedCustomer || ''}
setSelectedCustomer={setSelectedCustomer}
onSubmit={saveOptions}
onCancel={resetOptions}
loading={loading}
/>
</div>
);
};
export default App;