防抖
This commit is contained in:
@ -2,7 +2,7 @@ import { history } from 'umi';
|
|||||||
|
|
||||||
export function onRouteChange({ location }: any) {
|
export function onRouteChange({ location }: any) {
|
||||||
const token = sessionStorage.getItem('token');
|
const token = sessionStorage.getItem('token');
|
||||||
const whiteList = ['/login', '/forgot', '/403', '/404'];
|
const whiteList = ['/login', '/forgot', '/register/supplier', '/register/expert', '/403', '/404'];
|
||||||
if (!token && !whiteList.includes(location.pathname)) {
|
if (!token && !whiteList.includes(location.pathname)) {
|
||||||
history.replace('/login');
|
history.replace('/login');
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { treeData } from './services'; // 你的接口
|
|||||||
|
|
||||||
export interface AccessDepartmentSelectProps {
|
export interface AccessDepartmentSelectProps {
|
||||||
value?: string | number;
|
value?: string | number;
|
||||||
onChange?: (value: string | number) => void;
|
onChange?: (value: string | number, label: any, extra: any) => void;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
orgCategory?: string;
|
orgCategory?: string;
|
||||||
|
@ -100,7 +100,7 @@ const SupplierRegister: React.FC<supplierWithInputProps> = (props) => {
|
|||||||
fileType: values.attachments.file.response.fileType,
|
fileType: values.attachments.file.response.fileType,
|
||||||
fileSize: values.attachments.file.response.fileSize,
|
fileSize: values.attachments.file.response.fileSize,
|
||||||
filePath: values.attachments.file.response.filePath,
|
filePath: values.attachments.file.response.filePath,
|
||||||
fileUrl: values.attachments.file.response.filePath,
|
fileUrl: values.attachments.file.response.url,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import {
|
|||||||
Radio,
|
Radio,
|
||||||
Cascader,
|
Cascader,
|
||||||
Empty,
|
Empty,
|
||||||
|
Descriptions
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { UploadOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons';
|
import { UploadOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons';
|
||||||
import { message } from 'antd';
|
import { message } from 'antd';
|
||||||
@ -257,9 +258,8 @@ export const QualificationSection: React.FC<CommonFormSectionsProps> = ({ form }
|
|||||||
<FileUpload
|
<FileUpload
|
||||||
listType="text"
|
listType="text"
|
||||||
maxCount={1}
|
maxCount={1}
|
||||||
allowedTypes={['pdf', 'jpg', 'jpeg', 'png']}
|
allowedTypes={['pdf', 'doc', 'docx', 'jpg', 'jpeg', 'png']}
|
||||||
maxSize={10}
|
maxSize={10}
|
||||||
tip="pdf,jpg,jpeg,png类型的文件,大小不超过10MB"
|
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
),
|
),
|
||||||
@ -379,9 +379,8 @@ export const InvoiceSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
|
|||||||
<FileUpload
|
<FileUpload
|
||||||
listType="text"
|
listType="text"
|
||||||
maxCount={1}
|
maxCount={1}
|
||||||
allowedTypes={['pdf', 'jpg', 'jpeg', 'png']}
|
allowedTypes={['pdf', 'doc', 'docx', 'jpg', 'jpeg', 'png']}
|
||||||
maxSize={10}
|
maxSize={10}
|
||||||
tip="pdf,jpg,jpeg,png类型的文件,大小不超过10MB"
|
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Col>
|
</Col>
|
||||||
@ -474,40 +473,40 @@ export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form, su
|
|||||||
const domesticColumns: ColumnType[] =
|
const domesticColumns: ColumnType[] =
|
||||||
supplierType === 'dvs'
|
supplierType === 'dvs'
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
title: '银联号',
|
title: '银联号',
|
||||||
dataIndex: 'interbankNumber',
|
dataIndex: 'interbankNumber',
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[record.name, 'interbankNumber']}
|
name={[record.name, 'interbankNumber']}
|
||||||
noStyle
|
noStyle
|
||||||
rules={[{ required: true, message: '请输入银联号' }]}
|
rules={[{ required: true, message: '请输入银联号' }]}
|
||||||
>
|
>
|
||||||
<Input placeholder="请输入银联号" />
|
<Input placeholder="请输入银联号" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
// 境外企业特有列
|
// 境外企业特有列
|
||||||
const foreignColumns: ColumnType[] =
|
const foreignColumns: ColumnType[] =
|
||||||
supplierType === 'ovs'
|
supplierType === 'ovs'
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
title: 'SWIFT CODE',
|
title: 'SWIFT CODE',
|
||||||
dataIndex: 'swiftCode',
|
dataIndex: 'swiftCode',
|
||||||
render: (text, record) => (
|
render: (text, record) => (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[record.name, 'swiftCode']}
|
name={[record.name, 'swiftCode']}
|
||||||
noStyle
|
noStyle
|
||||||
rules={[{ required: true, message: '请输入SWIFT CODE' }]}
|
rules={[{ required: true, message: '请输入SWIFT CODE' }]}
|
||||||
>
|
>
|
||||||
<Input placeholder="请输入SWIFT CODE" />
|
<Input placeholder="请输入SWIFT CODE" />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
// 通用列
|
// 通用列
|
||||||
@ -818,19 +817,24 @@ export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) =
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="form-section-title">供应商反商业贿赂承诺书</div>
|
<div className="form-section-title">供应商反商业贿赂承诺书</div>
|
||||||
<Row gutter={24}>
|
<Descriptions
|
||||||
<Col span={12}>
|
column={1}
|
||||||
<div className="upload-label">
|
bordered
|
||||||
请加盖公司公章后上传
|
size="middle"
|
||||||
<Button
|
labelStyle={{ width: 240 }}
|
||||||
type="link"
|
style={{ background: '#fff' }}
|
||||||
href="/templates/anti-bribery-template.docx"
|
>
|
||||||
download="供应商反商业贿赂承诺书模板.docx"
|
<Descriptions.Item label="请下载模版,按模版填写">
|
||||||
>
|
<Button
|
||||||
下载模版
|
type="link"
|
||||||
</Button>
|
href="/templates/anti-bribery-template.docx"
|
||||||
</div>
|
download="供应商反商业贿赂承诺书模板.docx"
|
||||||
|
>
|
||||||
|
下载模版
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</Descriptions.Item>
|
||||||
|
<Descriptions.Item label="请加盖公司公章后上传">
|
||||||
<Form.List name="coscoSupplierSurveyAttachments">
|
<Form.List name="coscoSupplierSurveyAttachments">
|
||||||
{(fields, { add, remove }) => {
|
{(fields, { add, remove }) => {
|
||||||
// 确保至少有一项用于反商业贿赂承诺书
|
// 确保至少有一项用于反商业贿赂承诺书
|
||||||
@ -863,6 +867,7 @@ export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) =
|
|||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.name, 'fileUrl']}
|
name={[field.name, 'fileUrl']}
|
||||||
rules={[{ required: true, message: '请上传已盖章的反商业贿赂承诺书' }]}
|
rules={[{ required: true, message: '请上传已盖章的反商业贿赂承诺书' }]}
|
||||||
|
style={{marginBottom: 0}}
|
||||||
getValueFromEvent={(value) => {
|
getValueFromEvent={(value) => {
|
||||||
if (value && value.length > 0) {
|
if (value && value.length > 0) {
|
||||||
const file = value[0];
|
const file = value[0];
|
||||||
@ -891,7 +896,6 @@ export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) =
|
|||||||
maxCount={1}
|
maxCount={1}
|
||||||
allowedTypes={['pdf', 'doc', 'docx', 'jpg', 'jpeg', 'png']}
|
allowedTypes={['pdf', 'doc', 'docx', 'jpg', 'jpeg', 'png']}
|
||||||
maxSize={10}
|
maxSize={10}
|
||||||
tip="pdf,doc,docx,jpg,jpeg,png类型的文件,大小不超过10MB"
|
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
@ -900,16 +904,23 @@ export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) =
|
|||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.List>
|
</Form.List>
|
||||||
</Col>
|
|
||||||
</Row>
|
</Descriptions.Item>
|
||||||
|
|
||||||
|
</Descriptions>
|
||||||
|
|
||||||
<div className="form-section-title">其他附件</div>
|
<div className="form-section-title">其他附件</div>
|
||||||
<Row gutter={24}>
|
<Descriptions
|
||||||
<Col span={24}>
|
column={1}
|
||||||
<Form.List name="coscoSupplierSurveyAttachments">
|
bordered
|
||||||
|
size="middle"
|
||||||
|
labelStyle={{ width: 240 }}
|
||||||
|
style={{ background: '#fff' }}
|
||||||
|
>
|
||||||
|
<Descriptions.Item label="其他附件(非必须上传)">
|
||||||
|
<Form.List name="coscoSupplierSurveyAttachments">
|
||||||
{(fields, { add, remove }) => (
|
{(fields, { add, remove }) => (
|
||||||
<>
|
<>
|
||||||
<div className="upload-label">其他附件(非必须上传)</div>
|
|
||||||
{fields.map((field, index) => (
|
{fields.map((field, index) => (
|
||||||
<div
|
<div
|
||||||
key={field.key}
|
key={field.key}
|
||||||
@ -920,22 +931,22 @@ export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) =
|
|||||||
>
|
>
|
||||||
{index > 0 && (
|
{index > 0 && (
|
||||||
<>
|
<>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name={[field.name, 'attachmentsType']}
|
name={[field.name, 'attachmentsType']}
|
||||||
initialValue="accessory"
|
initialValue="accessory"
|
||||||
hidden
|
hidden
|
||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name={[field.name, 'fileName']} hidden>
|
<Form.Item name={[field.name, 'fileName']} hidden>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name={[field.name, 'fileType']} hidden>
|
<Form.Item name={[field.name, 'fileType']} hidden>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item name={[field.name, 'fileSize']} hidden>
|
<Form.Item name={[field.name, 'fileSize']} hidden>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -987,8 +998,8 @@ export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) =
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Form.List>
|
</Form.List>
|
||||||
</Col>
|
</Descriptions.Item>
|
||||||
</Row>
|
</Descriptions>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -337,7 +337,7 @@ const ForeignForm: React.FC<ForeignFormProps> = ({
|
|||||||
|
|
||||||
{/* 使用通用表单组件 */}
|
{/* 使用通用表单组件 */}
|
||||||
<QualificationSection form={form} />
|
<QualificationSection form={form} />
|
||||||
<InvoiceSection form={form} />
|
{/* <InvoiceSection form={form} /> */}
|
||||||
<BankAccountSection form={form} supplierType={'ovs'} />
|
<BankAccountSection form={form} supplierType={'ovs'} />
|
||||||
<SurveySection form={form} surveyQuestions={surveyQuestions} />
|
<SurveySection form={form} surveyQuestions={surveyQuestions} />
|
||||||
<AttachmentSection form={form} />
|
<AttachmentSection form={form} />
|
||||||
|
@ -10,7 +10,7 @@ import { categoryTree, add } from '../services';
|
|||||||
const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ visible, onCancel }) => {
|
const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ visible, onCancel }) => {
|
||||||
|
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
//名称输入
|
//名称输入
|
||||||
const [accessWorkNameEdited, setAccessWorkNameEdited] = useState(false);
|
const [accessWorkNameEdited, setAccessWorkNameEdited] = useState(false);
|
||||||
|
|
||||||
//品类选择
|
//品类选择
|
||||||
@ -20,6 +20,8 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
|
|||||||
const [supplierModalVisible, setSupplierModalVisible] = useState(false);
|
const [supplierModalVisible, setSupplierModalVisible] = useState(false);
|
||||||
//品类选择渲染数据
|
//品类选择渲染数据
|
||||||
const [categoriesTreeData, setCategoriesTreeData] = useState([]);
|
const [categoriesTreeData, setCategoriesTreeData] = useState([]);
|
||||||
|
//提交防抖
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
//品类选择数据中字段转换
|
//品类选择数据中字段转换
|
||||||
const convertTreeData = (data: any) => {
|
const convertTreeData = (data: any) => {
|
||||||
return data.map((item: any) => ({
|
return data.map((item: any) => ({
|
||||||
@ -54,69 +56,69 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
|
|||||||
? checkedKeysValue
|
? checkedKeysValue
|
||||||
: checkedKeysValue.checked;
|
: checkedKeysValue.checked;
|
||||||
|
|
||||||
// 只取叶子节点 key
|
// 只取叶子节点 key
|
||||||
const leafKeys = findLeafKeys(convertTreeData(categoriesTreeData));
|
const leafKeys = findLeafKeys(convertTreeData(categoriesTreeData));
|
||||||
const onlyLeafChecked = keys.filter(key => leafKeys.includes(String(key)));
|
const onlyLeafChecked = keys.filter(key => leafKeys.includes(String(key)));
|
||||||
|
|
||||||
console.log(onlyLeafChecked,'onlyLeafChecked', leafKeys ,keys);
|
console.log(onlyLeafChecked, 'onlyLeafChecked', leafKeys, keys);
|
||||||
|
|
||||||
|
|
||||||
setCheckedKeys(keys); // UI 显示用,还是全量
|
setCheckedKeys(keys); // UI 显示用,还是全量
|
||||||
form.setFieldsValue({ categoryIds: onlyLeafChecked }); // 只存叶子到表单
|
form.setFieldsValue({ categoryIds: onlyLeafChecked }); // 只存叶子到表单
|
||||||
|
|
||||||
// ==============================
|
// ==============================
|
||||||
// 增加自动拼标题的逻辑
|
// 增加自动拼标题的逻辑
|
||||||
// ==============================
|
// ==============================
|
||||||
if (!accessWorkNameEdited) {
|
if (!accessWorkNameEdited) {
|
||||||
// 1. 获取供应商名
|
// 1. 获取供应商名
|
||||||
const supplier = (form.getFieldValue('supplier') || [])[0];
|
const supplier = (form.getFieldValue('supplier') || [])[0];
|
||||||
let supplierName = '';
|
let supplierName = '';
|
||||||
if (supplier) {
|
if (supplier) {
|
||||||
supplierName = supplier.supplierType === 'ovs' ? supplier.nameEn : supplier.name;
|
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);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
dfs(treeData);
|
// 2. 获取已选品类名称
|
||||||
return names;
|
const findNamesByIds = (treeData: any[], ids: any[]) => {
|
||||||
};
|
let names: string[] = [];
|
||||||
const categoryNames = findNamesByIds(categoriesTreeData, onlyLeafChecked);
|
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;
|
let autoTitle = supplierName;
|
||||||
if (supplierName && categoryNames.length) {
|
if (supplierName && categoryNames.length) {
|
||||||
if (categoryNames.length === 1) {
|
if (categoryNames.length === 1) {
|
||||||
autoTitle = `${supplierName}-${categoryNames[0]}-品类准入工作`;
|
autoTitle = `${supplierName}-${categoryNames[0]}-品类准入工作`;
|
||||||
} else {
|
} else {
|
||||||
autoTitle = `${supplierName}-${categoryNames[0]}等-品类准入工作`;
|
autoTitle = `${supplierName}-${categoryNames[0]}等-品类准入工作`;
|
||||||
}
|
}
|
||||||
} else if (!supplierName && categoryNames.length) {
|
} else if (!supplierName && categoryNames.length) {
|
||||||
if (categoryNames.length === 1) {
|
if (categoryNames.length === 1) {
|
||||||
autoTitle = categoryNames[0];
|
autoTitle = categoryNames[0];
|
||||||
} else {
|
} else {
|
||||||
autoTitle = `${categoryNames[0]}等-品类准入工作`;
|
autoTitle = `${categoryNames[0]}等-品类准入工作`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
form.setFieldsValue({ accessWorkName: autoTitle });
|
form.setFieldsValue({ accessWorkName: autoTitle });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 提交
|
// 提交
|
||||||
const onFinish = async (values: any) => {
|
const onFinish = async (values: any) => {
|
||||||
const finalPayload: {
|
const finalPayload: {
|
||||||
coscoAccessWork: {
|
coscoAccessWork: {
|
||||||
accessWorkName: string;
|
accessWorkName: string;
|
||||||
deptId: string;
|
deptId: string;
|
||||||
};
|
};
|
||||||
categoryIds: string[];
|
categoryIds: string[];
|
||||||
supplierIds: string[];
|
supplierIds: string[];
|
||||||
} = {
|
} = {
|
||||||
coscoAccessWork: {
|
coscoAccessWork: {
|
||||||
accessWorkName: '',
|
accessWorkName: '',
|
||||||
@ -132,25 +134,33 @@ form.setFieldsValue({ accessWorkName: autoTitle });
|
|||||||
//品类选择
|
//品类选择
|
||||||
finalPayload.categoryIds = values.categoryIds;
|
finalPayload.categoryIds = values.categoryIds;
|
||||||
//选择供应商
|
//选择供应商
|
||||||
if(values.supplier.length != 0) {
|
if (values.supplier.length != 0) {
|
||||||
values.supplier.forEach((item: { id: string }) => {
|
values.supplier.forEach((item: { id: string }) => {
|
||||||
finalPayload.supplierIds.push(item.id)
|
finalPayload.supplierIds.push(item.id)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
console.log( finalPayload, values);
|
console.log(finalPayload, values);
|
||||||
const res = await add(finalPayload);
|
if (submitting) return; // 防重复提交
|
||||||
if (res?.success) {
|
setSubmitting(true);
|
||||||
message.success('创建成功');
|
|
||||||
form.resetFields();
|
try {
|
||||||
setCheckedKeys([]);
|
const res = await add(finalPayload);
|
||||||
onCancel();
|
if (res?.success) {
|
||||||
} else {
|
message.success('创建成功');
|
||||||
message.error('创建失败');
|
form.resetFields();
|
||||||
|
setCheckedKeys([]);
|
||||||
|
onCancel();
|
||||||
|
} else {
|
||||||
|
message.error('创建失败');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
setSubmitting(false); // 无论成功失败都解锁
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//初始化
|
//初始化
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if(visible) {
|
if (visible) {
|
||||||
categoryTree().then((res) => {
|
categoryTree().then((res) => {
|
||||||
const { code, data } = res;
|
const { code, data } = res;
|
||||||
if (code == 200) {
|
if (code == 200) {
|
||||||
@ -183,21 +193,21 @@ form.setFieldsValue({ accessWorkName: autoTitle });
|
|||||||
name="accessWorkName"
|
name="accessWorkName"
|
||||||
rules={[{ required: true, message: '请输入标题名称' }]}
|
rules={[{ required: true, message: '请输入标题名称' }]}
|
||||||
>
|
>
|
||||||
<Input placeholder="请输入标题名称" allowClear
|
<Input placeholder="请输入标题名称" allowClear
|
||||||
onChange={e => {
|
onChange={e => {
|
||||||
if (e.target.value) {
|
if (e.target.value) {
|
||||||
setAccessWorkNameEdited(true);
|
setAccessWorkNameEdited(true);
|
||||||
} else {
|
} else {
|
||||||
setAccessWorkNameEdited(false);
|
setAccessWorkNameEdited(false);
|
||||||
}
|
}
|
||||||
}}/>
|
}} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="准入部门"
|
label="准入部门"
|
||||||
name="deptId"
|
name="deptId"
|
||||||
rules={[{ required: true, message: '请选择准入部门' }]}
|
rules={[{ required: true, message: '请选择准入部门' }]}
|
||||||
>
|
>
|
||||||
<AccessDepartmentSelect style={{width: '100%'}} orgCategory='' />
|
<AccessDepartmentSelect style={{ width: '100%' }} orgCategory='' />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
|
||||||
@ -209,7 +219,7 @@ form.setFieldsValue({ accessWorkName: autoTitle });
|
|||||||
<Button onClick={() => setSupplierModalVisible(true)}>
|
<Button onClick={() => setSupplierModalVisible(true)}>
|
||||||
选择供应商
|
选择供应商
|
||||||
</Button>
|
</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>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@ -235,7 +245,7 @@ form.setFieldsValue({ accessWorkName: autoTitle });
|
|||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item wrapperCol={{ offset: 6 }}>
|
<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>
|
||||||
<Button
|
<Button
|
||||||
@ -257,13 +267,13 @@ form.setFieldsValue({ accessWorkName: autoTitle });
|
|||||||
form.setFieldsValue({ supplier: selected });
|
form.setFieldsValue({ supplier: selected });
|
||||||
setCheckedKeys([]);
|
setCheckedKeys([]);
|
||||||
setSupplierModalVisible(false);
|
setSupplierModalVisible(false);
|
||||||
// 取所有已选供应商的 categoryName 并分割
|
// 取所有已选供应商的 categoryName 并分割
|
||||||
const allCategories = selected
|
const allCategories = selected
|
||||||
.map(item => item.categoryIds) // 取出字符串
|
.map(item => item.categoryIds) // 取出字符串
|
||||||
.filter(Boolean) // 防止空
|
.filter(Boolean) // 防止空
|
||||||
.flatMap(str => str.split(',')) // 逗号切分
|
.flatMap(str => str.split(',')) // 逗号切分
|
||||||
.map(c => c.trim()) // 去空格
|
.map(c => c.trim()) // 去空格
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
setDisabledCategories(Array.from(new Set(allCategories))); // 去重
|
setDisabledCategories(Array.from(new Set(allCategories))); // 去重
|
||||||
|
|
||||||
//名称
|
//名称
|
||||||
@ -277,7 +287,7 @@ form.setFieldsValue({ accessWorkName: autoTitle });
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -46,6 +46,8 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
|
|||||||
const [supplierModalVisible, setSupplierModalVisible] = useState(false);
|
const [supplierModalVisible, setSupplierModalVisible] = useState(false);
|
||||||
const [reviewerModalVisible, setReviewerModalVisible] = useState(false);
|
const [reviewerModalVisible, setReviewerModalVisible] = useState(false);
|
||||||
const [divisionModalVisible, setDivisionModalVisible] = useState(false);
|
const [divisionModalVisible, setDivisionModalVisible] = useState(false);
|
||||||
|
//提交防抖
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
//品类选择渲染数据
|
//品类选择渲染数据
|
||||||
const [categoriesTreeData, setCategoriesTreeData] = useState([]);
|
const [categoriesTreeData, setCategoriesTreeData] = useState([]);
|
||||||
//品类选择数据中字段转换
|
//品类选择数据中字段转换
|
||||||
@ -132,92 +134,106 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
|
|||||||
message.error('上传失败');
|
message.error('上传失败');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
//获取 cuCompanyNumber
|
||||||
|
const onChangeDepartmentSelect = (value: any, label: any, extra: any) => {
|
||||||
|
form.setFieldsValue({ orgId: extra?.triggerNode?.props.cuCompanyNumber });
|
||||||
|
}
|
||||||
// 提交
|
// 提交
|
||||||
const onFinish = async (values: any) => {
|
const onFinish = async (values: any) => {
|
||||||
const finalPayload: {
|
if (submitting) return; // 防重复提交
|
||||||
coscoAccessWork: {
|
setSubmitting(true);
|
||||||
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: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
//标题名称
|
try {
|
||||||
finalPayload.coscoAccessWork.accessWorkName = values.accessWorkName;
|
const finalPayload: {
|
||||||
//准入方式
|
coscoAccessWork: {
|
||||||
finalPayload.coscoAccessWork.accessType = values.accessType;
|
startTime: string;
|
||||||
//准入部门
|
endTime: string;
|
||||||
finalPayload.coscoAccessWork.deptId = values.deptId;
|
accessType: string;
|
||||||
// 准入说明
|
accessWorkName: string;
|
||||||
finalPayload.coscoAccessWork.accessDesc = values.accessDesc;
|
deptId: string;
|
||||||
//品类选择
|
orgId: string;
|
||||||
finalPayload.categoryIds = values.categoryIds;
|
accessDesc: string;
|
||||||
//选择供应商
|
|
||||||
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[],
|
|
||||||
};
|
};
|
||||||
Object.entries(item.reviewerChecks || {}).forEach(([key, value]) => {
|
categoryIds: string[];
|
||||||
dataJson.reviewBy.push(key);
|
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);
|
//评审分工
|
||||||
});
|
values.division.forEach((item: any) => {
|
||||||
} else {
|
const dataJson = {
|
||||||
// 供应商符合性审查
|
itemName: item.itemName,
|
||||||
finalPayload.coscoAccessWorkAttachments = values.supplierCompliance[0].response;
|
reviewBy: [] as string[],
|
||||||
finalPayload.coscoAccessWorkAttachments.fileUrl = values.supplierCompliance[0].response.url;
|
};
|
||||||
}
|
Object.entries(item.reviewerChecks || {}).forEach(([key, value]) => {
|
||||||
|
dataJson.reviewBy.push(key);
|
||||||
const res = await add(finalPayload);
|
});
|
||||||
if (res?.success) {
|
finalPayload.coscoAccessItems.push(dataJson);
|
||||||
message.success('创建成功');
|
});
|
||||||
form.resetFields();
|
} else {
|
||||||
setCheckedKeys([]);
|
// 供应商符合性审查
|
||||||
setSelectedReviewers({ selected: [], leader: null, });
|
finalPayload.coscoAccessWorkAttachments = values.supplierCompliance[0].response;
|
||||||
setAdmissionMethod('online');
|
finalPayload.coscoAccessWorkAttachments.fileUrl = values.supplierCompliance[0].response.url;
|
||||||
onCancel();
|
}
|
||||||
} else {
|
const res = await add(finalPayload);
|
||||||
message.error('创建失败');
|
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"
|
name="deptId"
|
||||||
rules={[{ required: true, message: '请选择准入部门' }]}
|
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>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
@ -474,7 +493,7 @@ const CreateModal: React.FC<{ visible: boolean; onCancel: () => void; }> = ({ vi
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<Form.Item wrapperCol={{ offset: 6 }}>
|
<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' ? '提交审批' : '提交'}
|
{admissionMethod === 'online' ? '确认' : admissionMethod === 'offline' ? '提交审批' : '提交'}
|
||||||
|
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -51,7 +51,8 @@ const SupplierAddModal: React.FC<{
|
|||||||
const [categoryInfo, setCategoryInfo] = useState<CategoryInfo>({});
|
const [categoryInfo, setCategoryInfo] = useState<CategoryInfo>({});
|
||||||
// loading
|
// loading
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
//提交防抖
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
const supplierDetailModal = useSupplierDetailModal();
|
const supplierDetailModal = useSupplierDetailModal();
|
||||||
//供应商符合性审查
|
//供应商符合性审查
|
||||||
const [fileList, setFileList] = useState<UploadFile<any>[]>([]);
|
const [fileList, setFileList] = useState<UploadFile<any>[]>([]);
|
||||||
@ -145,15 +146,19 @@ const SupplierAddModal: React.FC<{
|
|||||||
attachmentsType: 'accessory'
|
attachmentsType: 'accessory'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (submitting) return; // 防重复提交
|
||||||
apply({ categoryLibraryId: storeId, supplierIds: selectedIds, ...values }).then((res) => {
|
setSubmitting(true);
|
||||||
if(res.code == 200) {
|
try {
|
||||||
message.success('操作成功');
|
apply({ categoryLibraryId: storeId, supplierIds: selectedIds, ...values }).then((res) => {
|
||||||
setSelectedIds([]);
|
if(res.code == 200) {
|
||||||
onSuccess && onSuccess();
|
message.success('操作成功');
|
||||||
}
|
setSelectedIds([]);
|
||||||
})
|
onSuccess && onSuccess();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
setSubmitting(false); // 无论成功失败都解锁
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 自定义上传
|
// 自定义上传
|
||||||
@ -233,7 +238,7 @@ const SupplierAddModal: React.FC<{
|
|||||||
visible={visible}
|
visible={visible}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
footer={[
|
footer={[
|
||||||
<Button key="ok" type="primary" onClick={handleOk}>确认入库</Button>,
|
<Button key="ok" type="primary" onClick={handleOk} disabled={submitting}>确认入库</Button>,
|
||||||
<Button key="cancel" onClick={onCancel}>取消</Button>,
|
<Button key="cancel" onClick={onCancel}>取消</Button>,
|
||||||
]}
|
]}
|
||||||
width={820}
|
width={820}
|
||||||
|
@ -60,6 +60,8 @@ const CategoryAddModal: React.FC<Props> = ({ visible, onCancel, onSuccess }) =>
|
|||||||
const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
|
const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
|
||||||
//供应商符合性审查
|
//供应商符合性审查
|
||||||
const [fileList, setFileList] = useState<UploadFile<any>[]>([]);
|
const [fileList, setFileList] = useState<UploadFile<any>[]>([]);
|
||||||
|
//提交防抖
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
|
|
||||||
const [deptOptions, setDeptOptions] = useState<DeptOption[]>([]);
|
const [deptOptions, setDeptOptions] = useState<DeptOption[]>([]);
|
||||||
// 自定义上传
|
// 自定义上传
|
||||||
@ -142,6 +144,8 @@ const CategoryAddModal: React.FC<Props> = ({ visible, onCancel, onSuccess }) =>
|
|||||||
|
|
||||||
// 提交校验
|
// 提交校验
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
|
if (submitting) return; // 防重复提交
|
||||||
|
setSubmitting(true);
|
||||||
try {
|
try {
|
||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
const submitData = {
|
const submitData = {
|
||||||
@ -172,7 +176,9 @@ const CategoryAddModal: React.FC<Props> = ({ visible, onCancel, onSuccess }) =>
|
|||||||
onSuccess && onSuccess();
|
onSuccess && onSuccess();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} catch { }
|
} finally {
|
||||||
|
setSubmitting(false); // 无论成功失败都解锁
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
@ -339,7 +345,7 @@ const CategoryAddModal: React.FC<Props> = ({ visible, onCancel, onSuccess }) =>
|
|||||||
|
|
||||||
|
|
||||||
<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: 'center', marginTop: 30 }}>
|
<Form.Item wrapperCol={{ span: 24 }} style={{ textAlign: 'center', marginTop: 30 }}>
|
||||||
<Button type="primary" style={{ width: 160 }} onClick={handleOk}>
|
<Button type="primary" style={{ width: 160 }} onClick={handleOk} disabled={submitting}>
|
||||||
提交审批
|
提交审批
|
||||||
</Button>
|
</Button>
|
||||||
<Button style={{ width: 120, marginLeft: 32 }} onClick={onCancel}>
|
<Button style={{ width: 120, marginLeft: 32 }} onClick={onCancel}>
|
||||||
|
@ -197,6 +197,7 @@ const SupplierRegisterAgent: React.FC = () => {
|
|||||||
visible={exitModalVisible}
|
visible={exitModalVisible}
|
||||||
exitId={exitId}
|
exitId={exitId}
|
||||||
onOk={() => {
|
onOk={() => {
|
||||||
|
fetchData(1, pagination.pageSize);
|
||||||
setExitModalVisible(false)
|
setExitModalVisible(false)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -38,7 +38,8 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
const [suppliers, setSuppliers] = useState<Supplier[]>([]);
|
const [suppliers, setSuppliers] = useState<Supplier[]>([]);
|
||||||
const [timelimitOption, setTimelimitOption] = useState<any[]>([]);
|
const [timelimitOption, setTimelimitOption] = useState<any[]>([]);
|
||||||
const supplierDetailModal = useSupplierDetailModal();
|
const supplierDetailModal = useSupplierDetailModal();
|
||||||
|
//提交防抖
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
const removeSupplier = (id: string) => {
|
const removeSupplier = (id: string) => {
|
||||||
setSuppliers(suppliers.filter((s) => s.id !== id));
|
setSuppliers(suppliers.filter((s) => s.id !== id));
|
||||||
};
|
};
|
||||||
@ -49,6 +50,8 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
|
if (submitting) return; // 防重复提交
|
||||||
|
setSubmitting(true);
|
||||||
try {
|
try {
|
||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
if (suppliers.length === 0) {
|
if (suppliers.length === 0) {
|
||||||
@ -75,6 +78,8 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// 校验失败
|
// 校验失败
|
||||||
|
} finally {
|
||||||
|
setSubmitting(false); // 无论成功失败都解锁
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -114,7 +119,7 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal
|
<Modal
|
||||||
title="供应商退出"
|
title="供应商黑名单"
|
||||||
visible={visible}
|
visible={visible}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
width={900}
|
width={900}
|
||||||
@ -143,19 +148,7 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
wrapperCol={{ flex: 1 }} // 输入框区域自适应剩余空间
|
wrapperCol={{ flex: 1 }} // 输入框区域自适应剩余空间
|
||||||
layout="horizontal"
|
layout="horizontal"
|
||||||
>
|
>
|
||||||
|
|
||||||
{/* <Form.Item
|
|
||||||
label="黑名单类型"
|
|
||||||
name="backlistType"
|
|
||||||
rules={[{ required: true, message: '请选择黑名单类型' }]}
|
|
||||||
>
|
|
||||||
<Select placeholder="请选择黑名单类型">
|
|
||||||
{DEPT_OPTIONS.map((opt) => (
|
|
||||||
<Option key={opt.value} value={opt.value}>{opt.label}</Option>
|
|
||||||
))}
|
|
||||||
</Select>
|
|
||||||
</Form.Item> */}
|
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="时限类型"
|
label="时限类型"
|
||||||
name="timelimitType"
|
name="timelimitType"
|
||||||
@ -181,7 +174,7 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ marginTop: 28, textAlign: "center" }}>
|
<div style={{ marginTop: 28, textAlign: "center" }}>
|
||||||
<Button type="primary" style={{ marginRight: 24 }} onClick={handleSubmit}>提交审批</Button>
|
<Button type="primary" style={{ marginRight: 24 }} onClick={handleSubmit} disabled={submitting}>提交审批</Button>
|
||||||
<Button onClick={onCancel}>取消</Button>
|
<Button onClick={onCancel}>取消</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -35,7 +35,8 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
const [selectVisible, setSelectVisible] = useState(false);
|
const [selectVisible, setSelectVisible] = useState(false);
|
||||||
const [suppliers, setSuppliers] = useState<Supplier[]>([]);
|
const [suppliers, setSuppliers] = useState<Supplier[]>([]);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
//提交防抖
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
const removeSupplier = (id: number) => {
|
const removeSupplier = (id: number) => {
|
||||||
setSuppliers(suppliers.filter((s) => s.id !== id));
|
setSuppliers(suppliers.filter((s) => s.id !== id));
|
||||||
};
|
};
|
||||||
@ -46,6 +47,8 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
|
if (submitting) return; // 防重复提交
|
||||||
|
setSubmitting(true);
|
||||||
try {
|
try {
|
||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
if (suppliers.length === 0) {
|
if (suppliers.length === 0) {
|
||||||
@ -76,6 +79,8 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// 校验失败
|
// 校验失败
|
||||||
|
} finally {
|
||||||
|
setSubmitting(false); // 无论成功失败都解锁
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -162,7 +167,7 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ marginTop: 28, textAlign: "center" }}>
|
<div style={{ marginTop: 28, textAlign: "center" }}>
|
||||||
<Button type="primary" style={{ marginRight: 24 }} onClick={handleSubmit}>提交审批</Button>
|
<Button type="primary" style={{ marginRight: 24 }} onClick={handleSubmit} disabled={submitting}>提交审批</Button>
|
||||||
<Button onClick={onCancel}>取消</Button>
|
<Button onClick={onCancel}>取消</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -39,7 +39,8 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
const [userDeptId, setUserDeptId] = useState('');
|
const [userDeptId, setUserDeptId] = useState('');
|
||||||
const currentUserStr = sessionStorage.getItem('currentUser');
|
const currentUserStr = sessionStorage.getItem('currentUser');
|
||||||
const currentUser = currentUserStr ? JSON.parse(currentUserStr) : null;
|
const currentUser = currentUserStr ? JSON.parse(currentUserStr) : null;
|
||||||
|
//提交防抖
|
||||||
|
const [submitting, setSubmitting] = useState(false);
|
||||||
//移除已选供应商
|
//移除已选供应商
|
||||||
const removeSupplier = (id: number) => {
|
const removeSupplier = (id: number) => {
|
||||||
setSuppliers(suppliers.filter((s) => s.id !== id));
|
setSuppliers(suppliers.filter((s) => s.id !== id));
|
||||||
@ -51,6 +52,8 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
};
|
};
|
||||||
//提交
|
//提交
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
|
if (submitting) return; // 防重复提交
|
||||||
|
setSubmitting(true);
|
||||||
try {
|
try {
|
||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
if (suppliers.length === 0) {
|
if (suppliers.length === 0) {
|
||||||
@ -80,6 +83,8 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
message.error("提交失败");
|
message.error("提交失败");
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
} finally {
|
||||||
|
setSubmitting(false); // 无论成功失败都解锁
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -165,7 +170,7 @@ const CreateBlacklistModal: React.FC<CreateBlacklistModalProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{ marginTop: 28, textAlign: "center" }}>
|
<div style={{ marginTop: 28, textAlign: "center" }}>
|
||||||
<Button type="primary" style={{ marginRight: 24 }} onClick={handleSubmit}>提交审批</Button>
|
<Button type="primary" style={{ marginRight: 24 }} onClick={handleSubmit} disabled={submitting}>提交审批</Button>
|
||||||
<Button onClick={onCancel}>取消</Button>
|
<Button onClick={onCancel}>取消</Button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
Reference in New Issue
Block a user