1
This commit is contained in:
196
src/pages/orders/OrderDetailDrawer.tsx
Normal file
196
src/pages/orders/OrderDetailDrawer.tsx
Normal file
@@ -0,0 +1,196 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Card, Descriptions, Drawer, Space, Spin, Table, Tag, Typography } from 'antd'
|
||||
import { toast } from 'sonner'
|
||||
import { merchantOrderDetail } from '@/apis/mallMerchant'
|
||||
import type { OrderDetailInfo } from '@/types/mall'
|
||||
import { formatUnixTime, getStatusColor, getStatusLabel, prettyJsonText } from '@/utils/mall'
|
||||
|
||||
interface OrderDetailDrawerProps {
|
||||
open: boolean
|
||||
merchantId: string
|
||||
orderId?: number
|
||||
refreshToken?: number
|
||||
onClose: () => void
|
||||
}
|
||||
|
||||
export default function OrderDetailDrawer({
|
||||
open,
|
||||
merchantId,
|
||||
orderId,
|
||||
refreshToken,
|
||||
onClose,
|
||||
}: OrderDetailDrawerProps) {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [data, setData] = useState<OrderDetailInfo | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (!open || !orderId) {
|
||||
return
|
||||
}
|
||||
|
||||
let cancelled = false
|
||||
const run = async () => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const result = await merchantOrderDetail({
|
||||
merchantId,
|
||||
orderId,
|
||||
})
|
||||
|
||||
if (!cancelled) {
|
||||
setData(result.data)
|
||||
}
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : '加载订单详情失败'
|
||||
toast.error(message)
|
||||
} finally {
|
||||
if (!cancelled) {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void run()
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}, [merchantId, open, orderId, refreshToken])
|
||||
|
||||
return (
|
||||
<Drawer title={orderId ? `订单详情 #${orderId}` : '订单详情'} width={920} open={open} onClose={onClose}>
|
||||
<Spin spinning={loading}>
|
||||
{!data ? null : (
|
||||
<Space direction="vertical" size={16} style={{ width: '100%' }}>
|
||||
<Card className="page-card" title="基础信息">
|
||||
<Descriptions column={2} size="small">
|
||||
<Descriptions.Item label="订单号">{data.orderNo}</Descriptions.Item>
|
||||
<Descriptions.Item label="交易号">{data.tradeNo}</Descriptions.Item>
|
||||
<Descriptions.Item label="订单 ID">{data.id}</Descriptions.Item>
|
||||
<Descriptions.Item label="会员 ID">{data.uid}</Descriptions.Item>
|
||||
<Descriptions.Item label="商家 ID">{data.merchantId}</Descriptions.Item>
|
||||
<Descriptions.Item label="商家名称">{data.merchantName || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="订单状态">
|
||||
<Tag color={getStatusColor(data.orderStatus)}>{getStatusLabel(data.orderStatus)}</Tag>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="售后状态">
|
||||
<Tag color={getStatusColor(data.afterSaleStatus)}>
|
||||
{getStatusLabel(data.afterSaleStatus)}
|
||||
</Tag>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="商品金额">{data.goodsAmount}</Descriptions.Item>
|
||||
<Descriptions.Item label="支付金额">{data.payAmount}</Descriptions.Item>
|
||||
<Descriptions.Item label="运费">{data.freightAmount}</Descriptions.Item>
|
||||
<Descriptions.Item label="优惠金额">{data.discountAmount}</Descriptions.Item>
|
||||
<Descriptions.Item label="币种">{data.currency || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="支付时间">{formatUnixTime(data.payTime)}</Descriptions.Item>
|
||||
<Descriptions.Item label="发货时间">{formatUnixTime(data.shipTime)}</Descriptions.Item>
|
||||
<Descriptions.Item label="完成时间">{formatUnixTime(data.finishTime)}</Descriptions.Item>
|
||||
<Descriptions.Item label="取消时间">{formatUnixTime(data.cancelTime)}</Descriptions.Item>
|
||||
<Descriptions.Item label="自动确认">{formatUnixTime(data.autoConfirmAt)}</Descriptions.Item>
|
||||
<Descriptions.Item label="支付渠道">{data.payChannel || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="创建时间">{formatUnixTime(data.createdAt)}</Descriptions.Item>
|
||||
<Descriptions.Item label="更新时间">{formatUnixTime(data.updatedAt)}</Descriptions.Item>
|
||||
<Descriptions.Item label="扩展 JSON" span={2}>
|
||||
<Typography.Text style={{ whiteSpace: 'pre-wrap' }}>
|
||||
{prettyJsonText(data.extraInfoJson) || '-'}
|
||||
</Typography.Text>
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</Card>
|
||||
|
||||
<Card className="page-card" title="收货与物流">
|
||||
<Descriptions column={2} size="small">
|
||||
<Descriptions.Item label="收货人">{data.receiverName}</Descriptions.Item>
|
||||
<Descriptions.Item label="手机号">{data.receiverMobile}</Descriptions.Item>
|
||||
<Descriptions.Item label="国家区号">{data.receiverCountryCode || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="省份">{data.receiverProvince || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="城市">{data.receiverCity || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="区县">{data.receiverDistrict || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="完整地址" span={2}>
|
||||
{[data.receiverProvince, data.receiverCity, data.receiverDistrict, data.receiverAddress]
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="邮编">{data.receiverZipCode || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="物流公司">{data.deliveryCompany || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="运单号">{data.deliveryNo || '-'}</Descriptions.Item>
|
||||
<Descriptions.Item label="商家备注" span={2}>
|
||||
{data.sellerRemark || '-'}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="买家备注" span={2}>
|
||||
{data.buyerRemark || '-'}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
</Card>
|
||||
|
||||
<Card className="page-card" title="商品明细">
|
||||
<Table
|
||||
rowKey="id"
|
||||
pagination={false}
|
||||
dataSource={data.items}
|
||||
columns={[
|
||||
{
|
||||
title: '商品',
|
||||
dataIndex: 'spuName',
|
||||
render: (_, record) => (
|
||||
<Space direction="vertical" size={2}>
|
||||
<Typography.Text strong>{record.spuName}</Typography.Text>
|
||||
<Typography.Text type="secondary">{record.skuName}</Typography.Text>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '规格 JSON',
|
||||
dataIndex: 'skuSpecJson',
|
||||
width: 260,
|
||||
render: value => (
|
||||
<Typography.Text style={{ whiteSpace: 'pre-wrap' }}>
|
||||
{prettyJsonText(value) || '-'}
|
||||
</Typography.Text>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '数量',
|
||||
dataIndex: 'buyNum',
|
||||
width: 90,
|
||||
},
|
||||
{
|
||||
title: '单价',
|
||||
dataIndex: 'salePrice',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '原价',
|
||||
dataIndex: 'originPrice',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '金额',
|
||||
dataIndex: 'itemAmount',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '优惠',
|
||||
dataIndex: 'discountAmount',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '退款',
|
||||
dataIndex: 'refundAmount',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '售后状态',
|
||||
dataIndex: 'afterSaleStatus',
|
||||
width: 120,
|
||||
render: value => <Tag color={getStatusColor(value)}>{getStatusLabel(value)}</Tag>,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Card>
|
||||
</Space>
|
||||
)}
|
||||
</Spin>
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user