import React, { useState, useEffect } from 'react' import { useParams, useNavigate } from 'react-router-dom' import { Card, Descriptions, Tag, Spin, Empty, Row, Col, Table, Button, Tabs, Typography, Badge } from 'antd' import { ArrowLeftOutlined, HomeOutlined, UserOutlined, PhoneOutlined, DollarOutlined, FileTextOutlined } from '@ant-design/icons' import apiClient from '../utils/request' import BusinessLedgerTab from '../components/BusinessLedgerTab' import { useLanguageStore } from '../store/languageStore' const { Title, Text } = Typography interface Contact { name: string position: string phone: string is_primary?: boolean } interface LedgerSummary { item_count: number total_contract_amount: number total_received_amount: number total_receivable_amount: number } interface LedgerItem { id: number type: string code: string name: string contract_amount: number received_amount: number receivable_amount: number status: string } interface Customer { id: number code: string name: string address: string contacts: Contact[] remark: string total_contract_amount: number total_received: number total_receivable: number ledger?: { summary: LedgerSummary items: LedgerItem[] } created_at: string } interface Quotation { id: number version: number quotation_date: string amount: number currency: string status: string created_at: string } interface BudgetProject { id: number name: string customer_id: number manager_name: string status: string quotations: Quotation[] created_at: string } const CustomerDetail: React.FC = () => { const { id } = useParams<{ id: string }>() const navigate = useNavigate() const { t, currentLanguage } = useLanguageStore() const [customer, setCustomer] = useState(null) const [budgetProjects, setBudgetProjects] = useState([]) const [loading, setLoading] = useState(true) const [activeTab, setActiveTab] = useState('basic') useEffect(() => { fetchCustomerDetail() fetchRelatedBudgetProjects() }, [id]) const fetchCustomerDetail = async () => { try { const res = await fetch(`/api/customers/${id}`) const data = await res.json() if (data.success) setCustomer(data.data) } catch (error) { console.error('获取客户详情失败:', error) } finally { setLoading(false) } } const fetchRelatedBudgetProjects = async () => { try { const res = await apiClient.get('/api/budget-projects', { params: { customer_id: id } }) if (res.data.success) setBudgetProjects(res.data.data || []) } catch (error) { console.error('获取预算项目失败:', error) } } if (loading) return if (!customer) return const budgetProjectColumns = [ { title: t('customer.projectName'), dataIndex: 'name', key: 'name', render: (v: string, record: BudgetProject) => ( navigate(`/budget-projects/${record.id}`)} style={{ cursor: 'pointer', color: '#1890ff' }}>{v} ) }, { title: t('customer.businessManager'), dataIndex: 'manager_name', key: 'manager_name' }, { title: t('common.status'), dataIndex: 'status', key: 'status', align: 'center' as const, render: (v: string) => { const map: Record = { negotiating: { status: 'processing', text: t('customer.inNegotiation') }, signed: { status: 'success', text: t('customer.signed') }, unsigned: { status: 'error', text: t('customer.unsigned') } } const c = map[v] || { status: 'default', text: v } return } }, { title: t('customer.quotationCount'), dataIndex: 'quotations', key: 'quotations', align: 'center' as const, render: (q: Quotation[]) => (q || []).length }, { title: t('customer.createdAt'), dataIndex: 'created_at', key: 'created_at', render: (v: string) => v?.split('T')[0] || '-' } ] return (
<HomeOutlined style={{ marginRight: 8, color: '#52c41a' }} /> {customer.name} {/* TAB1: 基本信息 */} {t('customer.basicInfo')}} key="basic"> {customer.code} {customer.address || '-'} {customer.remark && (
{t('customer.remarkLabel')}
{customer.remark}
)}
{/* TAB2: 联系人 */} {t('customer.contact')}} key="contacts"> {(customer.contacts || []).map((contact, i) => (
{contact.name || t('common.unnamed')} {contact.is_primary && {t('customer.mainContactTag')}}
{contact.position &&
{t('customer.positionLabel')}{contact.position}
} {contact.phone &&
{t('customer.phoneLabel')}{contact.phone}
}
))}
{(customer.contacts || []).length === 0 && }
{/* TAB3: 业务台账 */} {t('customer.ledger')}} key="ledger"> {/* TAB4: 关联预算 */} {t('customer.relatedBudget')}} key="budget"> {budgetProjects.length > 0 ? ( ) : ( )} ) } export default CustomerDetail