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