Files
fe_portal_frontend/src/pages/register/supplier/CommonFormSections.tsx

822 lines
32 KiB
TypeScript
Raw Normal View History

/**
*
*
*/
import React, { useEffect, useState } from 'react';
2025-06-16 19:33:33 +08:00
import {
Form,
Input,
Button,
Select,
DatePicker,
Row,
Col,
Table,
Radio,
Cascader,
Empty,
} from 'antd';
2025-06-30 14:16:17 +08:00
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons';
2025-06-16 19:33:33 +08:00
import { message } from 'antd';
import { useIntl } from 'umi';
2025-06-30 14:16:17 +08:00
import FileUpload from '@/components/FileUpload';
import type { DictItem } from '@/servers/api/dict';
import { getDictList } from '@/servers/api/dict';
2025-06-16 19:33:33 +08:00
const { Option } = Select;
// 中国省市区级联数据
export const addressOptions = [
2025-06-16 19:33:33 +08:00
{
value: '330000',
label: '浙江省',
children: [
{
value: '330100',
label: '杭州市',
children: [
{ value: '330102', label: '上城区' },
{ value: '330103', label: '下城区' },
{ value: '330104', label: '江干区' },
{ value: '330105', label: '拱墅区' },
{ value: '330106', label: '西湖区' },
{ value: '330108', label: '滨江区' },
],
},
],
},
{
value: '310000',
label: '上海市',
children: [
{
value: '310100',
label: '上海市',
children: [
{ value: '310101', label: '黄浦区' },
{ value: '310104', label: '徐汇区' },
{ value: '310105', label: '长宁区' },
],
},
],
},
];
interface CommonFormSectionsProps {
2025-06-16 19:33:33 +08:00
form: any;
}
// 扩展问卷部分的属性接口
interface SurveySectionProps extends CommonFormSectionsProps {
surveyQuestions?: API.SurveyQuestionResponse;
}
/**
*
*
*/
export const QualificationSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
const intl = useIntl();
// 资质证书类型
const [certTypeList, setCertTypeList] = useState<DictItem[]>([]);
const getDict = async () => {
// qualification_type 资质证书类型
const certTypeResponse = await getDictList('certificate');
setCertTypeList(certTypeResponse.data || []);
};
useEffect(() => {
getDict();
}, []);
2025-06-16 19:33:33 +08:00
return (
<>
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.qualification' })}</div>
2025-06-16 19:33:33 +08:00
<Form.List name="coscoSupplierQualifications">
2025-06-16 19:33:33 +08:00
{(fields, { add, remove }) => (
<>
<Table
dataSource={fields.map((field) => ({
...field,
key: field.key,
fieldKey: field.name,
}))}
pagination={false}
bordered
size="middle"
rowKey="key"
columns={[
{
title: intl.formatMessage({ id: 'register.form.table.no' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'name',
width: 60,
render: (_, __, index) => index + 1,
},
{
title: intl.formatMessage({ id: 'register.qualification.certType' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'certType',
render: (_, record) => (
<Form.Item
2025-06-30 14:16:17 +08:00
name={[record.name, 'certificateType']}
2025-06-16 19:33:33 +08:00
noStyle
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.certType.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Select placeholder={intl.formatMessage({ id: 'register.qualification.certType.placeholder' })} style={{ width: '100%' }}>
{certTypeList.map((item) => (
<Option key={item.code} value={item.code}>
{item.dicName}
</Option>
))}
2025-06-16 19:33:33 +08:00
</Select>
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.qualification.certName' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'certName',
render: (_, record) => (
<Form.Item
2025-06-30 14:16:17 +08:00
name={[record.name, 'name']}
2025-06-16 19:33:33 +08:00
noStyle
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.certName.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.qualification.certName.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.qualification.certNumber' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'certNumber',
render: (_, record) => (
<Form.Item
2025-06-30 14:16:17 +08:00
name={[record.name, 'code']}
2025-06-16 19:33:33 +08:00
noStyle
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.certNumber.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.qualification.certNumber.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.qualification.certLevel' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'certLevel',
render: (_, record) => (
2025-06-30 14:16:17 +08:00
<Form.Item name={[record.name, 'typeLevel']} noStyle>
<Input placeholder={intl.formatMessage({ id: 'register.qualification.certLevel.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.qualification.issuingAuthority' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'issuingAuthority',
render: (_, record) => (
<Form.Item
2025-06-30 14:16:17 +08:00
name={[record.name, 'authority']}
2025-06-16 19:33:33 +08:00
noStyle
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.issuingAuthority.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.qualification.issuingAuthority.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.qualification.issueDate' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'issueDate',
render: (_, record) => (
<Form.Item
name={[record.name, 'dateTime']}
2025-06-16 19:33:33 +08:00
noStyle
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.issueDate.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<DatePicker
placeholder={intl.formatMessage({ id: 'register.form.date.placeholder' })}
style={{ width: '100%' }}
format="YYYY-MM-DD"
/>
2025-06-16 19:33:33 +08:00
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.qualification.expiryDate' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'expiryDate',
render: (_, record) => (
<Form.Item
name={[record.name, 'termOfValidity']}
2025-06-16 19:33:33 +08:00
noStyle
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.expiryDate.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<DatePicker
placeholder={intl.formatMessage({ id: 'register.form.date.placeholder' })}
style={{ width: '100%' }}
format="YYYY-MM-DD"
/>
2025-06-16 19:33:33 +08:00
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.form.attachment' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'certFile',
render: (_, record) => (
<Form.Item
2025-06-30 14:16:17 +08:00
name={[record.name, 'accessory']}
2025-06-16 19:33:33 +08:00
noStyle
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.attachment.required' }) }]}
2025-06-30 15:24:09 +08:00
valuePropName="value"
2025-06-16 19:33:33 +08:00
>
2025-06-30 14:16:17 +08:00
<FileUpload
maxSize={10}
allowedTypes={['pdf', 'jpg', 'jpeg', 'png']}
maxCount={1}
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
2025-06-30 14:16:17 +08:00
/>
2025-06-16 19:33:33 +08:00
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.form.operation' }),
2025-06-16 19:33:33 +08:00
width: 70,
render: (_, record) => (
<Button
type="link"
danger
icon={<DeleteOutlined />}
onClick={() => remove(record.name)}
>
{intl.formatMessage({ id: 'register.form.delete' })}
2025-06-16 19:33:33 +08:00
</Button>
),
},
]}
/>
<Form.Item style={{ marginTop: 16 }} wrapperCol={{ span: 24 }}>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
{intl.formatMessage({ id: 'register.form.addRow' })}
2025-06-16 19:33:33 +08:00
</Button>
</Form.Item>
</>
)}
</Form.List>
</>
);
};
2025-06-16 19:33:33 +08:00
/**
*
*
*/
export const InvoiceSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
const intl = useIntl();
// 纳税人类型
const [taxpayerTypeList, setTaxpayerTypeList] = useState<DictItem[]>([]);
const getDict = async () => {
// taxpayer_type 纳税人类型
const taxpayerTypeResponse = await getDictList('taxpayer_type');
setTaxpayerTypeList(taxpayerTypeResponse.data || []);
};
useEffect(() => {
getDict();
}, []);
return (
<>
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.invoice' })}</div>
2025-06-16 19:33:33 +08:00
<Row gutter={24}>
<Col span={8}>
<Form.Item
name={['coscoSupplierInvoice', 'taxpayerType']}
label={intl.formatMessage({ id: 'register.invoice.taxpayerType' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.invoice.taxpayerType.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Select placeholder={intl.formatMessage({ id: 'register.invoice.taxpayerType.placeholder' })}>
{taxpayerTypeList.map((item) => (
<Option key={item.code} value={item.code}>
{item.dicName}
</Option>
))}
2025-06-16 19:33:33 +08:00
</Select>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
2025-06-30 14:16:17 +08:00
name={['coscoSupplierInvoice', 'head']}
label={intl.formatMessage({ id: 'register.invoice.head' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.invoice.head.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.invoice.head.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
2025-06-30 14:16:17 +08:00
name={['coscoSupplierInvoice', 'taxpayerCode']}
label={intl.formatMessage({ id: 'register.invoice.taxpayerCode' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.invoice.taxpayerCode.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.invoice.taxpayerCode.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierInvoice', 'address']}
label={intl.formatMessage({ id: 'register.invoice.address' })}
>
<Input placeholder={intl.formatMessage({ id: 'register.invoice.address.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierInvoice', 'phone']}
label={intl.formatMessage({ id: 'register.invoice.phone' })}
>
<Input placeholder={intl.formatMessage({ id: 'register.invoice.phone.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierInvoice', 'bank']}
label={intl.formatMessage({ id: 'register.invoice.bank' })}
>
<Input placeholder={intl.formatMessage({ id: 'register.invoice.bank.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierInvoice', 'account']}
label={intl.formatMessage({ id: 'register.invoice.account' })}
>
<Input placeholder={intl.formatMessage({ id: 'register.invoice.account.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
<Col span={8}>
2025-06-30 15:24:09 +08:00
<Form.Item
name={['coscoSupplierInvoice', 'qualificationCertificate']}
label={intl.formatMessage({ id: 'register.invoice.qualificationCertificate' })}
2025-06-30 15:24:09 +08:00
valuePropName="value"
>
2025-06-30 14:16:17 +08:00
<FileUpload
maxSize={10}
allowedTypes={['pdf', 'jpg', 'jpeg', 'png']}
2025-06-16 19:33:33 +08:00
maxCount={1}
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
2025-06-30 14:16:17 +08:00
/>
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
</Row>
</>
);
};
2025-06-16 19:33:33 +08:00
/**
*
*
*/
export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
const intl = useIntl();
return (
<>
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.bankAccount' })}</div>
2025-06-16 19:33:33 +08:00
<Form.List name="coscoSupplierBank">
2025-06-16 19:33:33 +08:00
{(fields, { add, remove }) => (
<>
<Table
dataSource={fields.map((field) => ({
...field,
key: field.key,
fieldKey: field.name,
}))}
pagination={false}
bordered
size="middle"
rowKey="key"
columns={[
{
title: intl.formatMessage({ id: 'register.form.table.no' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'name',
width: 60,
render: (_, __, index) => index + 1,
},
{
title: intl.formatMessage({ id: 'register.bank.bankName' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'bankName',
render: (_, record) => (
<Form.Item
2025-06-30 14:16:17 +08:00
name={[record.name, 'bank']}
2025-06-16 19:33:33 +08:00
noStyle
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.bankName.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.bank.bankName.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.bank.accountName' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'accountName',
render: (_, record) => (
<Form.Item
name={[record.name, 'accountName']}
noStyle
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.accountName.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.bank.accountName.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.bank.accountNumber' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'accountNumber',
render: (_, record) => (
<Form.Item
2025-06-30 14:16:17 +08:00
name={[record.name, 'account']}
2025-06-16 19:33:33 +08:00
noStyle
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.accountNumber.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.bank.accountNumber.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.bank.location' }),
2025-06-16 19:33:33 +08:00
dataIndex: 'location',
render: (_, record) => (
<Form.Item
name={[record.name, 'address']}
noStyle
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.location.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Cascader
options={addressOptions}
placeholder={intl.formatMessage({ id: 'register.bank.location.placeholder' })}
2025-06-16 19:33:33 +08:00
showSearch={{
filter: (inputValue, path) => {
return path.some((option) => {
if (typeof option.label === 'string') {
return (
option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1
);
}
return false;
});
},
}}
/>
</Form.Item>
),
},
{
title: intl.formatMessage({ id: 'register.form.operation' }),
2025-06-16 19:33:33 +08:00
width: 70,
render: (_, record) => (
<Button
type="link"
danger
icon={<DeleteOutlined />}
onClick={() => remove(record.name)}
>
{intl.formatMessage({ id: 'register.form.delete' })}
2025-06-16 19:33:33 +08:00
</Button>
),
},
]}
/>
<Form.Item style={{ marginTop: 16 }} wrapperCol={{ span: 24 }}>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
{intl.formatMessage({ id: 'register.form.addRow' })}
2025-06-16 19:33:33 +08:00
</Button>
</Form.Item>
</>
)}
</Form.List>
</>
);
};
2025-06-16 19:33:33 +08:00
/**
*
*
*/
export const SurveySection: React.FC<SurveySectionProps> = ({ form, surveyQuestions }) => {
const intl = useIntl();
// 使用API获取的问卷数据如果没有则显示无数据状态
2025-06-30 15:24:09 +08:00
const hasQuestions =
surveyQuestions && Array.isArray(surveyQuestions) && surveyQuestions.length > 0;
2025-06-30 14:16:17 +08:00
// 调试日志
console.log('调查问卷数据:', surveyQuestions);
return (
<>
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.survey' })}</div>
2025-06-16 19:33:33 +08:00
<div className="questionnaire-header">{intl.formatMessage({ id: 'register.survey.fillerInfo' })}</div>
2025-06-16 19:33:33 +08:00
<Row gutter={24}>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'supplierName']}
label={intl.formatMessage({ id: 'register.survey.supplierName' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.supplierName.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.survey.supplierName.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'name']}
label={intl.formatMessage({ id: 'register.survey.name' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.name.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.survey.name.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'position']}
label={intl.formatMessage({ id: 'register.survey.position' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.position.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.survey.position.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'phone']}
label={intl.formatMessage({ id: 'register.survey.phone' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.phone.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<Input placeholder={intl.formatMessage({ id: 'register.survey.phone.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'email']}
label={intl.formatMessage({ id: 'register.survey.email' })}
2025-06-16 19:33:33 +08:00
rules={[
{ type: 'email', message: intl.formatMessage({ id: 'register.email.invalid' }) },
{ required: true, message: intl.formatMessage({ id: 'register.survey.email.required' }) },
2025-06-16 19:33:33 +08:00
]}
>
<Input placeholder={intl.formatMessage({ id: 'register.survey.email.placeholder' })} />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'dateTime']}
label={intl.formatMessage({ id: 'register.survey.date' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.date.required' }) }]}
2025-06-16 19:33:33 +08:00
>
<DatePicker placeholder={intl.formatMessage({ id: 'register.form.date.placeholder' })} style={{ width: '100%' }} format="YYYY-MM-DD" />
2025-06-16 19:33:33 +08:00
</Form.Item>
</Col>
</Row>
<div className="questionnaire-header" style={{ marginTop: '20px' }}>
{intl.formatMessage({ id: 'register.survey.questionnaire' })}
2025-06-16 19:33:33 +08:00
</div>
{hasQuestions ? (
2025-06-30 15:24:09 +08:00
<Form.List
name="coscoSupplierSurveyQuestionReply"
initialValue={surveyQuestions.map((q: any, index) => ({
surveyQuestionId: q.id,
replyValue: '',
}))}
>
{(fields, { add, remove }) => {
2025-06-30 14:16:17 +08:00
console.log('Form.List fields:', fields);
return (
<Table
pagination={false}
bordered
size="middle"
2025-06-30 14:16:17 +08:00
rowKey={(record, index) => `survey_question_${index}`}
dataSource={surveyQuestions}
columns={[
{
title: intl.formatMessage({ id: 'register.form.table.no' }),
dataIndex: 'id',
width: 60,
align: 'center',
render: (text, record, index) => index + 1,
},
{
title: intl.formatMessage({ id: 'register.survey.question' }),
dataIndex: 'questionName',
render: (text) => <div style={{ whiteSpace: 'pre-line' }}>{text}</div>,
},
{
title: intl.formatMessage({ id: 'register.survey.reply' }),
width: 650,
2025-06-30 14:16:17 +08:00
render: (_, record, index) => {
return (
<>
<Form.Item
name={[index, 'surveyQuestionId']}
initialValue={record.id}
hidden
>
<Input />
</Form.Item>
<Form.Item
name={[index, 'replyValue']}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.answer.required' }, { index: index + 1 }) }]}
2025-06-30 14:16:17 +08:00
wrapperCol={{ span: 24 }}
>
2025-06-30 15:24:09 +08:00
{record.coscoSurveyQuestionOptionList &&
record.coscoSurveyQuestionOptionList.length > 0 ? (
2025-06-30 14:16:17 +08:00
<Radio.Group>
{record.coscoSurveyQuestionOptionList.map((option: any) => (
2025-06-30 15:24:09 +08:00
<Radio key={option.id} value={option.opentionValue}>
2025-06-30 14:16:17 +08:00
{option.optionName}
</Radio>
))}
</Radio.Group>
) : (
<Input placeholder={intl.formatMessage({ id: 'register.survey.answer.placeholder' })} />
2025-06-30 14:16:17 +08:00
)}
</Form.Item>
</>
);
2025-06-30 15:24:09 +08:00
},
},
]}
/>
);
}}
</Form.List>
) : (
<div style={{ padding: '30px 0' }}>
<Empty description={intl.formatMessage({ id: 'register.survey.noData' })} image={Empty.PRESENTED_IMAGE_SIMPLE} />
</div>
)}
</>
);
};
2025-06-16 19:33:33 +08:00
/**
* 贿
*/
export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
const intl = useIntl();
return (
<>
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.commitment' })}</div>
2025-06-16 19:33:33 +08:00
<Row gutter={24}>
<Col span={12}>
<div className="upload-label">
{intl.formatMessage({ id: 'register.attachment.stampUpload' })}
2025-06-16 19:33:33 +08:00
<Button
type="link"
href="/templates/anti-bribery-template.docx"
download="供应商反商业贿赂承诺书模板.docx"
>
{intl.formatMessage({ id: 'register.attachment.downloadTemplate' })}
2025-06-16 19:33:33 +08:00
</Button>
</div>
<Form.List name="coscoSupplierSurveyAttachments">
{(fields, { add, remove }) => {
// 确保至少有一项用于反商业贿赂承诺书
if (fields.length === 0) {
add({ attachmentsType: 'commitment' });
}
return (
<div>
{fields.map((field, index) => (
<div key={field.key} style={{ display: field.name === 0 ? 'block' : 'none' }}>
<Form.Item
name={[field.name, 'attachmentsType']}
initialValue="commitment"
hidden
>
<Input />
</Form.Item>
<Form.Item
name={[field.name, 'fileUrl']}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.attachment.commitment.required' }) }]}
2025-06-30 14:16:17 +08:00
valuePropName="value"
>
2025-06-30 14:16:17 +08:00
<FileUpload
maxSize={10}
allowedTypes={['pdf', 'doc', 'docx']}
maxCount={1}
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
2025-06-30 14:16:17 +08:00
onChange={(fileList) => {
if (fileList && fileList.length > 0) {
const file = fileList[0];
if (file.status === 'done' && file.response) {
const response = file.response;
if (response && response.success) {
// 填充文件信息
form.setFieldsValue({
coscoSupplierSurveyAttachments: [
{
...form.getFieldValue([
'coscoSupplierSurveyAttachments',
field.name,
]),
fileName: file.name,
fileType: file.type,
fileSize: file.size?.toString(),
filePath: response.filePath || response.url,
},
],
});
message.success(`${file.name} 上传成功`);
}
}
}
}}
2025-06-30 14:16:17 +08:00
/>
</Form.Item>
</div>
))}
</div>
);
}}
</Form.List>
2025-06-16 19:33:33 +08:00
</Col>
</Row>
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.otherAttachments' })}</div>
2025-06-16 19:33:33 +08:00
<Row gutter={24}>
<Col span={24}>
<Form.List name="coscoSupplierSurveyAttachments">
{(fields, { add, remove }) => (
<>
<div className="upload-label">{intl.formatMessage({ id: 'register.attachment.otherAttachments.hint' })}</div>
{fields.map((field, index) => (
<div
key={field.key}
style={{
display: index > 0 || fields.length === 1 ? 'block' : 'none',
marginBottom: 8,
}}
>
{index > 0 && (
<Form.Item
name={[field.name, 'attachmentsType']}
initialValue="accessory"
hidden
>
<Input />
</Form.Item>
)}
{index > 0 && (
2025-06-30 15:24:09 +08:00
<Form.Item name={[field.name, 'fileUrl']} valuePropName="value">
2025-06-30 14:16:17 +08:00
<FileUpload
maxSize={20}
allowedTypes={['*']}
maxCount={1}
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
2025-06-30 14:16:17 +08:00
onChange={(fileList) => {
if (fileList && fileList.length > 0) {
const file = fileList[0];
if (file.status === 'done' && file.response) {
const response = file.response;
if (response && response.success) {
// 填充文件信息
const fieldValue = form.getFieldValue([
'coscoSupplierSurveyAttachments',
field.name,
]);
form.setFieldsValue({
coscoSupplierSurveyAttachments: [
{
...fieldValue,
fileName: file.name,
fileType: file.type,
fileSize: file.size?.toString(),
filePath: response.filePath || response.url,
},
],
});
message.success(`${file.name} 上传成功`);
}
}
}
}}
2025-06-30 14:16:17 +08:00
/>
</Form.Item>
)}
</div>
))}
<Button
type="dashed"
onClick={() => add({ attachmentsType: 'accessory' })}
icon={<PlusOutlined />}
style={{ marginTop: 8 }}
>
{intl.formatMessage({ id: 'register.attachment.addMore' })}
</Button>
</>
)}
</Form.List>
2025-06-16 19:33:33 +08:00
</Col>
</Row>
</>
);
};