From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目
---
src/views/mall/home/components/TradeTrendCard.vue | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 208 insertions(+), 0 deletions(-)
diff --git a/src/views/mall/home/components/TradeTrendCard.vue b/src/views/mall/home/components/TradeTrendCard.vue
new file mode 100644
index 0000000..0bf284e
--- /dev/null
+++ b/src/views/mall/home/components/TradeTrendCard.vue
@@ -0,0 +1,208 @@
+<template>
+ <el-card shadow="never">
+ <template #header>
+ <div class="flex flex-row items-center justify-between">
+ <CardTitle title="浜ゆ槗閲忚秼鍔�" />
+ <!-- 鏌ヨ鏉′欢 -->
+ <div class="flex flex-row items-center gap-2">
+ <el-radio-group v-model="timeRangeType" @change="handleTimeRangeTypeChange">
+ <el-radio-button v-for="[key, value] in timeRange.entries()" :key="key" :value="key">
+ {{ value.name }}
+ </el-radio-button>
+ </el-radio-group>
+ </div>
+ </div>
+ </template>
+ <!-- 鎶樼嚎鍥� -->
+ <Echart :height="300" :options="eChartOptions" />
+ </el-card>
+</template>
+<script lang="ts" setup>
+import dayjs, { Dayjs } from 'dayjs'
+import { EChartsOption } from 'echarts'
+import * as TradeStatisticsApi from '@/api/mall/statistics/trade'
+import { fenToYuan } from '@/utils'
+import { formatDate } from '@/utils/formatTime'
+import { CardTitle } from '@/components/Card'
+
+/** 浜ゆ槗閲忚秼鍔� */
+defineOptions({ name: 'TradeTrendCard' })
+
+enum TimeRangeTypeEnum {
+ DAY30 = 1,
+ WEEK = 7,
+ MONTH = 30,
+ YEAR = 365
+} // 鏃ユ湡绫诲瀷
+const timeRangeType = ref(TimeRangeTypeEnum.DAY30) // 鏃ユ湡蹇嵎閫夋嫨鎸夐挳, 榛樿30澶�
+const loading = ref(true) // 鍔犺浇涓�
+// 鏃堕棿鑼冨洿 Map
+const timeRange = new Map()
+ .set(TimeRangeTypeEnum.DAY30, {
+ name: '30澶�',
+ series: [
+ { name: '璁㈠崟閲戦', type: 'bar', smooth: true, data: [] },
+ { name: '璁㈠崟鏁伴噺', type: 'line', smooth: true, data: [] }
+ ]
+ })
+ .set(TimeRangeTypeEnum.WEEK, {
+ name: '鍛�',
+ series: [
+ { name: '涓婂懆閲戦', type: 'bar', smooth: true, data: [] },
+ { name: '鏈懆閲戦', type: 'bar', smooth: true, data: [] },
+ { name: '涓婂懆鏁伴噺', type: 'line', smooth: true, data: [] },
+ { name: '鏈懆鏁伴噺', type: 'line', smooth: true, data: [] }
+ ]
+ })
+ .set(TimeRangeTypeEnum.MONTH, {
+ name: '鏈�',
+ series: [
+ { name: '涓婃湀閲戦', type: 'bar', smooth: true, data: [] },
+ { name: '鏈湀閲戦', type: 'bar', smooth: true, data: [] },
+ { name: '涓婃湀鏁伴噺', type: 'line', smooth: true, data: [] },
+ { name: '鏈湀鏁伴噺', type: 'line', smooth: true, data: [] }
+ ]
+ })
+ .set(TimeRangeTypeEnum.YEAR, {
+ name: '骞�',
+ series: [
+ { name: '鍘诲勾閲戦', type: 'bar', smooth: true, data: [] },
+ { name: '浠婂勾閲戦', type: 'bar', smooth: true, data: [] },
+ { name: '鍘诲勾鏁伴噺', type: 'line', smooth: true, data: [] },
+ { name: '浠婂勾鏁伴噺', type: 'line', smooth: true, data: [] }
+ ]
+ })
+/** 鍥捐〃閰嶇疆 */
+const eChartOptions = reactive<EChartsOption>({
+ grid: {
+ left: 20,
+ right: 20,
+ bottom: 20,
+ top: 80,
+ containLabel: true
+ },
+ legend: {
+ top: 50,
+ data: []
+ },
+ series: [],
+ toolbox: {
+ feature: {
+ // 鏁版嵁鍖哄煙缂╂斁
+ dataZoom: {
+ yAxisIndex: false // Y杞翠笉缂╂斁
+ },
+ brush: {
+ type: ['lineX', 'clear'] // 鍖哄煙缂╂斁鎸夐挳銆佽繕鍘熸寜閽�
+ },
+ saveAsImage: { show: true, name: '璁㈠崟閲忚秼鍔�' } // 淇濆瓨涓哄浘鐗�
+ }
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'cross'
+ },
+ padding: [5, 10]
+ },
+ xAxis: {
+ type: 'category',
+ inverse: true,
+ boundaryGap: false,
+ axisTick: {
+ show: false
+ },
+ data: [],
+ axisLabel: {
+ formatter: (date: string) => {
+ switch (timeRangeType.value) {
+ case TimeRangeTypeEnum.DAY30:
+ return formatDate(date, 'MM-DD')
+ case TimeRangeTypeEnum.WEEK:
+ let weekDay = formatDate(date, 'ddd')
+ if (weekDay == '0') weekDay = '鏃�'
+ return '鍛�' + weekDay
+ case TimeRangeTypeEnum.MONTH:
+ return formatDate(date, 'D')
+ case TimeRangeTypeEnum.YEAR:
+ return formatDate(date, 'M') + '鏈�'
+ default:
+ return date
+ }
+ }
+ }
+ },
+ yAxis: {
+ axisTick: {
+ show: false
+ }
+ }
+}) as EChartsOption
+
+/** 鏃堕棿鑼冨洿绫诲瀷鍗曢�夋寜閽�変腑 */
+const handleTimeRangeTypeChange = async () => {
+ // 璁剧疆鏃堕棿鑼冨洿
+ let beginTime: Dayjs
+ let endTime: Dayjs
+ switch (timeRangeType.value) {
+ case TimeRangeTypeEnum.WEEK:
+ beginTime = dayjs().startOf('week')
+ endTime = dayjs().endOf('week')
+ break
+ case TimeRangeTypeEnum.MONTH:
+ beginTime = dayjs().startOf('month')
+ endTime = dayjs().endOf('month')
+ break
+ case TimeRangeTypeEnum.YEAR:
+ beginTime = dayjs().startOf('year')
+ endTime = dayjs().endOf('year')
+ break
+ case TimeRangeTypeEnum.DAY30:
+ default:
+ beginTime = dayjs().subtract(30, 'day').startOf('d')
+ endTime = dayjs().endOf('d')
+ break
+ }
+ // 鍙戦�佹椂闂磋寖鍥撮�変腑浜嬩欢
+ await getOrderCountTrendComparison(beginTime, endTime)
+}
+
+/** 鏌ヨ璁㈠崟鏁伴噺瓒嬪娍瀵圭収鏁版嵁 */
+const getOrderCountTrendComparison = async (
+ beginTime: dayjs.ConfigType,
+ endTime: dayjs.ConfigType
+) => {
+ loading.value = true
+ // 鏌ヨ鏁版嵁
+ const list = await TradeStatisticsApi.getOrderCountTrendComparison(
+ timeRangeType.value,
+ beginTime,
+ endTime
+ )
+ // 澶勭悊鏁版嵁
+ const dates: string[] = []
+ const series = [...timeRange.get(timeRangeType.value).series]
+ for (let item of list) {
+ dates.push(item.value.date)
+ if (series.length === 2) {
+ series[0].data.push(fenToYuan(item?.value?.orderPayPrice || 0)) // 褰撳墠閲戦
+ series[1].data.push(item?.value?.orderPayCount || 0) // 褰撳墠鏁伴噺
+ } else {
+ series[0].data.push(fenToYuan(item?.reference?.orderPayPrice || 0)) // 瀵圭収閲戦
+ series[1].data.push(fenToYuan(item?.value?.orderPayPrice || 0)) // 褰撳墠閲戦
+ series[2].data.push(item?.reference?.orderPayCount || 0) // 瀵圭収鏁伴噺
+ series[3].data.push(item?.value?.orderPayCount || 0) // 褰撳墠鏁伴噺
+ }
+ }
+ eChartOptions.xAxis!['data'] = dates
+ eChartOptions.series = series
+ // legend 鍦� 4 涓垏鎹㈠埌 2 涓殑鏃跺�欙紝杩樻槸鏄剧ず鎴� 4 涓紝闇�瑕佹墜鍔ㄩ厤缃竴涓�
+ eChartOptions.legend['data'] = series.map((item) => item.name)
+ loading.value = false
+}
+
+/** 鍒濆鍖� **/
+onMounted(() => {
+ handleTimeRangeTypeChange()
+})
+</script>
--
Gitblit v1.8.0