import React, { useState, useEffect } from 'react' import { useNavigate } from 'react-router-dom' import { Table, Button, Modal, Form, Input, message, Space, Tag, Card, Row, Col, Statistic, Image } from 'antd' import { PlusOutlined, EditOutlined, DeleteOutlined, SearchOutlined, HomeOutlined, BankOutlined } from '@ant-design/icons' import type { ColumnsType } from 'antd/es/table' import FileUpload from '../components/FileUpload' 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 Customer { id: number code: string name: string address: string contacts: Contact[] payment_infos: PaymentInfo[] remark: string total_contract_amount: number total_received: number total_receivable: number created_at: string } const CustomerPage: React.FC = () => { const navigate = useNavigate() const [customers, setCustomers] = useState([]) const [loading, setLoading] = useState(false) const [modalVisible, setModalVisible] = useState(false) const [editingCustomer, setEditingCustomer] = useState(null) const [searchText, setSearchText] = useState('') const [form] = Form.useForm() const fetchCustomers = async () => { setLoading(true) try { const response = await fetch('/api/customers') const data = await response.json() if (data.success) setCustomers(data.data || []) } catch (error) { message.error('获取客户列表失败') } finally { setLoading(false) } } useEffect(() => { fetchCustomers() }, []) const stats = { total: customers.length, totalContract: customers.reduce((sum, c) => sum + (c.total_contract_amount || 0), 0), totalReceivable: customers.reduce((sum, c) => sum + (c.total_receivable || 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: 'code', key: 'code', width: 120 }, { title: '名称', dataIndex: 'name', key: 'name', render: (text, record) => ( ) }, { title: '地址', dataIndex: 'address', key: 'address', width: 150, render: (t) => t || '-' }, { title: '主联系人', key: 'primary_contact', width: 100, render: (_, record) => getPrimaryContact(record.contacts || []) }, { title: '收款信息', key: 'payment_info', width: 200, render: (_, record) => { const primary = getPrimaryPaymentInfo(record.payment_infos || []) if (!primary) return 未设置 return (
{primary.bank_name || '-'}
户名: {primary.account_name || '-'}
账号: {primary.bank_account ? primary.bank_account.slice(-4).padStart(primary.bank_account.length, '*') : '-'}
) } }, { title: '合同金额', dataIndex: 'total_contract_amount', key: 'total_contract_amount', width: 100, render: (v) => `¥${(v || 0).toLocaleString()}` }, { title: '应收金额', dataIndex: 'total_receivable', key: 'total_receivable', width: 100, render: (v) => 0 ? '#ff4d4f' : '#52c41a' }}>¥{(v || 0).toLocaleString()} }, { title: '操作', key: 'actions', width: 100, render: (_, record) => ( `共 ${total} 条` }} scroll={{ x: 1100 }} /> { setModalVisible(false); form.resetFields(); setEditingCustomer(null) }} onOk={() => form.submit()} width={800} >

联系人

{(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)} /> 主要收款账户
{fields.length > 0 && ( )}
))}
)}
) } export default CustomerPage