forked from yoone/WEB
1
0
Fork 0
WEB/src/pages/Subscription/Orders/index.tsx

231 lines
7.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useRef, useState } from 'react';
import { PageContainer } from '@ant-design/pro-layout';
import type { ProColumns, ActionType, ProTableProps } from '@ant-design/pro-components';
import { ProTable } from '@ant-design/pro-components';
import { App, Tag, Button, Drawer, List } from 'antd';
import dayjs from 'dayjs';
import { ordercontrollerGetorders } from '@/servers/api/order';
import { sitecontrollerAll } from '@/servers/api/site';
import { request } from 'umi';
interface OrderItemRow {
id: number;
externalOrderId: string;
siteId: string;
date_created: string;
customer_email: string;
payment_method: string;
total: number;
orderStatus: string;
}
const OrdersPage: React.FC = () => {
const actionRef = useRef<ActionType>();
const { message } = App.useApp();
// 抽屉状态用于展示与订阅相关的订单详情含行项目meta
const [drawerOpen, setDrawerOpen] = useState(false);
const [drawerTitle, setDrawerTitle] = useState<string>('订阅关联');
const [drawerItems, setDrawerItems] = useState<any[]>([]);
const [drawerMeta, setDrawerMeta] = useState<any[]>([]);
const [isSubscription, setIsSubscription] = useState<boolean>(false);
const columns: ProColumns<OrderItemRow>[] = [
{
title: '订单ID',
dataIndex: 'externalOrderId',
width: 120,
ellipsis: true,
hideInSearch: true,
},
{
title: '站点',
dataIndex: 'siteId',
width: 120,
valueType: 'select',
request: async () => {
const { data = [] } = await sitecontrollerAll();
return (data || []).map((item: any) => ({ label: item.siteName, value: item.id }));
},
},
{
title: '下单时间',
dataIndex: 'date_created',
width: 180,
hideInSearch: true,
render: (_, row) => (row?.date_created ? dayjs(row.date_created).format('YYYY-MM-DD HH:mm') : '-'),
},
{
title: '邮箱',
dataIndex: 'customer_email',
width: 200,
},
{
title: '支付方式',
dataIndex: 'payment_method',
width: 140,
},
{
title: '金额',
dataIndex: 'total',
width: 100,
hideInSearch: true,
},
{
title: 'ERP状态',
dataIndex: 'orderStatus',
width: 120,
hideInSearch: true,
render: (_, row) => <Tag>{row.orderStatus}</Tag>,
},
{
title: '订阅关联',
dataIndex: 'subscription_related',
width: 120,
hideInSearch: true,
render: (_, row) => (
<Button
size="small"
onClick={async () => {
try {
// 拉取订单详情(包含 items 与 meta_data用于判断是否为订阅订单
const resp = await request(`/order/${row.id}`, { method: 'GET' });
const { success, data, message: errMsg } = resp as any;
if (!success) throw new Error(errMsg || '获取失败');
const items: any[] = data?.items || [];
const orderMeta: any[] = data?.meta_data || [];
// 订阅识别:检查行项目 meta_data 中的关键键
const keys = [
'is_subscription',
'_wcs_bought_as_subscription',
'subscription_product_type',
'subscription_period',
'subscription_interval',
'_subscription',
'_subscription_period',
'_subscription_interval',
];
let detected = false;
for (const it of items) {
const md = Array.isArray(it?.meta_data) ? it.meta_data : [];
if (md.some((m: any) => keys.includes(String(m?.key)))) {
detected = true;
break;
}
}
setIsSubscription(detected);
setDrawerItems(items);
setDrawerMeta(orderMeta);
setDrawerTitle(`订阅关联(订单号:${row.externalOrderId}`);
setDrawerOpen(true);
} catch (e: any) {
message.error(e?.message || '获取失败');
}
}}
>
</Button>
),
},
{
title: '时间范围',
dataIndex: 'dateRange',
valueType: 'dateRange',
hideInTable: true,
},
{
title: '商品关键字',
dataIndex: 'keyword',
hideInTable: true,
},
];
const request: ProTableProps<OrderItemRow>['request'] = async (params) => {
try {
const { current = 1, pageSize = 10, siteId, keyword, customer_email, payment_method } = params as any;
const [startDate, endDate] = (params as any).dateRange || [];
const resp = await ordercontrollerGetorders({
current,
pageSize,
siteId,
keyword,
customer_email,
payment_method,
isSubscriptionOnly: true as any,
startDate: startDate ? (dayjs(startDate).toISOString() as any) : undefined,
endDate: endDate ? (dayjs(endDate).toISOString() as any) : undefined,
} as any);
const { success, data, message: errMsg } = resp as any;
if (!success) throw new Error(errMsg || '获取失败');
return {
data: (data?.items ?? []) as OrderItemRow[],
total: data?.total ?? 0,
success: true,
};
} catch (e: any) {
message.error(e?.message || '获取失败');
return { data: [], total: 0, success: false };
}
};
return (
<PageContainer title='订阅订单'>
<ProTable<OrderItemRow>
actionRef={actionRef}
rowKey='id'
columns={columns}
request={request}
pagination={{ showSizeChanger: true }}
search={{
labelWidth: 90,
span: 6,
}}
toolBarRender={false}
/>
{/* 订阅关联抽屉:展示行项目与订单元数据,标注是否订阅 */}
<Drawer
open={drawerOpen}
title={drawerTitle}
width={720}
onClose={() => setDrawerOpen(false)}
>
<div style={{ marginBottom: 12 }}>
<Tag color={isSubscription ? 'green' : 'default'}>
{isSubscription ? '订阅订单' : '非订阅订单'}
</Tag>
</div>
{/* 行项目列表,展示 meta_data 关键键值 */}
<List
header={<div></div>}
dataSource={drawerItems}
renderItem={(item: any) => (
<List.Item>
<List.Item.Meta
title={`${item?.name || '-'}(数量:${item?.quantity || 0}`}
description={`SKU${item?.sku || '-'}产品ID${item?.externalProductId || '-'}变体ID${item?.externalVariationId || '-'}`}
/>
<div style={{ maxWidth: 420 }}>
{(Array.isArray(item?.meta_data) ? item.meta_data : []).map((m: any) => (
<Tag key={`${m?.key}-${m?.id}`}>{`${m?.key}: ${m?.value}`}</Tag>
))}
</div>
</List.Item>
)}
/>
{/* 订单级元数据 */}
<List
style={{ marginTop: 16 }}
header={<div></div>}
dataSource={drawerMeta}
renderItem={(m: any) => (
<List.Item>
<Tag>{`${m?.key}: ${m?.value}`}</Tag>
</List.Item>
)}
/>
</Drawer>
</PageContainer>
);
};
export default OrdersPage;