822 lines
33 KiB
TypeScript
822 lines
33 KiB
TypeScript
/**
|
||
* 供应商注册表单通用部分
|
||
* 封装了国内企业和境外企业注册表单相同的部分
|
||
*/
|
||
import React, { useEffect, useState } from 'react';
|
||
import {
|
||
Form,
|
||
Input,
|
||
Button,
|
||
Select,
|
||
DatePicker,
|
||
Row,
|
||
Col,
|
||
Table,
|
||
Radio,
|
||
Cascader,
|
||
Empty,
|
||
} from 'antd';
|
||
import { PlusOutlined, DeleteOutlined } from '@ant-design/icons';
|
||
import { message } from 'antd';
|
||
import { useIntl } from 'umi';
|
||
import FileUpload from '@/components/FileUpload';
|
||
import type { DictItem } from '@/servers/api/dict';
|
||
import { getDictList } from '@/servers/api/dict';
|
||
|
||
const { Option } = Select;
|
||
|
||
// 中国省市区级联数据
|
||
export const addressOptions = [
|
||
{
|
||
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 {
|
||
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();
|
||
}, []);
|
||
return (
|
||
<div className="border-box">
|
||
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.qualification' })}</div>
|
||
|
||
<Form.List name="coscoSupplierQualifications">
|
||
{(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' }),
|
||
dataIndex: 'name',
|
||
width: 60,
|
||
render: (_, __, index) => index + 1,
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.qualification.certType' }),
|
||
dataIndex: 'certType',
|
||
render: (_, record) => (
|
||
<Form.Item
|
||
name={[record.name, 'certificateType']}
|
||
noStyle
|
||
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.certType.required' }) }]}
|
||
>
|
||
<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>
|
||
))}
|
||
</Select>
|
||
</Form.Item>
|
||
),
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.qualification.certName' }),
|
||
dataIndex: 'certName',
|
||
render: (_, record) => (
|
||
<Form.Item
|
||
name={[record.name, 'name']}
|
||
noStyle
|
||
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.certName.required' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.qualification.certName.placeholder' })} />
|
||
</Form.Item>
|
||
),
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.qualification.certNumber' }),
|
||
dataIndex: 'certNumber',
|
||
render: (_, record) => (
|
||
<Form.Item
|
||
name={[record.name, 'code']}
|
||
noStyle
|
||
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.certNumber.required' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.qualification.certNumber.placeholder' })} />
|
||
</Form.Item>
|
||
),
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.qualification.certLevel' }),
|
||
dataIndex: 'certLevel',
|
||
render: (_, record) => (
|
||
<Form.Item name={[record.name, 'typeLevel']} noStyle>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.qualification.certLevel.placeholder' })} />
|
||
</Form.Item>
|
||
),
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.qualification.issuingAuthority' }),
|
||
dataIndex: 'issuingAuthority',
|
||
render: (_, record) => (
|
||
<Form.Item
|
||
name={[record.name, 'authority']}
|
||
noStyle
|
||
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.issuingAuthority.required' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.qualification.issuingAuthority.placeholder' })} />
|
||
</Form.Item>
|
||
),
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.qualification.issueDate' }),
|
||
dataIndex: 'issueDate',
|
||
render: (_, record) => (
|
||
<Form.Item
|
||
name={[record.name, 'dateTime']}
|
||
noStyle
|
||
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.issueDate.required' }) }]}
|
||
>
|
||
<DatePicker
|
||
placeholder={intl.formatMessage({ id: 'register.form.date.placeholder' })}
|
||
style={{ width: '100%' }}
|
||
format="YYYY-MM-DD"
|
||
/>
|
||
</Form.Item>
|
||
),
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.qualification.expiryDate' }),
|
||
dataIndex: 'expiryDate',
|
||
render: (_, record) => (
|
||
<Form.Item
|
||
name={[record.name, 'termOfValidity']}
|
||
noStyle
|
||
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.expiryDate.required' }) }]}
|
||
>
|
||
<DatePicker
|
||
placeholder={intl.formatMessage({ id: 'register.form.date.placeholder' })}
|
||
style={{ width: '100%' }}
|
||
format="YYYY-MM-DD"
|
||
/>
|
||
</Form.Item>
|
||
),
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.form.attachment' }),
|
||
dataIndex: 'certFile',
|
||
render: (_, record) => (
|
||
<Form.Item
|
||
name={[record.name, 'accessory']}
|
||
noStyle
|
||
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.attachment.required' }) }]}
|
||
valuePropName="value"
|
||
>
|
||
<FileUpload
|
||
maxSize={10}
|
||
allowedTypes={['pdf', 'jpg', 'jpeg', 'png']}
|
||
maxCount={1}
|
||
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
|
||
/>
|
||
</Form.Item>
|
||
),
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.form.operation' }),
|
||
width: 70,
|
||
render: (_, record) => (
|
||
<Button
|
||
type="link"
|
||
danger
|
||
icon={<DeleteOutlined />}
|
||
onClick={() => remove(record.name)}
|
||
>
|
||
{intl.formatMessage({ id: 'register.form.delete' })}
|
||
</Button>
|
||
),
|
||
},
|
||
]}
|
||
/>
|
||
<Form.Item style={{ marginTop: 16 }} wrapperCol={{ span: 24 }}>
|
||
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
|
||
{intl.formatMessage({ id: 'register.form.addRow' })}
|
||
</Button>
|
||
</Form.Item>
|
||
</>
|
||
)}
|
||
</Form.List>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
/**
|
||
* 开票信息表单部分
|
||
* 包含纳税人类型、开票抬头、纳税人识别号、开票地址等
|
||
*/
|
||
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="border-box">
|
||
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.invoice' })}</div>
|
||
|
||
<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' }) }]}
|
||
>
|
||
<Select placeholder={intl.formatMessage({ id: 'register.invoice.taxpayerType.placeholder' })}>
|
||
{taxpayerTypeList.map((item) => (
|
||
<Option key={item.code} value={item.code}>
|
||
{item.dicName}
|
||
</Option>
|
||
))}
|
||
</Select>
|
||
</Form.Item>
|
||
</Col>
|
||
<Col span={8}>
|
||
<Form.Item
|
||
name={['coscoSupplierInvoice', 'head']}
|
||
label={intl.formatMessage({ id: 'register.invoice.head' })}
|
||
rules={[{ required: true, message: intl.formatMessage({ id: 'register.invoice.head.required' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.invoice.head.placeholder' })} />
|
||
</Form.Item>
|
||
</Col>
|
||
<Col span={8}>
|
||
<Form.Item
|
||
name={['coscoSupplierInvoice', 'taxpayerCode']}
|
||
label={intl.formatMessage({ id: 'register.invoice.taxpayerCode' })}
|
||
rules={[{ required: true, message: intl.formatMessage({ id: 'register.invoice.taxpayerCode.required' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.invoice.taxpayerCode.placeholder' })} />
|
||
</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' })} />
|
||
</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' })} />
|
||
</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' })} />
|
||
</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' })} />
|
||
</Form.Item>
|
||
</Col>
|
||
<Col span={8}>
|
||
<Form.Item
|
||
name={['coscoSupplierInvoice', 'qualificationCertificate']}
|
||
label={intl.formatMessage({ id: 'register.invoice.qualificationCertificate' })}
|
||
valuePropName="value"
|
||
>
|
||
<FileUpload
|
||
maxSize={10}
|
||
allowedTypes={['pdf', 'jpg', 'jpeg', 'png']}
|
||
maxCount={1}
|
||
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
|
||
/>
|
||
</Form.Item>
|
||
</Col>
|
||
</Row>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
/**
|
||
* 银行账户表单部分
|
||
* 包含开户银行、账户名称、账号、所在地区等
|
||
*/
|
||
export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
|
||
const intl = useIntl();
|
||
return (
|
||
<div className="border-box">
|
||
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.bankAccount' })}</div>
|
||
|
||
<Form.List name="coscoSupplierBank">
|
||
{(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' }),
|
||
dataIndex: 'name',
|
||
width: 60,
|
||
render: (_, __, index) => index + 1,
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.bank.bankName' }),
|
||
dataIndex: 'bankName',
|
||
render: (_, record) => (
|
||
<Form.Item
|
||
name={[record.name, 'bank']}
|
||
noStyle
|
||
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.bankName.required' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.bank.bankName.placeholder' })} />
|
||
</Form.Item>
|
||
),
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.bank.accountName' }),
|
||
dataIndex: 'accountName',
|
||
render: (_, record) => (
|
||
<Form.Item
|
||
name={[record.name, 'accountName']}
|
||
noStyle
|
||
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.accountName.required' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.bank.accountName.placeholder' })} />
|
||
</Form.Item>
|
||
),
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.bank.accountNumber' }),
|
||
dataIndex: 'accountNumber',
|
||
render: (_, record) => (
|
||
<Form.Item
|
||
name={[record.name, 'account']}
|
||
noStyle
|
||
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.accountNumber.required' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.bank.accountNumber.placeholder' })} />
|
||
</Form.Item>
|
||
),
|
||
},
|
||
{
|
||
title: intl.formatMessage({ id: 'register.bank.location' }),
|
||
dataIndex: 'location',
|
||
render: (_, record) => (
|
||
<Form.Item
|
||
name={[record.name, 'address']}
|
||
noStyle
|
||
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.location.required' }) }]}
|
||
>
|
||
<Cascader
|
||
options={addressOptions}
|
||
placeholder={intl.formatMessage({ id: 'register.bank.location.placeholder' })}
|
||
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' }),
|
||
width: 70,
|
||
render: (_, record) => (
|
||
<Button
|
||
type="link"
|
||
danger
|
||
icon={<DeleteOutlined />}
|
||
onClick={() => remove(record.name)}
|
||
>
|
||
{intl.formatMessage({ id: 'register.form.delete' })}
|
||
</Button>
|
||
),
|
||
},
|
||
]}
|
||
/>
|
||
<Form.Item style={{ marginTop: 16 }} wrapperCol={{ span: 24 }}>
|
||
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
|
||
{intl.formatMessage({ id: 'register.form.addRow' })}
|
||
</Button>
|
||
</Form.Item>
|
||
</>
|
||
)}
|
||
</Form.List>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
/**
|
||
* 社会准则符合性自查问卷部分
|
||
* 包含填写人信息和问卷内容
|
||
*/
|
||
export const SurveySection: React.FC<SurveySectionProps> = ({ form, surveyQuestions }) => {
|
||
const intl = useIntl();
|
||
// 使用API获取的问卷数据,如果没有则显示无数据状态
|
||
const hasQuestions =
|
||
surveyQuestions && Array.isArray(surveyQuestions) && surveyQuestions.length > 0;
|
||
|
||
// 调试日志
|
||
console.log('调查问卷数据:', surveyQuestions);
|
||
|
||
return (
|
||
<div className="border-box">
|
||
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.survey' })}</div>
|
||
|
||
<div className="questionnaire-header">{intl.formatMessage({ id: 'register.survey.fillerInfo' })}:</div>
|
||
<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' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.survey.supplierName.placeholder' })} />
|
||
</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' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.survey.name.placeholder' })} />
|
||
</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' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.survey.position.placeholder' })} />
|
||
</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' }) }]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.survey.phone.placeholder' })} />
|
||
</Form.Item>
|
||
</Col>
|
||
<Col span={8}>
|
||
<Form.Item
|
||
name={['coscoSupplierSurvey', 'email']}
|
||
label={intl.formatMessage({ id: 'register.survey.email' })}
|
||
rules={[
|
||
{ type: 'email', message: intl.formatMessage({ id: 'register.email.invalid' }) },
|
||
{ required: true, message: intl.formatMessage({ id: 'register.survey.email.required' }) },
|
||
]}
|
||
>
|
||
<Input placeholder={intl.formatMessage({ id: 'register.survey.email.placeholder' })} />
|
||
</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' }) }]}
|
||
>
|
||
<DatePicker placeholder={intl.formatMessage({ id: 'register.form.date.placeholder' })} style={{ width: '100%' }} format="YYYY-MM-DD" />
|
||
</Form.Item>
|
||
</Col>
|
||
</Row>
|
||
|
||
<div className="questionnaire-header" style={{ marginTop: '20px' }}>
|
||
{intl.formatMessage({ id: 'register.survey.questionnaire' })}:
|
||
</div>
|
||
|
||
{hasQuestions ? (
|
||
<Form.List
|
||
name="coscoSupplierSurveyQuestionReply"
|
||
initialValue={surveyQuestions.map((q: any, index) => ({
|
||
surveyQuestionId: q.id,
|
||
replyValue: '',
|
||
}))}
|
||
>
|
||
{(fields, { add, remove }) => {
|
||
console.log('Form.List fields:', fields);
|
||
|
||
return (
|
||
<Table
|
||
pagination={false}
|
||
bordered
|
||
size="middle"
|
||
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,
|
||
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 }) }]}
|
||
wrapperCol={{ span: 24 }}
|
||
>
|
||
{record.coscoSurveyQuestionOptionList &&
|
||
record.coscoSurveyQuestionOptionList.length > 0 ? (
|
||
<Radio.Group>
|
||
{record.coscoSurveyQuestionOptionList.map((option: any) => (
|
||
<Radio key={option.id} value={option.opentionValue}>
|
||
{option.optionName}
|
||
</Radio>
|
||
))}
|
||
</Radio.Group>
|
||
) : (
|
||
<Input placeholder={intl.formatMessage({ id: 'register.survey.answer.placeholder' })} />
|
||
)}
|
||
</Form.Item>
|
||
</>
|
||
);
|
||
},
|
||
},
|
||
]}
|
||
/>
|
||
);
|
||
}}
|
||
</Form.List>
|
||
) : (
|
||
<div style={{ padding: '30px 0' }}>
|
||
<Empty description={intl.formatMessage({ id: 'register.survey.noData' })} image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
};
|
||
|
||
/**
|
||
* 供应商反商业贿赂承诺书和其他附件部分
|
||
*/
|
||
export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
|
||
const intl = useIntl();
|
||
return (
|
||
<div className="border-box">
|
||
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.commitment' })}</div>
|
||
<Row gutter={24}>
|
||
<Col span={12}>
|
||
<div className="upload-label">
|
||
{intl.formatMessage({ id: 'register.attachment.stampUpload' })}
|
||
<Button
|
||
type="link"
|
||
href="/templates/anti-bribery-template.docx"
|
||
download="供应商反商业贿赂承诺书模板.docx"
|
||
>
|
||
{intl.formatMessage({ id: 'register.attachment.downloadTemplate' })}
|
||
</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' }) }]}
|
||
valuePropName="value"
|
||
>
|
||
<FileUpload
|
||
maxSize={10}
|
||
allowedTypes={['pdf', 'doc', 'docx']}
|
||
maxCount={1}
|
||
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
|
||
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} 上传成功`);
|
||
}
|
||
}
|
||
}
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
</div>
|
||
))}
|
||
</div>
|
||
);
|
||
}}
|
||
</Form.List>
|
||
</Col>
|
||
</Row>
|
||
|
||
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.otherAttachments' })}</div>
|
||
<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 && (
|
||
<Form.Item name={[field.name, 'fileUrl']} valuePropName="value">
|
||
<FileUpload
|
||
maxSize={20}
|
||
allowedTypes={['*']}
|
||
maxCount={1}
|
||
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
|
||
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} 上传成功`);
|
||
}
|
||
}
|
||
}
|
||
}}
|
||
/>
|
||
</Form.Item>
|
||
)}
|
||
</div>
|
||
))}
|
||
|
||
<Button
|
||
type="dashed"
|
||
onClick={() => add({ attachmentsType: 'accessory' })}
|
||
icon={<PlusOutlined />}
|
||
style={{ marginTop: 8 }}
|
||
>
|
||
{intl.formatMessage({ id: 'register.attachment.addMore' })}
|
||
</Button>
|
||
</>
|
||
)}
|
||
</Form.List>
|
||
</Col>
|
||
</Row>
|
||
</div>
|
||
);
|
||
};
|