import React, { useState, useEffect, useCallback } from 'react' import { useNavigate, useLocation } from 'react-router-dom' import { Table, Button, Modal, Form, Input, Select, message, Space, Tag, Card, Row, Col, Statistic } from 'antd' import { PlusOutlined, EditOutlined, DeleteOutlined, SearchOutlined, ShopOutlined, BankOutlined } from '@ant-design/icons' import type { ColumnsType } from 'antd/es/table' import FileUpload from '../components/FileUpload' import useFormDraft from '../hooks/useFormDraft' interface Contact { name: string position: string phone: string is_primary?: boolean } interface PaymentInfo { account_name: string bank_account: string bank_name: string qr_code?: string is_primary: boolean } interface Supplier { id: number code: string name: string supply_category: string country: string contacts: Contact[] payment_infos: PaymentInfo[] remark: string total_purchase_amount: number total_paid: number total_payable: number created_at: string } const SupplierPage: React.FC = () => { const navigate = useNavigate() const location = useLocation() const [suppliers, setSuppliers] = useState([]) const [loading, setLoading] = useState(false) const [modalVisible, setModalVisible] = useState(false) const [editingSupplier, setEditingSupplier] = useState(null) const [searchText, setSearchText] = useState('') const [form] = Form.useForm() // 从 location state 中获取返回路径 const returnTo = (location.state as { returnTo?: string })?.returnTo // 表单草稿保护 const { save: saveDraft, restore: restoreDraft, clear: clearDraft, hasDraft } = useFormDraft({ form, storageKey: 'supplier_create', }) const handleFormChange = useCallback(() => { saveDraft() }, [saveDraft]) const fetchSuppliers = async () => { setLoading(true) try { const response = await fetch('/api/suppliers') const data = await response.json() if (data.success) setSuppliers(data.data || []) } catch (error) { message.error('获取供应商列表失败') } finally { setLoading(false) } } useEffect(() => { fetchSuppliers() }, []) const stats = { total: suppliers.length, totalPurchase: suppliers.reduce((sum, s) => sum + (s.total_purchase_amount || 0), 0), totalPayable: suppliers.reduce((sum, s) => sum + (s.total_payable || 0), 0) } const getPrimaryContact = (contacts: Contact[]) => { const primary = contacts?.find(c => c.is_primary) return primary?.name || '-' } const getPrimaryPaymentInfo = (paymentInfos: PaymentInfo[]) => { const primary = paymentInfos?.find(p => p.is_primary) return primary } const columns: ColumnsType = [ { title: '名称', dataIndex: 'name', key: 'name', render: (text, record) => ( ) }, { title: '供应类别', dataIndex: 'supply_category', key: 'supply_category', width: 120 }, { title: '国家', dataIndex: 'country', key: 'country', width: 80, render: (country) => {country || '-'} }, { title: '采购金额', dataIndex: 'total_purchase_amount', key: 'total_purchase_amount', width: 100, render: (amount) => `¥${(amount || 0).toLocaleString()}` }, { title: '应付金额', dataIndex: 'total_payable', key: 'total_payable', width: 100, render: (amount) => 0 ? '#ff4d4f' : '#52c41a' }}>¥{(amount || 0).toLocaleString()} }, { title: '操作', key: 'actions', width: 100, render: (_, record) => ( `共 ${total} 条` }} scroll={{ x: 1100 }} /> { if (form.isFieldsTouched()) { Modal.confirm({ title: '确认关闭', content: '表单数据尚未保存,关闭后可通过草稿恢复。确定关闭吗?', okText: '关闭', cancelText: '继续编辑', onOk: () => { saveDraft() setModalVisible(false) form.resetFields() setEditingSupplier(null) }, }) } else { setModalVisible(false) form.resetFields() setEditingSupplier(null) } }} onOk={() => form.submit()} width={800} maskClosable={false} >

联系人

{(fields, { add, remove }) => (
{fields.map(({ key, name, ...restField }) => (
handleContactChange(name, 'is_primary', e.target.checked)} /> 主联系人
{fields.length > 1 && }
))}
)}

收款信息

{(fields, { add, remove }) => (
{fields.map(({ key, name, ...restField }) => (
handlePaymentInfoChange(name, 'is_primary', e.target.checked)} /> 主要收款账户
{ form.setFieldsValue({ payment_infos: form.getFieldValue('payment_infos').map((info: any, i: number) => { return i === Number(name) ? { ...info, qr_code: urls[0] || '' } : info }) }) }} /> {fields.length > 0 && ( )}
))}
)}
) } export default SupplierPage