zksu
/
WEB
forked from yoone/WEB
1
0
Fork 0

feat: 更新订单统计功能和相关类型定义

This commit is contained in:
zhuotianyuan 2025-12-30 10:34:45 +08:00
parent aae4b20938
commit 32e2759151
4 changed files with 228 additions and 18 deletions

View File

@ -73,6 +73,7 @@ import {
Tag, Tag,
} from 'antd'; } from 'antd';
import React, { useMemo, useRef, useState } from 'react'; import React, { useMemo, useRef, useState } from 'react';
import { request, useParams } from '@umijs/max';
import RelatedOrders from '../../Subscription/Orders/RelatedOrders'; import RelatedOrders from '../../Subscription/Orders/RelatedOrders';
const ListPage: React.FC = () => { const ListPage: React.FC = () => {
@ -494,15 +495,25 @@ const ListPage: React.FC = () => {
title="批量导出" title="批量导出"
description="确认导出选中的订单吗?" description="确认导出选中的订单吗?"
onConfirm={async () => { onConfirm={async () => {
console.log(selectedRowKeys);
try { try {
const { success, message: errMsg } = const res = await request('/order/order/export', {
await ordercontrollerExportorder({ method: 'GET',
params: {
ids: selectedRowKeys, ids: selectedRowKeys,
});
if (!success) {
throw new Error(errMsg);
} }
message.success('导出成功'); });
if (res?.success && res?.data?.csv) {
const blob = new Blob([res.data.csv], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'customers.csv';
a.click();
URL.revokeObjectURL(url);
} else {
message.error(res.message || '导出失败');
}
actionRef.current?.reload(); actionRef.current?.reload();
setSelectedRowKeys([]); setSelectedRowKeys([]);
} catch (error: any) { } catch (error: any) {
@ -510,14 +521,10 @@ const ListPage: React.FC = () => {
} }
}} }}
> >
<Button <Button type="primary" ghost>
type="primary"
disabled={selectedRowKeys.length === 0}
ghost
>
</Button> </Button>
</Popconfirm>, </Popconfirm>
]} ]}
request={async ({ date, ...param }: any) => { request={async ({ date, ...param }: any) => {
if (param.status === 'all') { if (param.status === 'all') {

View File

@ -21,7 +21,9 @@ import { Button, Space, Tag } from 'antd';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import ReactECharts from 'echarts-for-react'; import ReactECharts from 'echarts-for-react';
import { useEffect, useMemo, useRef, useState } from 'react'; import { useEffect, useMemo, useRef, useState } from 'react';
import weekOfYear from 'dayjs/plugin/weekOfYear';
dayjs.extend(weekOfYear);
const highlightText = (text: string, keyword: string) => { const highlightText = (text: string, keyword: string) => {
if (!keyword) return text; if (!keyword) return text;
const parts = text.split(new RegExp(`(${keyword})`, 'gi')); const parts = text.split(new RegExp(`(${keyword})`, 'gi'));
@ -128,7 +130,21 @@ const ListPage: React.FC = () => {
}); });
if (success) { if (success) {
const res = data?.sort(() => -1); const res = data?.sort(() => -1);
setXAxis(res?.map((v) => dayjs(v.order_date).format('YYYY-MM-DD'))); const formatMap = {
month: 'YYYY-MM',
week: 'YYYY年第WW周',
day: 'YYYY-MM-DD',
};
const format = formatMap[params.grouping] || 'YYYY-MM-DD';
if (params.grouping === 'week') {
setXAxis(res?.map((v) => {
const [year, week] = v.order_date.split('-');
return `${year}年第${week}`;
}));
} else {
setXAxis(res?.map((v) => dayjs(v.order_date).format(format)));
}
setSeries([ setSeries([
{ {
name: 'TOGO CPC订单数', name: 'TOGO CPC订单数',
@ -583,6 +599,16 @@ const ListPage: React.FC = () => {
name="date" name="date"
/> />
{/* <ProFormText label="关键词" name="keyword" /> */} {/* <ProFormText label="关键词" name="keyword" /> */}
<ProFormSelect
label="统计周期"
name="grouping"
initialValue="day"
options={[
{ label: '月', value: 'month' },
{ label: '周', value: 'week' },
{ label: '日', value: 'day' },
]}
/>
<ProFormSelect <ProFormSelect
label="站点" label="站点"
name="siteId" name="siteId"

View File

@ -39,6 +39,13 @@ const ListPage: React.FC = () => {
data: data?.inactiveRes?.map((v) => v.new_user_count)?.sort((_) => -1), data: data?.inactiveRes?.map((v) => v.new_user_count)?.sort((_) => -1),
label: { label: {
show: true, show: true,
formatter: function (params) {
if (!params.value) return '';
return Math.abs(params.value)
+'\n'
+Math.abs(data?.inactiveRes?.find((item) => item.order_month === params.name)?.new_user_total || 0);
},
color: '#000000',
}, },
emphasis: { emphasis: {
focus: 'series', focus: 'series',
@ -52,6 +59,13 @@ const ListPage: React.FC = () => {
data: data?.inactiveRes?.map((v) => v.old_user_count)?.sort((_) => -1), data: data?.inactiveRes?.map((v) => v.old_user_count)?.sort((_) => -1),
label: { label: {
show: true, show: true,
formatter: function (params) {
if (!params.value) return '';
return Math.abs(params.value)
+'\n'
+Math.abs(data?.inactiveRes?.find((item) => item.order_month === params.name)?.old_user_total || 0);
},
color: '#000000',
}, },
emphasis: { emphasis: {
focus: 'series', focus: 'series',
@ -69,9 +83,12 @@ const ListPage: React.FC = () => {
show: true, show: true,
formatter: function (params) { formatter: function (params) {
if (!params.value) return ''; if (!params.value) return '';
return Math.abs(params.value); return Math.abs(params.value)
+'\n'+
+Math.abs(data?.res?.find((item) => item.order_month === params.name &&
item.first_order_month_group === v)?.total || 0);
}, },
color: '#fff', color: '#000000',
}, },
data: xAxisData.map((month) => { data: xAxisData.map((month) => {
return ( return (

View File

@ -854,6 +854,7 @@ declare namespace API {
purchaseType?: 'all' | 'first_purchase' | 'repeat_purchase'; purchaseType?: 'all' | 'first_purchase' | 'repeat_purchase';
orderType?: 'all' | 'cpc' | 'non_cpc'; orderType?: 'all' | 'cpc' | 'non_cpc';
brand?: 'all' | 'zyn' | 'yoone' | 'zolt'; brand?: 'all' | 'zyn' | 'yoone' | 'zolt';
grouping?: 'day' | 'week' | 'month';
}; };
type OrderStatusCountDTO = { type OrderStatusCountDTO = {
@ -1573,6 +1574,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1587,6 +1592,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1601,6 +1610,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1615,6 +1628,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1629,6 +1646,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1643,6 +1664,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1657,6 +1682,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
customerId: number; customerId: number;
@ -1677,6 +1706,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1695,6 +1728,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1719,6 +1756,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1738,6 +1779,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1752,6 +1797,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1766,6 +1815,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -1785,6 +1838,10 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
siteId: number; siteId: number;
@ -2239,6 +2296,8 @@ declare namespace API {
email?: string; email?: string;
/** 电话 */ /** 电话 */
phone?: string; phone?: string;
/** 配送方式 */
method_title?: string;
}; };
type UnifiedCategoryDTO = { type UnifiedCategoryDTO = {
@ -2248,6 +2307,19 @@ declare namespace API {
name?: string; name?: string;
}; };
type UnifiedCouponLineDTO = {
/** 优惠券项ID */
id?: Record<string, any>;
/** 优惠券项代码 */
code?: string;
/** 优惠券项折扣 */
discount?: string;
/** 优惠券项税额 */
discount_tax?: string;
/** 优惠券项元数据 */
meta_data?: any;
};
type UnifiedCustomerDTO = { type UnifiedCustomerDTO = {
/** 客户ID */ /** 客户ID */
id?: Record<string, any>; id?: Record<string, any>;
@ -2292,6 +2364,29 @@ declare namespace API {
per_page?: number; per_page?: number;
/** 总页数 */ /** 总页数 */
totalPages?: number; totalPages?: number;
/** 分页后的数据 */
after?: string;
/** 分页前的数据 */
before?: string;
};
type UnifiedFeeLineDTO = {
/** 费用项ID */
id?: Record<string, any>;
/** 费用项名称 */
name?: string;
/** 税率类 */
tax_class?: string;
/** 税率状态 */
tax_status?: string;
/** 总金额 */
total?: string;
/** 总税额 */
total_tax?: string;
/** 税额详情 */
taxes?: any;
/** 元数据 */
meta_data?: any;
}; };
type UnifiedImageDTO = { type UnifiedImageDTO = {
@ -2333,6 +2428,10 @@ declare namespace API {
per_page?: number; per_page?: number;
/** 总页数 */ /** 总页数 */
totalPages?: number; totalPages?: number;
/** 分页后的数据 */
after?: string;
/** 分页前的数据 */
before?: string;
}; };
type UnifiedOrderDTO = { type UnifiedOrderDTO = {
@ -2344,6 +2443,8 @@ declare namespace API {
status?: string; status?: string;
/** 货币 */ /** 货币 */
currency?: string; currency?: string;
/** 货币符号 */
currency_symbol?: string;
/** 总金额 */ /** 总金额 */
total?: string; total?: string;
/** 客户ID */ /** 客户ID */
@ -2352,6 +2453,8 @@ declare namespace API {
customer_name?: string; customer_name?: string;
/** 客户邮箱 */ /** 客户邮箱 */
email?: string; email?: string;
/** 客户邮箱 */
customer_email?: string;
/** 订单项(具体的商品) */ /** 订单项(具体的商品) */
line_items?: UnifiedOrderLineItemDTO[]; line_items?: UnifiedOrderLineItemDTO[];
/** 销售项(兼容前端) */ /** 销售项(兼容前端) */
@ -2372,6 +2475,22 @@ declare namespace API {
date_modified?: string; date_modified?: string;
/** 原始数据 */ /** 原始数据 */
raw?: Record<string, any>; raw?: Record<string, any>;
/** 配送方式 */
shipping_lines?: UnifiedShippingLineDTO[];
/** 费用项 */
fee_lines?: UnifiedFeeLineDTO[];
/** 优惠券项 */
coupon_lines?: UnifiedCouponLineDTO[];
/** 支付时间 */
date_paid?: string;
/** 客户IP地址 */
customer_ip_address?: string;
/** UTM来源 */
utm_source?: string;
/** 设备类型 */
device_type?: string;
/** 来源类型 */
source_type?: string;
}; };
type UnifiedOrderLineItemDTO = { type UnifiedOrderLineItemDTO = {
@ -2402,6 +2521,10 @@ declare namespace API {
per_page?: number; per_page?: number;
/** 总页数 */ /** 总页数 */
totalPages?: number; totalPages?: number;
/** 分页后的数据 */
after?: string;
/** 分页前的数据 */
before?: string;
}; };
type UnifiedPaginationDTO = { type UnifiedPaginationDTO = {
@ -2415,6 +2538,10 @@ declare namespace API {
per_page?: number; per_page?: number;
/** 总页数 */ /** 总页数 */
totalPages?: number; totalPages?: number;
/** 分页后的数据 */
after?: string;
/** 分页前的数据 */
before?: string;
}; };
type UnifiedProductAttributeDTO = { type UnifiedProductAttributeDTO = {
@ -2486,6 +2613,10 @@ declare namespace API {
per_page?: number; per_page?: number;
/** 总页数 */ /** 总页数 */
totalPages?: number; totalPages?: number;
/** 分页后的数据 */
after?: string;
/** 分页前的数据 */
before?: string;
}; };
type UnifiedProductVariationDTO = { type UnifiedProductVariationDTO = {
@ -2541,6 +2672,10 @@ declare namespace API {
per_page?: number; per_page?: number;
/** 总页数 */ /** 总页数 */
totalPages?: number; totalPages?: number;
/** 分页后的数据 */
after?: string;
/** 分页前的数据 */
before?: string;
}; };
type UnifiedSearchParamsDTO = { type UnifiedSearchParamsDTO = {
@ -2552,10 +2687,31 @@ declare namespace API {
search?: string; search?: string;
/** 过滤条件对象 */ /** 过滤条件对象 */
where?: Record<string, any>; where?: Record<string, any>;
/** 创建时间后 */
after?: string;
/** 创建时间前 */
before?: string;
/** 排序对象,例如 { "sku": "desc" } */ /** 排序对象,例如 { "sku": "desc" } */
orderBy?: Record<string, any>; orderBy?: Record<string, any>;
}; };
type UnifiedShippingLineDTO = {
/** 配送方式ID */
id?: Record<string, any>;
/** 配送方式名称 */
method_title?: string;
/** 配送方式实例ID */
method_id?: string;
/** 配送方式金额 */
total?: string;
/** 配送方式税额 */
total_tax?: string;
/** 配送方式税额详情 */
taxes?: any;
/** 配送方式元数据 */
meta_data?: any;
};
type UnifiedSubscriptionDTO = { type UnifiedSubscriptionDTO = {
/** 订阅ID */ /** 订阅ID */
id?: Record<string, any>; id?: Record<string, any>;
@ -2592,6 +2748,10 @@ declare namespace API {
per_page?: number; per_page?: number;
/** 总页数 */ /** 总页数 */
totalPages?: number; totalPages?: number;
/** 分页后的数据 */
after?: string;
/** 分页前的数据 */
before?: string;
}; };
type UnifiedTagDTO = { type UnifiedTagDTO = {