Skip to content

Commit 654094b

Browse files
YunaiVgitee-org
authored andcommitted
!258 交易统计
Merge pull request !258 from 疯狂的世界/dev
2 parents fb94ae9 + 6475f81 commit 654094b

File tree

7 files changed

+677
-19
lines changed

7 files changed

+677
-19
lines changed

src/api/statistics/trade.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import request from '@/config/axios'
2+
import dayjs from 'dayjs'
3+
import { formatDate } from '@/utils/formatTime'
4+
5+
/** 交易统计对照 Response VO */
6+
export interface TradeStatisticsComparisonRespVO<T> {
7+
value: T
8+
reference: T
9+
}
10+
11+
/** 交易统计 Response VO */
12+
export interface TradeSummaryRespVO {
13+
yesterdayOrderCount: number
14+
monthOrderCount: number
15+
yesterdayPayPrice: number
16+
monthPayPrice: number
17+
}
18+
19+
/** 交易状况 Request VO */
20+
export interface TradeTrendReqVO {
21+
times: [dayjs.ConfigType, dayjs.ConfigType]
22+
}
23+
24+
/** 交易状况统计 Response VO */
25+
export interface TradeTrendSummaryRespVO {
26+
time: string
27+
turnover: number
28+
orderPayPrice: number
29+
rechargePrice: number
30+
expensePrice: number
31+
balancePrice: number
32+
brokerageSettlementPrice: number
33+
orderRefundPrice: number
34+
}
35+
36+
// 查询交易统计
37+
export const getTradeStatisticsSummary = () => {
38+
return request.get<TradeStatisticsComparisonRespVO<TradeSummaryRespVO>>({
39+
url: '/statistics/trade/summary'
40+
})
41+
}
42+
43+
// 获得交易状况统计
44+
export const getTradeTrendSummary = (params: TradeTrendReqVO) => {
45+
return request.get<TradeStatisticsComparisonRespVO<TradeTrendSummaryRespVO>>({
46+
url: '/statistics/trade/trend/summary',
47+
params: formatDateParam(params)
48+
})
49+
}
50+
51+
// 获得交易状况明细
52+
export const getTradeTrendList = (params: TradeTrendReqVO) => {
53+
return request.get<TradeTrendSummaryRespVO[]>({
54+
url: '/statistics/trade/trend/list',
55+
params: formatDateParam(params)
56+
})
57+
}
58+
59+
// 导出交易状况明细
60+
export const exportTradeTrend = (params: TradeTrendReqVO) => {
61+
return request.download({
62+
url: '/statistics/trade/trend/export-excel',
63+
params: formatDateParam(params)
64+
})
65+
}
66+
67+
/** 时间参数需要格式化, 确保接口能识别 */
68+
const formatDateParam = (params: TradeTrendReqVO) => {
69+
return { times: [formatDate(params.times[0]), formatDate(params.times[1])] } as TradeTrendReqVO
70+
}

src/components/CountTo/src/CountTo.vue

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@ const { getPrefixCls } = useDesign()
1111
const prefixCls = getPrefixCls('count-to')
1212
1313
const props = defineProps({
14-
startVal: propTypes.number.def(0),
15-
endVal: propTypes.number.def(2021),
16-
duration: propTypes.number.def(3000),
17-
autoplay: propTypes.bool.def(true),
18-
decimals: propTypes.number.validate((value: number) => value >= 0).def(0),
19-
decimal: propTypes.string.def('.'),
20-
separator: propTypes.string.def(','),
21-
prefix: propTypes.string.def(''),
22-
suffix: propTypes.string.def(''),
23-
useEasing: propTypes.bool.def(true),
14+
startVal: propTypes.number.def(0), // 开始播放值
15+
endVal: propTypes.number.def(2021), // 最终值
16+
duration: propTypes.number.def(3000), // 动画时长
17+
autoplay: propTypes.bool.def(true), // 是否自动播放动画, 默认播放
18+
decimals: propTypes.number.validate((value: number) => value >= 0).def(0), // 显示的小数位数, 默认不显示小数
19+
decimal: propTypes.string.def('.'), // 小数分隔符号, 默认为点
20+
separator: propTypes.string.def(','), // 数字每三位的分隔符, 默认为逗号
21+
prefix: propTypes.string.def(''), // 前缀, 数值前面显示的内容
22+
suffix: propTypes.string.def(''), // 后缀, 数值后面显示的内容
23+
useEasing: propTypes.bool.def(true), // 是否使用缓动效果, 默认启用
2424
easingFn: {
2525
type: Function as PropType<(t: number, b: number, c: number, d: number) => number>,
2626
default(t: number, b: number, c: number, d: number) {
2727
return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b
28-
}
28+
} // 缓动函数
2929
}
3030
})
3131

src/layout/components/useRenderLayout.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ export const useRenderLayout = () => {
107107
></ToolHeader>
108108

109109
{tagsView.value ? (
110-
<TagsView class="layout-border__bottom layout-border__top"></TagsView>
110+
<TagsView class="layout-border__top layout-border__bottom"></TagsView>
111111
) : undefined}
112112
</div>
113113

@@ -121,13 +121,13 @@ export const useRenderLayout = () => {
121121
const renderTopLeft = () => {
122122
return (
123123
<>
124-
<div class="flex items-center bg-[var(--top-header-bg-color)] relative layout-border__bottom dark:bg-[var(--el-bg-color)]">
124+
<div class="relative flex items-center bg-[var(--top-header-bg-color)] layout-border__bottom dark:bg-[var(--el-bg-color)]">
125125
{logo.value ? <Logo class="custom-hover"></Logo> : undefined}
126126

127127
<ToolHeader class="flex-1"></ToolHeader>
128128
</div>
129-
<div class="absolute top-[var(--logo-height)+1px] left-0 w-full h-[calc(100%-1px-var(--logo-height))] flex">
130-
<Menu class="!h-full relative layout-border__right"></Menu>
129+
<div class="absolute left-0 top-[var(--logo-height)+1px] h-[calc(100%-1px-var(--logo-height))] w-full flex">
130+
<Menu class="relative layout-border__right !h-full"></Menu>
131131
<div
132132
class={[
133133
`${prefixCls}-content`,
@@ -187,7 +187,7 @@ export const useRenderLayout = () => {
187187
]}
188188
>
189189
{logo.value ? <Logo class="custom-hover"></Logo> : undefined}
190-
<Menu class="flex-1 px-10px h-[var(--top-tool-height)]"></Menu>
190+
<Menu class="h-[var(--top-tool-height)] flex-1 px-10px"></Menu>
191191
<ToolHeader></ToolHeader>
192192
</div>
193193
<div
@@ -233,12 +233,12 @@ export const useRenderLayout = () => {
233233
const renderCutMenu = () => {
234234
return (
235235
<>
236-
<div class="flex items-center bg-[var(--top-header-bg-color)] relative layout-border__bottom">
236+
<div class="relative flex items-center bg-[var(--top-header-bg-color)] layout-border__bottom">
237237
{logo.value ? <Logo class="custom-hover !pr-15px"></Logo> : undefined}
238238

239239
<ToolHeader class="flex-1"></ToolHeader>
240240
</div>
241-
<div class="absolute top-[var(--logo-height)] left-0 w-[calc(100%-2px)] h-[calc(100%-var(--logo-height))] flex">
241+
<div class="absolute left-0 top-[var(--logo-height)] h-[calc(100%-var(--logo-height))] w-[calc(100%-2px)] flex">
242242
<TabMenu></TabMenu>
243243
<div
244244
class={[

src/utils/formatTime.ts

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import dayjs from 'dayjs'
1111
* @description format 季度 + 星期 + 几周:"YYYY-mm-dd HH:MM:SS WWW QQQQ ZZZ"
1212
* @returns 返回拼接后的时间字符串
1313
*/
14-
export function formatDate(date: Date | number, format?: string): string {
14+
export function formatDate(date: dayjs.ConfigType, format?: string): string {
1515
// 日期不存在,则返回空
1616
if (!date) {
1717
return ''
@@ -221,3 +221,68 @@ export function convertDate(param: Date | string) {
221221
}
222222
return param
223223
}
224+
225+
/**
226+
* 指定的两个日期, 是否为同一天
227+
* @param a 日期 A
228+
* @param b 日期 B
229+
*/
230+
export function isSameDay(a: dayjs.ConfigType, b: dayjs.ConfigType): boolean {
231+
if (!a || !b) return false
232+
233+
const aa = dayjs(a)
234+
const bb = dayjs(b)
235+
return aa.year() == bb.year() && aa.month() == bb.month() && aa.day() == bb.day()
236+
}
237+
238+
/**
239+
* 获取一天的开始时间、截止时间
240+
* @param date 日期
241+
* @param days 天数
242+
*/
243+
export function getDayRange(
244+
date: dayjs.ConfigType,
245+
days: number
246+
): [dayjs.ConfigType, dayjs.ConfigType] {
247+
const day = dayjs(date).add(days, 'd')
248+
return getDateRange(day, day)
249+
}
250+
251+
/**
252+
* 获取最近7天的开始时间、截止时间
253+
*/
254+
export function getLast7Days(): [dayjs.ConfigType, dayjs.ConfigType] {
255+
const lastWeekDay = dayjs().subtract(7, 'd')
256+
const yesterday = dayjs().subtract(1, 'd')
257+
return getDateRange(lastWeekDay, yesterday)
258+
}
259+
260+
/**
261+
* 获取最近30天的开始时间、截止时间
262+
*/
263+
export function getLast30Days(): [dayjs.ConfigType, dayjs.ConfigType] {
264+
const lastMonthDay = dayjs().subtract(30, 'd')
265+
const yesterday = dayjs().subtract(1, 'd')
266+
return getDateRange(lastMonthDay, yesterday)
267+
}
268+
269+
/**
270+
* 获取最近1年的开始时间、截止时间
271+
*/
272+
export function getLast1Year(): [dayjs.ConfigType, dayjs.ConfigType] {
273+
const lastYearDay = dayjs().subtract(1, 'y')
274+
const yesterday = dayjs().subtract(1, 'd')
275+
return getDateRange(lastYearDay, yesterday)
276+
}
277+
278+
/**
279+
* 获取指定日期的开始时间、截止时间
280+
* @param beginDate 开始日期
281+
* @param endDate 截止日期
282+
*/
283+
export function getDateRange(
284+
beginDate: dayjs.ConfigType,
285+
endDate: dayjs.ConfigType
286+
): [dayjs.ConfigType, dayjs.ConfigType] {
287+
return [dayjs(beginDate).startOf('d'), dayjs(endDate).endOf('d')]
288+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<template>
2+
<div class="bg flex flex-col gap-2 p-6">
3+
<div class="flex items-center justify-between text-gray-500">
4+
<span>{{ title }}</span>
5+
<el-tooltip :content="tooltip" placement="top-start" v-if="tooltip">
6+
<Icon icon="ep:warning" />
7+
</el-tooltip>
8+
</div>
9+
<div class="mb-4 text-3xl">
10+
<CountTo :prefix="prefix" :end-val="value" :decimals="decimals" />
11+
</div>
12+
<div class="flex flex-row gap-1 text-sm">
13+
<span class="text-gray-500">环比</span>
14+
<span :class="toNumber(percent) > 0 ? 'text-red-500' : 'text-green-500'">
15+
{{ Math.abs(toNumber(percent)) }}%
16+
<Icon :icon="toNumber(percent) > 0 ? 'ep:caret-top' : 'ep:caret-bottom'" class="!text-sm" />
17+
</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+
25+
/** 交易统计值组件 */
26+
defineOptions({ name: 'TradeStatisticValue' })
27+
28+
defineProps({
29+
tooltip: propTypes.string.def(''),
30+
title: propTypes.string.def(''),
31+
prefix: propTypes.string.def(''),
32+
value: propTypes.number.def(0),
33+
decimals: propTypes.number.def(0),
34+
percent: propTypes.oneOfType([Number, String]).def(0)
35+
})
36+
</script>
37+
<style scoped>
38+
.bg {
39+
background-color: var(--el-bg-color-overlay);
40+
}
41+
</style>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<template>
2+
<div class="mb-8 flex flex-row items-center gap-3">
3+
<div
4+
class="h-12 w-12 flex flex-shrink-0 items-center justify-center rounded-1"
5+
:class="`${iconColor} ${iconBgColor}`"
6+
>
7+
<Icon :icon="icon" class="!text-6" />
8+
</div>
9+
<div class="bg flex flex-col gap-1">
10+
<div class="flex items-center gap-1 text-gray-500">
11+
<span class="text-3.5">{{ title }}</span>
12+
<el-tooltip :content="tooltip" placement="top-start" v-if="tooltip">
13+
<Icon icon="ep:warning" class="item-center flex !text-3" />
14+
</el-tooltip>
15+
</div>
16+
<div class="flex flex-row items-baseline gap-2">
17+
<div class="text-7">
18+
<CountTo :prefix="prefix" :end-val="value" :decimals="decimals" />
19+
</div>
20+
<span :class="toNumber(percent) > 0 ? 'text-red-500' : 'text-green-500'">
21+
<span class="text-sm">{{ Math.abs(toNumber(percent)) }}%</span>
22+
<Icon
23+
:icon="toNumber(percent) > 0 ? 'ep:caret-top' : 'ep:caret-bottom'"
24+
class="ml-0.5 !text-3"
25+
/>
26+
</span>
27+
</div>
28+
</div>
29+
</div>
30+
</template>
31+
<script lang="ts" setup>
32+
import { propTypes } from '@/utils/propTypes'
33+
import { toNumber } from 'lodash-es'
34+
35+
/** 交易状况统计值组件 */
36+
defineOptions({ name: 'TradeTrendValue' })
37+
38+
defineProps({
39+
title: propTypes.string.def(''),
40+
tooltip: propTypes.string.def(''),
41+
icon: propTypes.string.def(''),
42+
iconColor: propTypes.string.def(''),
43+
iconBgColor: propTypes.string.def(''),
44+
prefix: propTypes.string.def(''),
45+
value: propTypes.number.def(0),
46+
decimals: propTypes.number.def(0),
47+
percent: propTypes.oneOfType([Number, String]).def(0)
48+
})
49+
</script>
50+
<style scoped>
51+
.bg {
52+
background-color: var(--el-bg-color-overlay);
53+
}
54+
</style>

0 commit comments

Comments
 (0)