Pārlūkot izejas kodu

feat(HomeView): 添加今日数据统计和折线图

- 新增今日数据统计卡片,展示总记录数、已扫描数和设备数量
- 添加近7日数据统计折线图,可选择不同渠道进行展示
- 实现渠道列表获取和数据刷新功能
- 集成 echarts 图表库
wui 9 mēneši atpakaļ
vecāks
revīzija
095771924e
3 mainītis faili ar 210 papildinājumiem un 2 dzēšanām
  1. 1 0
      package.json
  2. 189 2
      src/views/HomeView.vue
  3. 20 0
      yarn.lock

+ 1 - 0
package.json

@@ -19,6 +19,7 @@
     "ali-oss": "^6.18.1",
     "axios": "^1.3.6",
     "date-fns": "^2.29.3",
+    "echarts": "^5.6.0",
     "element-plus": "^2.3.3",
     "fast-uri": "^2.3.0",
     "pinia": "^2.0.32",

+ 189 - 2
src/views/HomeView.vue

@@ -1,5 +1,192 @@
 <template>
-    <el-main> </el-main>
+    <el-main>
+        <div class="mb-4 flex items-center gap-2">
+            <el-select v-model="selectedChannel" placeholder="请选择渠道" @change="handleChannelChange" v-if="isAdmin">
+                <el-option label="全部渠道" value="" />
+                <el-option v-for="item in channelOptions" :key="item" :label="item" :value="item" />
+            </el-select>
+            <el-button :icon="Refresh" circle @click="refreshData" :loading="loading" />
+        </div>
+
+        <!-- 今日数据表格 -->
+        <el-card class="mb-4">
+            <template #header>
+                <div class="flex items-center justify-between">
+                    <span>今日数据统计</span>
+                    <el-tag type="info">{{ todayData.date }}</el-tag>
+                </div>
+            </template>
+            <el-row :gutter="20">
+                <el-col :span="8">
+                    <div class="text-center">
+                        <div class="text-gray-500 mb-2">总记录数</div>
+                        <div class="text-2xl font-bold text-green-500">{{ todayData.total }}</div>
+                    </div>
+                </el-col>
+                <el-col :span="8">
+                    <div class="text-center">
+                        <div class="text-gray-500 mb-2">已扫描数</div>
+                        <div class="text-2xl font-bold text-orange-500">{{ todayData.scanned }}</div>
+                    </div>
+                </el-col>
+                <el-col :span="8">
+                    <div class="text-center">
+                        <div class="text-gray-500 mb-2">设备数量</div>
+                        <div class="text-2xl font-bold text-blue-500">{{ todayData.deviceCount }}</div>
+                    </div>
+                </el-col>
+            </el-row>
+        </el-card>
+
+        <!-- 折线图 -->
+        <el-card>
+            <template #header>
+                <div class="flex items-center justify-between">
+                    <span>近7日数据统计</span>
+                </div>
+            </template>
+            <div ref="chartRef" style="width: 100%; height: 400px"></div>
+        </el-card>
+    </el-main>
 </template>
 
-<script setup></script>
+<script setup>
+import { ref, onMounted, inject } from 'vue'
+import * as echarts from 'echarts'
+import { http } from '@/plugins/http'
+import { Refresh } from '@vicons/tabler'
+
+const isAdmin = inject('isAdminAndOperator')
+const chartRef = ref(null)
+let chart = null
+const selectedChannel = ref('')
+const channelOptions = ref([])
+const loading = ref(false)
+const todayData = ref({
+    date: '',
+    total: 0,
+    scanned: 0,
+    deviceCount: 0
+})
+
+onMounted(() => {
+    // 监听窗口大小变化,调整图表大小
+    window.addEventListener('resize', () => {
+        if (chart) {
+            chart.resize()
+        }
+    })
+
+    // 获取渠道列表并加载全部渠道数据
+    getChannelList()
+    handleChannelChange('')
+})
+
+// 获取今日数据
+async function getTodayData(channelName) {
+    try {
+        const response = await http.post('/ocrDevice/today', {
+            channel: channelName
+        })
+        todayData.value = response
+    } catch (error) {
+        console.error('获取今日数据失败:', error)
+    }
+}
+
+// 获取渠道列表
+async function getChannelList() {
+    try {
+        const response = await http.post('/ocrChannel/names')
+        console.log('获取渠道列表成功:', response.data)
+        channelOptions.value = response.data || []
+    } catch (error) {
+        console.error('获取渠道列表失败:', error)
+    }
+}
+
+// 刷新数据
+async function refreshData() {
+    await handleChannelChange(selectedChannel.value)
+}
+
+// 处理渠道变化
+async function handleChannelChange(channelName) {
+    if (!chart) {
+        chart = echarts.init(chartRef.value)
+    }
+
+    loading.value = true
+    try {
+        // 获取今日数据
+        await getTodayData(channelName)
+
+        // 获取渠道数据
+        const response = await http.post('/ocrDevice/getStatistics', {
+            channel: channelName
+        })
+
+        // 准备图表数据
+        const option = {
+            tooltip: {
+                trigger: 'axis'
+            },
+            legend: {
+                data: ['总记录数', '已扫描数', '设备数量']
+            },
+            xAxis: {
+                type: 'category',
+                data: response.dates
+            },
+            yAxis: {
+                type: 'value'
+            },
+            series: [
+                {
+                    name: '总记录数',
+                    type: 'line',
+                    data: response.total,
+                    label: {
+                        show: true,
+                        position: 'top'
+                    },
+                    itemStyle: {
+                        color: '#67C23A' // 绿色
+                    }
+                },
+                {
+                    name: '已扫描数',
+                    type: 'line',
+                    data: response.scanned,
+                    label: {
+                        show: true,
+                        position: 'top'
+                    },
+                    itemStyle: {
+                        color: '#E6A23C' // 橘色
+                    }
+                },
+                {
+                    name: '设备数量',
+                    type: 'line',
+                    data: response.deviceCount,
+                    label: {
+                        show: true,
+                        position: 'top'
+                    },
+                    itemStyle: {
+                        color: '#409EFF' // 蓝色
+                    }
+                }
+            ]
+        }
+
+        // 设置图表配置
+        chart.setOption(option)
+    } catch (error) {
+        console.error('获取数据失败:', error)
+    } finally {
+        loading.value = false
+    }
+}
+</script>

+ 20 - 0
yarn.lock

@@ -1948,6 +1948,14 @@ doctrine@^3.0.0:
   dependencies:
     esutils "^2.0.2"
 
+echarts@^5.6.0:
+  version "5.6.0"
+  resolved "https://registry.yarnpkg.com/echarts/-/echarts-5.6.0.tgz#2377874dca9fb50f104051c3553544752da3c9d6"
+  integrity sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==
+  dependencies:
+    tslib "2.3.0"
+    zrender "5.6.1"
+
 ee-first@~1.1.1:
   version "1.1.1"
   resolved "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -3459,6 +3467,11 @@ ts-interface-checker@^0.1.9:
   resolved "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
   integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
 
+tslib@2.3.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
+  integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
+
 tslib@^1.11.1:
   version "1.14.1"
   resolved "https://registry.npmmirror.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
@@ -3750,3 +3763,10 @@ yocto-queue@^0.1.0:
   version "0.1.0"
   resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
   integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+
+zrender@5.6.1:
+  version "5.6.1"
+  resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.6.1.tgz#e08d57ecf4acac708c4fcb7481eb201df7f10a6b"
+  integrity sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==
+  dependencies:
+    tslib "2.3.0"