修改注册页面;字典从接口取值;上传组件地址修改;维护注册页面及其组件多语言;

This commit is contained in:
linxd
2025-07-04 15:24:17 +08:00
parent 92a92b17cf
commit 21e7f15f64
10 changed files with 990 additions and 387 deletions

View File

@ -7,6 +7,8 @@ import DomesticForm from './supplier/DomesticForm';
import ForeignForm from './supplier/ForeignForm';
import { coscoSupplierBaseAdd, fetchSurveyQuestions } from '@/servers/api/register';
import './register.less';
import { getDictList } from '@/servers/api/dict';
import type { DictItem } from '@/servers/api/dict';
const SupplierRegister: React.FC = () => {
const [form] = Form.useForm();
@ -17,7 +19,23 @@ const SupplierRegister: React.FC = () => {
const [modalVisible, setModalVisible] = useState(false);
const [surveyQuestions, setSurveyQuestions] = useState<API.SurveyQuestionResponse>([]);
const [fetchingQuestions, setFetchingQuestions] = useState(false);
// 币种
const [currencyList, setCurrencyList] = useState<DictItem[]>([]);
// 企业类型
const [entTypeList, setEntTypeList] = useState<DictItem[]>([]);
const getDict = async () => {
// currency 币种
const currencyResponse = await getDictList('currency');
// entType 企业类型
const entTypeResponse = await getDictList('enterprise_type');
Promise.all([currencyResponse, entTypeResponse]).then(
([currencyListResponse, entTypeListResponse]) => {
setCurrencyList(currencyListResponse.data || []);
setEntTypeList(entTypeListResponse.data || []);
},
);
};
// 获取问卷列表
useEffect(() => {
const fetchQuestions = async () => {
@ -27,17 +45,19 @@ const SupplierRegister: React.FC = () => {
if (response.success) {
setSurveyQuestions(response.data || []);
} else {
message.error(response.message || '获取问卷列表失败');
message.error(response.message || intl.formatMessage({ id: 'register.submit.failed' }));
}
} catch (error) {
console.error('获取问卷列表出错:', error);
message.error('获取问卷列表出错');
message.error(intl.formatMessage({ id: 'register.submit.error' }));
} finally {
setFetchingQuestions(false);
}
};
fetchQuestions();
// 获取字典
getDict();
}, []);
// 获取短信验证码
@ -45,7 +65,7 @@ const SupplierRegister: React.FC = () => {
form
.validateFields(['contactPhone'])
.then((values) => {
message.success(`验证码已发送至 ${values.contactPhone}`);
message.success(intl.formatMessage({ id: 'register.captcha.sent' }, { phone: values.contactPhone }));
let count = 60;
setCountdown(count);
@ -58,7 +78,7 @@ const SupplierRegister: React.FC = () => {
}, 1000);
})
.catch((errorInfo) => {
message.error('请先输入正确的手机号');
message.error(intl.formatMessage({ id: 'register.captcha.phoneRequired' }));
});
};
@ -81,15 +101,23 @@ const SupplierRegister: React.FC = () => {
// 处理文件上传组件返回的文件列表值
// 处理营业执照附件
if (values.coscoSupplierBase.licenceAccessory && Array.isArray(values.coscoSupplierBase.licenceAccessory)) {
if (
values.coscoSupplierBase.licenceAccessory &&
Array.isArray(values.coscoSupplierBase.licenceAccessory)
) {
const licenceFile = values.coscoSupplierBase.licenceAccessory[0];
values.coscoSupplierBase.licenceAccessory = licenceFile?.response?.url || licenceFile?.response?.filePath || '';
values.coscoSupplierBase.licenceAccessory =
licenceFile?.response?.url || licenceFile?.response?.filePath || '';
}
// 处理纳税人资格证明
if (values.coscoSupplierInvoice?.qualificationCertificate && Array.isArray(values.coscoSupplierInvoice.qualificationCertificate)) {
if (
values.coscoSupplierInvoice?.qualificationCertificate &&
Array.isArray(values.coscoSupplierInvoice.qualificationCertificate)
) {
const taxFile = values.coscoSupplierInvoice.qualificationCertificate[0];
values.coscoSupplierInvoice.qualificationCertificate = taxFile?.response?.url || taxFile?.response?.filePath || '';
values.coscoSupplierInvoice.qualificationCertificate =
taxFile?.response?.url || taxFile?.response?.filePath || '';
}
// 处理资质证书附件
@ -97,7 +125,8 @@ const SupplierRegister: React.FC = () => {
values.coscoSupplierQualifications = values.coscoSupplierQualifications.map((qual: any) => {
if (qual.accessory && Array.isArray(qual.accessory)) {
const accessoryFile = qual.accessory[0];
qual.accessory = accessoryFile?.response?.url || accessoryFile?.response?.filePath || '';
qual.accessory =
accessoryFile?.response?.url || accessoryFile?.response?.filePath || '';
}
return qual;
});
@ -105,13 +134,15 @@ const SupplierRegister: React.FC = () => {
// 处理调查问卷附件
if (values.coscoSupplierSurveyAttachments) {
values.coscoSupplierSurveyAttachments = values.coscoSupplierSurveyAttachments.map((item: any) => {
if (item.fileUrl && Array.isArray(item.fileUrl)) {
const file = item.fileUrl[0];
item.fileUrl = file?.response?.url || file?.response?.filePath || '';
}
return item;
});
values.coscoSupplierSurveyAttachments = values.coscoSupplierSurveyAttachments.map(
(item: any) => {
if (item.fileUrl && Array.isArray(item.fileUrl)) {
const file = item.fileUrl[0];
item.fileUrl = file?.response?.url || file?.response?.filePath || '';
}
return item;
},
);
}
// 处理调查问卷回复
@ -121,7 +152,7 @@ const SupplierRegister: React.FC = () => {
.filter((item: any) => item && item.surveyQuestionId && item.replyValue)
.map((item: any) => ({
surveyQuestionId: item.surveyQuestionId,
replyValue: item.replyValue
replyValue: item.replyValue,
}));
console.log('处理后的问卷回复:', values.coscoSupplierSurveyQuestionReply);
@ -133,14 +164,14 @@ const SupplierRegister: React.FC = () => {
const response = await coscoSupplierBaseAdd(values);
if (response.success) {
message.success('注册成功,请登录');
message.success(intl.formatMessage({ id: 'register.submit.success' }));
history.push('/login');
} else {
message.error(response.message || '注册失败,请重试');
message.error(response.message || intl.formatMessage({ id: 'register.submit.failed' }));
}
} catch (error) {
console.error('注册出错:', error);
message.error('注册失败,请稍后重试');
message.error(intl.formatMessage({ id: 'register.submit.error' }));
} finally {
setLoading(false);
}
@ -181,10 +212,14 @@ const SupplierRegister: React.FC = () => {
labelCol={{ span: 7 }}
wrapperCol={{ span: 17 }}
>
<Form.Item label="身份类型" labelCol={{ span: 2 }} wrapperCol={{ span: 19 }}>
<Radio.Group onChange={handleSupplierTypeChange} buttonStyle="solid" value={supplierType}>
<Radio.Button value="dvs">/</Radio.Button>
<Radio.Button value="ovs"></Radio.Button>
<Form.Item label={intl.formatMessage({ id: 'register.supplier.identityType' })} labelCol={{ span: 2 }} wrapperCol={{ span: 19 }}>
<Radio.Group
onChange={handleSupplierTypeChange}
buttonStyle="solid"
value={supplierType}
>
<Radio.Button value="dvs">{intl.formatMessage({ id: 'register.supplier.domestic' })}</Radio.Button>
<Radio.Button value="ovs">{intl.formatMessage({ id: 'register.supplier.foreign' })}</Radio.Button>
</Radio.Group>
</Form.Item>
@ -194,6 +229,8 @@ const SupplierRegister: React.FC = () => {
countdown={countdown}
surveyQuestions={surveyQuestions}
handleGetCaptcha={handleGetCaptcha}
currencyList={currencyList}
entTypeList={entTypeList}
/>
) : (
<ForeignForm
@ -201,6 +238,8 @@ const SupplierRegister: React.FC = () => {
countdown={countdown}
handleGetCaptcha={handleGetCaptcha}
surveyQuestions={surveyQuestions}
currencyList={currencyList}
entTypeList={entTypeList}
/>
)}
<Form.Item
@ -213,12 +252,12 @@ const SupplierRegister: React.FC = () => {
validator: (_, value) =>
value
? Promise.resolve()
: Promise.reject(new Error('请阅读并同意注册信息承诺书')),
: Promise.reject(new Error(intl.formatMessage({ id: 'register.supplier.agreement.required' }))),
},
]}
>
<Checkbox>
{intl.formatMessage({ id: 'register.supplier.agreement' })}
<Button
type="link"
onClick={(e) => {
@ -227,7 +266,7 @@ const SupplierRegister: React.FC = () => {
setModalVisible(true);
}}
>
{intl.formatMessage({ id: 'register.supplier.commitment' })}
</Button>
</Checkbox>
</Form.Item>
@ -244,7 +283,7 @@ const SupplierRegister: React.FC = () => {
{/* 注册信息承诺书弹窗 */}
<Modal
title="注册信息承诺书"
title={intl.formatMessage({ id: 'register.supplier.commitment.title' })}
visible={modalVisible}
onOk={() => {
console.log('点击了确定按钮');
@ -255,31 +294,31 @@ const SupplierRegister: React.FC = () => {
setModalVisible(false);
}}
width={700}
okText="我知道了"
okText={intl.formatMessage({ id: 'register.supplier.commitment.ok' })}
cancelButtonProps={{ style: { display: 'none' } }}
destroyOnClose
// maskClosable={false}
>
<div style={{ maxHeight: '60vh', overflow: 'auto' }}>
<p></p>
<p>使</p>
<p>{intl.formatMessage({ id: 'register.supplier.commitment.content.intro1' })}</p>
<p>{intl.formatMessage({ id: 'register.supplier.commitment.content.intro2' })}</p>
<ol>
<li>
/
{intl.formatMessage({ id: 'register.supplier.commitment.content.item1' })}
</li>
<li>/</li>
<li>{intl.formatMessage({ id: 'register.supplier.commitment.content.item2' })}</li>
<li>
/
{intl.formatMessage({ id: 'register.supplier.commitment.content.item3' })}
</li>
<li>/</li>
<li>/使</li>
<li>{intl.formatMessage({ id: 'register.supplier.commitment.content.item4' })}</li>
<li>{intl.formatMessage({ id: 'register.supplier.commitment.content.item5' })}</li>
<li>
/
{intl.formatMessage({ id: 'register.supplier.commitment.content.item6' })}
</li>
<li>/</li>
<li>/</li>
<li>{intl.formatMessage({ id: 'register.supplier.commitment.content.item7' })}</li>
<li>{intl.formatMessage({ id: 'register.supplier.commitment.content.item8' })}</li>
</ol>
<p></p>
<p>{intl.formatMessage({ id: 'register.supplier.commitment.content.end' })}</p>
</div>
</Modal>
</div>

View File

@ -2,7 +2,7 @@
* 供应商注册表单通用部分
* 封装了国内企业和境外企业注册表单相同的部分
*/
import React from 'react';
import React, { useEffect, useState } from 'react';
import {
Form,
Input,
@ -18,7 +18,10 @@ import {
} 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;
@ -73,9 +76,20 @@ interface SurveySectionProps extends CommonFormSectionsProps {
* 包含资质证书类型、名称、编号、等级、发证机构、发证日期、有效期等
*/
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="form-section-title"></div>
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.qualification' })}</div>
<Form.List name="coscoSupplierQualifications">
{(fields, { add, remove }) => (
@ -92,89 +106,89 @@ export const QualificationSection: React.FC<CommonFormSectionsProps> = ({ form }
rowKey="key"
columns={[
{
title: '序号',
title: intl.formatMessage({ id: 'register.form.table.no' }),
dataIndex: 'name',
width: 60,
render: (_, __, index) => index + 1,
},
{
title: '资质证书类型',
title: intl.formatMessage({ id: 'register.qualification.certType' }),
dataIndex: 'certType',
render: (_, record) => (
<Form.Item
name={[record.name, 'certificateType']}
noStyle
rules={[{ required: false, message: '请选择资质证书类型' }]}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.certType.required' }) }]}
>
<Select placeholder="请选择类型" style={{ width: '100%' }}>
<Option value="机构资质"></Option>
<Option value="CMMI资质等级">CMMI资质等级</Option>
<Option value="质量体系认证"></Option>
<Option value="环境管理体系认证"></Option>
<Option value="行业资质"></Option>
<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: '资质名称',
title: intl.formatMessage({ id: 'register.qualification.certName' }),
dataIndex: 'certName',
render: (_, record) => (
<Form.Item
name={[record.name, 'name']}
noStyle
rules={[{ required: false, message: '请输入资质名称' }]}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.certName.required' }) }]}
>
<Input placeholder="请输入资质名称" />
<Input placeholder={intl.formatMessage({ id: 'register.qualification.certName.placeholder' })} />
</Form.Item>
),
},
{
title: '资质证书编号',
title: intl.formatMessage({ id: 'register.qualification.certNumber' }),
dataIndex: 'certNumber',
render: (_, record) => (
<Form.Item
name={[record.name, 'code']}
noStyle
rules={[{ required: false, message: '请输入资质证书编号' }]}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.certNumber.required' }) }]}
>
<Input placeholder="请输入证书编号" />
<Input placeholder={intl.formatMessage({ id: 'register.qualification.certNumber.placeholder' })} />
</Form.Item>
),
},
{
title: '资质类别和等级',
title: intl.formatMessage({ id: 'register.qualification.certLevel' }),
dataIndex: 'certLevel',
render: (_, record) => (
<Form.Item name={[record.name, 'typeLevel']} noStyle>
<Input placeholder="请输入资质类别和等级" />
<Input placeholder={intl.formatMessage({ id: 'register.qualification.certLevel.placeholder' })} />
</Form.Item>
),
},
{
title: '发证机构',
title: intl.formatMessage({ id: 'register.qualification.issuingAuthority' }),
dataIndex: 'issuingAuthority',
render: (_, record) => (
<Form.Item
name={[record.name, 'authority']}
noStyle
rules={[{ required: false, message: '请输入发证机构' }]}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.issuingAuthority.required' }) }]}
>
<Input placeholder="请输入发证机构" />
<Input placeholder={intl.formatMessage({ id: 'register.qualification.issuingAuthority.placeholder' })} />
</Form.Item>
),
},
{
title: '发证日期',
title: intl.formatMessage({ id: 'register.qualification.issueDate' }),
dataIndex: 'issueDate',
render: (_, record) => (
<Form.Item
name={[record.name, 'dateTime']}
noStyle
rules={[{ required: false, message: '请选择发证日期' }]}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.issueDate.required' }) }]}
>
<DatePicker
placeholder="年/月/日"
placeholder={intl.formatMessage({ id: 'register.form.date.placeholder' })}
style={{ width: '100%' }}
format="YYYY-MM-DD"
/>
@ -182,16 +196,16 @@ export const QualificationSection: React.FC<CommonFormSectionsProps> = ({ form }
),
},
{
title: '资质有效期至',
title: intl.formatMessage({ id: 'register.qualification.expiryDate' }),
dataIndex: 'expiryDate',
render: (_, record) => (
<Form.Item
name={[record.name, 'termOfValidity']}
noStyle
rules={[{ required: false, message: '请选择资质有效期' }]}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.expiryDate.required' }) }]}
>
<DatePicker
placeholder="年/月/日"
placeholder={intl.formatMessage({ id: 'register.form.date.placeholder' })}
style={{ width: '100%' }}
format="YYYY-MM-DD"
/>
@ -199,26 +213,26 @@ export const QualificationSection: React.FC<CommonFormSectionsProps> = ({ form }
),
},
{
title: '附件',
title: intl.formatMessage({ id: 'register.form.attachment' }),
dataIndex: 'certFile',
render: (_, record) => (
<Form.Item
name={[record.name, 'accessory']}
noStyle
rules={[{ required: false, message: '请上传资质证书附件' }]}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.qualification.attachment.required' }) }]}
valuePropName="value"
>
<FileUpload
maxSize={10}
allowedTypes={['pdf', 'jpg', 'jpeg', 'png']}
maxCount={1}
buttonText="上传"
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
/>
</Form.Item>
),
},
{
title: '操作',
title: intl.formatMessage({ id: 'register.form.operation' }),
width: 70,
render: (_, record) => (
<Button
@ -227,7 +241,7 @@ export const QualificationSection: React.FC<CommonFormSectionsProps> = ({ form }
icon={<DeleteOutlined />}
onClick={() => remove(record.name)}
>
{intl.formatMessage({ id: 'register.form.delete' })}
</Button>
),
},
@ -235,7 +249,7 @@ export const QualificationSection: React.FC<CommonFormSectionsProps> = ({ form }
/>
<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>
</>
@ -250,72 +264,98 @@ export const QualificationSection: React.FC<CommonFormSectionsProps> = ({ form }
* 包含纳税人类型、开票抬头、纳税人识别号、开票地址等
*/
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"></div>
<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="纳税人类型"
rules={[{ required: true, message: '请选择纳税人类型' }]}
label={intl.formatMessage({ id: 'register.invoice.taxpayerType' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.invoice.taxpayerType.required' }) }]}
>
<Select placeholder="请选择纳税人类型">
<Option value="general"></Option>
<Option value="small"></Option>
<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="开票抬头"
rules={[{ required: true, message: '请输入开票抬头' }]}
label={intl.formatMessage({ id: 'register.invoice.head' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.invoice.head.required' }) }]}
>
<Input placeholder="请输入开票抬头" />
<Input placeholder={intl.formatMessage({ id: 'register.invoice.head.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierInvoice', 'taxpayerCode']}
label="纳税人识别号"
rules={[{ required: true, message: '请输入纳税人识别号' }]}
label={intl.formatMessage({ id: 'register.invoice.taxpayerCode' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.invoice.taxpayerCode.required' }) }]}
>
<Input placeholder="请输入纳税人识别号" />
<Input placeholder={intl.formatMessage({ id: 'register.invoice.taxpayerCode.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item name={['coscoSupplierInvoice', 'address']} label="开票地址">
<Input placeholder="请输入开票地址" />
<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="开票电话">
<Input placeholder="请输入开票电话" />
<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="开票户行">
<Input placeholder="请输入开票银行" />
<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="开票户行账号">
<Input placeholder="请输入开票户行账号" />
<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="一般纳税人资格证明"
label={intl.formatMessage({ id: 'register.invoice.qualificationCertificate' })}
valuePropName="value"
>
<FileUpload
maxSize={10}
allowedTypes={['pdf', 'jpg', 'jpeg', 'png']}
maxCount={1}
buttonText="上传文件"
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
/>
</Form.Item>
</Col>
@ -329,9 +369,10 @@ export const InvoiceSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
* 包含开户银行、账户名称、账号、所在地区等
*/
export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
const intl = useIntl();
return (
<>
<div className="form-section-title"></div>
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.bankAccount' })}</div>
<Form.List name="coscoSupplierBank">
{(fields, { add, remove }) => (
@ -348,62 +389,62 @@ export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form })
rowKey="key"
columns={[
{
title: '序号',
title: intl.formatMessage({ id: 'register.form.table.no' }),
dataIndex: 'name',
width: 60,
render: (_, __, index) => index + 1,
},
{
title: '开户银行',
title: intl.formatMessage({ id: 'register.bank.bankName' }),
dataIndex: 'bankName',
render: (_, record) => (
<Form.Item
name={[record.name, 'bank']}
noStyle
rules={[{ required: true, message: '请输入开户银行' }]}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.bankName.required' }) }]}
>
<Input placeholder="请输入开户银行" />
<Input placeholder={intl.formatMessage({ id: 'register.bank.bankName.placeholder' })} />
</Form.Item>
),
},
{
title: '账户名称',
title: intl.formatMessage({ id: 'register.bank.accountName' }),
dataIndex: 'accountName',
render: (_, record) => (
<Form.Item
name={[record.name, 'accountName']}
noStyle
rules={[{ required: true, message: '请输入账户名称' }]}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.accountName.required' }) }]}
>
<Input placeholder="请输入账户名称" />
<Input placeholder={intl.formatMessage({ id: 'register.bank.accountName.placeholder' })} />
</Form.Item>
),
},
{
title: '账号',
title: intl.formatMessage({ id: 'register.bank.accountNumber' }),
dataIndex: 'accountNumber',
render: (_, record) => (
<Form.Item
name={[record.name, 'account']}
noStyle
rules={[{ required: true, message: '请输入账号' }]}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.accountNumber.required' }) }]}
>
<Input placeholder="请输入账号" />
<Input placeholder={intl.formatMessage({ id: 'register.bank.accountNumber.placeholder' })} />
</Form.Item>
),
},
{
title: '国家、省、市',
title: intl.formatMessage({ id: 'register.bank.location' }),
dataIndex: 'location',
render: (_, record) => (
<Form.Item
name={[record.name, 'address']}
noStyle
rules={[{ required: true, message: '请选择地址' }]}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.bank.location.required' }) }]}
>
<Cascader
options={addressOptions}
placeholder="请选择省市区"
placeholder={intl.formatMessage({ id: 'register.bank.location.placeholder' })}
showSearch={{
filter: (inputValue, path) => {
return path.some((option) => {
@ -421,7 +462,7 @@ export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form })
),
},
{
title: '操作',
title: intl.formatMessage({ id: 'register.form.operation' }),
width: 70,
render: (_, record) => (
<Button
@ -430,7 +471,7 @@ export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form })
icon={<DeleteOutlined />}
onClick={() => remove(record.name)}
>
{intl.formatMessage({ id: 'register.form.delete' })}
</Button>
),
},
@ -438,7 +479,7 @@ export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form })
/>
<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>
</>
@ -453,6 +494,7 @@ export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form })
* 包含填写人信息和问卷内容
*/
export const SurveySection: React.FC<SurveySectionProps> = ({ form, surveyQuestions }) => {
const intl = useIntl();
// 使用API获取的问卷数据如果没有则显示无数据状态
const hasQuestions =
surveyQuestions && Array.isArray(surveyQuestions) && surveyQuestions.length > 0;
@ -462,71 +504,71 @@ export const SurveySection: React.FC<SurveySectionProps> = ({ form, surveyQuesti
return (
<>
<div className="form-section-title"></div>
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.survey' })}</div>
<div className="questionnaire-header"></div>
<div className="questionnaire-header">{intl.formatMessage({ id: 'register.survey.fillerInfo' })}</div>
<Row gutter={24}>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'supplierName']}
label="供应商名称"
rules={[{ required: true, message: '请输入供应商名称' }]}
label={intl.formatMessage({ id: 'register.survey.supplierName' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.supplierName.required' }) }]}
>
<Input placeholder="请输入供应商名称" />
<Input placeholder={intl.formatMessage({ id: 'register.survey.supplierName.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'name']}
label="姓名"
rules={[{ required: true, message: '请输入姓名' }]}
label={intl.formatMessage({ id: 'register.survey.name' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.name.required' }) }]}
>
<Input placeholder="请输入姓名" />
<Input placeholder={intl.formatMessage({ id: 'register.survey.name.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'position']}
label="职位"
rules={[{ required: true, message: '请输入职位' }]}
label={intl.formatMessage({ id: 'register.survey.position' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.position.required' }) }]}
>
<Input placeholder="请输入职位" />
<Input placeholder={intl.formatMessage({ id: 'register.survey.position.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'phone']}
label="电话号"
rules={[{ required: true, message: '请输入电话号' }]}
label={intl.formatMessage({ id: 'register.survey.phone' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.phone.required' }) }]}
>
<Input placeholder="请输入电话号" />
<Input placeholder={intl.formatMessage({ id: 'register.survey.phone.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'email']}
label="邮箱"
label={intl.formatMessage({ id: 'register.survey.email' })}
rules={[
{ type: 'email', message: '请输入有效的电子邮箱' },
{ required: true, message: '请输入电子邮箱' },
{ type: 'email', message: intl.formatMessage({ id: 'register.email.invalid' }) },
{ required: true, message: intl.formatMessage({ id: 'register.survey.email.required' }) },
]}
>
<Input placeholder="请输入电子邮箱" />
<Input placeholder={intl.formatMessage({ id: 'register.survey.email.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierSurvey', 'dateTime']}
label="日期"
rules={[{ required: true, message: '请选择日期' }]}
label={intl.formatMessage({ id: 'register.survey.date' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.date.required' }) }]}
>
<DatePicker placeholder="请选择日期" style={{ width: '100%' }} format="YYYY-MM-DD" />
<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 ? (
@ -549,19 +591,19 @@ export const SurveySection: React.FC<SurveySectionProps> = ({ form, surveyQuesti
dataSource={surveyQuestions}
columns={[
{
title: '序号',
title: intl.formatMessage({ id: 'register.form.table.no' }),
dataIndex: 'id',
width: 60,
align: 'center',
render: (text, record, index) => index + 1,
},
{
title: '问题',
title: intl.formatMessage({ id: 'register.survey.question' }),
dataIndex: 'questionName',
render: (text) => <div style={{ whiteSpace: 'pre-line' }}>{text}</div>,
},
{
title: '回复',
title: intl.formatMessage({ id: 'register.survey.reply' }),
width: 650,
render: (_, record, index) => {
return (
@ -575,7 +617,7 @@ export const SurveySection: React.FC<SurveySectionProps> = ({ form, surveyQuesti
</Form.Item>
<Form.Item
name={[index, 'replyValue']}
rules={[{ required: true, message: `请选择问题${index + 1}的答案` }]}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.survey.answer.required' }, { index: index + 1 }) }]}
wrapperCol={{ span: 24 }}
>
{record.coscoSurveyQuestionOptionList &&
@ -588,7 +630,7 @@ export const SurveySection: React.FC<SurveySectionProps> = ({ form, surveyQuesti
))}
</Radio.Group>
) : (
<Input placeholder="请输入回答" />
<Input placeholder={intl.formatMessage({ id: 'register.survey.answer.placeholder' })} />
)}
</Form.Item>
</>
@ -602,7 +644,7 @@ export const SurveySection: React.FC<SurveySectionProps> = ({ form, surveyQuesti
</Form.List>
) : (
<div style={{ padding: '30px 0' }}>
<Empty description="暂无问卷数据" image={Empty.PRESENTED_IMAGE_SIMPLE} />
<Empty description={intl.formatMessage({ id: 'register.survey.noData' })} image={Empty.PRESENTED_IMAGE_SIMPLE} />
</div>
)}
</>
@ -613,19 +655,20 @@ export const SurveySection: React.FC<SurveySectionProps> = ({ form, surveyQuesti
* 供应商反商业贿赂承诺书和其他附件部分
*/
export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
const intl = useIntl();
return (
<>
<div className="form-section-title">贿</div>
<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>
@ -650,14 +693,14 @@ export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) =
<Form.Item
name={[field.name, 'fileUrl']}
rules={[{ required: true, message: '请上传已盖章的反商业贿赂承诺书' }]}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.attachment.commitment.required' }) }]}
valuePropName="value"
>
<FileUpload
maxSize={10}
allowedTypes={['pdf', 'doc', 'docx']}
maxCount={1}
buttonText="上传文件"
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
onChange={(fileList) => {
if (fileList && fileList.length > 0) {
const file = fileList[0];
@ -695,13 +738,13 @@ export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) =
</Col>
</Row>
<div className="form-section-title"></div>
<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"></div>
<div className="upload-label">{intl.formatMessage({ id: 'register.attachment.otherAttachments.hint' })}</div>
{fields.map((field, index) => (
<div
key={field.key}
@ -726,7 +769,7 @@ export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) =
maxSize={20}
allowedTypes={['*']}
maxCount={1}
buttonText="上传"
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
onChange={(fileList) => {
if (fileList && fileList.length > 0) {
const file = fileList[0];
@ -766,7 +809,7 @@ export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) =
icon={<PlusOutlined />}
style={{ marginTop: 8 }}
>
{intl.formatMessage({ id: 'register.attachment.addMore' })}
</Button>
</>
)}

View File

@ -2,7 +2,9 @@
import React from 'react';
import { Form, Input, Button, Select, DatePicker, Row, Col, message } from 'antd';
import { MobileOutlined, MailOutlined, EnvironmentOutlined } from '@ant-design/icons';
import { useIntl } from 'umi';
import FileUpload from '@/components/FileUpload';
import type { DictItem } from '@/servers/api/dict';
/**
* 引入通用表单组件
@ -25,6 +27,8 @@ interface DomesticFormProps {
countdown: number;
handleGetCaptcha: () => void;
surveyQuestions?: API.SurveyQuestionResponse; // 本身就是数组类型
currencyList: DictItem[];
entTypeList: DictItem[];
}
/**
@ -37,93 +41,98 @@ const DomesticForm: React.FC<DomesticFormProps> = ({
countdown,
handleGetCaptcha,
surveyQuestions,
currencyList,
entTypeList,
}) => {
const intl = useIntl();
return (
<>
<div className="form-section-title"></div>
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.basicInfo' })}</div>
{/* 营业执照附件和有效期 */}
<Row gutter={24}>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'enterpriseType']}
label="企业类型"
rules={[{ required: true, message: '请选择企业类型' }]}
label={intl.formatMessage({ id: 'register.domestic.enterpriseType' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.domestic.enterpriseType.required' }) }]}
valuePropName="value"
>
<Select placeholder="请选择企业类型">
<Option value="limited"></Option>
<Option value="joint"></Option>
<Option value="individual"></Option>
<Option value="other"></Option>
<Select placeholder={intl.formatMessage({ id: 'register.domestic.enterpriseType.placeholder' })}>
{entTypeList.map((item) => (
<Option key={item.code} value={item.code}>
{item.dicName}
</Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'licenceAccessory']}
label="营业执照附件"
rules={[{ required: true, message: '请上传营业执照附件' }]}
label={intl.formatMessage({ id: 'register.domestic.licenceAccessory' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.domestic.licenceAccessory.required' }) }]}
valuePropName="value"
>
<FileUpload
maxSize={10}
allowedTypes={['pdf', 'jpg', 'jpeg', 'png']}
maxCount={1}
buttonText="上传文件"
tip="支持PDF、JPG、PNG格式不超过10MB"
buttonText={intl.formatMessage({ id: 'register.form.upload' })}
tip={intl.formatMessage({ id: 'register.domestic.licenceAccessory.tip' })}
/>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'licenceDate']}
label="营业执照有效期"
rules={[{ required: true, message: '请选择营业执照有效期' }]}
label={intl.formatMessage({ id: 'register.domestic.licenceDate' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.domestic.licenceDate.required' }) }]}
>
<DatePicker placeholder="请选择日期" style={{ width: '100%' }} format="YYYY-MM-DD" />
<DatePicker placeholder={intl.formatMessage({ id: 'register.form.date.placeholder' })} style={{ width: '100%' }} format="YYYY-MM-DD" />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'name']}
label="企业名称"
rules={[{ required: true, message: '请输入企业名称' }]}
label={intl.formatMessage({ id: 'register.domestic.companyName' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.domestic.companyName.required' }) }]}
>
<Input placeholder="请输入企业名称" />
<Input placeholder={intl.formatMessage({ id: 'register.domestic.companyName.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'nameEn']}
label="企业英文名"
rules={[{ required: false, message: '请输入企业英文名' }]}
label={intl.formatMessage({ id: 'register.domestic.companyNameEn' })}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.domestic.companyNameEn.required' }) }]}
>
<Input placeholder="请输入企业英文名" />
<Input placeholder={intl.formatMessage({ id: 'register.domestic.companyNameEn.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'socialCreditCode']}
label="统一社会信用代码"
label={intl.formatMessage({ id: 'register.domestic.socialCreditCode' })}
rules={[
{ required: true, message: '请输入统一社会信用代码' },
{ pattern: /^[0-9A-HJ-NPQRTUWXY]{18}$/, message: '请输入正确的统一社会信用代码' },
{ required: true, message: intl.formatMessage({ id: 'register.domestic.socialCreditCode.required' }) },
{ pattern: /^[0-9A-HJ-NPQRTUWXY]{18}$/, message: intl.formatMessage({ id: 'register.domestic.socialCreditCode.pattern' }) },
]}
>
<Input placeholder="请输入正确的统一社会信用代码" />
<Input placeholder={intl.formatMessage({ id: 'register.domestic.socialCreditCode.placeholder' })} />
</Form.Item>
</Col>
<Col span={24} className="ant-form-item-label-fix">
<Form.Item
name={['coscoSupplierBase', 'range']}
label="经营范围"
rules={[{ required: true, message: '请输入经营范围' }]}
label={intl.formatMessage({ id: 'register.domestic.businessScope' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.domestic.businessScope.required' }) }]}
labelCol={{ span: 2 }}
wrapperCol={{ span: 22 }}
>
<TextArea
placeholder="金融专用产品、广告传媒"
placeholder={intl.formatMessage({ id: 'register.domestic.businessScope.placeholder' })}
rows={2}
maxLength={200}
showCount
@ -136,91 +145,94 @@ const DomesticForm: React.FC<DomesticFormProps> = ({
labelCol={{ span: 2 }}
wrapperCol={{ span: 22 }}
name={['coscoSupplierBase', 'regAddress']}
label="注册地址"
rules={[{ required: true, message: '请输入注册地址' }]}
label={intl.formatMessage({ id: 'register.domestic.regAddress' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.domestic.regAddress.required' }) }]}
>
<Input prefix={<EnvironmentOutlined />} placeholder="上海市普陀区XX路1888号" />
<Input prefix={<EnvironmentOutlined />} placeholder={intl.formatMessage({ id: 'register.domestic.regAddress.placeholder' })} />
</Form.Item>
</Col>
<Col span={24} className="ant-form-item-label-fix">
<Form.Item
name={['coscoSupplierBase', 'workAddress']}
label="办公地址"
label={intl.formatMessage({ id: 'register.domestic.workAddress' })}
labelCol={{ span: 2 }}
wrapperCol={{ span: 22 }}
>
<Input
prefix={<EnvironmentOutlined />}
placeholder="请具体注明省、市、区、路、门牌号"
placeholder={intl.formatMessage({ id: 'register.domestic.workAddress.placeholder' })}
/>
</Form.Item>
</Col>
<Col span={24} className="ant-form-item-label-fix">
<Form.Item
name={['coscoSupplierBase', 'parentCompanyInvestor']}
label="母公司/出资人"
label={intl.formatMessage({ id: 'register.domestic.parentCompany' })}
labelCol={{ span: 2 }}
wrapperCol={{ span: 22 }}
>
<Input placeholder="请输入母公司或出资人信息" />
<Input placeholder={intl.formatMessage({ id: 'register.domestic.parentCompany.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'legalPerson']}
label="企业法定代表人"
rules={[{ required: true, message: '请输入企业法定代表人/负责人' }]}
label={intl.formatMessage({ id: 'register.domestic.legalPerson' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.domestic.legalPerson.required' }) }]}
>
<Input placeholder="张三" />
<Input placeholder={intl.formatMessage({ id: 'register.domestic.legalPerson.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item name={['coscoSupplierBase', 'idCard']} label="联系人证件号码">
<Input placeholder="请填写联系人正确的身份证号" />
<Form.Item
name={['coscoSupplierBase', 'idCard']}
label={intl.formatMessage({ id: 'register.domestic.idCard' })}
>
<Input placeholder={intl.formatMessage({ id: 'register.domestic.idCard.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'capital']}
label="注册资本"
rules={[{ required: true, message: '请输入注册资本' }]}
label={intl.formatMessage({ id: 'register.domestic.capital' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.domestic.capital.required' }) }]}
>
<Input type="number" placeholder="请输入金额" addonBefore="人民币" addonAfter="万元" />
<Input type="number" placeholder={intl.formatMessage({ id: 'register.domestic.capital.placeholder' })} addonBefore="人民币" addonAfter="万元" />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'contactsName']}
label="联系人姓名"
rules={[{ required: true, message: '请输入联系人姓名' }]}
label={intl.formatMessage({ id: 'register.domestic.contactsName' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.domestic.contactsName.required' }) }]}
>
<Input placeholder="请输入联系人姓名" />
<Input placeholder={intl.formatMessage({ id: 'register.domestic.contactsName.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'contactsPhone']}
label="联系人手机"
label={intl.formatMessage({ id: 'register.domestic.contactsPhone' })}
rules={[
{ required: true, message: '请输入联系人手机号' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入有效的手机号' },
{ required: true, message: intl.formatMessage({ id: 'register.domestic.contactsPhone.required' }) },
{ pattern: /^1[3-9]\d{9}$/, message: intl.formatMessage({ id: 'register.domestic.contactsPhone.pattern' }) },
]}
>
<Input prefix={<MobileOutlined />} placeholder="请输入11位手机号码" />
<Input prefix={<MobileOutlined />} placeholder={intl.formatMessage({ id: 'register.domestic.contactsPhone.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name="captcha"
label="验证码"
rules={[{ required: true, message: '请输入验证码' }]}
label={intl.formatMessage({ id: 'register.captcha.label' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.captcha.required' }) }]}
>
<Row gutter={8}>
<Col span={14}>
<Input placeholder="请输入短信验证码" />
<Input placeholder={intl.formatMessage({ id: 'register.captcha.placeholder' })} />
</Col>
<Col span={10}>
<Button
@ -229,7 +241,7 @@ const DomesticForm: React.FC<DomesticFormProps> = ({
disabled={countdown > 0}
onClick={handleGetCaptcha}
>
{countdown > 0 ? `${countdown}s` : '获取验证码'}
{countdown > 0 ? `${countdown}s` : intl.formatMessage({ id: 'register.captcha.get' })}
</Button>
</Col>
</Row>
@ -239,18 +251,21 @@ const DomesticForm: React.FC<DomesticFormProps> = ({
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'contactsEmail']}
label="联系人邮箱"
label={intl.formatMessage({ id: 'register.domestic.contactsEmail' })}
rules={[
{ type: 'email', message: '请输入有效的电子邮箱' },
{ required: true, message: '请输入电子邮箱' },
{ type: 'email', message: intl.formatMessage({ id: 'register.email.invalid' }) },
{ required: true, message: intl.formatMessage({ id: 'register.domestic.contactsEmail.required' }) },
]}
>
<Input prefix={<MailOutlined />} placeholder="请输入企业联系电话" />
<Input prefix={<MailOutlined />} placeholder={intl.formatMessage({ id: 'register.domestic.contactsEmail.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item name={['coscoSupplierBase', 'telephone']} label="固定电话">
<Input placeholder="XXX@XXX.com" />
<Form.Item
name={['coscoSupplierBase', 'telephone']}
label={intl.formatMessage({ id: 'register.domestic.telephone' })}
>
<Input placeholder={intl.formatMessage({ id: 'register.domestic.telephone.placeholder' })} />
</Form.Item>
</Col>
</Row>

View File

@ -2,6 +2,7 @@
import React from 'react';
import { Form, Input, Button, Select, Row, Col } from 'antd';
import { MobileOutlined, MailOutlined, EnvironmentOutlined } from '@ant-design/icons';
import { useIntl } from 'umi';
/**
* 引入通用表单组件
*/
@ -12,6 +13,7 @@ import {
SurveySection,
AttachmentSection,
} from './CommonFormSections';
import type { DictItem } from '@/servers/api/dict';
const { Option } = Select;
const { TextArea } = Input;
@ -21,6 +23,8 @@ interface ForeignFormProps {
countdown: number;
handleGetCaptcha: () => void;
surveyQuestions?: API.SurveyQuestionResponse; // 本身就是数组类型
currencyList: DictItem[];
entTypeList: DictItem[];
}
/**
@ -33,115 +37,127 @@ const ForeignForm: React.FC<ForeignFormProps> = ({
countdown,
handleGetCaptcha,
surveyQuestions,
currencyList,
entTypeList,
}) => {
const intl = useIntl();
return (
<>
{/* 境外企业特有的基本信息部分 */}
<div className="form-section-title"></div>
<div className="form-section-title">{intl.formatMessage({ id: 'register.form.section.basicInfo' })}</div>
<Row gutter={24}>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'name']}
label="企业名称"
rules={[{ required: false, message: '请输入企业名称' }]}
label={intl.formatMessage({ id: 'register.foreign.companyName' })}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.foreign.companyName.required' }) }]}
>
<Input placeholder="请输入企业名称" />
<Input placeholder={intl.formatMessage({ id: 'register.foreign.companyName.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'nameEn']}
label="企业英文名称"
rules={[{ required: true, message: '请输入企业英文名称' }]}
label={intl.formatMessage({ id: 'register.foreign.companyNameEn' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.foreign.companyNameEn.required' }) }]}
>
<Input placeholder="请输入企业英文名称" />
<Input placeholder={intl.formatMessage({ id: 'register.foreign.companyNameEn.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name="country"
label="国家/地区"
rules={[{ required: true, message: '请选择国家/地区' }]}
label={intl.formatMessage({ id: 'register.foreign.country' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.foreign.country.required' }) }]}
>
<Select placeholder="请选择国家/地区">
<Option value="US"></Option>
<Option value="UK"></Option>
<Option value="JP"></Option>
<Option value="DE"></Option>
<Option value="FR"></Option>
<Option value="AU"></Option>
<Option value="CA"></Option>
<Option value="SG"></Option>
<Option value="HK"></Option>
<Option value="OTHER"></Option>
<Select placeholder={intl.formatMessage({ id: 'register.foreign.country.placeholder' })}>
<Option value="US">{intl.formatMessage({ id: 'register.foreign.country.US' })}</Option>
<Option value="UK">{intl.formatMessage({ id: 'register.foreign.country.UK' })}</Option>
<Option value="JP">{intl.formatMessage({ id: 'register.foreign.country.JP' })}</Option>
<Option value="DE">{intl.formatMessage({ id: 'register.foreign.country.DE' })}</Option>
<Option value="FR">{intl.formatMessage({ id: 'register.foreign.country.FR' })}</Option>
<Option value="AU">{intl.formatMessage({ id: 'register.foreign.country.AU' })}</Option>
<Option value="CA">{intl.formatMessage({ id: 'register.foreign.country.CA' })}</Option>
<Option value="SG">{intl.formatMessage({ id: 'register.foreign.country.SG' })}</Option>
<Option value="HK">{intl.formatMessage({ id: 'register.foreign.country.HK' })}</Option>
<Option value="OTHER">{intl.formatMessage({ id: 'register.foreign.country.OTHER' })}</Option>
</Select>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'vat']}
label="税号"
rules={[{ required: false, message: '请输入税号' }]}
label={intl.formatMessage({ id: 'register.foreign.vat' })}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.foreign.vat.required' }) }]}
>
<Input placeholder="请输入税号" />
<Input placeholder={intl.formatMessage({ id: 'register.foreign.vat.placeholder' })} />
</Form.Item>
</Col>
<Col span={24} className="ant-form-item-label-fix">
<Form.Item
name={['coscoSupplierBase', 'workAddress']}
label="办公地址"
label={intl.formatMessage({ id: 'register.foreign.workAddress' })}
labelCol={{ span: 2 }}
wrapperCol={{ span: 22 }}
>
<Input prefix={<EnvironmentOutlined />} placeholder="请具体注明" />
<Input prefix={<EnvironmentOutlined />} placeholder={intl.formatMessage({ id: 'register.foreign.workAddress.placeholder' })} />
</Form.Item>
</Col>
<Col span={24} className="ant-form-item-label-fix">
<Form.Item
name={['coscoSupplierBase', 'range']}
label="经营范围"
label={intl.formatMessage({ id: 'register.foreign.businessScope' })}
labelCol={{ span: 2 }}
wrapperCol={{ span: 22 }}
rules={[{ required: true, message: '请输入经营范围' }]}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.foreign.businessScope.required' }) }]}
>
<TextArea placeholder="请输入经营范围" rows={2} maxLength={200} showCount />
<TextArea
placeholder={intl.formatMessage({ id: 'register.foreign.businessScope.placeholder' })}
rows={2}
maxLength={200}
showCount
/>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item name={['coscoSupplierBase', 'parentCompanyInvestor']} label="母公司/出资人">
<Input placeholder="请输入母公司或出资人信息" />
<Form.Item
name={['coscoSupplierBase', 'parentCompanyInvestor']}
label={intl.formatMessage({ id: 'register.foreign.parentCompany' })}
>
<Input placeholder={intl.formatMessage({ id: 'register.foreign.parentCompany.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'legalPerson']}
label="企业法定代表人"
rules={[{ required: false, message: '请输入企业法定代表人' }]}
label={intl.formatMessage({ id: 'register.foreign.legalPerson' })}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.foreign.legalPerson.required' }) }]}
>
<Input placeholder="请输入企业法定代表人" />
<Input placeholder={intl.formatMessage({ id: 'register.foreign.legalPerson.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item label="注册资本" required style={{ marginBottom: 0 }}>
<Form.Item label={intl.formatMessage({ id: 'register.foreign.capital' })} required style={{ marginBottom: 0 }}>
<Input.Group compact style={{ display: 'flex' }}>
<Form.Item name="currency" noStyle initialValue="USD">
<Select style={{ width: 100, borderRadius: '2px 0 0 2px' }}>
<Option value="USD"></Option>
<Option value="EUR"></Option>
<Option value="GBP"></Option>
<Option value="JPY"></Option>
<Option value="HKD"></Option>
{currencyList.map((item) => (
<Option key={item.code} value={item.code}>
{item.dicName}
</Option>
))}
</Select>
</Form.Item>
<Form.Item
name={['coscoSupplierBase', 'capital']}
noStyle
rules={[{ required: false, message: '请输入注册资本金额' }]}
rules={[{ required: false, message: intl.formatMessage({ id: 'register.foreign.capital.required' }) }]}
>
<Input
type="number"
placeholder="请输入金额"
placeholder={intl.formatMessage({ id: 'register.foreign.capital.placeholder' })}
style={{ flex: 1, borderRadius: '0 2px 2px 0', marginLeft: -1 }}
/>
</Form.Item>
@ -151,30 +167,30 @@ const ForeignForm: React.FC<ForeignFormProps> = ({
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'contactsName']}
label="联系人姓名"
rules={[{ required: true, message: '请输入联系人姓名' }]}
label={intl.formatMessage({ id: 'register.foreign.contactsName' })}
rules={[{ required: true, message: intl.formatMessage({ id: 'register.foreign.contactsName.required' }) }]}
>
<Input placeholder="请输入联系人姓名" />
<Input placeholder={intl.formatMessage({ id: 'register.foreign.contactsName.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'contactsEmail']}
label="联系人邮箱"
label={intl.formatMessage({ id: 'register.foreign.contactsEmail' })}
rules={[
{ type: 'email', message: '请输入有效的电子邮箱' },
{ required: true, message: '请输入电子邮箱' },
{ type: 'email', message: intl.formatMessage({ id: 'register.email.invalid' }) },
{ required: true, message: intl.formatMessage({ id: 'register.foreign.contactsEmail.required' }) },
]}
>
<Input prefix={<MailOutlined />} placeholder="XXX@XXX.com" addonAfter={
<Input prefix={<MailOutlined />} placeholder={intl.formatMessage({ id: 'register.foreign.contactsEmail.placeholder' })} addonAfter={
<Button
type="link"
size="small"
disabled={countdown > 0}
onClick={handleGetCaptcha}
>
{countdown ? `${countdown}秒后重新获取` : '获取验证码'}
{countdown ? intl.formatMessage({ id: 'register.captcha.countdown' }, { count: countdown }) : intl.formatMessage({ id: 'register.captcha.get' })}
</Button>
} />
</Form.Item>
@ -182,26 +198,26 @@ const ForeignForm: React.FC<ForeignFormProps> = ({
<Col span={8}>
<Form.Item
name="verificationCode"
label="验证码"
label={intl.formatMessage({ id: 'register.captcha.label' })}
rules={[
{ required: true, message: '请输入验证码' },
{ pattern: /^\d{6}$/, message: '请输入6位数字验证码' },
{ required: true, message: intl.formatMessage({ id: 'register.captcha.required' }) },
{ pattern: /^\d{6}$/, message: intl.formatMessage({ id: 'register.captcha.pattern' }) },
]}
extra="该邮箱用于后续联系和找回密码"
extra={intl.formatMessage({ id: 'register.foreign.contactsEmail.extra' })}
>
<Input placeholder="请输入验证码" />
<Input placeholder={intl.formatMessage({ id: 'register.captcha.placeholder' })} />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item
name={['coscoSupplierBase', 'contactsPhone']}
label="联系电话"
label={intl.formatMessage({ id: 'register.foreign.contactsPhone' })}
rules={[
{ required: false, message: '请输入联系电话' }
{ required: false, message: intl.formatMessage({ id: 'register.foreign.contactsPhone.required' }) }
]}
>
<Input
placeholder="请输入联系电话"
placeholder={intl.formatMessage({ id: 'register.foreign.contactsPhone.placeholder' })}
prefix={<MobileOutlined />}
/>
</Form.Item>