import React, { useState, useEffect, useCallback } from 'react'; import { Card, Table, Tag, Button, Space, Modal, Form, Input, Select, DatePicker, message, Tooltip, Row, Col, Statistic, Badge, Dropdown, Menu, Tabs, InputNumber, Timeline, Alert, Drawer, Divider, Typography, Image, Steps, } from 'antd'; import { EyeOutlined, SyncOutlined, CheckCircleOutlined, ClockCircleOutlined, TruckOutlined, CloseCircleOutlined, MoreOutlined, SearchOutlined, ExportOutlined, WarningOutlined, FileTextOutlined, EnvironmentOutlined, CheckOutlined, UndoOutlined, CustomerServiceOutlined, DollarOutlined, FilterOutlined, SortAscendingOutlined, PrinterOutlined, MessageOutlined, ExclamationCircleOutlined, } from '@ant-design/icons'; import type { ColumnsType, TablePaginationConfig } from 'antd/es/table'; import type { FilterValue, SorterResult, TableCurrentDataSource } from 'antd/es/table/interface'; import moment from 'moment'; const { Title, Text } = Typography; const { Option } = Select; const { RangePicker } = DatePicker; const { TabPane } = Tabs; const { Step } = Steps; const { Search } = Input; interface Order { id: string; orderId: string; platform: 'AMAZON' | 'EBAY' | 'SHOPIFY' | 'SHOPEE' | 'LAZADA'; customerName: string; customerEmail: string; customerPhone: string; customerAddress: string; totalAmount: number; currency: string; status: 'PENDING' | 'CONFIRMED' | 'SHIPPED' | 'DELIVERED' | 'COMPLETED' | 'CANCELLED' | 'REFUNDING' | 'REFUNDED'; paymentStatus: 'PENDING' | 'PAID' | 'REFUNDED'; itemCount: number; createdAt: string; updatedAt: string; shopId: string; shopName: string; trackingNumber?: string; carrier?: string; estimatedDelivery?: string; actualDelivery?: string; exceptionReason?: string; items: OrderItem[]; } interface OrderItem { id: string; productName: string; sku: string; quantity: number; price: number; image: string; } interface FilterState { keyword: string; status: string[]; platform: string[]; paymentStatus: string[]; dateRange: [moment.Moment, moment.Moment] | null; } interface SortState { field: string; order: 'ascend' | 'descend' | null; } const STATUS_CONFIG: Record = { PENDING: { color: 'default', text: '待处理', icon: , step: 0 }, CONFIRMED: { color: 'blue', text: '已确认', icon: , step: 1 }, SHIPPED: { color: 'processing', text: '已发货', icon: , step: 2 }, DELIVERED: { color: 'cyan', text: '已送达', icon: , step: 3 }, COMPLETED: { color: 'success', text: '已完成', icon: , step: 4 }, CANCELLED: { color: 'error', text: '已取消', icon: , step: -1 }, REFUNDING: { color: 'warning', text: '退款中', icon: , step: -1 }, REFUNDED: { color: 'default', text: '已退款', icon: , step: -1 }, }; const PLATFORM_CONFIG: Record = { AMAZON: { color: 'orange', text: 'Amazon' }, EBAY: { color: 'blue', text: 'eBay' }, SHOPIFY: { color: 'green', text: 'Shopify' }, SHOPEE: { color: 'red', text: 'Shopee' }, LAZADA: { color: 'purple', text: 'Lazada' }, }; const MOCK_ORDERS: Order[] = [ { id: '1', orderId: 'ORD-2026-001', platform: 'AMAZON', customerName: '张三', customerEmail: 'zhangsan@email.com', customerPhone: '+86-138-0000-0001', customerAddress: '北京市朝阳区xxx街道xxx号', totalAmount: 159.99, currency: 'USD', status: 'SHIPPED', paymentStatus: 'PAID', itemCount: 3, createdAt: '2026-03-18 10:30:00', updatedAt: '2026-03-18 14:00:00', shopId: 'SHOP_001', shopName: '主店铺', trackingNumber: '1Z999AA10123456784', carrier: 'UPS', estimatedDelivery: '2026-03-22', items: [ { id: 'i1', productName: '工业温度传感器', sku: 'TP-TEMP-001', quantity: 2, price: 89.99, image: 'https://via.placeholder.com/60x60' }, { id: 'i2', productName: '连接线 1m', sku: 'TP-CABLE-001', quantity: 1, price: 19.99, image: 'https://via.placeholder.com/60x60' }, ], }, { id: '2', orderId: 'ORD-2026-002', platform: 'EBAY', customerName: '李四', customerEmail: 'lisi@email.com', customerPhone: '+86-138-0000-0002', customerAddress: '上海市浦东新区xxx路xxx号', totalAmount: 299.99, currency: 'USD', status: 'PENDING', paymentStatus: 'PAID', itemCount: 1, createdAt: '2026-03-18 09:15:00', updatedAt: '2026-03-18 09:15:00', shopId: 'SHOP_002', shopName: 'eBay店铺', items: [ { id: 'i3', productName: 'PLC控制器', sku: 'TP-PLC-001', quantity: 1, price: 299.99, image: 'https://via.placeholder.com/60x60' }, ], }, { id: '3', orderId: 'ORD-2026-003', platform: 'SHOPIFY', customerName: '王五', customerEmail: 'wangwu@email.com', customerPhone: '+86-138-0000-0003', customerAddress: '广州市天河区xxx大道xxx号', totalAmount: 459.98, currency: 'USD', status: 'CONFIRMED', paymentStatus: 'PAID', itemCount: 2, createdAt: '2026-03-17 16:45:00', updatedAt: '2026-03-18 08:00:00', shopId: 'SHOP_003', shopName: '独立站', items: [ { id: 'i4', productName: '压力传感器', sku: 'TP-PRES-001', quantity: 2, price: 129.99, image: 'https://via.placeholder.com/60x60' }, { id: 'i5', productName: '安装支架', sku: 'TP-BRACKET-001', quantity: 2, price: 29.99, image: 'https://via.placeholder.com/60x60' }, ], }, { id: '4', orderId: 'ORD-2026-004', platform: 'SHOPEE', customerName: '赵六', customerEmail: 'zhaoliu@email.com', customerPhone: '+86-138-0000-0004', customerAddress: '深圳市南山区xxx街xxx号', totalAmount: 89.99, currency: 'USD', status: 'DELIVERED', paymentStatus: 'PAID', itemCount: 1, createdAt: '2026-03-15 11:20:00', updatedAt: '2026-03-18 09:30:00', shopId: 'SHOP_004', shopName: 'Shopee店铺', trackingNumber: 'SF1234567890', carrier: '顺丰', actualDelivery: '2026-03-18', items: [ { id: 'i6', productName: '温度传感器标准版', sku: 'TP-TEMP-002', quantity: 1, price: 89.99, image: 'https://via.placeholder.com/60x60' }, ], }, { id: '5', orderId: 'ORD-2026-005', platform: 'AMAZON', customerName: '钱七', customerEmail: 'qianqi@email.com', customerPhone: '+86-138-0000-0005', customerAddress: '杭州市西湖区xxx路xxx号', totalAmount: 599.99, currency: 'USD', status: 'COMPLETED', paymentStatus: 'PAID', itemCount: 3, createdAt: '2026-03-10 14:00:00', updatedAt: '2026-03-16 10:00:00', shopId: 'SHOP_001', shopName: '主店铺', trackingNumber: '1Z888BB20234567890', carrier: 'UPS', actualDelivery: '2026-03-16', items: [ { id: 'i7', productName: '流量计', sku: 'TP-FLOW-001', quantity: 1, price: 299.99, image: 'https://via.placeholder.com/60x60' }, { id: 'i8', productName: '显示屏', sku: 'TP-DISP-001', quantity: 2, price: 149.99, image: 'https://via.placeholder.com/60x60' }, ], }, { id: '6', orderId: 'ORD-2026-006', platform: 'EBAY', customerName: '孙八', customerEmail: 'sunba@email.com', customerPhone: '+86-138-0000-0006', customerAddress: '成都市武侯区xxx街xxx号', totalAmount: 129.99, currency: 'USD', status: 'CANCELLED', paymentStatus: 'REFUNDED', itemCount: 1, createdAt: '2026-03-17 09:00:00', updatedAt: '2026-03-17 15:30:00', shopId: 'SHOP_002', shopName: 'eBay店铺', exceptionReason: '客户取消订单', items: [ { id: 'i9', productName: '电磁阀', sku: 'TP-VALVE-001', quantity: 1, price: 129.99, image: 'https://via.placeholder.com/60x60' }, ], }, { id: '7', orderId: 'ORD-2026-007', platform: 'SHOPIFY', customerName: '周九', customerEmail: 'zhoujiu@email.com', customerPhone: '+86-138-0000-0007', customerAddress: '武汉市江汉区xxx路xxx号', totalAmount: 349.99, currency: 'USD', status: 'REFUNDING', paymentStatus: 'PAID', itemCount: 2, createdAt: '2026-03-14 13:30:00', updatedAt: '2026-03-18 11:00:00', shopId: 'SHOP_003', shopName: '独立站', exceptionReason: '商品质量问题', items: [ { id: 'i10', productName: '步进电机', sku: 'TP-MOTOR-001', quantity: 1, price: 199.99, image: 'https://via.placeholder.com/60x60' }, { id: 'i11', productName: '驱动器', sku: 'TP-DRIVER-001', quantity: 1, price: 149.99, image: 'https://via.placeholder.com/60x60' }, ], }, ]; export const OrderList: React.FC = () => { const [orders, setOrders] = useState([]); const [loading, setLoading] = useState(false); const [selectedRows, setSelectedRows] = useState([]); const [currentOrder, setCurrentOrder] = useState(null); const [filterVisible, setFilterVisible] = useState(false); const [sortDrawerVisible, setSortDrawerVisible] = useState(false); const [detailDrawerVisible, setDetailDrawerVisible] = useState(false); const [confirmModalVisible, setConfirmModalVisible] = useState(false); const [shipModalVisible, setShipModalVisible] = useState(false); const [cancelModalVisible, setCancelModalVisible] = useState(false); const [afterSalesModalVisible, setAfterSalesModalVisible] = useState(false); const [activeTab, setActiveTab] = useState('all'); const [shipForm] = Form.useForm(); const [cancelForm] = Form.useForm(); const [afterSalesForm] = Form.useForm(); const [filters, setFilters] = useState({ keyword: '', status: [], platform: [], paymentStatus: [], dateRange: null, }); const [sort, setSort] = useState({ field: 'createdAt', order: 'descend', }); useEffect(() => { fetchOrders(); }, []); const fetchOrders = useCallback(async () => { setLoading(true); await new Promise(resolve => setTimeout(resolve, 500)); setOrders(MOCK_ORDERS); setLoading(false); }, []); const handleFilterChange = (key: keyof FilterState, value: any) => { setFilters(prev => ({ ...prev, [key]: value })); }; const handleSortChange = (field: string, order: 'ascend' | 'descend') => { setSort({ field, order }); setSortDrawerVisible(false); message.success(`已按 ${field} ${order === 'ascend' ? '升序' : '降序'} 排序`); }; const handleTableChange = ( pagination: TablePaginationConfig, filters: Record, sorter: SorterResult | SorterResult[], extra: TableCurrentDataSource ) => { if (!Array.isArray(sorter) && sorter.field) { setSort({ field: sorter.field as string, order: sorter.order || null, }); } }; const handleSearch = (value: string) => { handleFilterChange('keyword', value); }; const handleResetFilters = () => { setFilters({ keyword: '', status: [], platform: [], paymentStatus: [], dateRange: null, }); message.success('筛选条件已重置'); }; const handleConfirmOrder = (record: Order) => { setCurrentOrder(record); setConfirmModalVisible(true); }; const handleConfirmSubmit = () => { if (currentOrder) { updateOrderStatus(currentOrder.id, 'CONFIRMED'); setConfirmModalVisible(false); message.success('订单确认成功'); } }; const handleShipOrder = (record: Order) => { setCurrentOrder(record); setShipModalVisible(true); shipForm.resetFields(); }; const handleShipSubmit = async () => { try { const values = await shipForm.validateFields(); if (currentOrder) { updateOrderStatus(currentOrder.id, 'SHIPPED'); setShipModalVisible(false); message.success('订单发货成功'); } } catch (error) { console.error('Form validation failed:', error); } }; const handleCompleteOrder = (record: Order) => { Modal.confirm({ title: '确认完成订单', content: `确定要完成订单 "${record.orderId}" 吗?`, onOk: () => { updateOrderStatus(record.id, 'COMPLETED'); message.success('订单已完成'); }, }); }; const handleCancelOrder = (record: Order) => { setCurrentOrder(record); setCancelModalVisible(true); cancelForm.resetFields(); }; const handleCancelSubmit = async () => { try { const values = await cancelForm.validateFields(); if (currentOrder) { updateOrderStatus(currentOrder.id, 'CANCELLED'); setCancelModalVisible(false); message.success('订单已取消'); } } catch (error) { console.error('Form validation failed:', error); } }; const handleAfterSales = (record: Order) => { setCurrentOrder(record); setAfterSalesModalVisible(true); afterSalesForm.resetFields(); }; const handleAfterSalesSubmit = async () => { try { const values = await afterSalesForm.validateFields(); if (currentOrder) { updateOrderStatus(currentOrder.id, 'REFUNDING'); setAfterSalesModalVisible(false); message.success('售后申请已提交'); } } catch (error) { console.error('Form validation failed:', error); } }; const handleViewDetail = (record: Order) => { setCurrentOrder(record); setDetailDrawerVisible(true); }; const updateOrderStatus = (orderId: string, status: Order['status']) => { setOrders(orders.map(o => o.id === orderId ? { ...o, status, updatedAt: moment().format('YYYY-MM-DD HH:mm:ss') } : o )); }; const handleTabChange = (key: string) => { setActiveTab(key); if (key === 'all') { setFilters(prev => ({ ...prev, status: [] })); } else { setFilters(prev => ({ ...prev, status: [key.toUpperCase()] })); } }; const filteredOrders = orders.filter(order => { if (filters.keyword && !order.orderId.toLowerCase().includes(filters.keyword.toLowerCase()) && !order.customerName.toLowerCase().includes(filters.keyword.toLowerCase())) { return false; } if (filters.status.length > 0 && !filters.status.includes(order.status)) { return false; } if (filters.platform.length > 0 && !filters.platform.includes(order.platform)) { return false; } if (filters.paymentStatus.length > 0 && !filters.paymentStatus.includes(order.paymentStatus)) { return false; } return true; }); const sortedOrders = [...filteredOrders].sort((a, b) => { const field = sort.field as keyof Order; const aValue = a[field]; const bValue = b[field]; if (sort.order === 'ascend') { return aValue > bValue ? 1 : -1; } else { return aValue < bValue ? 1 : -1; } }); const stats = { total: orders.length, pending: orders.filter(o => o.status === 'PENDING').length, processing: orders.filter(o => ['CONFIRMED', 'SHIPPED'].includes(o.status)).length, completed: orders.filter(o => o.status === 'COMPLETED').length, exception: orders.filter(o => ['CANCELLED', 'REFUNDING', 'REFUNDED'].includes(o.status)).length, totalAmount: orders.reduce((sum, o) => sum + o.totalAmount, 0), }; const columns: ColumnsType = [ { title: '订单号', dataIndex: 'orderId', key: 'orderId', render: (text, record) => ( {text} {PLATFORM_CONFIG[record.platform].text} ), }, { title: '客户信息', key: 'customer', render: (_, record) => ( {record.customerName} {record.customerPhone} ), }, { title: '金额', dataIndex: 'totalAmount', key: 'totalAmount', render: (value, record) => ( ${value.toFixed(2)} {record.currency} ), sorter: true, }, { title: '商品数', dataIndex: 'itemCount', key: 'itemCount', render: (value) => , }, { title: '状态', dataIndex: 'status', key: 'status', render: (status) => { const config = STATUS_CONFIG[status]; return ( {config.text} ); }, filters: Object.entries(STATUS_CONFIG).map(([key, config]) => ({ text: config.text, value: key, })), }, { title: '支付状态', dataIndex: 'paymentStatus', key: 'paymentStatus', render: (status) => { const config = { PENDING: { color: 'warning', text: '待支付' }, PAID: { color: 'success', text: '已支付' }, REFUNDED: { color: 'default', text: '已退款' }, }[status]; return {config.text}; }, }, { title: '店铺', dataIndex: 'shopName', key: 'shopName', }, { title: '创建时间', dataIndex: 'createdAt', key: 'createdAt', sorter: true, }, { title: '操作', key: 'action', fixed: 'right', width: 200, render: (_, record) => { const menu = ( } onClick={() => handleViewDetail(record)}> 查看详情 {record.status === 'PENDING' && ( } onClick={() => handleConfirmOrder(record)}> 确认订单 )} {record.status === 'CONFIRMED' && ( } onClick={() => handleShipOrder(record)}> 发货 )} {record.status === 'DELIVERED' && ( } onClick={() => handleCompleteOrder(record)}> 完成订单 )} {(record.status === 'PENDING' || record.status === 'CONFIRMED') && ( } onClick={() => handleCancelOrder(record)}> 取消订单 )} {(record.status === 'COMPLETED' || record.status === 'DELIVERED') && ( } onClick={() => handleAfterSales(record)}> 售后申请 )} }> 打印订单 }> 联系客户 ); // 根据订单状态显示主要操作按钮 const getPrimaryActionButton = () => { switch (record.status) { case 'PENDING': return ( ); case 'CONFIRMED': return ( ); case 'DELIVERED': return ( ); case 'COMPLETED': return ( ); default: return null; } }; return ( {getPrimaryActionButton()} ); }, }, ]; const rowSelection = { selectedRowKeys: selectedRows.map(r => r.id), onChange: (selectedRowKeys: React.Key[], selectedRows: Order[]) => { setSelectedRows(selectedRows); }, }; return ( {selectedRows.length > 0 && ( )} `共 ${total} 条`, pageSizeOptions: ['10', '20', '50', '100'], }} size="middle" bordered /> setFilterVisible(false)} visible={filterVisible} width={400} >
handleFilterChange('dateRange', dates)} style={{ width: '100%' }} />
setSortDrawerVisible(false)} visible={sortDrawerVisible} width={300} > {[ { key: 'orderId', label: '订单号' }, { key: 'totalAmount', label: '金额' }, { key: 'itemCount', label: '商品数' }, { key: 'createdAt', label: '创建时间' }, { key: 'updatedAt', label: '更新时间' }, ].map(item => (
{item.label}
))}
setDetailDrawerVisible(false)} visible={detailDrawerVisible} width={600} > {currentOrder && ( } /> } /> } /> } /> } /> {currentOrder.items.map(item => (
{item.productName}
SKU: {item.sku}
数量: {item.quantity} ${item.price.toFixed(2)}
))}

姓名: {currentOrder.customerName}

电话: {currentOrder.customerPhone}

邮箱: {currentOrder.customerEmail}

地址: {currentOrder.customerAddress}

{currentOrder.trackingNumber ? ( <>

物流单号: {currentOrder.trackingNumber}

承运商: {currentOrder.carrier}

{currentOrder.estimatedDelivery && (

预计送达: {currentOrder.estimatedDelivery}

)} {currentOrder.actualDelivery && (

实际送达: {currentOrder.actualDelivery}

)} ) : ( 暂无物流信息 )}
)}
setConfirmModalVisible(false)} >

确定要确认订单 "{currentOrder?.orderId}" 吗?

客户: {currentOrder?.customerName}

金额: ${currentOrder?.totalAmount.toFixed(2)}

setShipModalVisible(false)} >
setCancelModalVisible(false)} >
setAfterSalesModalVisible(false)} width={600} >
); }; export default OrderList;