- 删除无用的文件和错误日志 - 创建统一的 imports 模块集中管理依赖 - 重构组件使用新的 imports 方式 - 修复文档路径大小写问题 - 优化类型定义和接口导出 - 更新依赖版本 - 改进错误处理和API配置 - 统一组件导出方式
421 lines
11 KiB
TypeScript
421 lines
11 KiB
TypeScript
import {
|
|
useState,
|
|
useEffect,
|
|
Table,
|
|
Button,
|
|
Input,
|
|
Select,
|
|
message,
|
|
Card,
|
|
Modal,
|
|
Form,
|
|
InputNumber,
|
|
Row,
|
|
Col,
|
|
Tag,
|
|
Rate,
|
|
PlusOutlined,
|
|
EditOutlined,
|
|
DeleteOutlined,
|
|
SearchOutlined,
|
|
UserOutlined,
|
|
PhoneOutlined,
|
|
MailOutlined,
|
|
HomeOutlined,
|
|
useNavigate,
|
|
Option,
|
|
Search,
|
|
TextArea,
|
|
FC,
|
|
} from '@/imports';
|
|
import { suppliersDataSource, Supplier } from '@/services/suppliersDataSource';
|
|
|
|
const Suppliers: FC = () => {
|
|
const navigate = useNavigate();
|
|
const [suppliers, setSuppliers] = useState<Supplier[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
const [modalVisible, setModalVisible] = useState(false);
|
|
const [editingSupplier, setEditingSupplier] = useState<Supplier | null>(null);
|
|
const [form] = Form.useForm();
|
|
const [filters, setFilters] = useState({
|
|
category: '',
|
|
status: '',
|
|
search: '',
|
|
});
|
|
|
|
useEffect(() => {
|
|
fetchSuppliers();
|
|
}, [filters]);
|
|
|
|
const fetchSuppliers = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const data = await suppliersDataSource.fetchSuppliers();
|
|
setSuppliers(data);
|
|
} catch (error) {
|
|
message.error('Failed to load suppliers');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const handleAddSupplier = () => {
|
|
setEditingSupplier(null);
|
|
form.resetFields();
|
|
form.setFieldsValue({
|
|
status: 'active',
|
|
rating: 3,
|
|
leadTime: 7,
|
|
minOrder: 100,
|
|
paymentTerms: 'Net 30',
|
|
});
|
|
setModalVisible(true);
|
|
};
|
|
|
|
const handleEditSupplier = (id: string) => {
|
|
const supplier = suppliers.find(s => s.id === id);
|
|
if (supplier) {
|
|
setEditingSupplier(supplier);
|
|
form.setFieldsValue(supplier);
|
|
setModalVisible(true);
|
|
}
|
|
};
|
|
|
|
const handleSaveSupplier = async () => {
|
|
try {
|
|
const values = await form.validateFields();
|
|
if (editingSupplier) {
|
|
const updatedSuppliers = suppliers.map(s =>
|
|
s.id === editingSupplier.id ? { ...s, ...values } : s
|
|
);
|
|
setSuppliers(updatedSuppliers);
|
|
message.success('供应商已更新');
|
|
} else {
|
|
const newSupplier: Supplier = {
|
|
id: `supplier-${Date.now()}`,
|
|
...values,
|
|
createdAt: new Date().toISOString(),
|
|
};
|
|
setSuppliers([...suppliers, newSupplier]);
|
|
message.success('供应商已添加');
|
|
}
|
|
setModalVisible(false);
|
|
} catch (error) {
|
|
message.error('保存失败');
|
|
}
|
|
};
|
|
|
|
const handleDeleteSupplier = (id: string) => {
|
|
const updatedSuppliers = suppliers.filter(s => s.id !== id);
|
|
setSuppliers(updatedSuppliers);
|
|
message.success('供应商已删除');
|
|
};
|
|
|
|
const columns = [
|
|
{
|
|
title: '供应商名称',
|
|
dataIndex: 'name',
|
|
key: 'name',
|
|
},
|
|
{
|
|
title: '联系人',
|
|
dataIndex: 'contactName',
|
|
key: 'contactName',
|
|
},
|
|
{
|
|
title: '邮箱',
|
|
dataIndex: 'email',
|
|
key: 'email',
|
|
},
|
|
{
|
|
title: '电话',
|
|
dataIndex: 'phone',
|
|
key: 'phone',
|
|
},
|
|
{
|
|
title: '类别',
|
|
dataIndex: 'category',
|
|
key: 'category',
|
|
render: (category: string) => {
|
|
const colorMap: Record<string, string> = {
|
|
Electronics: 'blue',
|
|
Clothing: 'purple',
|
|
'Home Goods': 'green',
|
|
};
|
|
return <Tag color={colorMap[category] || 'default'}>{category}</Tag>;
|
|
},
|
|
},
|
|
{
|
|
title: '状态',
|
|
dataIndex: 'status',
|
|
key: 'status',
|
|
render: (status: string) => {
|
|
const statusMap: Record<string, { label: string; color: string }> = {
|
|
active: { label: '活跃', color: 'success' },
|
|
inactive: { label: '非活跃', color: 'default' },
|
|
pending: { label: '待审核', color: 'warning' },
|
|
};
|
|
const config = statusMap[status] || { label: status, color: 'default' };
|
|
return <Tag color={config.color}>{config.label}</Tag>;
|
|
},
|
|
},
|
|
{
|
|
title: '评分',
|
|
dataIndex: 'rating',
|
|
key: 'rating',
|
|
render: (rating: number) => <Rate disabled defaultValue={rating || 3} />,
|
|
},
|
|
{
|
|
title: '交货期(天)',
|
|
dataIndex: 'leadTime',
|
|
key: 'leadTime',
|
|
},
|
|
{
|
|
title: '最小订单量',
|
|
dataIndex: 'minOrder',
|
|
key: 'minOrder',
|
|
},
|
|
{
|
|
title: '操作',
|
|
key: 'action',
|
|
render: (_: any, record: Supplier) => (
|
|
<div>
|
|
<Button
|
|
type="link"
|
|
icon={<EditOutlined />}
|
|
onClick={() => handleEditSupplier(record.id)}
|
|
>
|
|
编辑
|
|
</Button>
|
|
<Button
|
|
type="link"
|
|
danger
|
|
icon={<DeleteOutlined />}
|
|
onClick={() => handleDeleteSupplier(record.id)}
|
|
>
|
|
删除
|
|
</Button>
|
|
</div>
|
|
),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div className="suppliers">
|
|
<div className="page-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }}>
|
|
<h1>供应商管理</h1>
|
|
<Button
|
|
type="primary"
|
|
icon={<PlusOutlined />}
|
|
onClick={handleAddSupplier}
|
|
>
|
|
添加供应商
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="filter-section" style={{ marginBottom: 24, display: 'flex', gap: 16, flexWrap: 'wrap' }}>
|
|
<Search
|
|
placeholder="搜索供应商名称或联系人"
|
|
style={{ width: 300 }}
|
|
onChange={(e) => setFilters({ ...filters, search: e.target.value })}
|
|
/>
|
|
<Select
|
|
placeholder="类别"
|
|
style={{ width: 120 }}
|
|
onChange={(value) => setFilters({ ...filters, category: value })}
|
|
>
|
|
<Option value="">全部</Option>
|
|
<Option value="Electronics">Electronics</Option>
|
|
<Option value="Clothing">Clothing</Option>
|
|
<Option value="Home Goods">Home Goods</Option>
|
|
</Select>
|
|
<Select
|
|
placeholder="状态"
|
|
style={{ width: 120 }}
|
|
onChange={(value) => setFilters({ ...filters, status: value })}
|
|
>
|
|
<Option value="">全部</Option>
|
|
<Option value="active">活跃</Option>
|
|
<Option value="inactive">非活跃</Option>
|
|
<Option value="pending">待审核</Option>
|
|
</Select>
|
|
<Button
|
|
icon={<SearchOutlined />}
|
|
onClick={fetchSuppliers}
|
|
>
|
|
筛选
|
|
</Button>
|
|
</div>
|
|
|
|
<Card title="供应商列表">
|
|
<Table
|
|
columns={columns}
|
|
dataSource={suppliers}
|
|
loading={loading}
|
|
rowKey="id"
|
|
pagination={{
|
|
pageSize: 10,
|
|
showSizeChanger: true,
|
|
}}
|
|
/>
|
|
</Card>
|
|
|
|
<Modal
|
|
title={editingSupplier ? '编辑供应商' : '添加供应商'}
|
|
open={modalVisible}
|
|
onCancel={() => setModalVisible(false)}
|
|
onOk={handleSaveSupplier}
|
|
width={800}
|
|
>
|
|
<Form
|
|
form={form}
|
|
layout="vertical"
|
|
>
|
|
<Row gutter={16}>
|
|
<Col span={12}>
|
|
<Form.Item
|
|
name="name"
|
|
label="供应商名称"
|
|
rules={[{ required: true, message: '请输入供应商名称' }]}
|
|
>
|
|
<Input placeholder="输入供应商名称" />
|
|
</Form.Item>
|
|
</Col>
|
|
<Col span={12}>
|
|
<Form.Item
|
|
name="category"
|
|
label="类别"
|
|
rules={[{ required: true, message: '请选择类别' }]}
|
|
>
|
|
<Select placeholder="选择类别">
|
|
<Option value="Electronics">Electronics</Option>
|
|
<Option value="Clothing">Clothing</Option>
|
|
<Option value="Home Goods">Home Goods</Option>
|
|
<Option value="Other">Other</Option>
|
|
</Select>
|
|
</Form.Item>
|
|
</Col>
|
|
</Row>
|
|
|
|
<Row gutter={16}>
|
|
<Col span={12}>
|
|
<Form.Item
|
|
name="contactName"
|
|
label="联系人"
|
|
rules={[{ required: true, message: '请输入联系人' }]}
|
|
>
|
|
<Input placeholder="输入联系人姓名" />
|
|
</Form.Item>
|
|
</Col>
|
|
<Col span={12}>
|
|
<Form.Item
|
|
name="status"
|
|
label="状态"
|
|
rules={[{ required: true, message: '请选择状态' }]}
|
|
>
|
|
<Select placeholder="选择状态">
|
|
<Option value="active">活跃</Option>
|
|
<Option value="inactive">非活跃</Option>
|
|
<Option value="pending">待审核</Option>
|
|
</Select>
|
|
</Form.Item>
|
|
</Col>
|
|
</Row>
|
|
|
|
<Row gutter={16}>
|
|
<Col span={12}>
|
|
<Form.Item
|
|
name="email"
|
|
label="邮箱"
|
|
rules={[
|
|
{ required: true, message: '请输入邮箱' },
|
|
{ type: 'email', message: '请输入有效的邮箱地址' },
|
|
]}
|
|
>
|
|
<Input placeholder="输入邮箱地址" />
|
|
</Form.Item>
|
|
</Col>
|
|
<Col span={12}>
|
|
<Form.Item
|
|
name="phone"
|
|
label="电话"
|
|
rules={[{ required: true, message: '请输入电话' }]}
|
|
>
|
|
<Input placeholder="输入电话号码" />
|
|
</Form.Item>
|
|
</Col>
|
|
</Row>
|
|
|
|
<Row gutter={16}>
|
|
<Col span={12}>
|
|
<Form.Item
|
|
name="rating"
|
|
label="评分"
|
|
>
|
|
<Rate />
|
|
</Form.Item>
|
|
</Col>
|
|
<Col span={12}>
|
|
<Form.Item
|
|
name="paymentTerms"
|
|
label="付款条款"
|
|
>
|
|
<Select placeholder="选择付款条款">
|
|
<Option value="Net 30">Net 30</Option>
|
|
<Option value="Net 60">Net 60</Option>
|
|
<Option value="Net 90">Net 90</Option>
|
|
<Option value="Prepaid">预付款</Option>
|
|
<Option value="COD">货到付款</Option>
|
|
</Select>
|
|
</Form.Item>
|
|
</Col>
|
|
</Row>
|
|
|
|
<Row gutter={16}>
|
|
<Col span={12}>
|
|
<Form.Item
|
|
name="leadTime"
|
|
label="交货期 (天)"
|
|
>
|
|
<InputNumber
|
|
min={1}
|
|
style={{ width: '100%' }}
|
|
placeholder="输入交货期"
|
|
/>
|
|
</Form.Item>
|
|
</Col>
|
|
<Col span={12}>
|
|
<Form.Item
|
|
name="minOrder"
|
|
label="最小订单量"
|
|
>
|
|
<InputNumber
|
|
min={1}
|
|
style={{ width: '100%' }}
|
|
placeholder="输入最小订单量"
|
|
/>
|
|
</Form.Item>
|
|
</Col>
|
|
</Row>
|
|
|
|
<Form.Item
|
|
name="address"
|
|
label="地址"
|
|
>
|
|
<Input placeholder="输入供应商地址" />
|
|
</Form.Item>
|
|
|
|
<Form.Item
|
|
name="description"
|
|
label="备注"
|
|
>
|
|
<TextArea rows={3} placeholder="输入备注信息" />
|
|
</Form.Item>
|
|
</Form>
|
|
</Modal>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Suppliers;
|