|
@@ -1,5 +1,192 @@
|
|
|
<template>
|
|
<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>
|
|
</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>
|