Files
makemd/dashboard/src/pages/Suppliers/index.tsx
wurenzhi 22308fe042 refactor: 重构项目结构并优化代码
- 删除无用的文件和错误日志
- 创建统一的 imports 模块集中管理依赖
- 重构组件使用新的 imports 方式
- 修复文档路径大小写问题
- 优化类型定义和接口导出
- 更新依赖版本
- 改进错误处理和API配置
- 统一组件导出方式
2026-03-27 16:56:06 +08:00

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;