feat: 视频中心仪表盘卡片组件封装
This commit is contained in:
parent
59e4bacd74
commit
1eda294d48
|
@ -0,0 +1,10 @@
|
|||
import server from '@/utils/request'
|
||||
import type { Agg, AggPlaying } from '@/views/media/DashBoard/typings'
|
||||
|
||||
export default {
|
||||
// 录像数量
|
||||
agg: () => server.get<Agg>(`/media/record/file/agg`),
|
||||
// 播放中数量
|
||||
aggPlaying: () => server.get<AggPlaying>(`/media/channel/playing/agg`),
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<div class="page-container"></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style lang="less" scoped></style>
|
|
@ -0,0 +1,94 @@
|
|||
<template>
|
||||
<div class="top-card">
|
||||
<div class="top-card-content">
|
||||
<div class="content-left">
|
||||
<div class="content-left-title">
|
||||
<span>{{ title }}</span>
|
||||
<a-tooltip placement="top" v-if="tooltip">
|
||||
<template #title>
|
||||
<span>{{ tooltip }}</span>
|
||||
</template>
|
||||
<AIcon type="QuestionCircleOutlined" />
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div class="content-left-value">{{ value }}</div>
|
||||
</div>
|
||||
<div class="content-right">
|
||||
<img :src="img" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="top-card-footer">
|
||||
<template v-for="(item, index) in footer" :key="index">
|
||||
<a-badge :text="item.title" :status="item.status" />
|
||||
<div class="footer-item-value">{{ item.value }}</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType } from 'vue';
|
||||
import type { Footer } from '@/views/media/DashBoard/typings';
|
||||
|
||||
const props = defineProps({
|
||||
title: { type: String, default: '' },
|
||||
tooltip: { type: String, default: '' },
|
||||
img: { type: String, default: '' },
|
||||
footer: { type: Array as PropType<Footer[]>, default: '' },
|
||||
value: { type: Number, default: 0 },
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.top-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// height: 200px;
|
||||
padding: 24px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #e0e4e8;
|
||||
border-radius: 2px;
|
||||
.top-card-content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-grow: 1;
|
||||
.content-left {
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
&-title {
|
||||
color: rgba(0, 0, 0, 0.64);
|
||||
}
|
||||
&-value {
|
||||
padding: 12px 0;
|
||||
color: #323130;
|
||||
font-weight: 700;
|
||||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
.content-right {
|
||||
width: 0;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
align-items: flex-end;
|
||||
justify-content: flex-end;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.top-card-footer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
.footer-item-value {
|
||||
color: #323130;
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,7 +1,93 @@
|
|||
<template>
|
||||
<div class="page-container">仪表盘</div>
|
||||
<div class="page-container">
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="6">
|
||||
<TopCard
|
||||
title="设备数量"
|
||||
:img="getImage('/media/dashboard-1.png')"
|
||||
:footer="deviceFooter"
|
||||
:value="deviceTotal"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<TopCard
|
||||
title="通道数量"
|
||||
:img="getImage('/media/dashboard-2.png')"
|
||||
:footer="channelFooter"
|
||||
:value="channelTotal"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<TopCard
|
||||
title="录像数量"
|
||||
:img="getImage('/media/dashboard-3.png')"
|
||||
:footer="aggFooter"
|
||||
:value="aggTotal"
|
||||
/>
|
||||
</a-col>
|
||||
<a-col :span="6">
|
||||
<TopCard
|
||||
title="播放中数量"
|
||||
tooltip="当前正在播放的通道数量之和"
|
||||
:img="getImage('/media/dashboard-4.png')"
|
||||
:footer="aggPlayingFooter"
|
||||
:value="aggPlayingTotal"
|
||||
/>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
import TopCard from '@/views/media/DashBoard/components/TopCard.vue'
|
||||
import { getImage } from '@/utils/comm';
|
||||
import homeApi from '@/api/media/home';
|
||||
import dashboardApi from '@/api/media/dashboard';
|
||||
import type { Footer } from '@/views/media/DashBoard/typings';
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
// 设备
|
||||
const deviceFooter = ref<Footer[]>([]);
|
||||
const deviceTotal = ref(0);
|
||||
const getDeviceData = () => {
|
||||
homeApi.deviceCount().then((res) => {
|
||||
deviceTotal.value = res.result;
|
||||
});
|
||||
};
|
||||
getDeviceData();
|
||||
|
||||
// 通道
|
||||
const channelFooter = ref<Footer[]>([]);
|
||||
const channelTotal = ref(0);
|
||||
const getChannelData = () => {
|
||||
homeApi.channelCount().then((res) => {
|
||||
channelTotal.value = res.result;
|
||||
});
|
||||
};
|
||||
getChannelData();
|
||||
|
||||
// 录像
|
||||
const aggFooter = ref<Footer[]>([]);
|
||||
const aggTotal = ref(0);
|
||||
const getAggData = () => {
|
||||
dashboardApi.agg().then((res) => {
|
||||
aggTotal.value = res.result.total;
|
||||
});
|
||||
};
|
||||
getAggData();
|
||||
|
||||
// 播放中
|
||||
const aggPlayingFooter = ref<Footer[]>([]);
|
||||
const aggPlayingTotal = ref(0);
|
||||
const getAggPlayingData = () => {
|
||||
dashboardApi.aggPlaying().then((res) => {
|
||||
aggTotal.value = res.result.playingTotal;
|
||||
});
|
||||
};
|
||||
getAggPlayingData();
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page-container {
|
||||
padding: 24px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
export type Agg = {
|
||||
duration: number
|
||||
total: number
|
||||
}
|
||||
|
||||
export type AggPlaying = {
|
||||
playerTotal: number
|
||||
playingTotal: number
|
||||
}
|
||||
|
||||
export type Footer = {
|
||||
title: string;
|
||||
value: number;
|
||||
status?: "default" | "error" | "success" | "warning" | "processing"
|
||||
}
|
||||
|
|
@ -13,12 +13,12 @@
|
|||
<div class="box-item">
|
||||
<div class="label">设备数量</div>
|
||||
<div class="value">{{ deviceCount }}</div>
|
||||
<img src="/images/home/top-2.png" alt="" />
|
||||
<img :src="getImage('/home/top-1.png')" alt="" />
|
||||
</div>
|
||||
<div class="box-item">
|
||||
<div class="label">通道数量</div>
|
||||
<div class="value">{{ channelCount }}</div>
|
||||
<img src="/images/home/top-1.png" alt="" />
|
||||
<img :src="getImage('/home/top-2.png')" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
|
@ -26,6 +26,7 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import homeApi from '@/api/media/home';
|
||||
import { getImage } from '@/utils/comm';
|
||||
|
||||
const channelCount = ref(0);
|
||||
const deviceCount = ref(0);
|
||||
|
|
Loading…
Reference in New Issue