Files
fe_supplier_frontend/src/pages/supplierEvaluateManage/supplierTaskManage/components/SupplierSelectStep.tsx
2025-06-23 21:39:51 +08:00

415 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
import { Card, Row, Col, Input, Select, Radio, Table, Button, Space, Pagination, Form } from 'antd';
import { SearchOutlined, ArrowRightOutlined } from '@ant-design/icons';
import styles from '../supplierTaskManageAdd.less';
const { Option } = Select;
interface SupplierSelectStepProps {
formData: any;
onFormDataChange: (data: any) => void;
}
interface SupplierItem {
key: string;
supplierName: string;
socialCreditCode: string;
category: string;
}
const SupplierSelectStep = forwardRef<any, SupplierSelectStepProps>(({ formData, onFormDataChange }, ref) => {
const [filterForm] = Form.useForm();
const [categoryKeyword, setCategoryKeyword] = useState<string>('');
const [selectedCategory, setSelectedCategory] = useState<string | undefined>(undefined);
const [hasPaymentLastYear, setHasPaymentLastYear] = useState<string>('是');
const [department, setDepartment] = useState<string | undefined>(undefined);
const [pendingSuppliers, setPendingSuppliers] = useState<SupplierItem[]>([]);
const [selectedSuppliers, setSelectedSuppliers] = useState<SupplierItem[]>([]);
const [pendingKeyword, setPendingKeyword] = useState<string>('');
const [selectedKeyword, setSelectedKeyword] = useState<string>('');
const [pendingSelectedRowKeys, setPendingSelectedRowKeys] = useState<React.Key[]>([]);
const [selectedSelectedRowKeys, setSelectedSelectedRowKeys] = useState<React.Key[]>([]);
// 暴露表单方法给父组件
useImperativeHandle(ref, () => ({
validateFields: () => {
// 这里可以添加自定义验证逻辑
return Promise.resolve();
},
getFieldsValue: () => {
return {
selectedSuppliers,
supplierIds: selectedSuppliers.map(supplier => ({ id: supplier.key }))
};
},
setFieldsValue: (values: any) => {
if (values.selectedSuppliers) {
setSelectedSuppliers(values.selectedSuppliers);
}
},
}));
// 初始化数据
useEffect(() => {
// 从formData中恢复已选供应商
if (formData.selectedSuppliers) {
setSelectedSuppliers(formData.selectedSuppliers);
}
// 初始化筛选表单
filterForm.setFieldsValue({
category: selectedCategory,
categoryKeyword: categoryKeyword,
categoryRange: undefined,
hasPaymentLastYear: hasPaymentLastYear,
department: department
});
// 模拟获取待选供应商列表
const mockPendingSuppliers: SupplierItem[] = [
{ key: '1', supplierName: '供应商A', socialCreditCode: '2425322525', category: '润滑油' },
{ key: '2', supplierName: '供应商B', socialCreditCode: '2425322525', category: '燃油' },
{ key: '3', supplierName: '供应商C', socialCreditCode: '2425322525', category: '备件' },
{ key: '4', supplierName: '供应商D', socialCreditCode: '2425322525', category: '润滑油' },
{ key: '5', supplierName: '供应商E', socialCreditCode: '2425322525', category: '燃油' },
{ key: '6', supplierName: '供应商F', socialCreditCode: '2425322525', category: '备件' },
{ key: '7', supplierName: '供应商G', socialCreditCode: '2425322525', category: '润滑油' },
{ key: '8', supplierName: '供应商H', socialCreditCode: '2425322525', category: '燃油' },
{ key: '9', supplierName: '供应商I', socialCreditCode: '2425322525', category: '备件' },
{ key: '10', supplierName: '供应商J', socialCreditCode: '2425322525', category: '计算机' },
];
// 模拟已选供应商列表
const mockSelectedSuppliers: SupplierItem[] = [
{ key: '11', supplierName: '供应商A', socialCreditCode: '4636373737', category: '润滑油' },
{ key: '12', supplierName: '供应商B', socialCreditCode: '4636373737', category: '燃油' },
{ key: '13', supplierName: '供应商C', socialCreditCode: '4636373737', category: '备件' },
{ key: '14', supplierName: '供应商D', socialCreditCode: '4636373737', category: '润滑油' },
{ key: '15', supplierName: '供应商E', socialCreditCode: '4636373737', category: '燃油' },
{ key: '16', supplierName: '供应商F', socialCreditCode: '4636373737', category: '备件' },
{ key: '17', supplierName: '供应商G', socialCreditCode: '4636373737', category: '润滑油' },
{ key: '18', supplierName: '供应商H', socialCreditCode: '4636373737', category: '燃油' },
{ key: '19', supplierName: '供应商I', socialCreditCode: '4636373737', category: '备件' },
{ key: '20', supplierName: '供应商J', socialCreditCode: '4636373737', category: '计算机' },
];
setPendingSuppliers(mockPendingSuppliers);
// 如果没有从formData中恢复则使用模拟数据
if (!formData.selectedSuppliers) {
setSelectedSuppliers(mockSelectedSuppliers);
}
}, [formData]);
// 更新表单数据
const updateFormData = (suppliers: SupplierItem[]) => {
onFormDataChange({
selectedSuppliers: suppliers,
supplierIds: suppliers.map(supplier => ({ id: supplier.key }))
});
};
// 处理筛选条件变化
const handleFilterChange = (changedValues: any, allValues: any) => {
if ('category' in changedValues) {
setSelectedCategory(changedValues.category);
}
if ('categoryKeyword' in changedValues) {
setCategoryKeyword(changedValues.categoryKeyword);
}
if ('hasPaymentLastYear' in changedValues) {
setHasPaymentLastYear(changedValues.hasPaymentLastYear);
}
if ('department' in changedValues) {
setDepartment(changedValues.department);
}
// 这里可以添加筛选逻辑,根据筛选条件更新待选供应商列表
};
// 处理添加供应商
const handleAddSuppliers = () => {
if (pendingSelectedRowKeys.length === 0) return;
// 找出选中的供应商
const suppliersToAdd = pendingSuppliers.filter(item =>
pendingSelectedRowKeys.includes(item.key)
);
// 更新已选供应商列表
const newSelectedSuppliers = [...selectedSuppliers, ...suppliersToAdd];
setSelectedSuppliers(newSelectedSuppliers);
// 从待选列表中移除
const newPendingSuppliers = pendingSuppliers.filter(item =>
!pendingSelectedRowKeys.includes(item.key)
);
setPendingSuppliers(newPendingSuppliers);
// 清空选中状态
setPendingSelectedRowKeys([]);
// 更新表单数据
updateFormData(newSelectedSuppliers);
};
// 处理移除供应商
const handleRemoveSuppliers = () => {
if (selectedSelectedRowKeys.length === 0) return;
// 找出选中的供应商
const suppliersToRemove = selectedSuppliers.filter(item =>
selectedSelectedRowKeys.includes(item.key)
);
// 更新待选供应商列表
const newPendingSuppliers = [...pendingSuppliers, ...suppliersToRemove];
setPendingSuppliers(newPendingSuppliers);
// 从已选列表中移除
const newSelectedSuppliers = selectedSuppliers.filter(item =>
!selectedSelectedRowKeys.includes(item.key)
);
setSelectedSuppliers(newSelectedSuppliers);
// 清空选中状态
setSelectedSelectedRowKeys([]);
// 更新表单数据
updateFormData(newSelectedSuppliers);
};
// 过滤待选供应商
const filteredPendingSuppliers = pendingSuppliers.filter(item => {
// 按关键词过滤
const matchKeyword = pendingKeyword ?
(item.supplierName.includes(pendingKeyword) ||
item.socialCreditCode.includes(pendingKeyword)) : true;
return matchKeyword;
});
// 过滤已选供应商
const filteredSelectedSuppliers = selectedSuppliers.filter(item => {
// 按关键词过滤
const matchKeyword = selectedKeyword ?
(item.supplierName.includes(selectedKeyword) ||
item.socialCreditCode.includes(selectedKeyword)) : true;
return matchKeyword;
});
// 表格列定义
const columns = [
{
title: '供应商名称',
dataIndex: 'supplierName',
key: 'supplierName',
},
{
title: '统一社会信用代码',
dataIndex: 'socialCreditCode',
key: 'socialCreditCode',
},
{
title: '准入品类',
dataIndex: 'category',
key: 'category',
}
];
// 待选表格行选择配置
const pendingRowSelection = {
selectedRowKeys: pendingSelectedRowKeys,
onChange: (selectedRowKeys: React.Key[]) => {
setPendingSelectedRowKeys(selectedRowKeys);
}
};
// 已选表格行选择配置
const selectedRowSelection = {
selectedRowKeys: selectedSelectedRowKeys,
onChange: (selectedRowKeys: React.Key[]) => {
setSelectedSelectedRowKeys(selectedRowKeys);
}
};
// 部门选项
const departmentOptions = [
{ value: '1', label: '采购部' },
{ value: '2', label: '技术部' },
{ value: '3', label: '质量部' },
{ value: '4', label: '生产部' },
];
// 类别选项
const categoryOptions = [
{ value: '润滑油', label: '润滑油' },
{ value: '燃油', label: '燃油' },
{ value: '备件', label: '备件' },
{ value: '计算机', label: '计算机' },
];
return (
<div className={styles.supplierSelectStep}>
<Card title="筛选条件" bordered={false} className="inner-card">
<Form
form={filterForm}
layout="horizontal"
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
onValuesChange={handleFilterChange}
>
<Row gutter={24}>
<Col span={8}>
<Form.Item label="选择类别" name="category">
<Select
placeholder="请选择"
allowClear
>
{categoryOptions.map(option => (
<Option key={option.value} value={option.value}>{option.label}</Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item label="品类关键字" name="categoryKeyword">
<Input placeholder="请输入" allowClear />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item label="品类范围" name="categoryRange">
<Input placeholder="请输入" allowClear />
</Form.Item>
</Col>
<Col span={8}>
<Form.Item label="近一年有付款" name="hasPaymentLastYear" initialValue="是">
<Radio.Group>
<Radio value="是"></Radio>
<Radio value="否"></Radio>
</Radio.Group>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item label="准入部门" name="department">
<Select
placeholder="请选择"
allowClear
>
{departmentOptions.map(option => (
<Option key={option.value} value={option.value}>{option.label}</Option>
))}
</Select>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item wrapperCol={{ offset: 6, span: 18 }}>
<Button type="primary" onClick={() => filterForm.submit()}>
</Button>
<Button style={{ marginLeft: 8 }} onClick={() => filterForm.resetFields()}>
</Button>
</Form.Item>
</Col>
</Row>
</Form>
</Card>
<Row gutter={24} style={{ marginTop: '16px' }}>
<Col span={11}>
<Card
title="待选列表"
bordered={false}
className="inner-card"
extra={<span>2/50</span>}
>
<div className="search-bar">
<Input
placeholder="输入关键词"
prefix={<SearchOutlined />}
value={pendingKeyword}
onChange={e => setPendingKeyword(e.target.value)}
allowClear
/>
</div>
<Table
rowSelection={pendingRowSelection}
columns={columns}
dataSource={filteredPendingSuppliers}
pagination={false}
size="middle"
rowKey="key"
/>
<div className="pagination-container">
<Pagination
size="small"
total={50}
current={1}
pageSize={10}
showSizeChanger={false}
/>
</div>
</Card>
</Col>
<Col span={2} style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<Space direction="vertical">
<Button
type="primary"
icon={<ArrowRightOutlined />}
onClick={handleAddSuppliers}
disabled={pendingSelectedRowKeys.length === 0}
/>
<Button
icon={<ArrowRightOutlined style={{ transform: 'rotate(180deg)' }} />}
onClick={handleRemoveSuppliers}
disabled={selectedSelectedRowKeys.length === 0}
/>
</Space>
</Col>
<Col span={11}>
<Card
title="已选列表"
bordered={false}
className="inner-card"
extra={<span>2/50</span>}
>
<div className="search-bar">
<Input
placeholder="输入关键词"
prefix={<SearchOutlined />}
value={selectedKeyword}
onChange={e => setSelectedKeyword(e.target.value)}
allowClear
/>
</div>
<Table
rowSelection={selectedRowSelection}
columns={columns}
dataSource={filteredSelectedSuppliers}
pagination={false}
size="middle"
rowKey="key"
/>
<div className="pagination-container">
<Pagination
size="small"
total={50}
current={1}
pageSize={10}
showSizeChanger={false}
/>
</div>
</Card>
</Col>
</Row>
</div>
);
});
export default SupplierSelectStep;