|
|
@@ -0,0 +1,316 @@
|
|
|
+<template>
|
|
|
+ <el-container>
|
|
|
+ <el-header>
|
|
|
+ <el-card shadow="hover" style="margin-top: 10px">
|
|
|
+ <el-row justify="end" align="middle">
|
|
|
+ <el-col :span="19" style="text-align: right">
|
|
|
+ <el-radio-group v-model="timeRadio" size="small" @change="handleDateRangeChange">
|
|
|
+ <!-- <el-radio-button label="今日" value="today" />-->
|
|
|
+ <el-radio-button label="近7天" value="week" />
|
|
|
+ <el-radio-button label="近30天" value="month" />
|
|
|
+ </el-radio-group>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="5" style="text-align: right">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="dateRange"
|
|
|
+ type="daterange"
|
|
|
+ range-separator="-"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ style="margin-left: 10px; margin-right: 30px"
|
|
|
+ />
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
+ </el-header>
|
|
|
+
|
|
|
+ <el-main style="margin-top: 20px">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-card shadow="hover" class="stat-card">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="8">
|
|
|
+ <h2 style="color: green; font-size: 30px">{{ totalNum }}</h2>
|
|
|
+ <p class="success">总内容量</p>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="16">
|
|
|
+ <div ref="createLine" style="height: 150px"></div>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-card shadow="hover" class="stat-card">
|
|
|
+ <h2 style="color: orange; font-size: 30px">{{ imageNum }}</h2>
|
|
|
+ <p class="warning">图片素材</p>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-card shadow="hover" class="stat-card">
|
|
|
+ <h2 style="color: green; font-size: 30px">{{ videoNum }}</h2>
|
|
|
+ <p class="success">视频素材</p>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="20" style="margin-top: 20px">
|
|
|
+ <el-col :span="18">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-card shadow="hover">
|
|
|
+ <h3>内容占比</h3>
|
|
|
+ <div ref="typePie" class="chart-placeholder"></div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-card shadow="hover">
|
|
|
+ <h3>类型占比</h3>
|
|
|
+ <div ref="tagPie" class="chart-placeholder"></div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-card shadow="hover">
|
|
|
+ <h3>素材统计</h3>
|
|
|
+ <div ref="typeAndTag" class="chart-placeholder"></div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row :gutter="20" style="margin-top: 20px">
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-card shadow="hover">
|
|
|
+ <h3>空间使用情况</h3>
|
|
|
+ <div ref="onlineTime" class="chart-placeholder"></div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-card shadow="hover">
|
|
|
+ <h3>播放时长统计</h3>
|
|
|
+ <div ref="alarmNum" class="chart-placeholder"></div>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-card shadow="hover">
|
|
|
+ <h3>告警清单</h3>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-main>
|
|
|
+ </el-container>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import * as echarts from 'echarts';
|
|
|
+import { fileStatistics, fileStatisticsByTag, numLine, statisticsByTypeAndTag } from '@/api/smsb/source/minioData';
|
|
|
+
|
|
|
+const timeRadio = ref('week');
|
|
|
+const dateRange = ref(['2025-01-01', '2025-01-01']);
|
|
|
+const totalNum = ref(0);
|
|
|
+const imageNum = ref(0);
|
|
|
+const videoNum = ref(0);
|
|
|
+const createLine = ref();
|
|
|
+const typePie = ref();
|
|
|
+const tagPie = ref();
|
|
|
+const typeAndTag = ref();
|
|
|
+
|
|
|
+const getNumByTypeAndTag = async () => {
|
|
|
+ const res = await statisticsByTypeAndTag();
|
|
|
+ const imageTagList = res.data.imageTagList;
|
|
|
+ const videoTagList = res.data.videoTagList;
|
|
|
+ const typeAndTagInstance = echarts.init(typeAndTag.value, 'macaroons');
|
|
|
+ typeAndTagInstance.setOption({
|
|
|
+ legend: {},
|
|
|
+ tooltip: {},
|
|
|
+ dataset: {
|
|
|
+ source: [['product', '广告', '公益', '视频'], ['图片'].concat(imageTagList), ['视频'].concat(videoTagList)]
|
|
|
+ },
|
|
|
+ xAxis: { type: 'category' },
|
|
|
+ yAxis: {},
|
|
|
+ series: [{ type: 'bar' }, { type: 'bar' }, { type: 'bar' }]
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const getNumByTag = async () => {
|
|
|
+ const res = await fileStatisticsByTag();
|
|
|
+ const tagPieInstance = echarts.init(tagPie.value, 'macaroons');
|
|
|
+ tagPieInstance.setOption({
|
|
|
+ title: {
|
|
|
+ text: '',
|
|
|
+ subtext: '',
|
|
|
+ left: 'center'
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item'
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ orient: 'vertical',
|
|
|
+ left: 'left'
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '内容占比',
|
|
|
+ type: 'pie',
|
|
|
+ radius: '65%',
|
|
|
+ data: [
|
|
|
+ { value: (res.data.ggNum / res.data.totalNum) * 100, name: '广告' },
|
|
|
+ { value: (res.data.gyNum / res.data.totalNum) * 100, name: '公益' },
|
|
|
+ { value: (res.data.xcNum / res.data.totalNum) * 100, name: '宣传' }
|
|
|
+ ],
|
|
|
+ emphasis: {
|
|
|
+ itemStyle: {
|
|
|
+ shadowBlur: 10,
|
|
|
+ shadowOffsetX: 0,
|
|
|
+ shadowColor: 'rgba(0, 0, 0, 0.5)'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const getNumAndLine = async () => {
|
|
|
+ const params = {
|
|
|
+ startTime: dateRange.value[0],
|
|
|
+ endTime: dateRange.value[1]
|
|
|
+ };
|
|
|
+ const res = await fileStatistics();
|
|
|
+ totalNum.value = res.data.totalNum;
|
|
|
+ imageNum.value = res.data.imageNum;
|
|
|
+ videoNum.value = res.data.videoNum;
|
|
|
+ const lineRes = await numLine(params);
|
|
|
+ const createLineInstance = echarts.init(createLine.value, 'macaroons');
|
|
|
+ createLineInstance.setOption({
|
|
|
+ title: {
|
|
|
+ text: ''
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis'
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ data: ['']
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ left: '3%',
|
|
|
+ right: '4%',
|
|
|
+ bottom: '3%',
|
|
|
+ containLabel: true
|
|
|
+ },
|
|
|
+ toolbox: {
|
|
|
+ feature: {
|
|
|
+ saveAsImage: {}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ boundaryGap: false,
|
|
|
+ data: lineRes.data.timeList
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value'
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '',
|
|
|
+ type: 'line',
|
|
|
+ stack: 'Total',
|
|
|
+ data: lineRes.data.numberList
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ });
|
|
|
+ const typePieInstance = echarts.init(typePie.value, 'macaroons');
|
|
|
+ typePieInstance.setOption({
|
|
|
+ title: {
|
|
|
+ text: '',
|
|
|
+ subtext: '',
|
|
|
+ left: 'center'
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item'
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ orient: 'vertical',
|
|
|
+ left: 'left'
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '内容占比',
|
|
|
+ type: 'pie',
|
|
|
+ radius: '65%',
|
|
|
+ data: [
|
|
|
+ { value: (res.data.imageNum / res.data.totalNum) * 100, name: '图片' },
|
|
|
+ { value: (res.data.videoNum / res.data.totalNum) * 100, name: '视频' }
|
|
|
+ ],
|
|
|
+ emphasis: {
|
|
|
+ itemStyle: {
|
|
|
+ shadowBlur: 10,
|
|
|
+ shadowOffsetX: 0,
|
|
|
+ shadowColor: 'rgba(0, 0, 0, 0.5)'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ });
|
|
|
+};
|
|
|
+const handleDateRangeChange = () => {
|
|
|
+ const rangeType = timeRadio.value;
|
|
|
+ const today = new Date();
|
|
|
+ const startDate = new Date();
|
|
|
+ const endDate = new Date();
|
|
|
+ switch (rangeType) {
|
|
|
+ case 'today':
|
|
|
+ break;
|
|
|
+ case 'week':
|
|
|
+ startDate.setDate(today.getDate() - 7);
|
|
|
+ break;
|
|
|
+ case 'month':
|
|
|
+ startDate.setMonth(today.getMonth() - 1);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new Error('Invalid range type');
|
|
|
+ }
|
|
|
+ dateRange.value = [formatDate(startDate), formatDate(endDate)];
|
|
|
+ getNumAndLine();
|
|
|
+};
|
|
|
+const formatDate = (date: Date) => {
|
|
|
+ const year = date.getFullYear();
|
|
|
+ const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
|
+ const day = String(date.getDate()).padStart(2, '0');
|
|
|
+ return `${year}-${month}-${day}`;
|
|
|
+};
|
|
|
+onMounted(() => {
|
|
|
+ handleDateRangeChange();
|
|
|
+ getNumAndLine();
|
|
|
+ getNumByTag();
|
|
|
+ getNumByTypeAndTag();
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.stat-card {
|
|
|
+ text-align: center;
|
|
|
+ height: 170px;
|
|
|
+}
|
|
|
+
|
|
|
+.number {
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+.success {
|
|
|
+ color: green;
|
|
|
+}
|
|
|
+
|
|
|
+.danger {
|
|
|
+ color: red;
|
|
|
+}
|
|
|
+
|
|
|
+.warning {
|
|
|
+ color: orange;
|
|
|
+}
|
|
|
+
|
|
|
+.chart-placeholder {
|
|
|
+ height: 250px;
|
|
|
+ /*background: #f5f5f5;*/
|
|
|
+ border-radius: 8px;
|
|
|
+}
|
|
|
+</style>
|