|
@@ -1,447 +0,0 @@
|
|
|
-<template>
|
|
|
- <div class="page">
|
|
|
- <div class="flex-row" style="gap: 12px">
|
|
|
- <el-card shadow="nover">
|
|
|
- <div class="title flex-row">
|
|
|
- <div class="">
|
|
|
- 今日告警 <el-tag size="small">{{ todayCount.currentDayCount }}</el-tag>
|
|
|
- </div>
|
|
|
- <div>
|
|
|
- 本月告警 <el-tag size="small">{{ todayCount.currentMonthCount }}</el-tag>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <VueUiXy v-if="dataset?.length" :config="config" :dataset="dataset" />
|
|
|
- <VueUiSkeleton v-else :config="{ type: 'bar' }" />
|
|
|
- </el-card>
|
|
|
- <el-card shadow="nover">
|
|
|
- <div class="title">告警设备top10</div>
|
|
|
- <VueUiXy v-if="dataset2?.length" :config="config2" :dataset="dataset2" />
|
|
|
- <VueUiSkeleton v-else :config="{ type: 'bar' }" />
|
|
|
- </el-card>
|
|
|
- <el-card shadow="nover">
|
|
|
- <div class="title">最新告警</div>
|
|
|
- <el-table class="flex1" :data="alarmNewList" border style="width: 100%" size="small">
|
|
|
- <el-table-column prop="createdAt" label="告警日期" width="140" align="center" />
|
|
|
- <el-table-column prop="status" :formatter="(row:any) => (row.status ? '已处理' : '未处理')" label="告警状态" width="70" align="center" />
|
|
|
- <el-table-column prop="level" label="告警等级" :formatter="(row:any) => typeFormat(row.level)" width="100" align="center" />
|
|
|
- <el-table-column prop="ruleName" label="告警说明" show-overflow-tooltip aign="center" />
|
|
|
- </el-table>
|
|
|
- </el-card>
|
|
|
- </div>
|
|
|
- <div class="flex-row" style="gap: 12px">
|
|
|
- <el-card shadow="nover">
|
|
|
- <div class="title">
|
|
|
- 告警统计
|
|
|
- <el-date-picker
|
|
|
- v-model="dateRange"
|
|
|
- type="daterange"
|
|
|
- range-separator="至"
|
|
|
- start-placeholder="开始日期"
|
|
|
- end-placeholder="结束日期"
|
|
|
- @change="getAlarmStatistics"
|
|
|
- format="YYYY-MM-DD"
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
- size="small"
|
|
|
- style="max-width: 200px"
|
|
|
- :clearable="false"
|
|
|
- :disabledDate="disabledDate"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <VueUiXy v-if="dataset4?.length" :config="config4" :dataset="dataset4" />
|
|
|
- <VueUiSkeleton v-else :config="{ type: 'bar' }" />
|
|
|
- </el-card>
|
|
|
- <el-card shadow="nover">
|
|
|
- <div class="title">告警增长趋势</div>
|
|
|
- <VueUiXy v-if="dataset5?.length" :config="config5" :dataset="dataset5" />
|
|
|
- <VueUiSkeleton v-else :config="{ type: 'donut' }" />
|
|
|
- </el-card>
|
|
|
- <el-card shadow="nover">
|
|
|
- <div class="title">
|
|
|
- 部门告警分析
|
|
|
- <el-date-picker
|
|
|
- v-model="deptAlarmDate"
|
|
|
- type="daterange"
|
|
|
- range-separator="至"
|
|
|
- start-placeholder="开始日期"
|
|
|
- end-placeholder="结束日期"
|
|
|
- @change="getDeptAlarm"
|
|
|
- format="YYYY-MM-DD"
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
- size="small"
|
|
|
- style="max-width: 200px"
|
|
|
- :clearable="false"
|
|
|
- :disabledDate="disabledDate"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <VueUiXy v-if="dataset6?.length" :config="config6" :dataset="dataset6" />
|
|
|
- <VueUiSkeleton v-else :config="{ type: 'bar' }" />
|
|
|
- </el-card>
|
|
|
- </div>
|
|
|
- <div class="flex-row" style="gap: 12px">
|
|
|
- <el-card shadow="nover">
|
|
|
- <div class="title">
|
|
|
- 告警状态
|
|
|
- <el-date-picker
|
|
|
- v-model="alarmStatusDate"
|
|
|
- type="daterange"
|
|
|
- range-separator="至"
|
|
|
- start-placeholder="开始日期"
|
|
|
- end-placeholder="结束日期"
|
|
|
- @change="getAlarmStatus"
|
|
|
- format="YYYY-MM-DD"
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
- size="small"
|
|
|
- style="max-width: 200px"
|
|
|
- :clearable="false"
|
|
|
- :disabledDate="disabledDate"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <VueUiDonut v-if="dataset7?.length" :config="config7" :dataset="dataset7" />
|
|
|
- <VueUiSkeleton v-else :config="{ type: 'donut' }" />
|
|
|
- </el-card>
|
|
|
- <el-card shadow="nover">
|
|
|
- <div class="title">
|
|
|
- 告警等级
|
|
|
- <el-date-picker
|
|
|
- v-model="alarmLevelDate"
|
|
|
- type="daterange"
|
|
|
- range-separator="至"
|
|
|
- start-placeholder="开始日期"
|
|
|
- end-placeholder="结束日期"
|
|
|
- format="YYYY-MM-DD"
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
- @change="getAlarmLevel"
|
|
|
- size="small"
|
|
|
- style="max-width: 200px"
|
|
|
- :clearable="false"
|
|
|
- :disabledDate="disabledDate"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <VueUiXy v-if="dataset9?.length" :config="config9" :dataset="dataset9" />
|
|
|
- <VueUiSkeleton v-else :config="{ type: 'bar' }" />
|
|
|
- </el-card>
|
|
|
- <el-card shadow="nover">
|
|
|
- <div class="title">
|
|
|
- 告警类型
|
|
|
- <el-date-picker
|
|
|
- v-model="alarmTypeDate"
|
|
|
- type="daterange"
|
|
|
- range-separator="至"
|
|
|
- start-placeholder="开始日期"
|
|
|
- end-placeholder="结束日期"
|
|
|
- format="YYYY-MM-DD"
|
|
|
- value-format="YYYY-MM-DD"
|
|
|
- @change="getAlarmType"
|
|
|
- size="small"
|
|
|
- style="max-width: 200px"
|
|
|
- :clearable="false"
|
|
|
- :disabledDate="disabledDate"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <VueUiDonut v-if="dataset8?.length" :config="config8" :dataset="dataset8" />
|
|
|
- <VueUiSkeleton v-else :config="{ type: 'donut' }" />
|
|
|
- </el-card>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script lang="ts" setup>
|
|
|
-import { unref, reactive, getCurrentInstance, ref } from 'vue'
|
|
|
-import { VueUiXy, VueUiDonut, VueUiSkeleton } from 'vue-data-ui'
|
|
|
-import 'vue-data-ui/style.css'
|
|
|
-import { getBarData, getPieSmallData } from '/@/utils/dataUiOptions'
|
|
|
-import api from '/@/api/alarm'
|
|
|
-import { useThemeChange } from '/@/hooks/useCommon'
|
|
|
-import dayjs from 'dayjs'
|
|
|
-
|
|
|
-const { proxy } = getCurrentInstance() as any
|
|
|
-const { alarm_type } = proxy.useDict('alarm_type')
|
|
|
-
|
|
|
-const disabledDate = (time: any) => time.getTime() > Date.now()
|
|
|
-
|
|
|
-function typeFormat(type: string) {
|
|
|
- return proxy.selectDictLabel(unref(alarm_type), type)
|
|
|
-}
|
|
|
-
|
|
|
-const config = ref<any>({})
|
|
|
-const config2 = ref<any>({})
|
|
|
-const config4 = ref<any>({})
|
|
|
-const config5 = ref<any>({})
|
|
|
-const config6 = ref<any>({})
|
|
|
-const config7 = ref<any>({})
|
|
|
-const config8 = ref<any>({})
|
|
|
-const config9 = ref<any>({})
|
|
|
-const dataset = ref<any[]>([])
|
|
|
-const dataset2 = ref<any[]>([])
|
|
|
-const dataset4 = ref<any[]>([])
|
|
|
-const dataset5 = ref<any[]>([])
|
|
|
-const dataset6 = ref<any[]>([])
|
|
|
-const dataset7 = ref<any[]>([])
|
|
|
-const dataset8 = ref<any[]>([])
|
|
|
-const dataset9 = ref<any[]>([])
|
|
|
-
|
|
|
-// 监听暗黑模式变化,将 vue-data-ui 的 config 传进来,就能自动更新主题
|
|
|
-useThemeChange([config, config2, config4, config5, config6, config7, config8, config9])
|
|
|
-
|
|
|
-const todayCount = reactive({
|
|
|
- currentDayCount: '-',
|
|
|
- currentMonthCount: '-',
|
|
|
-})
|
|
|
-
|
|
|
-const alarmNewList = ref<any[]>([])
|
|
|
-
|
|
|
-const defaultDateRange = [dayjs().subtract(7, 'day').format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')]
|
|
|
-const dateRange = ref([...defaultDateRange])
|
|
|
-const analyzeTrendDate = ref(dayjs().format('YYYY-MM'))
|
|
|
-const deptAlarmDate = ref([...defaultDateRange])
|
|
|
-const alarmStatusDate = ref([...defaultDateRange])
|
|
|
-const alarmTypeDate = ref([...defaultDateRange])
|
|
|
-const alarmLevelDate = ref([...defaultDateRange])
|
|
|
-
|
|
|
-getData()
|
|
|
-
|
|
|
-function getData() {
|
|
|
- // 今日告警信息
|
|
|
- api.dashboard.getCurrentDayInfo().then((res: any) => {
|
|
|
- const list = res?.data.alarmList || []
|
|
|
- todayCount.currentDayCount = res?.data?.currentDayCount
|
|
|
- todayCount.currentMonthCount = res?.data?.currentMonthCount
|
|
|
-
|
|
|
- const chartData = getBarData({
|
|
|
- xAxis: list.map((item: any) => item.alarmDate),
|
|
|
- legend: ['今日告警'],
|
|
|
- datas: [list.map((item: any) => item.alarmCount)],
|
|
|
- width: 300,
|
|
|
- height: 300,
|
|
|
- colors: ['#4B79F2'],
|
|
|
- modulo: 3,
|
|
|
- responsive: true,
|
|
|
- })
|
|
|
- config.value = chartData.config
|
|
|
- dataset.value = chartData.dataset
|
|
|
- })
|
|
|
- // 最新告警
|
|
|
- api.dashboard.getAlarmNewList().then((res: any) => {
|
|
|
- alarmNewList.value = res || []
|
|
|
- })
|
|
|
- // 告警统计
|
|
|
- getAlarmStatistics()
|
|
|
- // 告警趋势统计
|
|
|
- getAnalyzeTrend()
|
|
|
- // 部门告警统计
|
|
|
- getDeptAlarm()
|
|
|
- // 告警状态统计
|
|
|
- getAlarmStatus()
|
|
|
- // 告警类型统计
|
|
|
- getAlarmType()
|
|
|
- // 告警等级统计
|
|
|
- getAlarmLevel()
|
|
|
- // 告警设备top10
|
|
|
- api.dashboard.getDeviceAlarmTop10().then((res: any) => {
|
|
|
- const list = res || []
|
|
|
- const chartData = getBarData({
|
|
|
- xAxis: list.map((item: any) => item.deviceName),
|
|
|
- legend: ['告警设备top10'],
|
|
|
- datas: [list.map((item: any) => item.alarmCount)],
|
|
|
- colors: ['#FF7D5C'],
|
|
|
- responsive: true,
|
|
|
- })
|
|
|
- config2.value = chartData.config
|
|
|
- dataset2.value = chartData.dataset
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-function getAlarmStatistics() {
|
|
|
- api.dashboard
|
|
|
- .getAlarmStatistics({
|
|
|
- startDate: dateRange.value[0],
|
|
|
- endDate: dateRange.value[1],
|
|
|
- })
|
|
|
- .then((res: any) => {
|
|
|
- const list = res || []
|
|
|
- const chartData = getBarData({
|
|
|
- xAxis: list.map((item: any) => item.alarmDate),
|
|
|
- legend: ['告警统计'],
|
|
|
- datas: [list.map((item: any) => item.alarmCount || 0)],
|
|
|
- modulo: 3,
|
|
|
- colors: ['#5AD8A6'],
|
|
|
- responsive: true,
|
|
|
- })
|
|
|
- config4.value = chartData.config
|
|
|
- dataset4.value = chartData.dataset
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-function getAnalyzeTrend() {
|
|
|
- api.dashboard
|
|
|
- .getAnalyzeTrend({
|
|
|
- searchMonth: analyzeTrendDate.value,
|
|
|
- })
|
|
|
- .then((res: any) => {
|
|
|
- const list = res || []
|
|
|
- const chartData = getBarData({
|
|
|
- xAxis: list.map((item: any) => item.month),
|
|
|
- legend: ['部门告警'],
|
|
|
- datas: [list.map((item: any) => item.alarmCount)],
|
|
|
- modulo: 5,
|
|
|
- colors: ['#FFB64D'],
|
|
|
- responsive: true,
|
|
|
- })
|
|
|
- config5.value = chartData.config
|
|
|
- dataset5.value = chartData.dataset
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-function getDeptAlarm() {
|
|
|
- api.dashboard
|
|
|
- .getDeptAlarm({
|
|
|
- startDate: deptAlarmDate.value[0],
|
|
|
- endDate: deptAlarmDate.value[1],
|
|
|
- })
|
|
|
- .then((res: any) => {
|
|
|
- const list = res || []
|
|
|
- const chartData = getBarData({
|
|
|
- xAxis: list.map((item: any) => item.deptName),
|
|
|
- legend: ['部门告警'],
|
|
|
- datas: [list.map((item: any) => item.alarmCount)],
|
|
|
- modulo: 5,
|
|
|
- colors: ['#5B8FF9'],
|
|
|
- responsive: true,
|
|
|
- })
|
|
|
- config6.value = chartData.config
|
|
|
- dataset6.value = chartData.dataset
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-function getAlarmStatus() {
|
|
|
- api.dashboard
|
|
|
- .getAlarmStatus({
|
|
|
- startDate: alarmStatusDate.value[0],
|
|
|
- endDate: alarmStatusDate.value[1],
|
|
|
- })
|
|
|
- .then((res: any) => {
|
|
|
- const list = res || []
|
|
|
- const chartData = getPieSmallData({
|
|
|
- legend: list.map((item: any) => (item.status === '1' ? '已处理' : '未处理')),
|
|
|
- datas: list.map((item: any) => [item.alarmCount]),
|
|
|
- colors: ['#5AD8A6', '#E86452'],
|
|
|
- responsive: true,
|
|
|
- })
|
|
|
- config7.value = chartData.config
|
|
|
- dataset7.value = chartData.dataset
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-function getAlarmType() {
|
|
|
- api.dashboard
|
|
|
- .getAlarmType({
|
|
|
- startDate: alarmTypeDate.value[0],
|
|
|
- endDate: alarmTypeDate.value[1],
|
|
|
- })
|
|
|
- .then((res: any) => {
|
|
|
- const list = res || []
|
|
|
- const chartData = getPieSmallData({
|
|
|
- legend: list.map((item: any) => (item.alarmType === '1' ? '规则告警' : '自助上报告警')),
|
|
|
- datas: list.map((item: any) => [item.alarmCount]),
|
|
|
- colors: ['#7453E5', '#FFB64D'],
|
|
|
- responsive: true,
|
|
|
- })
|
|
|
- config8.value = chartData.config
|
|
|
- dataset8.value = chartData.dataset
|
|
|
- })
|
|
|
-}
|
|
|
-
|
|
|
-function getAlarmLevel() {
|
|
|
- api.dashboard
|
|
|
- .getAlarmLevel({
|
|
|
- startDate: alarmLevelDate.value[0],
|
|
|
- endDate: alarmLevelDate.value[1],
|
|
|
- })
|
|
|
- .then((res: any) => {
|
|
|
- const list = res || []
|
|
|
- const chartData = getBarData({
|
|
|
- xAxis: list.map((item: any) => item.levelName),
|
|
|
- legend: ['告警等级'],
|
|
|
- datas: [list.map((item: any) => item.alarmCount)],
|
|
|
- modulo: 3,
|
|
|
- colors: ['#269A99'],
|
|
|
- responsive: true,
|
|
|
- })
|
|
|
- config9.value = chartData.config
|
|
|
- dataset9.value = chartData.dataset
|
|
|
- })
|
|
|
-}
|
|
|
-</script>
|
|
|
-
|
|
|
-<style scoped lang="scss">
|
|
|
-.page {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: space-between;
|
|
|
- gap: 12px;
|
|
|
-
|
|
|
- .vue-ui-skeleton {
|
|
|
- height: 100%;
|
|
|
-
|
|
|
- & ::v-deep > svg {
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .title {
|
|
|
- font-size: 14px;
|
|
|
- color: #333;
|
|
|
- font-weight: 500;
|
|
|
- line-height: 1;
|
|
|
- height: 24px;
|
|
|
- min-height: 24px;
|
|
|
- margin-bottom: 6px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- }
|
|
|
-
|
|
|
- .flex-row {
|
|
|
- flex: 1;
|
|
|
-
|
|
|
- .el-card {
|
|
|
- height: 100%;
|
|
|
- flex: 1;
|
|
|
- // overflow: hidden;
|
|
|
- box-sizing: border-box;
|
|
|
-
|
|
|
- & ::v-deep .el-card__body {
|
|
|
- padding: 1.5vh 1vw;
|
|
|
- // gap: 10px;
|
|
|
- height: 100%;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- justify-content: space-between;
|
|
|
- // overflow: hidden;
|
|
|
-
|
|
|
- .vue-ui-xy,
|
|
|
- .vue-ui-donut,
|
|
|
- .vue-ui-skeleton {
|
|
|
- // flex: 1 !important;
|
|
|
- height: calc(100% - 30px) !important;
|
|
|
- // overflow: auto;
|
|
|
- // display: flex;
|
|
|
- // flex-direction: column;
|
|
|
- // justify-content: center;
|
|
|
- // align-items: center;
|
|
|
- &-svg {
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- .vue-data-ui-fulscreen--off {
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .vue-ui-skeleton {
|
|
|
- overflow: hidden;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|