import React, { useEffect, useMemo, useRef, useState } from 'react'; import { App, Button, Card, Divider, Drawer, Empty, Popconfirm, Space, Tag, } from 'antd'; import { ActionType } from '@ant-design/pro-components'; import { CopyOutlined, DownOutlined, FileDoneOutlined } from '@ant-design/icons'; // 服务器 API 引用(保持与原 index.tsx 一致) import { ordercontrollerChangestatus, ordercontrollerGetorderdetail, ordercontrollerSyncorderbyid, } from '@/servers/api/order'; import { logisticscontrollerDelshipment } from '@/servers/api/logistics'; // 工具与子组件 import { formatShipmentState, formatSource } from '@/utils/format'; import RelatedOrders from './RelatedOrders'; // 中文注释:为保持原文件结构简单,此处从 index.tsx 引入的子组件仍由原文件导出或保持原状 // 若后续需要彻底解耦,可将 OrderNote / Shipping / SalesChange 也独立到文件 // 当前按你的要求仅抽离详情 Drawer type OrderRecord = API.Order; interface OrderDetailDrawerProps { tableRef: React.MutableRefObject; // 中文注释:列表刷新引用 orderId: number; // 中文注释:订单主键 ID record: OrderRecord; // 中文注释:订单行记录 open: boolean; // 中文注释:是否打开抽屉 onClose: () => void; // 中文注释:关闭抽屉回调 setActiveLine: (id: number) => void; // 中文注释:高亮当前行 OrderNoteComponent: React.ComponentType; // 中文注释:备注组件(从外部注入) SalesChangeComponent: React.ComponentType; // 中文注释:换货组件(从外部注入) } const OrderDetailDrawer: React.FC = ({ tableRef, orderId, record, open, onClose, setActiveLine, OrderNoteComponent, SalesChangeComponent, }) => { const { message } = App.useApp(); const ref = useRef(); const [detail, setDetail] = useState(null); // 中文注释:加载详情数据(与 index.tsx 中完全保持一致) const initRequest = async () => { const { data, success }: API.OrderDetailRes = await ordercontrollerGetorderdetail({ orderId }); if (!success || !data) return null; // 中文注释:销售项合并 SKU,展示数量汇总 data.sales = data.sales?.reduce( (acc: API.OrderSale[], cur: API.OrderSale) => { const idx = acc.findIndex((v: any) => v.productId === cur.productId); if (idx === -1) acc.push(cur); else acc[idx].quantity += cur.quantity; return acc; }, [], ); return data; }; useEffect(() => { (async () => { if (open && orderId) { try { const data = await initRequest(); setDetail(data); } catch (e) { setDetail(null); } } else { setDetail(null); } })(); }, [open, orderId]); return ( , ...(['after_sale_pending', 'pending_reshipment'].includes( record.orderStatus, ) ? [] : [ , , ]), ...([ 'processing', 'pending_reshipment', 'completed', 'pending_refund', ].includes(record.orderStatus) ? [ , { try { const { success, message: errMsg } = await ordercontrollerChangestatus( { id: record.id }, { status: 'after_sale_pending' }, ); if (!success) throw new Error(errMsg); tableRef.current?.reload(); } catch (error: any) { message.error(error.message); } }} > , ] : []), ...(record.orderStatus === 'after_sale_pending' ? [ , { try { const { success, message: errMsg } = await ordercontrollerChangestatus( { id: record.id }, { status: 'cancelled' }, ); if (!success) throw new Error(errMsg); tableRef.current?.reload(); } catch (error: any) { message.error(error.message); } }} > , , { try { const { success, message: errMsg } = await ordercontrollerChangestatus( { id: record.id }, { status: 'refund_requested' }, ); if (!success) throw new Error(errMsg); tableRef.current?.reload(); } catch (error: any) { message.error(error.message); } }} > , , { try { const { success, message: errMsg } = await ordercontrollerChangestatus( { id: record.id }, { status: 'completed' }, ); if (!success) throw new Error(errMsg); tableRef.current?.reload(); } catch (error: any) { message.error(error.message); } }} > , ] : []), ]} > {(() => { setActiveLine(record.id as number); return null; })()} {/** 中文注释:优先使用详情数据,其次使用列表行数据 */} {(() => { const drec: any = detail || record; {/* 中文注释:基本信息展示(保持原有格式) */} return (<>
{drec?.orderStatus} {formatSource(drec.source_type, drec.utm_source)}
{/* 中文注释:原始订单行项目 */}
原始订单
{Array.isArray((drec as any)?.items) && drec.items.length > 0 ? (
    {drec.items.map((item: any) => (
  • {item.name}:{item.quantity}
  • ))}
) : ( )}
{/* 中文注释:关联(订阅/订单),使用已存在的 RelatedOrders 组件 */}
关联
{/* 中文注释:订单内容(销售项) */}
订单内容
{Array.isArray((drec as any)?.sales) && drec.sales.length > 0 ? (
    {drec.sales.map((item: any) => (
  • {item.name}:{item.quantity}
  • ))}
) : ( )}
{/* 中文注释:备注 */}
备注
{Array.isArray((drec as any)?.notes) && drec.notes.length > 0 ? (
{drec.notes.map((note: any) => (
{note.username} {note.createdAt}
{note.content}
))}
) : ( )}
{/* 中文注释:物流信息 */}
物流信息
{Array.isArray((drec as any)?.shipment) && drec.shipment.length > 0 ? (
{(drec as any).shipment.map((v: any) => ( {v.tracking_provider} {v.primary_tracking_number} { try { await navigator.clipboard.writeText(v.tracking_url); message.success('复制成功!'); } catch (err) { message.error('复制失败!'); } }} /> } actions={ v.state === 'waiting-for-scheduling' || v.state === 'waiting-for-transit' ? [ { try { const { success, message: errMsg } = await logisticscontrollerDelshipment({ id: v.id }); if (!success) throw new Error(errMsg); tableRef.current?.reload(); } catch (error: any) { message.error(error.message); } }} > 取消运单 , ] : [] } >
订单号: {Array.isArray(v?.orderIds) ? v.orderIds.join(',') : '-'}
{Array.isArray(v?.items) && v.items.map((item: any) => (
{item.name}: {item.quantity}
))}
))}
) : ( )}
{/* 中文注释:换货(外部传入组件) */}
); })()}
); }; export default OrderDetailDrawer;