From 609a1931953b2298016bd2b0d6b410666b5ad7b9 Mon Sep 17 00:00:00 2001
From: rk <94314517@qq.com>
Date: 星期四, 02 七月 2026 09:19:15 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/3.0.1' into 3.0.1

---
 admin/src/views/data.vue |  189 +++++++++++++++++++++++++++++++---------------
 1 files changed, 126 insertions(+), 63 deletions(-)

diff --git a/admin/src/views/data.vue b/admin/src/views/data.vue
index 09baf43..8394bce 100644
--- a/admin/src/views/data.vue
+++ b/admin/src/views/data.vue
@@ -8,9 +8,9 @@
           <span v-if="card.prefix" class="stat-prefix">{{ card.prefix }}</span>
           {{ card.value }}
         </div>
-        <div class="stat-sub">
-          <span>鏄ㄦ棩 {{ card.yesterday }}</span>
-          <span>浠婃棩 {{ card.today }}</span>
+        <div class="stat-sub" v-if="card.label !== '杞﹁締鎬绘暟'">
+          <span>鏄ㄦ棩 {{ card.label === '鏈湀鏀剁泭' ? '锟�' : ''}}{{ card.yesterday }}</span>
+          <span>浠婃棩 {{ card.label === '鏈湀鏀剁泭' ? '锟�' : ''}}{{ card.today }}</span>
         </div>
       </div>
     </div>
@@ -32,12 +32,12 @@
               <el-button
                 :type="vehicleType === 'bicycle' ? 'primary' : 'default'"
                 size="mini"
-                @click="vehicleType = 'bicycle'"
+                @click="switchVehicleType('bicycle')"
               >鑷杞�</el-button>
               <el-button
                 :type="vehicleType === 'electric' ? 'primary' : 'default'"
                 size="mini"
-                @click="vehicleType = 'electric'"
+                @click="switchVehicleType('electric')"
               >鐢靛姩杞�</el-button>
             </el-button-group>
           </div>
@@ -55,12 +55,12 @@
               <el-button
                 :type="salesPeriod === 'month' ? 'primary' : 'default'"
                 size="mini"
-                @click="salesPeriod = 'month'"
+                @click="switchSalesPeriod('month')"
               >鏈湀</el-button>
               <el-button
                 :type="salesPeriod === 'year' ? 'primary' : 'default'"
                 size="mini"
-                @click="salesPeriod = 'year'"
+                @click="switchSalesPeriod('year')"
               >鏈勾</el-button>
             </el-button-group>
           </div>
@@ -73,19 +73,16 @@
 
 <script>
 import * as echarts from 'echarts'
-
+import { dashboard, packageSourceStat, bikeUsageStat, incomeStat30 } from '@/api/business/report.js'
 export default {
   data () {
     return {
-      statCards: [
-        { label: '鏈湀鏀剁泭', prefix: '楼', value: '32242.34', yesterday: '24243.23', today: '235.34' },
-        { label: '鏈湀璁㈠崟', value: '2849', yesterday: '345', today: '243' },
-        { label: '鍦ㄥ鎴锋暟', value: '243', yesterday: '23', today: '12' },
-        { label: '杞﹁締鎬绘暟', value: '243', yesterday: '鍦ㄧ嚎 240', today: '绂荤嚎 3' }
-      ],
+      statCards: [],
       vehicleType: 'bicycle',
-      vehicleTotal: 142,
+      vehicleTotal: 0,
+      bikeUsageData: null,
       salesPeriod: 'month',
+      packageSourceData: null,
       barChart: null,
       donutChart: null,
       pieChart: null
@@ -97,6 +94,7 @@
       this.initDonutChart()
       this.initPieChart()
     })
+    this.loadDashboard()
     window.addEventListener('resize', this.handleResize)
   },
   beforeDestroy () {
@@ -108,52 +106,84 @@
   methods: {
     initBarChart () {
       const chart = echarts.init(this.$refs.barChart)
-      const data = [111, 227, 147, 163, 178, 200, 126]
-      const dates = ['6-15', '6-16', '6-17', '6-18', '6-19', '6-20', '6-21']
-      chart.setOption({
-        tooltip: { trigger: 'axis' },
-        legend: {
-          data: ['鏀跺叆'],
-          bottom: 0
-        },
-        grid: {
-          left: 10,
-          right: 10,
-          top: 20,
-          bottom: 40,
-          containLabel: true
-        },
-        xAxis: {
-          type: 'category',
-          data: dates,
-          axisLine: { lineStyle: { color: '#e0e0e0' } },
-          axisTick: { show: false }
-        },
-        yAxis: {
-          type: 'value',
-          axisLine: { show: false },
-          axisTick: { show: false },
-          splitLine: { lineStyle: { color: '#f0f0f0' } }
-        },
-        series: [{
-          name: '鏀跺叆',
-          type: 'bar',
-          barWidth: 30,
-          itemStyle: { color: '#5B8FF9' },
-          label: {
-            show: true,
-            position: 'top',
-            color: '#5B8FF9',
-            fontSize: 11
+      incomeStat30({}).then(res => {
+        const data = res.dailyList || []
+        const dates = data.map(item => {
+          const d = item.date.split('-')
+          return `${d[1]}-${d[2]}`
+        })
+        const incomes = data.map(item => item.income)
+        chart.setOption({
+          tooltip: { trigger: 'axis' },
+          legend: {
+            data: ['鏀跺叆'],
+            bottom: 50
           },
-          data: data
-        }]
+          grid: {
+            left: 10,
+            right: 10,
+            top: 20,
+            bottom: 80,
+            containLabel: true
+          },
+          dataZoom: [
+            {
+              type: 'inside',
+              xAxisIndex: 0,
+              start: 0,
+              end: 100
+            },
+            {
+              type: 'slider',
+              xAxisIndex: 0,
+              start: 0,
+              end: 100,
+              bottom: 20,
+              height: 20
+            }
+          ],
+          xAxis: {
+            type: 'category',
+            data: dates,
+            axisLine: { lineStyle: { color: '#e0e0e0' } },
+            axisTick: { show: false }
+          },
+          yAxis: {
+            type: 'value',
+            axisLine: { show: false },
+            axisTick: { show: false },
+            splitLine: { lineStyle: { color: '#f0f0f0' } }
+          },
+          series: [{
+            name: '鏀跺叆',
+            type: 'bar',
+            barWidth: '60%',
+            itemStyle: { color: '#5B8FF9' },
+            data: incomes
+          }]
+        })
+      }).catch(e => {
+        this.$tip.apiFailed(e)
       })
       this.barChart = chart
     },
     initDonutChart () {
       const chart = echarts.init(this.$refs.donutChart)
-      chart.setOption({
+      this.donutChart = chart
+      bikeUsageStat({}).then(res => {
+        this.bikeUsageData = res
+        this.updateDonutChart()
+      }).catch(e => {
+        this.$tip.apiFailed(e)
+      })
+    },
+    updateDonutChart () {
+      if (!this.bikeUsageData || !this.donutChart) return
+      const isBicycle = this.vehicleType === 'bicycle'
+      const idle = isBicycle ? this.bikeUsageData.bikeIdle || 0 : this.bikeUsageData.eleBikeIdle || 0
+      const inUse = isBicycle ? this.bikeUsageData.bikeInUse || 0 : this.bikeUsageData.eleBikeInUse || 0
+      this.vehicleTotal = idle + inUse
+      this.donutChart.setOption({
         tooltip: { trigger: 'item' },
         legend: {
           orient: 'horizontal',
@@ -175,16 +205,32 @@
             fontSize: 12
           },
           data: [
-            { value: 60, name: '绌洪棽', itemStyle: { color: '#73C0DE' } },
-            { value: 180, name: '浣跨敤涓�', itemStyle: { color: '#5B8FF9' } }
+            { value: idle, name: '绌洪棽', itemStyle: { color: '#73C0DE' } },
+            { value: inUse, name: '浣跨敤涓�', itemStyle: { color: '#5B8FF9' } }
           ]
         }]
       })
-      this.donutChart = chart
+    },
+    switchVehicleType (type) {
+      this.vehicleType = type
+      this.updateDonutChart()
     },
     initPieChart () {
       const chart = echarts.init(this.$refs.pieChart)
-      chart.setOption({
+      this.pieChart = chart
+      packageSourceStat({}).then(res => {
+        this.packageSourceData = res
+        this.updatePieChart()
+      }).catch(e => {
+        this.$tip.apiFailed(e)
+      })
+    },
+    updatePieChart () {
+      if (!this.packageSourceData || !this.pieChart) return
+      const data = this.salesPeriod === 'month' ? this.packageSourceData.month : this.packageSourceData.year
+      const douyinCount = data ? (data.douyinCount || 0) : 0
+      const miniCount = data ? (data.miniCount || 0) : 0
+      this.pieChart.setOption({
         tooltip: { trigger: 'item' },
         legend: {
           orient: 'horizontal',
@@ -206,17 +252,34 @@
             fontSize: 12
           },
           data: [
-            { value: 130, name: '鎶栭煶鍥㈣喘', itemStyle: { color: '#73C0DE' } },
-            { value: 100, name: '灏忕▼搴忛攢鍞�', itemStyle: { color: '#5B8FF9' } }
+            { value: douyinCount, name: '鎶栭煶鍥㈣喘', itemStyle: { color: '#73C0DE' } },
+            { value: miniCount, name: '灏忕▼搴忛攢鍞�', itemStyle: { color: '#5B8FF9' } }
           ]
         }]
       })
-      this.pieChart = chart
+    },
+    switchSalesPeriod (period) {
+      this.salesPeriod = period
+      this.updatePieChart()
     },
     handleResize () {
       if (this.barChart) this.barChart.resize()
       if (this.donutChart) this.donutChart.resize()
       if (this.pieChart) this.pieChart.resize()
+    },
+    loadDashboard () {
+      dashboard({}).then(res => {
+        if (res) {
+          this.statCards = [
+            { label: '鏈湀鏀剁泭', prefix: '楼', value: res.monthIncome || 0, yesterday: res.yesterdayIncome || 0, today: res.todayIncome || 0 },
+            { label: '鏈湀璁㈠崟', value: res.monthOrderCount || 0, yesterday: res.yesterdayOrderCount || 0, today: res.todayOrderCount || 0 },
+            { label: '鍦ㄥ鎴锋暟', value: res.totalMemberCount || 0, yesterday: res.yesterdayNewMember || 0, today: res.todayNewMember || 0 },
+            { label: '杞﹁締鎬绘暟', value: res.totalBikeCount || 0, yesterday: '', today: '' }
+          ]
+        }
+      }).catch(e => {
+        this.$tip.apiFailed(e)
+      })
     }
   }
 }
@@ -239,7 +302,7 @@
 
 .stat-card {
   flex: 1;
-  background: #e8f0fe;
+  background: #eff6ff;
   border-radius: 8px;
   padding: 20px 24px;
 }

--
Gitblit v1.9.3