This commit is contained in:
孙景学
2025-07-21 14:04:20 +08:00
parent 58dd501cb2
commit e9ebd6ac1c
13 changed files with 320 additions and 265 deletions

View File

@ -10,7 +10,7 @@ import { categoryTree, add } from '../services';
const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ visible, onCancel }) => {
const [form] = Form.useForm();
//名称输入
//名称输入
const [accessWorkNameEdited, setAccessWorkNameEdited] = useState(false);
//品类选择
@ -20,6 +20,8 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
const [supplierModalVisible, setSupplierModalVisible] = useState(false);
//品类选择渲染数据
const [categoriesTreeData, setCategoriesTreeData] = useState([]);
//提交防抖
const [submitting, setSubmitting] = useState(false);
//品类选择数据中字段转换
const convertTreeData = (data: any) => {
return data.map((item: any) => ({
@ -54,69 +56,69 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
? checkedKeysValue
: checkedKeysValue.checked;
// 只取叶子节点 key
// 只取叶子节点 key
const leafKeys = findLeafKeys(convertTreeData(categoriesTreeData));
const onlyLeafChecked = keys.filter(key => leafKeys.includes(String(key)));
console.log(onlyLeafChecked,'onlyLeafChecked', leafKeys ,keys);
console.log(onlyLeafChecked, 'onlyLeafChecked', leafKeys, keys);
setCheckedKeys(keys); // UI 显示用,还是全量
form.setFieldsValue({ categoryIds: onlyLeafChecked }); // 只存叶子到表单
// ==============================
// 增加自动拼标题的逻辑
// ==============================
if (!accessWorkNameEdited) {
// 1. 获取供应商名
const supplier = (form.getFieldValue('supplier') || [])[0];
let supplierName = '';
if (supplier) {
supplierName = supplier.supplierType === 'ovs' ? supplier.nameEn : supplier.name;
}
// 2. 获取已选品类名称
const findNamesByIds = (treeData: any[], ids: any[]) => {
let names: string[] = [];
const dfs = (list: any[]) => {
list.forEach(item => {
if (ids.includes(item.id)) {
names.push(item.categoryName);
}
if (item.children) dfs(item.children);
});
// ==============================
// 增加自动拼标题的逻辑
// ==============================
if (!accessWorkNameEdited) {
// 1. 获取供应商名
const supplier = (form.getFieldValue('supplier') || [])[0];
let supplierName = '';
if (supplier) {
supplierName = supplier.supplierType === 'ovs' ? supplier.nameEn : supplier.name;
}
dfs(treeData);
return names;
};
const categoryNames = findNamesByIds(categoriesTreeData, onlyLeafChecked);
// 2. 获取已选品类名称
const findNamesByIds = (treeData: any[], ids: any[]) => {
let names: string[] = [];
const dfs = (list: any[]) => {
list.forEach(item => {
if (ids.includes(item.id)) {
names.push(item.categoryName);
}
if (item.children) dfs(item.children);
});
}
dfs(treeData);
return names;
};
const categoryNames = findNamesByIds(categoriesTreeData, onlyLeafChecked);
let autoTitle = supplierName;
if (supplierName && categoryNames.length) {
if (categoryNames.length === 1) {
autoTitle = `${supplierName}-${categoryNames[0]}-品类准入工作`;
} else {
autoTitle = `${supplierName}-${categoryNames[0]}等-品类准入工作`;
}
} else if (!supplierName && categoryNames.length) {
if (categoryNames.length === 1) {
autoTitle = categoryNames[0];
} else {
autoTitle = `${categoryNames[0]}等-品类准入工作`;
}
}
form.setFieldsValue({ accessWorkName: autoTitle });
}
let autoTitle = supplierName;
if (supplierName && categoryNames.length) {
if (categoryNames.length === 1) {
autoTitle = `${supplierName}-${categoryNames[0]}-品类准入工作`;
} else {
autoTitle = `${supplierName}-${categoryNames[0]}等-品类准入工作`;
}
} else if (!supplierName && categoryNames.length) {
if (categoryNames.length === 1) {
autoTitle = categoryNames[0];
} else {
autoTitle = `${categoryNames[0]}等-品类准入工作`;
}
}
form.setFieldsValue({ accessWorkName: autoTitle });
}
};
// 提交
const onFinish = async (values: any) => {
const finalPayload: {
coscoAccessWork: {
accessWorkName: string;
deptId: string;
};
categoryIds: string[];
supplierIds: string[];
};
categoryIds: string[];
supplierIds: string[];
} = {
coscoAccessWork: {
accessWorkName: '',
@ -132,25 +134,33 @@ form.setFieldsValue({ accessWorkName: autoTitle });
//品类选择
finalPayload.categoryIds = values.categoryIds;
//选择供应商
if(values.supplier.length != 0) {
if (values.supplier.length != 0) {
values.supplier.forEach((item: { id: string }) => {
finalPayload.supplierIds.push(item.id)
})
}
console.log( finalPayload, values);
const res = await add(finalPayload);
if (res?.success) {
message.success('创建成功');
form.resetFields();
setCheckedKeys([]);
onCancel();
} else {
message.error('创建失败');
console.log(finalPayload, values);
if (submitting) return; // 防重复提交
setSubmitting(true);
try {
const res = await add(finalPayload);
if (res?.success) {
message.success('创建成功');
form.resetFields();
setCheckedKeys([]);
onCancel();
} else {
message.error('创建失败');
}
}
finally {
setSubmitting(false); // 无论成功失败都解锁
}
};
//初始化
useEffect(() => {
if(visible) {
if (visible) {
categoryTree().then((res) => {
const { code, data } = res;
if (code == 200) {
@ -183,21 +193,21 @@ form.setFieldsValue({ accessWorkName: autoTitle });
name="accessWorkName"
rules={[{ required: true, message: '请输入标题名称' }]}
>
<Input placeholder="请输入标题名称" allowClear
onChange={e => {
if (e.target.value) {
setAccessWorkNameEdited(true);
} else {
setAccessWorkNameEdited(false);
}
}}/>
<Input placeholder="请输入标题名称" allowClear
onChange={e => {
if (e.target.value) {
setAccessWorkNameEdited(true);
} else {
setAccessWorkNameEdited(false);
}
}} />
</Form.Item>
<Form.Item
label="准入部门"
name="deptId"
rules={[{ required: true, message: '请选择准入部门' }]}
>
<AccessDepartmentSelect style={{width: '100%'}} orgCategory='' />
<AccessDepartmentSelect style={{ width: '100%' }} orgCategory='' />
</Form.Item>
@ -209,7 +219,7 @@ form.setFieldsValue({ accessWorkName: autoTitle });
<Button onClick={() => setSupplierModalVisible(true)}>
</Button>
<span style={{marginLeft: 10}}>{`${form.getFieldValue('supplier')? form.getFieldValue('supplier')[0].supplierType === 'ovs' ? form.getFieldValue('supplier')[0].nameEn : form.getFieldValue('supplier')[0].name : ''}`}</span>
<span style={{ marginLeft: 10 }}>{`${form.getFieldValue('supplier') ? form.getFieldValue('supplier')[0].supplierType === 'ovs' ? form.getFieldValue('supplier')[0].nameEn : form.getFieldValue('supplier')[0].name : ''}`}</span>
</Form.Item>
<Form.Item
@ -235,7 +245,7 @@ form.setFieldsValue({ accessWorkName: autoTitle });
</Form.Item>
<Form.Item wrapperCol={{ offset: 6 }}>
<Button type="primary" htmlType="submit" style={{ marginRight: 8 }}>
<Button type="primary" htmlType="submit" style={{ marginRight: 8 }} disabled={submitting}>
</Button>
<Button
@ -257,13 +267,13 @@ form.setFieldsValue({ accessWorkName: autoTitle });
form.setFieldsValue({ supplier: selected });
setCheckedKeys([]);
setSupplierModalVisible(false);
// 取所有已选供应商的 categoryName 并分割
// 取所有已选供应商的 categoryName 并分割
const allCategories = selected
.map(item => item.categoryIds) // 取出字符串
.filter(Boolean) // 防止空
.flatMap(str => str.split(',')) // 逗号切分
.map(c => c.trim()) // 去空格
.filter(Boolean);
.map(item => item.categoryIds) // 取出字符串
.filter(Boolean) // 防止空
.flatMap(str => str.split(',')) // 逗号切分
.map(c => c.trim()) // 去空格
.filter(Boolean);
setDisabledCategories(Array.from(new Set(allCategories))); // 去重
//名称
@ -277,7 +287,7 @@ form.setFieldsValue({ accessWorkName: autoTitle });
}
}
}}
/>
/>
</Modal>
);
};

View File

@ -46,6 +46,8 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
const [supplierModalVisible, setSupplierModalVisible] = useState(false);
const [reviewerModalVisible, setReviewerModalVisible] = useState(false);
const [divisionModalVisible, setDivisionModalVisible] = useState(false);
//提交防抖
const [submitting, setSubmitting] = useState(false);
//品类选择渲染数据
const [categoriesTreeData, setCategoriesTreeData] = useState([]);
//品类选择数据中字段转换
@ -132,92 +134,106 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
message.error('上传失败');
}
};
//获取 cuCompanyNumber
const onChangeDepartmentSelect = (value: any, label: any, extra: any) => {
form.setFieldsValue({ orgId: extra?.triggerNode?.props.cuCompanyNumber });
}
// 提交
const onFinish = async (values: any) => {
const finalPayload: {
coscoAccessWork: {
startTime: string;
endTime: string;
accessType: string;
accessWorkName: string;
deptId: string;
accessDesc: string;
};
categoryIds: string[];
supplierIds: string[];
coscoAccessUserls: { userId: string; deptId: string; isLeader: number }[];
coscoAccessItems: { itemName: string; reviewBy: string[] }[];
coscoAccessWorkAttachments: any;
attachmentsType: any;
} = {
coscoAccessWork: {
startTime: '',
endTime: '',
accessType: '',
accessWorkName: '',
deptId: '',
accessDesc: '',
},
categoryIds: [],
supplierIds: [],
coscoAccessUserls: [],
coscoAccessItems: [],
coscoAccessWorkAttachments: {},
attachmentsType: {},
};
if (submitting) return; // 防重复提交
setSubmitting(true);
//标题名称
finalPayload.coscoAccessWork.accessWorkName = values.accessWorkName;
//准入方式
finalPayload.coscoAccessWork.accessType = values.accessType;
//准入部门
finalPayload.coscoAccessWork.deptId = values.deptId;
// 准入说明
finalPayload.coscoAccessWork.accessDesc = values.accessDesc;
//品类选择
finalPayload.categoryIds = values.categoryIds;
//选择供应商
values.supplier.forEach((item: { id: string }) => {
finalPayload.supplierIds.push(item.id)
})
if (values.accessType === 'online') {
// 评审时间
if (values.rangePicker && values.rangePicker.length === 2) {
const [start, end] = values.rangePicker;
finalPayload.coscoAccessWork.startTime = start.format('YYYY-MM-DD HH:mm');
finalPayload.coscoAccessWork.endTime = end.format('YYYY-MM-DD HH:mm');
}
//选择评审人员
finalPayload.coscoAccessUserls = values.reviewers.selected.map((item: { userId: string, deptId: string, isLeader: number }) => {
return { userId: item.userId, deptId: item.deptId, isLeader: item.isLeader }
});
//评审分工
values.division.forEach((item: any) => {
const dataJson = {
itemName: item.itemName,
reviewBy: [] as string[],
try {
const finalPayload: {
coscoAccessWork: {
startTime: string;
endTime: string;
accessType: string;
accessWorkName: string;
deptId: string;
orgId: string;
accessDesc: string;
};
Object.entries(item.reviewerChecks || {}).forEach(([key, value]) => {
dataJson.reviewBy.push(key);
categoryIds: string[];
supplierIds: string[];
coscoAccessUserls: { userId: string; deptId: string; isLeader: number }[];
coscoAccessItems: { itemName: string; reviewBy: string[] }[];
coscoAccessWorkAttachments: any;
attachmentsType: any;
} = {
coscoAccessWork: {
startTime: '',
endTime: '',
accessType: '',
accessWorkName: '',
deptId: '',
orgId: '',
accessDesc: '',
},
categoryIds: [],
supplierIds: [],
coscoAccessUserls: [],
coscoAccessItems: [],
coscoAccessWorkAttachments: {},
attachmentsType: {},
};
//标题名称
finalPayload.coscoAccessWork.accessWorkName = values.accessWorkName;
//准入方式
finalPayload.coscoAccessWork.accessType = values.accessType;
//准入部门
finalPayload.coscoAccessWork.deptId = values.deptId;
//准入单位
finalPayload.coscoAccessWork.orgId = values.orgId;
// 准入说明
finalPayload.coscoAccessWork.accessDesc = values.accessDesc;
//品类选择
finalPayload.categoryIds = values.categoryIds;
//选择供应商
values.supplier.forEach((item: { id: string }) => {
finalPayload.supplierIds.push(item.id)
})
if (values.accessType === 'online') {
// 评审时间
if (values.rangePicker && values.rangePicker.length === 2) {
const [start, end] = values.rangePicker;
finalPayload.coscoAccessWork.startTime = start.format('YYYY-MM-DD HH:mm');
finalPayload.coscoAccessWork.endTime = end.format('YYYY-MM-DD HH:mm');
}
//选择评审人员
finalPayload.coscoAccessUserls = values.reviewers.selected.map((item: { userId: string, deptId: string, isLeader: number }) => {
return { userId: item.userId, deptId: item.deptId, isLeader: item.isLeader }
});
finalPayload.coscoAccessItems.push(dataJson);
});
} else {
// 供应商符合性审查
finalPayload.coscoAccessWorkAttachments = values.supplierCompliance[0].response;
finalPayload.coscoAccessWorkAttachments.fileUrl = values.supplierCompliance[0].response.url;
}
const res = await add(finalPayload);
if (res?.success) {
message.success('创建成功');
form.resetFields();
setCheckedKeys([]);
setSelectedReviewers({ selected: [], leader: null, });
setAdmissionMethod('online');
onCancel();
} else {
message.error('创建失败');
//评审分工
values.division.forEach((item: any) => {
const dataJson = {
itemName: item.itemName,
reviewBy: [] as string[],
};
Object.entries(item.reviewerChecks || {}).forEach(([key, value]) => {
dataJson.reviewBy.push(key);
});
finalPayload.coscoAccessItems.push(dataJson);
});
} else {
// 供应商符合性审查
finalPayload.coscoAccessWorkAttachments = values.supplierCompliance[0].response;
finalPayload.coscoAccessWorkAttachments.fileUrl = values.supplierCompliance[0].response.url;
}
const res = await add(finalPayload);
if (res?.success) {
message.success('创建成功');
form.resetFields();
setCheckedKeys([]);
setSelectedReviewers({ selected: [], leader: null, });
setAdmissionMethod('online');
onCancel();
} else {
message.error('创建失败');
}
} finally {
setSubmitting(false); // 无论成功失败都解锁
}
};
//初始化
@ -273,7 +289,10 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
name="deptId"
rules={[{ required: true, message: '请选择准入部门' }]}
>
<AccessDepartmentSelect style={{width: '100%'}} orgCategory='' />
<AccessDepartmentSelect style={{width: '100%'}} orgCategory='' onChange={onChangeDepartmentSelect} />
</Form.Item>
<Form.Item name="orgId" noStyle>
<Input type="hidden" />
</Form.Item>
<Form.Item
@ -474,7 +493,7 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
)}
<Form.Item wrapperCol={{ offset: 6 }}>
<Button type="primary" htmlType="submit" style={{ marginRight: 8 }}>
<Button type="primary" htmlType="submit" style={{ marginRight: 8 }} disabled={submitting}>
{admissionMethod === 'online' ? '确认' : admissionMethod === 'offline' ? '提交审批' : '提交'}
</Button>