Skip to content

Commit 7b9ea62

Browse files
YunaiVgitee-org
authored andcommitted
!273 商城首页
Merge pull request !273 from 疯狂的世界/dev
2 parents 99172ea + edfd039 commit 7b9ea62

File tree

16 files changed

+1086
-327
lines changed

16 files changed

+1086
-327
lines changed

src/api/mall/statistics/common.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/** 数据对照 Response VO */
2+
export interface DataComparisonRespVO<T> {
3+
value: T
4+
reference: T
5+
}

src/api/mall/statistics/member.ts

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import request from '@/config/axios'
22
import dayjs from 'dayjs'
3-
import { TradeStatisticsComparisonRespVO } from '@/api/mall/statistics/trade'
3+
import { DataComparisonRespVO } from '@/api/mall/statistics/common'
44
import { formatDate } from '@/utils/formatTime'
55

66
/** 会员分析 Request VO */
@@ -10,17 +10,17 @@ export interface MemberAnalyseReqVO {
1010

1111
/** 会员分析 Response VO */
1212
export interface MemberAnalyseRespVO {
13-
visitorCount: number
13+
visitUserCount: number
1414
orderUserCount: number
1515
payUserCount: number
1616
atv: number
17-
comparison: TradeStatisticsComparisonRespVO<MemberAnalyseComparisonRespVO>
17+
comparison: DataComparisonRespVO<MemberAnalyseComparisonRespVO>
1818
}
1919

2020
/** 会员分析对照数据 Response VO */
2121
export interface MemberAnalyseComparisonRespVO {
22-
userCount: number
23-
activeUserCount: number
22+
registerUserCount: number
23+
visitUserCount: number
2424
rechargeUserCount: number
2525
}
2626

@@ -29,8 +29,8 @@ export interface MemberAreaStatisticsRespVO {
2929
areaId: number
3030
areaName: string
3131
userCount: number
32-
orderCreateCount: number
33-
orderPayCount: number
32+
orderCreateUserCount: number
33+
orderPayUserCount: number
3434
orderPayPrice: number
3535
}
3636

@@ -54,6 +54,20 @@ export interface MemberTerminalStatisticsRespVO {
5454
userCount: number
5555
}
5656

57+
/** 会员数量统计 Response VO */
58+
export interface MemberCountRespVO {
59+
/** 用户访问量 */
60+
visitUserCount: string
61+
/** 新增用户数量 */
62+
createUserCount: number
63+
}
64+
65+
/** 会员注册数量 Response VO */
66+
export interface MemberRegisterCountRespVO {
67+
date: string
68+
count: number
69+
}
70+
5771
// 查询会员统计
5872
export const getMemberSummary = () => {
5973
return request.get<MemberSummaryRespVO>({
@@ -89,3 +103,21 @@ export const getMemberTerminalStatisticsList = () => {
89103
url: '/statistics/member/get-terminal-statistics-list'
90104
})
91105
}
106+
107+
// 获得用户数量量对照
108+
export const getUserCountComparison = () => {
109+
return request.get<DataComparisonRespVO<MemberCountRespVO>>({
110+
url: '/statistics/member/user-count-comparison'
111+
})
112+
}
113+
114+
// 获得会员注册数量列表
115+
export const getMemberRegisterCountList = (
116+
beginTime: dayjs.ConfigType,
117+
endTime: dayjs.ConfigType
118+
) => {
119+
return request.get<MemberRegisterCountRespVO[]>({
120+
url: '/statistics/member/register-count-list',
121+
params: { times: [formatDate(beginTime), formatDate(endTime)] }
122+
})
123+
}

src/api/mall/statistics/pay.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import request from '@/config/axios'
2+
3+
/** 获取钱包充值金额 */
4+
export const getWalletRechargePrice = async () => {
5+
return await request.get<number>({ url: `/statistics/pay/wallet-recharge-price` })
6+
}

src/api/mall/statistics/trade.ts

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
import request from '@/config/axios'
22
import dayjs from 'dayjs'
33
import { formatDate } from '@/utils/formatTime'
4-
5-
/** 交易统计对照 Response VO */
6-
export interface TradeStatisticsComparisonRespVO<T> {
7-
value: T
8-
reference: T
9-
}
4+
import { DataComparisonRespVO } from '@/api/mall/statistics/common'
105

116
/** 交易统计 Response VO */
127
export interface TradeSummaryRespVO {
@@ -24,46 +19,100 @@ export interface TradeTrendReqVO {
2419
/** 交易状况统计 Response VO */
2520
export interface TradeTrendSummaryRespVO {
2621
time: string
27-
turnover: number
22+
turnoverPrice: number
2823
orderPayPrice: number
2924
rechargePrice: number
3025
expensePrice: number
31-
balancePrice: number
26+
orderWalletPayPrice: number
3227
brokerageSettlementPrice: number
3328
orderRefundPrice: number
3429
}
3530

31+
/** 交易订单数量 Response VO */
32+
export interface TradeOrderCountRespVO {
33+
/** 待发货 */
34+
undelivered?: number
35+
/** 待核销 */
36+
pickUp?: number
37+
/** 退款中 */
38+
afterSaleApply?: number
39+
/** 提现待审核 */
40+
auditingWithdraw?: number
41+
}
42+
43+
/** 交易订单统计 Response VO */
44+
export interface TradeOrderSummaryRespVO {
45+
/** 支付订单商品数 */
46+
orderPayCount?: number
47+
/** 总支付金额,单位:分 */
48+
orderPayPrice?: number
49+
}
50+
51+
/** 订单量趋势统计 Response VO */
52+
export interface TradeOrderTrendRespVO {
53+
/** 日期 */
54+
date: string
55+
/** 订单数量 */
56+
orderPayCount: number
57+
/** 订单支付金额 */
58+
orderPayPrice: number
59+
}
60+
3661
// 查询交易统计
3762
export const getTradeStatisticsSummary = () => {
38-
return request.get<TradeStatisticsComparisonRespVO<TradeSummaryRespVO>>({
63+
return request.get<DataComparisonRespVO<TradeSummaryRespVO>>({
3964
url: '/statistics/trade/summary'
4065
})
4166
}
4267

4368
// 获得交易状况统计
4469
export const getTradeTrendSummary = (params: TradeTrendReqVO) => {
45-
return request.get<TradeStatisticsComparisonRespVO<TradeTrendSummaryRespVO>>({
70+
return request.get<DataComparisonRespVO<TradeTrendSummaryRespVO>>({
4671
url: '/statistics/trade/trend/summary',
4772
params: formatDateParam(params)
4873
})
4974
}
5075

5176
// 获得交易状况明细
52-
export const getTradeTrendList = (params: TradeTrendReqVO) => {
77+
export const getTradeStatisticsList = (params: TradeTrendReqVO) => {
5378
return request.get<TradeTrendSummaryRespVO[]>({
54-
url: '/statistics/trade/trend/list',
79+
url: '/statistics/trade/list',
5580
params: formatDateParam(params)
5681
})
5782
}
5883

5984
// 导出交易状况明细
60-
export const exportTradeTrend = (params: TradeTrendReqVO) => {
85+
export const exportTradeStatisticsExcel = (params: TradeTrendReqVO) => {
6186
return request.download({
62-
url: '/statistics/trade/trend/export-excel',
87+
url: '/statistics/trade/export-excel',
6388
params: formatDateParam(params)
6489
})
6590
}
6691

92+
// 获得交易订单数量
93+
export const getOrderCount = async () => {
94+
return await request.get<TradeOrderCountRespVO>({ url: `/statistics/trade/order-count` })
95+
}
96+
97+
// 获得交易订单数量对照
98+
export const getOrderComparison = async () => {
99+
return await request.get<DataComparisonRespVO<TradeOrderSummaryRespVO>>({
100+
url: `/statistics/trade/order-comparison`
101+
})
102+
}
103+
104+
// 获得订单量趋势统计
105+
export const getOrderCountTrendComparison = (
106+
type: number,
107+
beginTime: dayjs.ConfigType,
108+
endTime: dayjs.ConfigType
109+
) => {
110+
return request.get<DataComparisonRespVO<TradeOrderTrendRespVO>[]>({
111+
url: '/statistics/trade/order-count-trend',
112+
params: { type, beginTime: formatDate(beginTime), endTime: formatDate(endTime) }
113+
})
114+
}
115+
67116
/** 时间参数需要格式化, 确保接口能识别 */
68117
const formatDateParam = (params: TradeTrendReqVO) => {
69118
return { times: [formatDate(params.times[0]), formatDate(params.times[1])] } as TradeTrendReqVO
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<template>
2+
<div class="flex flex-row items-center gap-2">
3+
<el-radio-group v-model="shortcutDays" @change="handleShortcutDaysChange">
4+
<el-radio-button :label="1">昨天</el-radio-button>
5+
<el-radio-button :label="7">最近7天</el-radio-button>
6+
<el-radio-button :label="30">最近30天</el-radio-button>
7+
</el-radio-group>
8+
<el-date-picker
9+
v-model="times"
10+
value-format="YYYY-MM-DD HH:mm:ss"
11+
type="daterange"
12+
start-placeholder="开始日期"
13+
end-placeholder="结束日期"
14+
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
15+
:shortcuts="shortcuts"
16+
class="!w-240px"
17+
@change="emitDateRangePicker"
18+
/>
19+
<slot></slot>
20+
</div>
21+
</template>
22+
<script lang="ts" setup>
23+
import dayjs from 'dayjs'
24+
import * as DateUtil from '@/utils/formatTime'
25+
26+
/** 快捷日期范围选择组件 */
27+
defineOptions({ name: 'ShortcutDateRangePicker' })
28+
29+
const shortcutDays = ref(7) // 日期快捷天数(单选按钮组), 默认7天
30+
const times = ref<[dayjs.ConfigType, dayjs.ConfigType]>(['', '']) // 时间范围参数
31+
defineExpose({ times }) // 暴露时间范围参数
32+
/** 日期快捷选择 */
33+
const shortcuts = [
34+
{
35+
text: '昨天',
36+
value: () => DateUtil.getDayRange(new Date(), -1)
37+
},
38+
{
39+
text: '最近7天',
40+
value: () => DateUtil.getLast7Days()
41+
},
42+
{
43+
text: '本月',
44+
value: () => [dayjs().startOf('M'), dayjs().subtract(1, 'd')]
45+
},
46+
{
47+
text: '最近30天',
48+
value: () => DateUtil.getLast30Days()
49+
},
50+
{
51+
text: '最近1年',
52+
value: () => DateUtil.getLast1Year()
53+
}
54+
]
55+
56+
/** 设置时间范围 */
57+
function setTimes() {
58+
const beginDate = dayjs().subtract(shortcutDays.value, 'd')
59+
const yesterday = dayjs().subtract(1, 'd')
60+
times.value = DateUtil.getDateRange(beginDate, yesterday)
61+
}
62+
63+
/** 快捷日期单选按钮选中 */
64+
const handleShortcutDaysChange = async () => {
65+
// 设置时间范围
66+
setTimes()
67+
// 发送时间范围选中事件
68+
await emitDateRangePicker()
69+
}
70+
71+
/** 触发事件:时间范围选中 */
72+
const emits = defineEmits<{
73+
(e: 'change', times: [dayjs.ConfigType, dayjs.ConfigType]): void
74+
}>()
75+
/** 触发时间范围选中事件 */
76+
const emitDateRangePicker = async () => {
77+
// 开始与截止在同一天的, 折线图出不来, 需要延长一天
78+
if (DateUtil.isSameDay(times.value[0], times.value[1])) {
79+
// 前天
80+
times.value[0] = DateUtil.formatDate(dayjs(times.value[0]).subtract(1, 'd'))
81+
}
82+
emits('change', times.value)
83+
}
84+
85+
/** 初始化 **/
86+
onMounted(() => {
87+
handleShortcutDaysChange()
88+
})
89+
</script>

src/utils/index.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,16 @@ export const yuanToFen = (amount: string | number): number => {
233233
export const fenToYuan = (price: string | number): number => {
234234
return formatToFraction(price)
235235
}
236+
237+
/**
238+
* 计算环比
239+
*
240+
* @param value 当前数值
241+
* @param reference 对比数值
242+
*/
243+
export const calculateRelativeRate = (value?: number, reference?: number) => {
244+
// 防止除0
245+
if (!reference) return 0
246+
247+
return ((100 * ((value || 0) - reference)) / reference).toFixed(0)
248+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<template>
2+
<div class="flex flex-col gap-2 bg-[var(--el-bg-color-overlay)] p-6">
3+
<div class="flex items-center justify-between text-gray-500">
4+
<span>{{ title }}</span>
5+
<el-tag>{{ tag }}</el-tag>
6+
</div>
7+
<div class="flex flex-row items-baseline justify-between">
8+
<CountTo :prefix="prefix" :end-val="value" :decimals="decimals" class="text-3xl" />
9+
<span :class="toNumber(percent) > 0 ? 'text-red-500' : 'text-green-500'">
10+
{{ Math.abs(toNumber(percent)) }}%
11+
<Icon :icon="toNumber(percent) > 0 ? 'ep:caret-top' : 'ep:caret-bottom'" class="!text-sm" />
12+
</span>
13+
</div>
14+
<el-divider class="mb-1! mt-2!" />
15+
<div class="flex flex-row items-center justify-between text-sm">
16+
<span class="text-gray-500">昨日数据</span>
17+
<span>{{ prefix || '' }}{{ reference }}</span>
18+
</div>
19+
</div>
20+
</template>
21+
<script lang="ts" setup>
22+
import { propTypes } from '@/utils/propTypes'
23+
import { toNumber } from 'lodash-es'
24+
import { calculateRelativeRate } from '@/utils'
25+
26+
/** 交易对照卡片 */
27+
defineOptions({ name: 'ComparisonCard' })
28+
29+
const props = defineProps({
30+
title: propTypes.string.def('').isRequired,
31+
tag: propTypes.string.def(''),
32+
prefix: propTypes.string.def(''),
33+
value: propTypes.number.def(0).isRequired,
34+
reference: propTypes.number.def(0).isRequired,
35+
decimals: propTypes.number.def(0)
36+
})
37+
38+
// 计算环比
39+
const percent = computed(() =>
40+
calculateRelativeRate(props.value as number, props.reference as number)
41+
)
42+
</script>

0 commit comments

Comments
 (0)