2025-06-16 21:05:23 +08:00
|
|
|
|
/**
|
|
|
|
|
* 供应商注册表单通用部分
|
|
|
|
|
* 封装了国内企业和境外企业注册表单相同的部分
|
|
|
|
|
*/
|
2025-06-16 19:33:33 +08:00
|
|
|
|
import React from 'react';
|
|
|
|
|
import {
|
2025-06-17 14:03:57 +08:00
|
|
|
|
Form,
|
|
|
|
|
Input,
|
|
|
|
|
Button,
|
|
|
|
|
Select,
|
|
|
|
|
Upload,
|
|
|
|
|
DatePicker,
|
|
|
|
|
Row,
|
|
|
|
|
Col,
|
|
|
|
|
Table,
|
|
|
|
|
Radio,
|
|
|
|
|
Cascader,
|
|
|
|
|
Empty,
|
|
|
|
|
} from 'antd';
|
|
|
|
|
import { UploadOutlined, PlusOutlined, DeleteOutlined } from '@ant-design/icons';
|
2025-06-16 19:33:33 +08:00
|
|
|
|
import { message } from 'antd';
|
2025-06-17 14:03:57 +08:00
|
|
|
|
import { validateFileSize } from '@/utils/utils';
|
2025-06-16 19:33:33 +08:00
|
|
|
|
|
|
|
|
|
const { Option } = Select;
|
|
|
|
|
|
|
|
|
|
// 中国省市区级联数据
|
2025-06-16 21:05:23 +08:00
|
|
|
|
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: '长宁区' },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
2025-06-16 21:05:23 +08:00
|
|
|
|
interface CommonFormSectionsProps {
|
2025-06-16 19:33:33 +08:00
|
|
|
|
form: any;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-17 14:03:57 +08:00
|
|
|
|
// 扩展问卷部分的属性接口
|
|
|
|
|
interface SurveySectionProps extends CommonFormSectionsProps {
|
|
|
|
|
surveyQuestions?: API.SurveyQuestionResponse;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-16 21:05:23 +08:00
|
|
|
|
/**
|
|
|
|
|
* 资质信息表单部分
|
|
|
|
|
* 包含资质证书类型、名称、编号、等级、发证机构、发证日期、有效期等
|
|
|
|
|
*/
|
|
|
|
|
export const QualificationSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
|
2025-06-16 19:33:33 +08:00
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<div className="form-section-title">资质信息</div>
|
|
|
|
|
|
2025-06-17 14:03:57 +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: '序号',
|
|
|
|
|
dataIndex: 'name',
|
|
|
|
|
width: 60,
|
|
|
|
|
render: (_, __, index) => index + 1,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '资质证书类型',
|
|
|
|
|
dataIndex: 'certType',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item
|
|
|
|
|
name={[record.name, 'certType']}
|
|
|
|
|
noStyle
|
|
|
|
|
rules={[{ required: true, message: '请选择资质证书类型' }]}
|
|
|
|
|
>
|
|
|
|
|
<Select placeholder="请选择类型" style={{ width: '100%' }}>
|
|
|
|
|
<Option value="机构资质">机构资质</Option>
|
|
|
|
|
<Option value="CMMI资质等级">CMMI资质等级</Option>
|
|
|
|
|
<Option value="质量体系认证">质量体系认证</Option>
|
|
|
|
|
<Option value="环境管理体系认证">环境管理体系认证</Option>
|
|
|
|
|
<Option value="行业资质">行业资质</Option>
|
|
|
|
|
</Select>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '资质名称',
|
|
|
|
|
dataIndex: 'certName',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item
|
|
|
|
|
name={[record.name, 'certName']}
|
|
|
|
|
noStyle
|
|
|
|
|
rules={[{ required: true, message: '请输入资质名称' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入资质名称" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '资质证书编号',
|
|
|
|
|
dataIndex: 'certNumber',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item
|
|
|
|
|
name={[record.name, 'certNumber']}
|
|
|
|
|
noStyle
|
|
|
|
|
rules={[{ required: true, message: '请输入资质证书编号' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入证书编号" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '资质类别和等级',
|
|
|
|
|
dataIndex: 'certLevel',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item name={[record.name, 'certLevel']} noStyle>
|
|
|
|
|
<Input placeholder="请输入资质类别和等级" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '发证机构',
|
|
|
|
|
dataIndex: 'issuingAuthority',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item
|
|
|
|
|
name={[record.name, 'issuingAuthority']}
|
|
|
|
|
noStyle
|
|
|
|
|
rules={[{ required: true, message: '请输入发证机构' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入发证机构" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '发证日期',
|
|
|
|
|
dataIndex: 'issueDate',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item
|
2025-06-17 14:03:57 +08:00
|
|
|
|
name={[record.name, 'dateTime']}
|
2025-06-16 19:33:33 +08:00
|
|
|
|
noStyle
|
|
|
|
|
rules={[{ required: true, message: '请选择发证日期' }]}
|
|
|
|
|
>
|
2025-06-17 14:03:57 +08:00
|
|
|
|
<DatePicker
|
|
|
|
|
placeholder="年/月/日"
|
|
|
|
|
style={{ width: '100%' }}
|
|
|
|
|
format="YYYY-MM-DD"
|
|
|
|
|
/>
|
2025-06-16 19:33:33 +08:00
|
|
|
|
</Form.Item>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '资质有效期至',
|
|
|
|
|
dataIndex: 'expiryDate',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item
|
2025-06-17 14:03:57 +08:00
|
|
|
|
name={[record.name, 'termOfValidity']}
|
2025-06-16 19:33:33 +08:00
|
|
|
|
noStyle
|
|
|
|
|
rules={[{ required: true, message: '请选择资质有效期' }]}
|
|
|
|
|
>
|
2025-06-17 14:03:57 +08:00
|
|
|
|
<DatePicker
|
|
|
|
|
placeholder="年/月/日"
|
|
|
|
|
style={{ width: '100%' }}
|
|
|
|
|
format="YYYY-MM-DD"
|
|
|
|
|
/>
|
2025-06-16 19:33:33 +08:00
|
|
|
|
</Form.Item>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '附件',
|
|
|
|
|
dataIndex: 'certFile',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item
|
|
|
|
|
name={[record.name, 'certFile']}
|
|
|
|
|
noStyle
|
|
|
|
|
rules={[{ required: true, message: '请上传资质证书附件' }]}
|
|
|
|
|
>
|
|
|
|
|
<Upload name="certFile" action="/api/upload" listType="text" maxCount={1}>
|
2025-06-17 14:03:57 +08:00
|
|
|
|
<Button type="link" size="small">
|
|
|
|
|
上传
|
|
|
|
|
</Button>
|
2025-06-16 19:33:33 +08:00
|
|
|
|
</Upload>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '操作',
|
|
|
|
|
width: 70,
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Button
|
|
|
|
|
type="link"
|
|
|
|
|
danger
|
|
|
|
|
icon={<DeleteOutlined />}
|
|
|
|
|
onClick={() => remove(record.name)}
|
|
|
|
|
>
|
|
|
|
|
删除
|
|
|
|
|
</Button>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
/>
|
|
|
|
|
<Form.Item style={{ marginTop: 16 }} wrapperCol={{ span: 24 }}>
|
|
|
|
|
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
|
|
|
|
|
添加行
|
|
|
|
|
</Button>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</Form.List>
|
2025-06-16 21:05:23 +08:00
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
2025-06-16 19:33:33 +08:00
|
|
|
|
|
2025-06-16 21:05:23 +08:00
|
|
|
|
/**
|
|
|
|
|
* 开票信息表单部分
|
|
|
|
|
* 包含纳税人类型、开票抬头、纳税人识别号、开票地址等
|
|
|
|
|
*/
|
|
|
|
|
export const InvoiceSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
|
|
|
|
|
return (
|
|
|
|
|
<>
|
2025-06-16 19:33:33 +08:00
|
|
|
|
<div className="form-section-title">开票信息</div>
|
|
|
|
|
|
|
|
|
|
<Row gutter={24}>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item
|
2025-06-17 14:03:57 +08:00
|
|
|
|
name={['coscoSupplierInvoice', 'taxpayerType']}
|
2025-06-16 19:33:33 +08:00
|
|
|
|
label="纳税人类型"
|
|
|
|
|
rules={[{ required: true, message: '请选择纳税人类型' }]}
|
|
|
|
|
>
|
|
|
|
|
<Select placeholder="请选择纳税人类型">
|
|
|
|
|
<Option value="general">一般纳税人</Option>
|
|
|
|
|
<Option value="small">小规模纳税人</Option>
|
|
|
|
|
</Select>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item
|
|
|
|
|
name="invoiceTitle"
|
|
|
|
|
label="开票抬头"
|
|
|
|
|
rules={[{ required: true, message: '请输入开票抬头' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入开票抬头" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item
|
|
|
|
|
name="taxpayerNumber"
|
|
|
|
|
label="纳税人识别号"
|
|
|
|
|
rules={[{ required: true, message: '请输入纳税人识别号' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入纳税人识别号" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item name="invoiceAddress" label="开票地址">
|
|
|
|
|
<Input placeholder="请输入开票地址" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item name="invoicePhone" label="开票电话">
|
|
|
|
|
<Input placeholder="请输入开票电话" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item name="invoiceBank" label="开票户行">
|
|
|
|
|
<Input placeholder="请输入开票银行" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item name="bankAccountNumber" label="开票户行账号">
|
|
|
|
|
<Input placeholder="请输入开票户行账号" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item name="generalTaxpayerCert" label="一般纳税人资格证明">
|
|
|
|
|
<Upload
|
|
|
|
|
name="generalTaxpayerCert"
|
|
|
|
|
action="/api/upload"
|
|
|
|
|
listType="text"
|
|
|
|
|
maxCount={1}
|
2025-06-17 14:03:57 +08:00
|
|
|
|
beforeUpload={(file) => validateFileSize(file, 10, ['pdf', 'jpg', 'jpeg', 'png'])}
|
2025-06-16 19:33:33 +08:00
|
|
|
|
>
|
|
|
|
|
<Button icon={<UploadOutlined />}>上传文件</Button>
|
|
|
|
|
</Upload>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
2025-06-16 21:05:23 +08:00
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
2025-06-16 19:33:33 +08:00
|
|
|
|
|
2025-06-16 21:05:23 +08:00
|
|
|
|
/**
|
|
|
|
|
* 银行账户表单部分
|
|
|
|
|
* 包含开户银行、账户名称、账号、所在地区等
|
|
|
|
|
*/
|
|
|
|
|
export const BankAccountSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
|
|
|
|
|
return (
|
|
|
|
|
<>
|
2025-06-16 19:33:33 +08:00
|
|
|
|
<div className="form-section-title">银行账户</div>
|
|
|
|
|
|
2025-06-17 14:03:57 +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: '序号',
|
|
|
|
|
dataIndex: 'name',
|
|
|
|
|
width: 60,
|
|
|
|
|
render: (_, __, index) => index + 1,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '开户银行',
|
|
|
|
|
dataIndex: 'bankName',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item
|
|
|
|
|
name={[record.name, 'bankName']}
|
|
|
|
|
noStyle
|
|
|
|
|
rules={[{ required: true, message: '请输入开户银行' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入开户银行" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '账户名称',
|
|
|
|
|
dataIndex: 'accountName',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item
|
|
|
|
|
name={[record.name, 'accountName']}
|
|
|
|
|
noStyle
|
|
|
|
|
rules={[{ required: true, message: '请输入账户名称' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入账户名称" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '账号',
|
|
|
|
|
dataIndex: 'accountNumber',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item
|
|
|
|
|
name={[record.name, 'accountNumber']}
|
|
|
|
|
noStyle
|
|
|
|
|
rules={[{ required: true, message: '请输入账号' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入账号" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '国家、省、市',
|
|
|
|
|
dataIndex: 'location',
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Form.Item
|
|
|
|
|
name={[record.name, 'address']}
|
|
|
|
|
noStyle
|
|
|
|
|
rules={[{ required: true, message: '请选择地址' }]}
|
|
|
|
|
>
|
|
|
|
|
<Cascader
|
|
|
|
|
options={addressOptions}
|
|
|
|
|
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: '操作',
|
|
|
|
|
width: 70,
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
<Button
|
|
|
|
|
type="link"
|
|
|
|
|
danger
|
|
|
|
|
icon={<DeleteOutlined />}
|
|
|
|
|
onClick={() => remove(record.name)}
|
|
|
|
|
>
|
|
|
|
|
删除
|
|
|
|
|
</Button>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
/>
|
|
|
|
|
<Form.Item style={{ marginTop: 16 }} wrapperCol={{ span: 24 }}>
|
|
|
|
|
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
|
|
|
|
|
添加行
|
|
|
|
|
</Button>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</Form.List>
|
2025-06-16 21:05:23 +08:00
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
2025-06-16 19:33:33 +08:00
|
|
|
|
|
2025-06-16 21:05:23 +08:00
|
|
|
|
/**
|
|
|
|
|
* 社会准则符合性自查问卷部分
|
|
|
|
|
* 包含填写人信息和问卷内容
|
|
|
|
|
*/
|
2025-06-17 14:03:57 +08:00
|
|
|
|
export const SurveySection: React.FC<SurveySectionProps> = ({ form, surveyQuestions }) => {
|
|
|
|
|
// 使用API获取的问卷数据,如果没有则显示无数据状态
|
|
|
|
|
const hasQuestions = surveyQuestions && surveyQuestions.length > 0;
|
|
|
|
|
|
2025-06-16 21:05:23 +08:00
|
|
|
|
return (
|
|
|
|
|
<>
|
2025-06-16 19:33:33 +08:00
|
|
|
|
<div className="form-section-title">社会准则符合性自查问卷</div>
|
|
|
|
|
|
|
|
|
|
<div className="questionnaire-header">填写人信息:</div>
|
|
|
|
|
<Row gutter={24}>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item
|
2025-06-17 14:03:57 +08:00
|
|
|
|
name={['coscoSupplierSurvey', 'supplierName']}
|
2025-06-16 19:33:33 +08:00
|
|
|
|
label="供应商名称"
|
|
|
|
|
rules={[{ required: true, message: '请输入供应商名称' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入供应商名称" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item
|
2025-06-17 14:03:57 +08:00
|
|
|
|
name={['coscoSupplierSurvey', 'name']}
|
2025-06-16 19:33:33 +08:00
|
|
|
|
label="姓名"
|
|
|
|
|
rules={[{ required: true, message: '请输入姓名' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入姓名" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item
|
2025-06-17 14:03:57 +08:00
|
|
|
|
name={['coscoSupplierSurvey', 'position']}
|
2025-06-16 19:33:33 +08:00
|
|
|
|
label="职位"
|
|
|
|
|
rules={[{ required: true, message: '请输入职位' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入职位" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item
|
2025-06-17 14:03:57 +08:00
|
|
|
|
name={['coscoSupplierSurvey', 'phone']}
|
2025-06-16 19:33:33 +08:00
|
|
|
|
label="电话号"
|
|
|
|
|
rules={[{ required: true, message: '请输入电话号' }]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入电话号" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item
|
2025-06-17 14:03:57 +08:00
|
|
|
|
name={['coscoSupplierSurvey', 'email']}
|
2025-06-16 19:33:33 +08:00
|
|
|
|
label="邮箱"
|
|
|
|
|
rules={[
|
|
|
|
|
{ type: 'email', message: '请输入有效的电子邮箱' },
|
|
|
|
|
{ required: true, message: '请输入电子邮箱' },
|
|
|
|
|
]}
|
|
|
|
|
>
|
|
|
|
|
<Input placeholder="请输入电子邮箱" />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Col>
|
|
|
|
|
<Col span={8}>
|
|
|
|
|
<Form.Item
|
2025-06-17 14:03:57 +08:00
|
|
|
|
name={['coscoSupplierSurvey', 'dateTime']}
|
2025-06-16 19:33:33 +08:00
|
|
|
|
label="日期"
|
|
|
|
|
rules={[{ required: true, message: '请选择日期' }]}
|
|
|
|
|
>
|
2025-06-17 14:03:57 +08:00
|
|
|
|
<DatePicker 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' }}>
|
|
|
|
|
问卷:
|
|
|
|
|
</div>
|
2025-06-17 14:03:57 +08:00
|
|
|
|
|
|
|
|
|
{hasQuestions ? (
|
|
|
|
|
<Form.List name="coscoSupplierSurveyQuestionReply">
|
|
|
|
|
{(fields, { add, remove }) => {
|
|
|
|
|
// 确保有足够的表单项对应每个问题
|
|
|
|
|
if (fields.length < surveyQuestions.length) {
|
|
|
|
|
const diff = surveyQuestions.length - fields.length;
|
|
|
|
|
for (let i = 0; i < diff; i++) {
|
|
|
|
|
add();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Table
|
|
|
|
|
pagination={false}
|
|
|
|
|
bordered
|
|
|
|
|
size="middle"
|
|
|
|
|
rowKey="id"
|
|
|
|
|
dataSource={surveyQuestions}
|
|
|
|
|
columns={[
|
|
|
|
|
{
|
|
|
|
|
title: '序号',
|
|
|
|
|
dataIndex: 'id',
|
|
|
|
|
width: 60,
|
|
|
|
|
align: 'center',
|
|
|
|
|
render: (text, record, index) => index + 1,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '问题',
|
|
|
|
|
dataIndex: 'questionName',
|
|
|
|
|
render: (text) => <div style={{ whiteSpace: 'pre-line' }}>{text}</div>,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
title: '回复',
|
|
|
|
|
width: 650,
|
|
|
|
|
render: (_, record, index) => (
|
|
|
|
|
<>
|
|
|
|
|
<Form.Item
|
|
|
|
|
name={[index, 'surveyQuestionId']}
|
|
|
|
|
initialValue={record.id}
|
|
|
|
|
hidden
|
|
|
|
|
>
|
|
|
|
|
<Input />
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item
|
|
|
|
|
name={[index, 'replyValue']}
|
|
|
|
|
rules={[{ required: true, message: '请选择答案' }]}
|
|
|
|
|
wrapperCol={{ span: 24 }}
|
|
|
|
|
>
|
|
|
|
|
<Radio.Group>
|
|
|
|
|
{record.coscoSurveyQuestionOptionList?.map((option: any) => (
|
|
|
|
|
<Radio key={option.id} value={option.opentionValue}>
|
|
|
|
|
{option.optionName}
|
|
|
|
|
</Radio>
|
|
|
|
|
))}
|
|
|
|
|
</Radio.Group>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}}
|
|
|
|
|
</Form.List>
|
|
|
|
|
) : (
|
|
|
|
|
<div style={{ padding: '30px 0' }}>
|
|
|
|
|
<Empty description="暂无问卷数据" image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2025-06-16 21:05:23 +08:00
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|
2025-06-16 19:33:33 +08:00
|
|
|
|
|
2025-06-16 21:05:23 +08:00
|
|
|
|
/**
|
|
|
|
|
* 供应商反商业贿赂承诺书和其他附件部分
|
|
|
|
|
*/
|
|
|
|
|
export const AttachmentSection: React.FC<CommonFormSectionsProps> = ({ form }) => {
|
|
|
|
|
return (
|
|
|
|
|
<>
|
2025-06-16 19:33:33 +08:00
|
|
|
|
<div className="form-section-title">供应商反商业贿赂承诺书</div>
|
|
|
|
|
<Row gutter={24}>
|
|
|
|
|
<Col span={12}>
|
|
|
|
|
<div className="upload-label">
|
|
|
|
|
请加盖公司公章后上传
|
|
|
|
|
<Button
|
|
|
|
|
type="link"
|
|
|
|
|
href="/templates/anti-bribery-template.docx"
|
|
|
|
|
download="供应商反商业贿赂承诺书模板.docx"
|
|
|
|
|
>
|
|
|
|
|
下载模版
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
2025-06-17 14:03:57 +08:00
|
|
|
|
|
|
|
|
|
<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: '请上传已盖章的反商业贿赂承诺书' }]}
|
|
|
|
|
>
|
|
|
|
|
<Upload
|
|
|
|
|
name="file"
|
|
|
|
|
action="/api/upload"
|
|
|
|
|
listType="text"
|
|
|
|
|
maxCount={1}
|
|
|
|
|
beforeUpload={(file) =>
|
|
|
|
|
validateFileSize(file, 10, ['pdf', 'doc', 'docx'])
|
|
|
|
|
}
|
|
|
|
|
onChange={(info) => {
|
|
|
|
|
if (info.file.status === 'done') {
|
|
|
|
|
const response = info.file.response;
|
|
|
|
|
if (response && response.success) {
|
|
|
|
|
// 填充文件信息
|
|
|
|
|
form.setFieldsValue({
|
|
|
|
|
coscoSupplierSurveyAttachments: [
|
|
|
|
|
{
|
|
|
|
|
...form.getFieldValue([
|
|
|
|
|
'coscoSupplierSurveyAttachments',
|
|
|
|
|
field.name,
|
|
|
|
|
]),
|
|
|
|
|
fileName: info.file.name,
|
|
|
|
|
fileType: info.file.type,
|
|
|
|
|
fileSize: info.file.size.toString(),
|
|
|
|
|
filePath: response.filePath || response.url,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
message.success(`${info.file.name} 上传成功`);
|
|
|
|
|
} else {
|
|
|
|
|
message.error(`${info.file.name} 上传失败`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Button icon={<UploadOutlined />}>上传文件</Button>
|
|
|
|
|
</Upload>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}}
|
|
|
|
|
</Form.List>
|
2025-06-16 19:33:33 +08:00
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
<div className="form-section-title">其他附件</div>
|
|
|
|
|
<Row gutter={24}>
|
|
|
|
|
<Col span={24}>
|
2025-06-17 14:03:57 +08:00
|
|
|
|
<Form.List name="coscoSupplierSurveyAttachments">
|
|
|
|
|
{(fields, { add, remove }) => (
|
|
|
|
|
<>
|
|
|
|
|
<div className="upload-label">其他附件(非必须上传)</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']}>
|
|
|
|
|
<Upload
|
|
|
|
|
name="file"
|
|
|
|
|
action="/api/upload"
|
|
|
|
|
listType="text"
|
|
|
|
|
maxCount={1}
|
|
|
|
|
beforeUpload={(file) => validateFileSize(file, 20, ['*'])}
|
|
|
|
|
onChange={(info) => {
|
|
|
|
|
if (info.file.status === 'done') {
|
|
|
|
|
const response = info.file.response;
|
|
|
|
|
if (response && response.success) {
|
|
|
|
|
// 填充文件信息
|
|
|
|
|
const fieldValue = form.getFieldValue([
|
|
|
|
|
'coscoSupplierSurveyAttachments',
|
|
|
|
|
field.name,
|
|
|
|
|
]);
|
|
|
|
|
form.setFieldsValue({
|
|
|
|
|
coscoSupplierSurveyAttachments: [
|
|
|
|
|
{
|
|
|
|
|
...fieldValue,
|
|
|
|
|
fileName: info.file.name,
|
|
|
|
|
fileType: info.file.type,
|
|
|
|
|
fileSize: info.file.size.toString(),
|
|
|
|
|
filePath: response.filePath || response.url,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
});
|
|
|
|
|
message.success(`${info.file.name} 上传成功`);
|
|
|
|
|
} else {
|
|
|
|
|
message.error(`${info.file.name} 上传失败`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<Button icon={<UploadOutlined />}>上传</Button>
|
|
|
|
|
</Upload>
|
|
|
|
|
</Form.Item>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
type="dashed"
|
|
|
|
|
onClick={() => add({ attachmentsType: 'accessory' })}
|
|
|
|
|
icon={<PlusOutlined />}
|
|
|
|
|
style={{ marginTop: 8 }}
|
|
|
|
|
>
|
|
|
|
|
添加更多附件
|
|
|
|
|
</Button>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</Form.List>
|
2025-06-16 19:33:33 +08:00
|
|
|
|
</Col>
|
|
|
|
|
</Row>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|