开发对接供应商评价管理
This commit is contained in:
@ -0,0 +1,249 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Form, Input, Select, DatePicker, Row, Col, Card } from 'antd';
|
||||
import moment from 'moment';
|
||||
import CategorySelector from '@/components/CategorySelector';
|
||||
import styles from '../supplierTaskManageAdd.less';
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
interface BasicInfoStepProps {
|
||||
formData: any;
|
||||
onFormDataChange: (data: any) => void;
|
||||
}
|
||||
|
||||
interface TemplateItem {
|
||||
id: string;
|
||||
templateName: string;
|
||||
isUnlimitedCategory?: boolean;
|
||||
}
|
||||
|
||||
const BasicInfoStep: React.FC<BasicInfoStepProps> = ({ formData, onFormDataChange }) => {
|
||||
const [form] = Form.useForm();
|
||||
const [templates, setTemplates] = useState<TemplateItem[]>([]);
|
||||
const [categoryTemplates, setCategoryTemplates] = useState<any[]>([]);
|
||||
const [selectedCategoryId, setSelectedCategoryId] = useState<string | undefined>(undefined);
|
||||
|
||||
// 获取评价模板和初始化表单数据
|
||||
useEffect(() => {
|
||||
// 模拟API调用获取模板列表
|
||||
const mockTemplates = [
|
||||
{ id: '1', templateName: '不限品类', isUnlimitedCategory: true },
|
||||
{ id: '2', templateName: '按品类', isUnlimitedCategory: false },
|
||||
];
|
||||
setTemplates(mockTemplates);
|
||||
|
||||
// 初始化表单数据
|
||||
if (formData) {
|
||||
const initialValues = {
|
||||
...formData,
|
||||
evaluateStartTime: formData.evaluateStartTime ? moment(formData.evaluateStartTime) : undefined,
|
||||
evaluateEndTime: formData.evaluateEndTime ? moment(formData.evaluateEndTime) : undefined,
|
||||
};
|
||||
form.setFieldsValue(initialValues);
|
||||
|
||||
// 设置已选品类
|
||||
if (formData.categoryId) {
|
||||
setSelectedCategoryId(formData.categoryId);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 获取品类对应的模板数据
|
||||
useEffect(() => {
|
||||
if (selectedCategoryId) {
|
||||
// 模拟API调用,根据品类ID获取对应的模板列表
|
||||
const mockCategoryTemplates = [
|
||||
{ id: 'ct1', templateName: '硬件设备评价模板' },
|
||||
{ id: 'ct2', templateName: '备件评价模板' },
|
||||
{ id: 'ct3', templateName: '通用备件评价模板' },
|
||||
];
|
||||
setCategoryTemplates(mockCategoryTemplates);
|
||||
} else {
|
||||
setCategoryTemplates([]);
|
||||
}
|
||||
}, [selectedCategoryId]);
|
||||
|
||||
// 检查当前选择的模板是否限制品类
|
||||
const isTemplateUnlimitedCategory = () => {
|
||||
const templateId = form.getFieldValue('templateId');
|
||||
const currentTemplate = templates.find(t => t.id === templateId);
|
||||
return currentTemplate?.isUnlimitedCategory;
|
||||
};
|
||||
|
||||
// 表单值变化时触发
|
||||
const handleValuesChange = (changedValues: any, allValues: any) => {
|
||||
// 处理模板变更
|
||||
if (changedValues.templateId) {
|
||||
// 如果选择了不限品类的模板,清空品类选择和品类模板选择
|
||||
if (isTemplateUnlimitedCategory()) {
|
||||
form.setFieldsValue({
|
||||
categoryId: undefined,
|
||||
categoryTemplateId: undefined
|
||||
});
|
||||
setSelectedCategoryId(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理品类变更
|
||||
if (changedValues.categoryId) {
|
||||
setSelectedCategoryId(changedValues.categoryId?.[0]);
|
||||
form.setFieldsValue({ categoryTemplateId: undefined });
|
||||
}
|
||||
|
||||
// 将moment对象转换为字符串再传递
|
||||
const formattedValues = {
|
||||
...allValues,
|
||||
evaluateStartTime: allValues.evaluateStartTime?.format('YYYY-MM-DD'),
|
||||
evaluateEndTime: allValues.evaluateEndTime?.format('YYYY-MM-DD'),
|
||||
};
|
||||
onFormDataChange(formattedValues);
|
||||
};
|
||||
|
||||
// 年度选项生成
|
||||
const yearOptions = () => {
|
||||
const currentYear = new Date().getFullYear();
|
||||
return Array.from({ length: 11 }, (_, i) => currentYear - 5 + i).map(year => (
|
||||
<Option key={year} value={year.toString()}>{year}</Option>
|
||||
));
|
||||
};
|
||||
|
||||
// 判断是否显示品类选择器
|
||||
const shouldShowCategorySelector = () => {
|
||||
const templateId = form.getFieldValue('templateId');
|
||||
if (!templateId) return false;
|
||||
|
||||
const currentTemplate = templates.find(t => t.id === templateId);
|
||||
return currentTemplate && !currentTemplate.isUnlimitedCategory;
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.basicInfoStep}>
|
||||
<Card title="基本信息" bordered={false} className="inner-card">
|
||||
<Form
|
||||
form={form}
|
||||
layout="vertical"
|
||||
onValuesChange={handleValuesChange}
|
||||
initialValues={formData}
|
||||
>
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="评价主题"
|
||||
name="evaluateTheme"
|
||||
rules={[{ required: true, message: '请输入评价主题' }]}
|
||||
>
|
||||
<Input placeholder="请输入" maxLength={50} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="评价年度"
|
||||
name="evaluateYear"
|
||||
rules={[{ required: true, message: '请选择评价年度' }]}
|
||||
>
|
||||
<Select placeholder="2025" style={{ width: '100%' }}>
|
||||
{yearOptions()}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="评价开始时间"
|
||||
name="evaluateStartTime"
|
||||
rules={[{ required: true, message: '请选择评价开始时间' }]}
|
||||
>
|
||||
<DatePicker
|
||||
style={{ width: '100%' }}
|
||||
format="YYYY-MM-DD"
|
||||
placeholder="年/月/日"
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="评价结束时间"
|
||||
name="evaluateEndTime"
|
||||
rules={[{ required: true, message: '请选择评价结束时间' }]}
|
||||
>
|
||||
<DatePicker
|
||||
style={{ width: '100%' }}
|
||||
format="YYYY-MM-DD"
|
||||
placeholder="年/月/日"
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row gutter={24} align="middle">
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="适用评价模板"
|
||||
name="templateId"
|
||||
rules={[{ required: true, message: '请选择适用评价模板' }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择"
|
||||
style={{ width: '100%' }}
|
||||
allowClear
|
||||
>
|
||||
{templates.map(template => (
|
||||
<Option key={template.id} value={template.id}>
|
||||
{template.templateName}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
{shouldShowCategorySelector() && (
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="选择品类"
|
||||
name="categoryId"
|
||||
rules={[{ required: true, message: '请选择品类' }]}
|
||||
>
|
||||
<CategorySelector
|
||||
onChange={(values: string[]) => {
|
||||
const categoryId = values?.[0];
|
||||
setSelectedCategoryId(categoryId);
|
||||
|
||||
if (!categoryId) {
|
||||
form.setFieldsValue({ categoryTemplateId: undefined });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
)}
|
||||
</Row>
|
||||
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
label="选择模板"
|
||||
name="categoryTemplateId"
|
||||
rules={[{ required: true, message: '请选择模板' }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择"
|
||||
style={{ width: '100%' }}
|
||||
allowClear
|
||||
>
|
||||
{categoryTemplates.map(template => (
|
||||
<Option key={template.id} value={template.id}>
|
||||
{template.templateName}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BasicInfoStep;
|
@ -0,0 +1,373 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Card, Button, Table, Space, Modal, Tag, Tooltip, Input, Form, InputNumber } from 'antd';
|
||||
import { UserOutlined, SettingOutlined } from '@ant-design/icons';
|
||||
import styles from '../supplierTaskManageAdd.less';
|
||||
import EvaluateTaskPersonnelSelector, { PersonnelItem } from '@/components/EvaluateTaskPersonnelSelector/EvaluateTaskPersonnelSelector';
|
||||
|
||||
interface EvaluatorSelectStepProps {
|
||||
formData: any;
|
||||
onFormDataChange: (data: any) => void;
|
||||
}
|
||||
|
||||
interface SupplierItem {
|
||||
key: string;
|
||||
supplierName: string;
|
||||
socialCreditCode: string;
|
||||
category: string;
|
||||
department: string;
|
||||
evaluatorCount: number;
|
||||
evaluators?: PersonnelItem[];
|
||||
}
|
||||
|
||||
interface WeightUnit {
|
||||
id: string;
|
||||
name: string;
|
||||
weight: number;
|
||||
}
|
||||
|
||||
const EvaluatorSelectStep: React.FC<EvaluatorSelectStepProps> = ({ formData, onFormDataChange }) => {
|
||||
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
||||
const [suppliers, setSuppliers] = useState<SupplierItem[]>([]);
|
||||
const [batchSelectModalVisible, setBatchSelectModalVisible] = useState(false);
|
||||
const [weightSettingModalVisible, setWeightSettingModalVisible] = useState(false);
|
||||
const [evaluatorModalVisible, setEvaluatorModalVisible] = useState(false);
|
||||
const [currentSupplier, setCurrentSupplier] = useState<SupplierItem | null>(null);
|
||||
const [weightUnits, setWeightUnits] = useState<WeightUnit[]>([
|
||||
{ id: '1', name: '集运', weight: 0 },
|
||||
{ id: '2', name: '散运', weight: 0 },
|
||||
{ id: '3', name: '能源', weight: 0 },
|
||||
{ id: '4', name: '特运', weight: 0 },
|
||||
{ id: '5', name: '化运', weight: 0 },
|
||||
]);
|
||||
const [form] = Form.useForm();
|
||||
|
||||
// 从上一步获取供应商数据
|
||||
useEffect(() => {
|
||||
if (formData.selectedSuppliers) {
|
||||
// 转换上一步的供应商数据,添加评价人员数量字段
|
||||
const suppliersWithEvaluators = formData.selectedSuppliers.map((supplier: any) => ({
|
||||
...supplier,
|
||||
department: supplier.department || '采购部', // 假设部门数据,实际应该从上一步获取
|
||||
evaluatorCount: supplier.evaluators?.length || 0,
|
||||
}));
|
||||
setSuppliers(suppliersWithEvaluators);
|
||||
} else {
|
||||
// 如果没有从上一步获取到数据,使用模拟数据
|
||||
const mockSuppliers: SupplierItem[] = [
|
||||
{ key: '1', supplierName: '供应商A', socialCreditCode: '123456789012345678', category: '润滑油', department: '采购部', evaluatorCount: 2, evaluators: [
|
||||
{ id: '1', name: '张三', department: '采购部' },
|
||||
{ id: '2', name: '李四', department: '技术部' }
|
||||
] },
|
||||
{ key: '2', supplierName: '供应商B', socialCreditCode: '123456789012345679', category: '燃油', department: '技术部', evaluatorCount: 0 },
|
||||
{ key: '3', supplierName: '供应商C', socialCreditCode: '123456789012345680', category: '备件', department: '质量部', evaluatorCount: 1, evaluators: [
|
||||
{ id: '3', name: '王五', department: '质量部' }
|
||||
] },
|
||||
{ key: '4', supplierName: '供应商D', socialCreditCode: '123456789012345681', category: '计算机', department: '生产部', evaluatorCount: 0 },
|
||||
];
|
||||
setSuppliers(mockSuppliers);
|
||||
}
|
||||
|
||||
// 初始化权重数据(如果有)
|
||||
if (formData.weightUnits) {
|
||||
setWeightUnits(formData.weightUnits);
|
||||
}
|
||||
}, [formData]);
|
||||
|
||||
// 更新表单数据
|
||||
const updateFormData = (updatedData: any) => {
|
||||
onFormDataChange({
|
||||
...formData,
|
||||
...updatedData
|
||||
});
|
||||
};
|
||||
|
||||
// 处理批量选择
|
||||
const handleBatchSelect = () => {
|
||||
if (selectedRowKeys.length === 0) return;
|
||||
setBatchSelectModalVisible(true);
|
||||
};
|
||||
|
||||
// 处理设置评分单位权重
|
||||
const handleWeightSetting = () => {
|
||||
// 设置初始表单值
|
||||
form.setFieldsValue({
|
||||
weightUnits: weightUnits.reduce((acc, unit) => {
|
||||
acc[unit.id] = unit.weight;
|
||||
return acc;
|
||||
}, {} as Record<string, number>)
|
||||
});
|
||||
|
||||
setWeightSettingModalVisible(true);
|
||||
};
|
||||
|
||||
// 保存权重设置
|
||||
const handleSaveWeights = () => {
|
||||
form.validateFields().then(values => {
|
||||
const updatedWeightUnits = weightUnits.map(unit => ({
|
||||
...unit,
|
||||
weight: values.weightUnits[unit.id]
|
||||
}));
|
||||
|
||||
setWeightUnits(updatedWeightUnits);
|
||||
updateFormData({ weightUnits: updatedWeightUnits });
|
||||
setWeightSettingModalVisible(false);
|
||||
});
|
||||
};
|
||||
|
||||
// 处理选择评价人员
|
||||
const handleSelectEvaluators = (supplier: SupplierItem) => {
|
||||
setCurrentSupplier(supplier);
|
||||
setEvaluatorModalVisible(true);
|
||||
};
|
||||
|
||||
// 处理评价人员选择确认
|
||||
const handleEvaluatorSelect = (selectedEvaluators: PersonnelItem[]) => {
|
||||
if (!currentSupplier) return;
|
||||
|
||||
const updatedSuppliers = suppliers.map(supplier => {
|
||||
if (supplier.key === currentSupplier.key) {
|
||||
return {
|
||||
...supplier,
|
||||
evaluators: selectedEvaluators,
|
||||
evaluatorCount: selectedEvaluators.length
|
||||
};
|
||||
}
|
||||
return supplier;
|
||||
});
|
||||
|
||||
setSuppliers(updatedSuppliers);
|
||||
updateFormData({ suppliersWithEvaluators: updatedSuppliers });
|
||||
setEvaluatorModalVisible(false);
|
||||
};
|
||||
|
||||
// 处理批量选择评价人员确认
|
||||
const handleBatchEvaluatorSelect = (selectedEvaluators: PersonnelItem[]) => {
|
||||
if (selectedRowKeys.length === 0) return;
|
||||
|
||||
const updatedSuppliers = suppliers.map(supplier => {
|
||||
if (selectedRowKeys.includes(supplier.key)) {
|
||||
return {
|
||||
...supplier,
|
||||
evaluators: selectedEvaluators,
|
||||
evaluatorCount: selectedEvaluators.length
|
||||
};
|
||||
}
|
||||
return supplier;
|
||||
});
|
||||
|
||||
setSuppliers(updatedSuppliers);
|
||||
updateFormData({ suppliersWithEvaluators: updatedSuppliers });
|
||||
setBatchSelectModalVisible(false);
|
||||
};
|
||||
|
||||
// 处理删除供应商
|
||||
const handleDeleteSupplier = (key: string) => {
|
||||
const updatedSuppliers = suppliers.filter(item => item.key !== key);
|
||||
setSuppliers(updatedSuppliers);
|
||||
updateFormData({ suppliersWithEvaluators: updatedSuppliers });
|
||||
};
|
||||
|
||||
// 删除确认对话框
|
||||
const showDeleteConfirm = (record: SupplierItem) => {
|
||||
Modal.confirm({
|
||||
title: '确定要删除此供应商吗?',
|
||||
content: `供应商: ${record.supplierName}`,
|
||||
okText: '确定',
|
||||
okType: 'danger',
|
||||
cancelText: '取消',
|
||||
onOk: () => handleDeleteSupplier(record.key),
|
||||
});
|
||||
};
|
||||
|
||||
// 表格行选择配置
|
||||
const rowSelection = {
|
||||
selectedRowKeys,
|
||||
onChange: (keys: React.Key[]) => {
|
||||
setSelectedRowKeys(keys);
|
||||
}
|
||||
};
|
||||
|
||||
// 表格列定义
|
||||
const columns = [
|
||||
{
|
||||
title: '供应商名称',
|
||||
dataIndex: 'supplierName',
|
||||
key: 'supplierName',
|
||||
},
|
||||
{
|
||||
title: '统一社会信用代码',
|
||||
dataIndex: 'socialCreditCode',
|
||||
key: 'socialCreditCode',
|
||||
},
|
||||
{
|
||||
title: '品类',
|
||||
dataIndex: 'category',
|
||||
key: 'category',
|
||||
render: (text: string) => <Tag color="blue">{text}</Tag>,
|
||||
},
|
||||
{
|
||||
title: '准入部门',
|
||||
dataIndex: 'department',
|
||||
key: 'department',
|
||||
},
|
||||
{
|
||||
title: '评价人员数',
|
||||
dataIndex: 'evaluatorCount',
|
||||
key: 'evaluatorCount',
|
||||
render: (count: number) => (
|
||||
<span style={{ color: count === 0 ? 'red' : 'inherit' }}>
|
||||
{count}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
render: (_: any, record: SupplierItem) => (
|
||||
<>
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => handleSelectEvaluators(record)}
|
||||
>
|
||||
选择评价人员
|
||||
</Button>
|
||||
|
||||
{record.evaluatorCount > 0 && (
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => handleSelectEvaluators(record)}
|
||||
>
|
||||
查看
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<Button
|
||||
type="link"
|
||||
onClick={() => showDeleteConfirm(record)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
// 权重表格列定义
|
||||
const weightColumns = [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
width: 80,
|
||||
render: (_: string, __: any, index: number) => index + 1
|
||||
},
|
||||
{
|
||||
title: '评价单位',
|
||||
dataIndex: 'name',
|
||||
key: 'name'
|
||||
},
|
||||
{
|
||||
title: <span style={{ color: 'red' }}>*权重 (%)</span>,
|
||||
dataIndex: 'weight',
|
||||
key: 'weight',
|
||||
render: (_: number, record: WeightUnit) => (
|
||||
<Form.Item
|
||||
name={['weightUnits', record.id]}
|
||||
rules={[
|
||||
{ required: true, message: '请输入权重' },
|
||||
{ type: 'number', min: 0, max: 100, message: '权重范围为0-100' },
|
||||
]}
|
||||
style={{ margin: 0 }}
|
||||
>
|
||||
<InputNumber min={0} max={100} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className={styles.evaluatorSelectStep}>
|
||||
<div className={styles.toolBar}>
|
||||
<Space>
|
||||
{selectedRowKeys.length > 0 && (
|
||||
<Button
|
||||
type="primary"
|
||||
icon={<UserOutlined />}
|
||||
onClick={handleBatchSelect}
|
||||
>
|
||||
批量选择
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
icon={<SettingOutlined />}
|
||||
onClick={handleWeightSetting}
|
||||
>
|
||||
设置评分单位权重
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
|
||||
<Card title="已选供应商列表" bordered={false} className="inner-card">
|
||||
<Table
|
||||
rowSelection={rowSelection}
|
||||
columns={columns}
|
||||
dataSource={suppliers}
|
||||
pagination={false}
|
||||
size="middle"
|
||||
rowKey="key"
|
||||
/>
|
||||
</Card>
|
||||
|
||||
{/* 批量选择模态框 */}
|
||||
<Modal
|
||||
title="批量选择评价人员"
|
||||
visible={batchSelectModalVisible}
|
||||
footer={null}
|
||||
onCancel={() => setBatchSelectModalVisible(false)}
|
||||
width={800}
|
||||
destroyOnClose
|
||||
>
|
||||
<EvaluateTaskPersonnelSelector
|
||||
onSelect={handleBatchEvaluatorSelect}
|
||||
selectedPersonnel={currentSupplier?.evaluators}
|
||||
/>
|
||||
</Modal>
|
||||
|
||||
{/* 设置评分单位权重模态框 */}
|
||||
<Modal
|
||||
title="评分单位权重设置"
|
||||
visible={weightSettingModalVisible}
|
||||
onOk={handleSaveWeights}
|
||||
onCancel={() => setWeightSettingModalVisible(false)}
|
||||
width={600}
|
||||
>
|
||||
<Form form={form} layout="vertical">
|
||||
<Table
|
||||
columns={weightColumns}
|
||||
dataSource={weightUnits}
|
||||
pagination={false}
|
||||
rowKey="id"
|
||||
bordered
|
||||
/>
|
||||
</Form>
|
||||
</Modal>
|
||||
|
||||
{/* 评价人员选择/查看模态框 */}
|
||||
<Modal
|
||||
title={currentSupplier?.supplierName + ' - 评价人员选择'}
|
||||
visible={evaluatorModalVisible}
|
||||
footer={null}
|
||||
onCancel={() => setEvaluatorModalVisible(false)}
|
||||
width={800}
|
||||
destroyOnClose
|
||||
>
|
||||
<EvaluateTaskPersonnelSelector
|
||||
onSelect={handleEvaluatorSelect}
|
||||
selectedPersonnel={currentSupplier?.evaluators}
|
||||
/>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EvaluatorSelectStep;
|
@ -0,0 +1,396 @@
|
||||
import React, { useState, useEffect } 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: React.FC<SupplierSelectStepProps> = ({ formData, onFormDataChange }) => {
|
||||
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[]>([]);
|
||||
|
||||
// 初始化数据
|
||||
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 });
|
||||
};
|
||||
|
||||
// 处理筛选条件变化
|
||||
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={12}>
|
||||
<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={12}>
|
||||
<Form.Item label="品类关键字" name="categoryKeyword">
|
||||
<Input placeholder="请输入" allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<Form.Item label="品类范围" name="categoryRange">
|
||||
<Input placeholder="请输入" allowClear />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item label="近一年有付款" name="hasPaymentLastYear" initialValue="是">
|
||||
<Radio.Group>
|
||||
<Radio value="是">是</Radio>
|
||||
<Radio value="否">否</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={24}>
|
||||
<Col span={12}>
|
||||
<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={12}>
|
||||
<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;
|
Reference in New Issue
Block a user