163 lines
4.5 KiB
TypeScript
163 lines
4.5 KiB
TypeScript
import { ordercontrollerGetordersales } from '@/servers/api/order';
|
|
import { sitecontrollerAll } from '@/servers/api/site';
|
|
import type {
|
|
ActionType,
|
|
ProColumns,
|
|
ProTableProps,
|
|
} from '@ant-design/pro-components';
|
|
import { ProTable } from '@ant-design/pro-components';
|
|
import { PageContainer } from '@ant-design/pro-layout';
|
|
import { App } from 'antd';
|
|
import dayjs from 'dayjs';
|
|
import React, { useRef } from 'react';
|
|
|
|
// 列表行数据结构(订单商品聚合)
|
|
interface OrderItemAggRow {
|
|
externalProductId: number; // 商品ID(来自 WooCommerce 产品ID)
|
|
externalVariationId: number; // 变体ID(来自 WooCommerce 变体ID)
|
|
name: string; // 商品名称
|
|
totalQuantity: number; // 总售出数量(时间范围内)
|
|
totalOrders: number; // 涉及订单数(去重)
|
|
firstOrderCount: number; // 客户首单次数(该商品)
|
|
secondOrderCount: number; // 客户第二次购买次数(该商品)
|
|
thirdOrderCount: number; // 客户第三次购买次数(该商品)
|
|
moreThirdOrderCount: number; // 客户超过三次购买次数(该商品)
|
|
}
|
|
|
|
const OrderItemsPage: React.FC = () => {
|
|
const actionRef = useRef<ActionType>();
|
|
const { message } = App.useApp();
|
|
|
|
// 列配置(中文标题,符合当前项目风格;显示英文默认语言可后续走国际化)
|
|
const columns: ProColumns<OrderItemAggRow>[] = [
|
|
{
|
|
title: '商品名称',
|
|
dataIndex: 'name',
|
|
width: 220,
|
|
},
|
|
{
|
|
title: '商品ID',
|
|
dataIndex: 'externalProductId',
|
|
width: 120,
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '变体ID',
|
|
dataIndex: 'externalVariationId',
|
|
width: 120,
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '总售出数量',
|
|
dataIndex: 'totalQuantity',
|
|
width: 130,
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '订单数',
|
|
dataIndex: 'totalOrders',
|
|
width: 110,
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '首单次数',
|
|
dataIndex: 'firstOrderCount',
|
|
width: 120,
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '第二次购买',
|
|
dataIndex: 'secondOrderCount',
|
|
width: 120,
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '第三次购买',
|
|
dataIndex: 'thirdOrderCount',
|
|
width: 120,
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '超过三次购买',
|
|
dataIndex: 'moreThirdOrderCount',
|
|
width: 140,
|
|
hideInSearch: true,
|
|
},
|
|
// 搜索区域字段
|
|
{
|
|
title: '站点',
|
|
dataIndex: 'siteId',
|
|
valueType: 'select',
|
|
request: async () => {
|
|
// 拉取站点列表(后台 /site/all)
|
|
const { data = [] } = await sitecontrollerAll();
|
|
return (data || []).map((item: any) => ({
|
|
label: item.name,
|
|
value: item.id,
|
|
}));
|
|
},
|
|
},
|
|
{
|
|
title: '时间范围',
|
|
dataIndex: 'dateRange',
|
|
valueType: 'dateRange',
|
|
hideInTable: true,
|
|
},
|
|
{
|
|
title: '商品关键字',
|
|
dataIndex: 'name',
|
|
hideInTable: true,
|
|
},
|
|
];
|
|
|
|
// 表格请求方法:调用 /order/getOrderSales 接口并设置 isSource=true 获取订单项聚合
|
|
const request: ProTableProps<OrderItemAggRow>['request'] = async (
|
|
params: any,
|
|
) => {
|
|
try {
|
|
const { current = 1, pageSize = 10, siteId, name } = params as any;
|
|
const [startDate, endDate] = (params as any).dateRange || [];
|
|
// 调用后端接口(isSource=true 表示按订单项聚合)
|
|
const resp = await ordercontrollerGetordersales({
|
|
current,
|
|
pageSize,
|
|
siteId,
|
|
name,
|
|
isSource: 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 OrderItemAggRow[],
|
|
total: data?.total ?? 0,
|
|
success: true,
|
|
};
|
|
} catch (e: any) {
|
|
message.error(e?.message || '获取失败');
|
|
return { data: [], total: 0, success: false };
|
|
}
|
|
};
|
|
|
|
return (
|
|
<PageContainer title="订单商品概览">
|
|
<ProTable<OrderItemAggRow>
|
|
actionRef={actionRef}
|
|
rowKey={(r) =>
|
|
`${r.externalProductId}-${r.externalVariationId}-${r.name}`
|
|
}
|
|
columns={columns}
|
|
request={request}
|
|
pagination={{ showSizeChanger: true }}
|
|
search={{ labelWidth: 90, span: 6 }}
|
|
toolBarRender={false}
|
|
/>
|
|
</PageContainer>
|
|
);
|
|
};
|
|
|
|
export default OrderItemsPage;
|