feat: 新增通用组件接口 测点实时值

This commit is contained in:
huanghao1412 2024-01-24 15:15:05 +08:00
parent c60b2c2b8f
commit 4eaa03d080
43 changed files with 2514 additions and 103 deletions

View File

@ -0,0 +1,16 @@
import { publicInterface } from "@/api/path";
import { commonDataType, PointRealTimeType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { CreateComponentType } from '@/packages/index.d'
export const handlePointRealTime = (targetComponent: CreateComponentType) => {
let { enable, point_uid, limit, with_device_name, space_complete_name_prefix } = (targetComponent.commonData as commonDataType).pointRealTime as PointRealTimeType
if(!enable) return
const query = {
point_uid,
limit,
with_device_name,
space_complete_name_prefix,
}
return publicInterface('/dcim/system/custom_large_screen', 'get_point_realtime_data', query)
}

View File

@ -9,6 +9,7 @@ import { cloneDeep } from 'lodash'
import { handlePointHistory } from './commonDataComponents/usePointHistoryRes'
import { handleEnergyUseHistory } from './commonDataComponents/useEnergyUseHistoryRes';
import { handleRecordValueHistory } from './commonDataComponents/useRecordValueHistoryRes'
import { handlePointRealTime } from './commonDataComponents/usePointRealTimeRes'
import { ResultErrcode } from '@/enums/httpEnum'
// 获取类型
@ -85,13 +86,15 @@ export const useChartCommonData = (
case CurrentSourceEnum.RECORDVALUEHISTORY:
res = await handleRecordValueHistory(targetComponent)
break;
case CurrentSourceEnum.POINTREALTIME:
res = await handlePointRealTime(targetComponent)
break;
default:
break;
}
if (res && res.errcode === ResultErrcode.SUCCESS) {
try {
const { data } = res
console.log(data)
if(Object.prototype.toString.call(data) === '[object Array]') {
if(data.length) echartsUpdateHandle(data[0])
}

View File

@ -0,0 +1,32 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { DeviceAlarmOverviewConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
// import logo from '@/assets/logo.png'
export const option = {
// 图片路径
dataset: '',
// 适应方式
fit: 'contain',
// 圆角
borderRadius: 0
}
export default class Config extends PublicConfigClass implements CreateComponentType
{
constructor() {
super();
this.attr.w = 450
this.attr.h = 300
this.request.requestInterval = 15
}
public key = DeviceAlarmOverviewConfig.key
public chartConfig = cloneDeep(DeviceAlarmOverviewConfig)
public option = cloneDeep(option)
public customData = cloneDeep({
title: '当前设备告警概况',
showInterval: true,
space_complete_id: '',
})
}

View File

@ -0,0 +1,7 @@
<template>
</template>
<script setup lang="ts">
</script>

View File

@ -0,0 +1,17 @@
<template>
<setting-item-box name="标题" :alone="true">
<n-input v-model:value="props.customData.title" size="small" placeholder="请输入标题"/>
</setting-item-box>
<setting-item-box name="空间ID" :alone="true">
<n-input v-model:value="props.customData.space_complete_id" size="small" placeholder="请输入空间ID"/>
</setting-item-box>
</template>
<script lang="ts" setup>
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
const props = defineProps(['customData', 'request'])
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,15 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/CustomComponents/index.d'
export const DeviceAlarmOverviewConfig: ConfigType = {
key: 'DeviceAlarmOverview',
chartKey: 'VDeviceAlarmOverview',
conKey: 'VCDeviceAlarmOverview',
conDataKey: 'VCDDeviceAlarmOverview',
title: '当前设备告警概况',
category: ChatCategoryEnum.ALARMDIAGRAM,
categoryName: ChatCategoryEnumName.ALARMDIAGRAM,
package: PackagesCategoryEnum.CUSTOMCOMPONENTS,
chartFrame: ChartFrameEnum.COMMON,
image: 'DeviceAlarmOverview.png'
}

View File

@ -0,0 +1,196 @@
<template>
<div :style="getStyle(borderRadius)">
<BorderBox :title="chartConfig?.customData?.title">
<div class="item">
<BareMetalServerIcon class="left"/>
<div class="right">
<div class="label">设备总数</div>
<div class="value">{{obj.data1}}</div>
</div>
</div>
<div class="item">
<BareMetalServerIcon class="left leftRed"/>
<div class="right rightRed">
<div class="label">设备告警数</div>
<div class="value">{{obj.data2}}</div>
</div>
</div>
<div class="item">
<SteeringWheelIcon class="left"/>
<div class="right">
<div class="label">测点总数</div>
<div class="value">{{obj.data3}}</div>
</div>
</div>
<div class="item">
<SteeringWheelIcon class="left leftRed"/>
<div class="right rightRed">
<div class="label">测点告警数</div>
<div class="value">{{obj.data4}}</div>
</div>
</div>
</BorderBox>
</div>
</template>
<script setup lang="ts">
import { PropType, shallowReactive, watch, toRefs, reactive, onMounted, onUnmounted } from 'vue'
import { useChartDataFetch } from '@/hooks'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { BareMetalServer as BareMetalServerIcon } from '@vicons/carbon'
import { SteeringWheel as SteeringWheelIcon } from '@vicons/tabler'
import { publicInterface } from '@/api/path/business.api'
import BorderBox from '../components/BorderBox.vue'
import {selectTimeOptions} from "@/views/chart/ContentConfigurations/components/ChartData/index.d";
import {RequestHttpIntervalEnum} from "@/enums/httpEnum";
import {isPreview} from "@/utils";
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { w, h } = toRefs(props.chartConfig.attr)
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
const option = shallowReactive({
dataset: ''
})
const getStyle = (radius: number) => {
return {
borderRadius: `${radius}px`,
overflow: 'hidden'
}
}
type objType = number|null
const obj = reactive({
data1: null as objType,
data2: null as objType,
data3: null as objType,
data4: null as objType
})
const getData = () => {
let query = {
space_complete_id: props.chartConfig.customData?.space_complete_id
}
publicInterface('/dcim/dems/statistic', 'count_device_all', query).then(res => {
if (res && res.data) {
let data = res.data as {
active_device_count:number
active_device_alarm:number
active_device_offline:number
}
obj.data1 = data.active_device_count
obj.data2 = data.active_device_alarm + data.active_device_offline
}
})
publicInterface('/dcim/dems/statistic', 'count_point_all', query).then(res => {
if (res && res.data) {
let data = res.data as {
active_point_count:number
active_point_alarm:number
}
obj.data3 = data.active_point_count
obj.data4 = data.active_point_alarm
}
})
}
let timer:unknown
watch(() => [props.chartConfig.request.requestInterval, props.chartConfig.request.requestIntervalUnit, props.chartConfig.customData?.space_complete_id].join('&&'), v => {
if(!isPreview()) return
if(props.chartConfig.request.requestInterval) {
if(timer) clearInterval(timer as number)
const obj = selectTimeOptions.find(_ => _.value === props.chartConfig.request.requestIntervalUnit) || {unit: 0}
const unit = obj.unit
const number = unit * props.chartConfig.request.requestInterval
timer = setInterval(() => {
getData()
}, number)
}
})
onMounted(() => {
getData()
if(!isPreview()) return
const obj = selectTimeOptions.find(_ => _.value === props.chartConfig.request.requestIntervalUnit) || {unit: 0}
const unit = obj.unit
const number = unit * props.chartConfig.request.requestInterval!
timer = setInterval(() => {
getData()
}, number)
})
onUnmounted(() => {
clearInterval(timer as number)
})
//
watch(
() => props.chartConfig.option.dataset,
(newData: any) => {
option.dataset = newData
},
{
immediate: true
}
)
//
useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
option.dataset = newData
})
</script>
<style lang="scss" scoped>
.item{
background: rgba(65,150,255,.08);
width: calc(50% - 7px);
height: calc(50% - 7px);
display: flex;
align-items: center;
justify-content: center;
.left{
color: #0ff;
height: 50%;
width: 50%;
}
.right{
width: 50%;
height: 80%;
margin-left: 10px;
display: flex;
flex-direction: column;
justify-content: space-evenly;
.label{
color: #fff;
height: 20px;
line-height: 20px;
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.value{
color: #0ff;
height: 20px;
line-height: 20px;
font-size: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.leftRed{
color: #f43b42;
}
.rightRed{
.value{
color: #f43b42;
}
}
}
</style>

View File

@ -0,0 +1,568 @@
<template>
<div class="box" ref="box">
<img class="scaner" :style="{width: shorterSide, height: shorterSide}" src="@/assets/customComponents/RealTimeAlarmStatistics/scanner.png" alt="">
<svg v-show="alarmLevelsLength === 5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
<g>
<g>
<circle style="opacity:0.2;fill-rule:evenodd;clip-rule:evenodd;fill:#4196FF;" cx="100" cy="100" r="100" />
</g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;fill-opacity:0.6;" cx="100" cy="100" r="92" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;" cx="100" cy="100" r="92" />
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;" cx="100" cy="100" r="92" />
</g>
<g>
<radialGradient id="real_time_alarm_statistics_5_1_" cx="100" cy="100" r="92" gradientUnits="userSpaceOnUse">
<stop offset="0.836" style="stop-color:#FFFFFF;stop-opacity:0.05" />
<stop offset="1" style="stop-color:#D0E3EA;stop-opacity:0.9" />
</radialGradient>
<path style="fill:url(#real_time_alarm_statistics_5_1_);" d="M100,8C49.189,8,8,49.189,8,100s41.189,92,92,92s92-41.189,92-92S150.811,8,100,8L100,8z" />
</g>
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#091C38;" cx="100" cy="100" r="92" />
</g>
<g>
<g style="opacity:0.5;">
<path style="fill:#FFFFFF;" d="M100,11c49.074,0,89,39.925,89,89c0,49.075-39.926,89-89,89c-49.075,0-89-39.925-89-89C11,50.925,50.925,11,100,11 M100,8C49.189,8,8,49.189,8,100s41.189,92,92,92s92-41.189,92-92S150.811,8,100,8L100,8z" />
</g>
</g>
<radialGradient id="real_time_alarm_statistics_5_2_" cx="100" cy="100" r="72.8008" gradientUnits="userSpaceOnUse">
<stop offset="0.9032" style="stop-color:#D0E3EA;stop-opacity:0.9" />
<stop offset="1" style="stop-color:#D0E3EA;stop-opacity:0.05" />
</radialGradient>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#real_time_alarm_statistics_5_2_);fill-opacity:0.6;" cx="100" cy="100" r="72.801" />
<path style="fill:#091C38;" d="M100,27.6c-39.984,0-72.4,32.413-72.4,72.4s32.416,72.4,72.4,72.4c39.986,0,72.4-32.413,72.4-72.4S139.986,27.6,100,27.6L100,27.6z" />
<g style="opacity:0.2;">
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="100" y2="29.6" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="81.778" y2="32" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="64.801" y2="39.032" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="50.219" y2="50.219" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="39.032" y2="64.801" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="31.998" y2="81.778" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="29.6" y2="100" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="31.998" y2="118.222" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="39.032" y2="135.199" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="50.219" y2="149.781" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="64.803" y2="160.968" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="81.779" y2="168" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="100" y2="170.399" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="118.221" y2="168" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="135.198" y2="160.967" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="149.781" y2="149.778" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="160.968" y2="135.199" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="168.004" y2="118.222" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="170.4" y2="100" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="168.004" y2="81.777" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="160.967" y2="64.798" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="149.781" y2="50.218" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="135.198" y2="39.032" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="118.221" y2="32" />
</g>
<path style="opacity:0.1;fill:#4196FF;" d="M100,96.434c1.969,0,3.568,1.598,3.568,3.566s-1.6,3.566-3.568,3.566s-3.568-1.598-3.568-3.566S98.031,96.434,100,96.434 M100,95.633c-2.412,0-4.369,1.955-4.369,4.367s1.957,4.367,4.369,4.367s4.367-1.955,4.367-4.367S102.412,95.633,100,95.633L100,95.633z" />
<path style="opacity:0.12;fill:#4196FF;" d="M100,88.18c6.52,0,11.822,5.301,11.822,11.82S106.52,111.82,100,111.82S88.176,106.52,88.176,100S93.48,88.18,100,88.18 M100,87.379c-6.972,0-12.621,5.65-12.621,12.621s5.649,12.621,12.621,12.621s12.621-5.65,12.621-12.621S106.972,87.379,100,87.379L100,87.379z" />
<path style="opacity:0.14;fill:#4196FF;" d="M100,79.924c11.071,0,20.077,9.006,20.077,20.076s-9.006,20.076-20.077,20.076S79.923,111.07,79.923,100S88.929,79.924,100,79.924 M100,79.123c-11.531,0-20.877,9.347-20.877,20.877s9.346,20.876,20.877,20.876c11.529,0,20.877-9.346,20.877-20.876S111.529,79.123,100,79.123L100,79.123z" />
<path style="opacity:0.16;fill:#4196FF;" d="M100,71.67c15.623,0,28.33,12.708,28.33,28.33s-12.707,28.33-28.33,28.33S71.67,115.622,71.67,100S84.377,71.67,100,71.67 M100,70.869c-16.09,0-29.131,13.045-29.131,29.131S83.91,129.131,100,129.131s29.131-13.045,29.131-29.131S116.09,70.869,100,70.869L100,70.869z" />
<path style="opacity:0.18;fill:#4196FF;" d="M100,63.416c20.173,0,36.584,16.412,36.584,36.584c0,20.173-16.411,36.584-36.584,36.584c-20.174,0-36.584-16.411-36.584-36.584C63.416,79.828,79.826,63.416,100,63.416M100,62.615c-20.646,0-37.385,16.738-37.385,37.385c0,20.646,16.738,37.385,37.385,37.385s37.385-16.739,37.385-37.385C137.385,79.354,120.646,62.615,100,62.615L100,62.615z" />
<path style="opacity:0.2;fill:#4196FF;" d="M100,55.163c24.724,0,44.84,20.112,44.84,44.837s-20.116,44.837-44.84,44.837c-24.725,0-44.84-20.112-44.84-44.837S75.275,55.163,100,55.163 M100,54.363c-25.205,0-45.641,20.432-45.641,45.637S74.795,145.637,100,145.637s45.637-20.432,45.637-45.637S125.205,54.363,100,54.363L100,54.363z" />
<path style="opacity:0.22;fill:#4196FF;" d="M100,46.906c29.275,0,53.092,23.818,53.092,53.094S129.275,153.094,100,153.094S46.906,129.275,46.906,100S70.725,46.906,100,46.906 M100,46.109c-29.765,0-53.891,24.127-53.891,53.891c0,29.763,24.126,53.891,53.891,53.891s53.891-24.128,53.891-53.891C153.891,70.236,129.765,46.109,100,46.109L100,46.109z" />
<path style="opacity:0.24;fill:#4196FF;" d="M100,38.654c33.826,0,61.346,27.52,61.346,61.346s-27.52,61.346-61.346,61.346S38.654,133.826,38.654,100S66.174,38.654,100,38.654 M100,37.854c-34.322,0-62.146,27.823-62.146,62.146c0,34.32,27.824,62.146,62.146,62.146S162.146,134.32,162.146,100C162.146,65.677,134.322,37.854,100,37.854L100,37.854z" />
<path style="opacity:0.26;fill:#4196FF;" d="M100,30.4c38.378,0,69.6,31.222,69.6,69.6s-31.222,69.6-69.6,69.6S30.4,138.378,30.4,100S61.622,30.4,100,30.4 M100,29.6c-38.881,0-70.4,31.521-70.4,70.4c0,38.879,31.52,70.4,70.4,70.4c38.883,0,70.4-31.521,70.4-70.4C170.4,61.12,138.883,29.6,100,29.6L100,29.6z" />
<circle style="opacity:0;fill:#F43B42;" cx="100" cy="100" r="0.471" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;" d="M31.521,77.75C40.896,48.877,68.004,28,100,28c0-6.904,0-13.677,0-20C59.114,8,24.465,34.673,12.486,71.564L31.521,77.75z" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;" d="M28,100c0-7.768,1.245-15.241,3.521-22.25l-19.034-6.186C9.578,80.521,8,90.075,8,100c0,30.6,14.942,57.704,37.924,74.43l11.762-16.189C39.7,145.15,28,123.947,28,100z" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#F8CA00;" d="M154.076,174.43l-11.762-16.189C130.434,166.887,115.817,172,100,172c-15.818,0-30.435-5.113-42.314-13.76L45.924,174.43C61.104,185.478,79.789,192,100,192S138.896,185.478,154.076,174.43z" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#14C6BD;" d="M100,28c31.999,0,59.104,20.879,68.479,49.75l19.035-6.185C175.535,34.673,140.886,8,100,8C100,14.323,100,21.096,100,28z" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#4FBADB;" d="M187.514,71.565l-19.035,6.185C170.755,84.759,172,92.232,172,100c0,23.948-11.701,45.15-29.686,58.24l11.762,16.189C177.058,157.704,192,130.6,192,100C192,90.075,190.422,80.521,187.514,71.565z" />
<g>
<text transform="matrix(0.809 0.5878 -0.5878 0.809 135.6914 29.3159)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:12.5001;">{{ eventName }}</text>
</g>
<g>
<text transform="matrix(0.309 -0.9511 0.9511 0.309 176.5986 139.2744)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:12.5001;">{{ commonName }}</text>
</g>
<g>
<text transform="matrix(1 0 0 1 86.3184 184.9395)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:12.5001;">{{ importantName }}</text>
</g>
<g>
<text transform="matrix(0.309 0.9511 -0.9511 0.309 16.4736 115.8477)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:12.5001;">{{ seriousName }}</text>
</g>
<g>
<text transform="matrix(0.809 -0.5878 0.5878 0.809 42.084 46.4502)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:12.5001;">{{ urgentName }}</text>
</g>
</g>
<!-- <image class="scaner" style="overflow:visible;" width="734" height="734" xlink:href="@/assets/customComponents/RealTimeAlarmStatistics/scanner.png" transform="matrix(0.192 0 0 0.192 29.5996 29.5996)" />-->
<g>
<g>
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#4FBADB;fill-opacity:0.3;" d="M151,119.578c0,2.209-1.79,3.998-3.998,3.998c-2.211,0-4.002-1.789-4.002-3.998c0-2.211,1.791-4.002,4.002-4.002C149.21,115.576,151,117.367,151,119.578z" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#4FBADB;fill-opacity:0.6;" cx="147" cy="119.578" r="2.399" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#4FBADB;" cx="147.002" cy="119.578" r="1.2" />
</g>
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#14C6BD;fill-opacity:0.3;" cx="132.799" cy="59.001" r="4" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#14C6BD;fill-opacity:0.6;" cx="132.799" cy="59.001" r="2.399" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#14C6BD;" cx="132.801" cy="59.001" r="1.2" />
</g>
<g>
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;fill-opacity:0.3;" d="M58,119.579c0,2.209-1.791,3.998-4.001,3.998c-2.208,0-3.999-1.789-3.999-3.998c0-2.211,1.791-4.002,3.999-4.002C56.209,115.577,58,117.368,58,119.579z" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;fill-opacity:0.6;" d="M56.4,119.579c0,1.324-1.076,2.398-2.401,2.398c-1.323,0-2.401-1.074-2.401-2.398c0-1.326,1.078-2.4,2.401-2.4C55.324,117.179,56.4,118.253,56.4,119.579z" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;" cx="53.999" cy="119.579" r="1.2" />
</g>
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;fill-opacity:0.3;" cx="68.801" cy="59.109" r="4" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;fill-opacity:0.6;" cx="68.8" cy="59.109" r="2.401" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;" cx="68.8" cy="59.109" r="1.2" />
</g>
<g>
<text transform="matrix(1 0 0 1 63.8945 80)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ alarmMonitorData ? alarmMonitorData["urgent"] : 0 }}</text>
</g>
<g>
<text transform="matrix(1 0 0 1 49.0938 109)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ alarmMonitorData ? alarmMonitorData["serious"] : 0 }}</text>
</g>
<g>
<text transform="matrix(1 0 0 1 142.0957 109)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ alarmMonitorData ? alarmMonitorData["important"] : 0 }}</text>
</g>
<g>
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#F8CA00;fill-opacity:0.3;" d="M104,154.002c0,2.209-1.79,3.998-3.998,3.998c-2.211,0-4.002-1.789-4.002-3.998c0-2.211,1.791-4.002,4.002-4.002C102.21,150,104,151.791,104,154.002z" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F8CA00;fill-opacity:0.6;" cx="100" cy="154.002" r="2.399" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F8CA00;" cx="100.002" cy="154.002" r="1.2" />
</g>
<g>
<text transform="matrix(1 0 0 1 95.0957 143.4238)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ alarmMonitorData ? alarmMonitorData["secondary"] : 0 }}</text>
</g>
<g>
<text transform="matrix(1 0 0 1 124.5898 78.2905)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ alarmMonitorData ? alarmMonitorData["record"] : 0 }}</text>
</g>
</g>
</svg>
<svg v-show="alarmLevelsLength === 4 || alarmLevelsLength === 0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
<defs>
<radialGradient id="real_time_alarm_statistics_35" cx="100" cy="660" r="92" gradientTransform="matrix(1, 0, 0, -1, 0, 760)" gradientUnits="userSpaceOnUse">
<stop offset="0.84" stop-color="#fff" stop-opacity="0.05" />
<stop offset="1" stop-color="#d0e3ea" stop-opacity="0.9" />
</radialGradient>
<radialGradient id="real_time_alarm_statistics_36" cx="100" cy="660" r="72.8" gradientTransform="matrix(1, 0, 0, -1, 0, 760)" gradientUnits="userSpaceOnUse">
<stop offset="0.9" stop-color="#d0e3ea" stop-opacity="0.9" />
<stop offset="1" stop-color="#d0e3ea" stop-opacity="0.05" />
</radialGradient>
</defs>
<g>
<circle cx="100" cy="100" r="100" style="fill:#4196ff;opacity:0.20000000298023224;isolation:isolate" />
<circle cx="100" cy="100" r="92" style="fill:#d0e3ea;fill-opacity:0.6000000238418579" />
<circle cx="100" cy="100" r="92" style="fill:#d0e3ea" />
<circle cx="100" cy="100" r="92" style="fill:#d0e3ea" />
<path d="M100,8a92,92,0,1,0,92,92A92,92,0,0,0,100,8Z" style="fill:url(#real_time_alarm_statistics_35)" />
<circle cx="100" cy="100" r="92" style="fill:#091c38" />
<g style="opacity:0.5">
<path d="M100,11a89,89,0,1,1-89,89,89,89,0,0,1,89-89m0-3a92,92,0,1,0,92,92A92,92,0,0,0,100,8Z" style="fill:#fff" />
</g>
<circle cx="100" cy="100" r="72.8" style="fill-opacity:0.6000000238418579;fill:url(#real_time_alarm_statistics_36)" />
<path d="M100,27.6A72.4,72.4,0,1,0,172.4,100,72.4,72.4,0,0,0,100,27.6Z" style="fill:#091c38" />
<g style="opacity:0.20000000298023224">
<line x1="100" y1="100" x2="100" y2="29.6" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="81.78" y2="32" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="64.8" y2="39.03" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="50.22" y2="50.22" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="39.03" y2="64.8" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="32" y2="81.78" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="29.6" y2="100" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="32" y2="118.22" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="39.03" y2="135.2" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="50.22" y2="149.78" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="64.8" y2="160.97" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="81.78" y2="168" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="100" y2="170.4" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="118.22" y2="168" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="135.2" y2="160.97" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="149.78" y2="149.78" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="160.97" y2="135.2" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="168" y2="118.22" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="170.4" y2="100" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="168" y2="81.78" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="160.97" y2="64.8" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="149.78" y2="50.22" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="135.2" y2="39.03" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
<line x1="100" y1="100" x2="118.22" y2="32" style="fill:none;stroke:#4196ff;stroke-linecap:round;stroke-linejoin:round" />
</g>
<path d="M100,96.43A3.57,3.57,0,1,1,96.43,100h0A3.57,3.57,0,0,1,100,96.43m0-.8a4.37,4.37,0,1,0,4.37,4.37A4.37,4.37,0,0,0,100,95.63Z" style="fill:#4196ff;opacity:0.10000000149011612;isolation:isolate" />
<path d="M100,88.18A11.82,11.82,0,1,1,88.18,100h0A11.83,11.83,0,0,1,100,88.18m0-.8A12.62,12.62,0,1,0,112.62,100,12.62,12.62,0,0,0,100,87.38Z" style="fill:#4196ff;opacity:0.11999999731779099;isolation:isolate" />
<path d="M100,79.92A20.08,20.08,0,1,1,79.92,100h0A20.1,20.1,0,0,1,100,79.92m0-.8A20.88,20.88,0,1,0,120.88,100,20.88,20.88,0,0,0,100,79.12Z" style="fill:#4196ff;opacity:0.14000000059604645;isolation:isolate" />
<path d="M100,71.67A28.33,28.33,0,1,1,71.67,100h0A28.36,28.36,0,0,1,100,71.67m0-.8A29.13,29.13,0,1,0,129.13,100,29.13,29.13,0,0,0,100,70.87Z" style="fill:#4196ff;opacity:0.1599999964237213;isolation:isolate" />
<path d="M100,63.42A36.58,36.58,0,1,1,63.42,100h0A36.63,36.63,0,0,1,100,63.42m0-.8A37.38,37.38,0,1,0,137.38,100,37.38,37.38,0,0,0,100,62.62Z" style="fill:#4196ff;opacity:0.18000000715255737;isolation:isolate" />
<path d="M100,55.16A44.84,44.84,0,1,1,55.16,100h0A44.89,44.89,0,0,1,100,55.16m0-.8A45.64,45.64,0,1,0,145.64,100,45.64,45.64,0,0,0,100,54.36Z" style="fill:#4196ff;opacity:0.20000000298023224;isolation:isolate" />
<path d="M100,46.91A53.09,53.09,0,1,1,46.91,100h0A53.15,53.15,0,0,1,100,46.91m0-.8A53.89,53.89,0,1,0,153.89,100,53.89,53.89,0,0,0,100,46.11Z" style="fill:#4196ff;opacity:0.2199999988079071;isolation:isolate" />
<path d="M100,38.65A61.35,61.35,0,1,1,38.65,100h0A61.42,61.42,0,0,1,100,38.65m0-.8A62.15,62.15,0,1,0,162.15,100,62.15,62.15,0,0,0,100,37.85h0Z" style="fill:#4196ff;opacity:0.23999999463558197;isolation:isolate" />
<path d="M100,30.4A69.6,69.6,0,1,1,30.4,100h0A69.68,69.68,0,0,1,100,30.4m0-.8A70.4,70.4,0,1,0,170.4,100,70.4,70.4,0,0,0,100,29.6h0Z" style="fill:#4196ff;opacity:0.25999999046325684;isolation:isolate" />
<circle cx="100" cy="100" r="0.47" style="fill:#cc3c35;fill-opacity:0" />
<path d="M100,8V28a72,72,0,0,1,72,72h20A92,92,0,0,0,100,8Z" style="fill:#f8ca00" />
<path d="M8,100H28a72,72,0,0,1,72-72V8A92,92,0,0,0,8,100Z" style="fill:#f00" />
<path d="M100,192V172a72,72,0,0,1-72-72H8A92,92,0,0,0,100,192Z" style="fill:#f43b42" />
<path d="M192,100H172a72,72,0,0,1-72,72v20A92,92,0,0,0,192,100Z" style="fill:#fc8358" />
<text transform="translate(146.31 35.77) rotate(45)" style="isolation:isolate;font-size:12.500060081481934px;fill:#fff;font-family:MicrosoftYaHei, Microsoft YaHei">{{ commonName }}</text>
<text transform="translate(150.42 169.77) rotate(-45)" style="isolation:isolate;font-size:12.500060081481934px;fill:#fff;font-family:MicrosoftYaHei, Microsoft YaHei">{{ importantName }}</text>
<text transform="translate(32.77 152.04) rotate(45)" style="isolation:isolate;font-size:12.500060081481934px;fill:#fff;font-family:MicrosoftYaHei, Microsoft YaHei">{{ seriousName }}</text>
<text transform="translate(34.42 56.17) rotate(-45)" style="isolation:isolate;font-size:12.500060081481934px;fill:#fff;font-family:MicrosoftYaHei, Microsoft YaHei">{{ urgentName }}</text>
<!-- <image class="scaner" width="735" height="736" transform="translate(29.6 29.6) scale(0.19 0.19)" xlink:href="@/assets/customComponents/RealTimeAlarmStatistics/scanner.png" />-->
<circle cx="132.8" cy="132.8" r="4" style="fill:#e3bb26;fill-opacity:0.30000001192092896" />
<circle cx="132.8" cy="132.8" r="2.4" style="fill:#e3bb26;fill-opacity:0.6000000238418579" />
<circle cx="132.8" cy="132.8" r="1.2" style="fill:#e3bb26" />
<circle cx="132.8" cy="69.6" r="4" style="fill:#4fa5c2;fill-opacity:0.30000001192092896" />
<circle cx="132.8" cy="69.6" r="2.4" style="fill:#4fa5c2;fill-opacity:0.6000000238418579" />
<circle cx="132.8" cy="69.6" r="1.2" style="fill:#4fa5c2" />
<circle cx="68.8" cy="132.8" r="4" style="fill:#e27b56;fill-opacity:0.30000001192092896" />
<circle cx="68.8" cy="132.8" r="2.4" style="fill:#e27b56;fill-opacity:0.6000000238418579" />
<circle cx="68.8" cy="132.8" r="1.2" style="fill:#e27b56" />
<circle cx="68.8" cy="69.6" r="4" style="fill:#d73d40;fill-opacity:0.30000001192092896" />
<circle cx="68.8" cy="69.6" r="2.4" style="fill:#d73d40;fill-opacity:0.6000000238418579" />
<circle cx="68.8" cy="69.6" r="1.2" style="fill:#d73d40" />
<text transform="translate(63.89 90.49)" style="isolation:isolate;font-size:14px;fill:#fff;font-family:MicrosoftYaHei, Microsoft YaHei">{{ alarmMonitorData ? alarmMonitorData["urgent"] : 0 }}</text>
<text transform="translate(63.89 122.22)" style="isolation:isolate;font-size:14px;fill:#fff;font-family:MicrosoftYaHei, Microsoft YaHei">{{ alarmMonitorData ? alarmMonitorData["serious"] : 0 }}</text>
<text transform="translate(127.89 122.22)" style="isolation:isolate;font-size:14px;fill:#fff;font-family:MicrosoftYaHei, Microsoft YaHei">{{ alarmMonitorData ? alarmMonitorData["important"] : 0 }}</text>
<text transform="translate(124.59 88.89)" style="isolation:isolate;font-size:14px;fill:#fff;font-family:MicrosoftYaHei, Microsoft YaHei">{{ alarmMonitorData ? alarmMonitorData["secondary"] : 0 }}</text>
</g>
</svg>
<svg v-show="alarmLevelsLength === 3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
<g>
<g>
<circle style="opacity:0.2;fill-rule:evenodd;clip-rule:evenodd;fill:#4196FF;" cx="100" cy="100" r="100" />
</g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;fill-opacity:0.6;" cx="100" cy="100" r="92" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;" cx="100" cy="100" r="92" />
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;" cx="100" cy="100" r="92" />
</g>
<g>
<radialGradient id="real_time_alarm_statistics_3_1_" cx="100" cy="100" r="92" gradientUnits="userSpaceOnUse">
<stop offset="0.836" style="stop-color:#FFFFFF;stop-opacity:0.05" />
<stop offset="1" style="stop-color:#D0E3EA;stop-opacity:0.9" />
</radialGradient>
<path style="fill:url(#real_time_alarm_statistics_3_1_);" d="M100,8C49.189,8,8,49.189,8,100s41.189,92,92,92s92-41.189,92-92S150.811,8,100,8L100,8z" />
</g>
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#091C38;" cx="100" cy="100" r="92" />
</g>
<g>
<g style="opacity:0.5;">
<path style="fill:#FFFFFF;" d="M100,11c49.075,0,89,39.925,89,89c0,49.075-39.925,89-89,89s-89-39.925-89-89C11,50.925,50.925,11,100,11 M100,8C49.189,8,8,49.189,8,100s41.189,92,92,92s92-41.189,92-92S150.811,8,100,8L100,8z" />
</g>
</g>
<radialGradient id="real_time_alarm_statistics_3_2_" cx="100" cy="100" r="72.8008" gradientUnits="userSpaceOnUse">
<stop offset="0.9032" style="stop-color:#D0E3EA;stop-opacity:0.9" />
<stop offset="1" style="stop-color:#D0E3EA;stop-opacity:0.05" />
</radialGradient>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#real_time_alarm_statistics_3_2_);fill-opacity:0.6;" cx="100" cy="100" r="72.801" />
<path style="fill:#091C38;" d="M100,27.6c-39.984,0-72.4,32.413-72.4,72.4s32.416,72.4,72.4,72.4c39.986,0,72.4-32.413,72.4-72.4S139.986,27.6,100,27.6L100,27.6z" />
<g style="opacity:0.2;">
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="100" y2="29.6" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="81.778" y2="32" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="64.801" y2="39.032" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="50.219" y2="50.219" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="39.032" y2="64.801" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="31.998" y2="81.778" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="29.6" y2="100" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="31.998" y2="118.222" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="39.032" y2="135.199" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="50.219" y2="149.781" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="64.803" y2="160.968" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="81.779" y2="168" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="100" y2="170.399" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="118.221" y2="168" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="135.198" y2="160.967" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="149.781" y2="149.778" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="160.968" y2="135.199" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="168.004" y2="118.222" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="170.4" y2="100" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="168.004" y2="81.777" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="160.967" y2="64.798" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="149.781" y2="50.218" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="135.198" y2="39.032" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="118.221" y2="32" />
</g>
<path style="opacity:0.1;fill:#4196FF;" d="M100,96.434c1.969,0,3.568,1.598,3.568,3.566s-1.6,3.566-3.568,3.566s-3.568-1.598-3.568-3.566S98.031,96.434,100,96.434 M100,95.633c-2.412,0-4.369,1.955-4.369,4.367s1.957,4.367,4.369,4.367s4.367-1.955,4.367-4.367S102.412,95.633,100,95.633L100,95.633z" />
<path style="opacity:0.12;fill:#4196FF;" d="M100,88.18c6.52,0,11.822,5.301,11.822,11.82S106.52,111.82,100,111.82S88.176,106.52,88.176,100S93.48,88.18,100,88.18 M100,87.379c-6.972,0-12.621,5.65-12.621,12.621s5.649,12.621,12.621,12.621s12.621-5.65,12.621-12.621S106.972,87.379,100,87.379L100,87.379z" />
<path style="opacity:0.14;fill:#4196FF;" d="M100,79.924c11.071,0,20.077,9.006,20.077,20.076s-9.006,20.076-20.077,20.076S79.923,111.07,79.923,100S88.929,79.924,100,79.924 M100,79.123c-11.531,0-20.877,9.347-20.877,20.877s9.346,20.876,20.877,20.876c11.529,0,20.877-9.346,20.877-20.876S111.529,79.123,100,79.123L100,79.123z" />
<path style="opacity:0.16;fill:#4196FF;" d="M100,71.67c15.623,0,28.33,12.708,28.33,28.33s-12.707,28.33-28.33,28.33S71.67,115.622,71.67,100S84.377,71.67,100,71.67 M100,70.869c-16.09,0-29.131,13.045-29.131,29.131S83.91,129.131,100,129.131s29.131-13.045,29.131-29.131S116.09,70.869,100,70.869L100,70.869z" />
<path style="opacity:0.18;fill:#4196FF;" d="M100,63.416c20.173,0,36.584,16.412,36.584,36.584c0,20.173-16.411,36.584-36.584,36.584c-20.174,0-36.584-16.411-36.584-36.584C63.416,79.828,79.826,63.416,100,63.416M100,62.615c-20.646,0-37.385,16.738-37.385,37.385c0,20.646,16.738,37.385,37.385,37.385s37.385-16.739,37.385-37.385C137.385,79.354,120.646,62.615,100,62.615L100,62.615z" />
<path style="opacity:0.2;fill:#4196FF;" d="M100,55.163c24.724,0,44.84,20.112,44.84,44.837s-20.116,44.837-44.84,44.837c-24.725,0-44.84-20.112-44.84-44.837S75.275,55.163,100,55.163 M100,54.363c-25.205,0-45.641,20.432-45.641,45.637S74.795,145.637,100,145.637s45.637-20.432,45.637-45.637S125.205,54.363,100,54.363L100,54.363z" />
<path style="opacity:0.22;fill:#4196FF;" d="M100,46.906c29.275,0,53.092,23.818,53.092,53.094S129.275,153.094,100,153.094S46.906,129.275,46.906,100S70.725,46.906,100,46.906 M100,46.109c-29.765,0-53.891,24.127-53.891,53.891c0,29.763,24.126,53.891,53.891,53.891s53.891-24.128,53.891-53.891C153.891,70.236,129.765,46.109,100,46.109L100,46.109z" />
<path style="opacity:0.24;fill:#4196FF;" d="M100,38.654c33.826,0,61.346,27.52,61.346,61.346s-27.52,61.346-61.346,61.346S38.654,133.826,38.654,100S66.174,38.654,100,38.654 M100,37.854c-34.322,0-62.146,27.823-62.146,62.146c0,34.32,27.824,62.146,62.146,62.146S162.146,134.32,162.146,100C162.146,65.677,134.322,37.854,100,37.854L100,37.854z" />
<path style="opacity:0.26;fill:#4196FF;" d="M100,30.4c38.378,0,69.6,31.222,69.6,69.6s-31.222,69.6-69.6,69.6S30.4,138.378,30.4,100S61.622,30.4,100,30.4 M100,29.6c-38.881,0-70.4,31.521-70.4,70.4c0,38.879,31.52,70.4,70.4,70.4c38.883,0,70.4-31.521,70.4-70.4C170.4,61.12,138.883,29.6,100,29.6L100,29.6z" />
<circle style="opacity:0;fill:#F43B42;" cx="100" cy="100" r="0.471" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;" d="M100,8C65.95,8,36.223,26.499,20.314,53.994l17.339,10.01C50.104,42.486,73.353,28,100,28c26.648,0,49.896,14.487,62.347,36.004l17.339-10.01C163.777,26.499,134.05,8,100,8z" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#F8CA00;" d="M162.347,64.004C168.475,74.596,172,86.883,172,100c0,39.768-32.237,72-72,72v20c50.811,0,92-41.189,92-92c0-16.761-4.484-32.473-12.314-46.006L162.347,64.004z" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;" d="M28,100c0-13.118,3.525-25.404,9.654-35.996l-17.34-10.011C12.484,67.527,8,83.239,8,100c0,50.811,41.189,92,92,92v-20C60.232,172,28,139.764,28,100z" />
<g>
<text transform="matrix(0.5 -0.866 0.866 0.5 166.7588 154.3428)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:12.5001;">{{ importantName }}</text>
</g>
<g>
<text transform="matrix(0.5 0.866 -0.866 0.5 21.5938 132.8682)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:12.5001;">{{ seriousName }}</text>
</g>
<g>
<text transform="matrix(1 0 0 1 87.5 22.5889)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:12.5001;">{{ urgentName }}</text>
</g>
</g>
<!-- <image class="scaner" style="overflow:visible;" width="734" height="734" xlink:href="@/assets/customComponents/RealTimeAlarmStatistics/scanner.png" transform="matrix(0.192 0 0 0.192 29.5996 29.5996)" />-->
<g>
<g>
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#F8CA00;fill-opacity:0.3;" d="M147,122.579c0,2.209-1.79,3.998-3.998,3.998c-2.211,0-4.002-1.789-4.002-3.998c0-2.211,1.791-4.002,4.002-4.002C145.21,118.577,147,120.368,147,122.579z" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F8CA00;fill-opacity:0.6;" cx="143" cy="122.579" r="2.399" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F8CA00;" cx="143.002" cy="122.579" r="1.2" />
</g>
<g>
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;fill-opacity:0.3;" d="M62,122.579c0,2.209-1.791,3.998-4.001,3.998c-2.208,0-3.999-1.789-3.999-3.998c0-2.211,1.791-4.002,3.999-4.002C60.209,118.577,62,120.368,62,122.579z" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;fill-opacity:0.6;" d="M60.4,122.579c0,1.324-1.076,2.398-2.401,2.398c-1.323,0-2.401-1.074-2.401-2.398c0-1.326,1.078-2.4,2.401-2.4C59.324,120.179,60.4,121.253,60.4,122.579z" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;" cx="57.999" cy="122.579" r="1.2" />
</g>
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;fill-opacity:0.3;" cx="100" cy="49.001" r="4" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;fill-opacity:0.6;" cx="99.999" cy="49.001" r="2.401" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;" cx="99.999" cy="49.001" r="1.2" />
</g>
<g>
<text transform="matrix(1 0 0 1 95.0938 69.8911)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ alarmMonitorData ? alarmMonitorData["urgent"] : 0 }}</text>
</g>
<g>
<text transform="matrix(1 0 0 1 53.0938 112)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ alarmMonitorData ? alarmMonitorData["serious"] : 0 }}</text>
</g>
<g>
<text transform="matrix(1 0 0 1 138.0957 112.001)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ alarmMonitorData ? alarmMonitorData["important"] : 0 }}</text>
</g>
</g>
</svg>
<svg v-show="alarmLevelsLength === 2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
<g>
<g>
<circle style="opacity:0.2;fill-rule:evenodd;clip-rule:evenodd;fill:#4196FF;" cx="100" cy="100" r="100" />
</g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;fill-opacity:0.6;" cx="100" cy="100" r="92" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;" cx="100" cy="100" r="92" />
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;" cx="100" cy="100" r="92" />
</g>
<g>
<radialGradient id="real_time_alarm_statistics_2_1_" cx="100" cy="100" r="92" gradientUnits="userSpaceOnUse">
<stop offset="0.836" style="stop-color:#FFFFFF;stop-opacity:0.05" />
<stop offset="1" style="stop-color:#D0E3EA;stop-opacity:0.9" />
</radialGradient>
<path style="fill:url(#real_time_alarm_statistics_2_1_);" d="M100,8C49.189,8,8,49.189,8,100s41.189,92,92,92s92-41.189,92-92S150.811,8,100,8L100,8z" />
</g>
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#091C38;" cx="100" cy="100" r="92" />
</g>
<g>
<g style="opacity:0.5;">
<path style="fill:#FFFFFF;" d="M100,11c49.075,0,89,39.925,89,89c0,49.075-39.925,89-89,89s-89-39.925-89-89C11,50.925,50.925,11,100,11 M100,8C49.189,8,8,49.189,8,100s41.189,92,92,92s92-41.189,92-92S150.811,8,100,8L100,8z" />
</g>
</g>
<radialGradient id="real_time_alarm_statistics_2_2_" cx="100" cy="100" r="72.8008" gradientUnits="userSpaceOnUse">
<stop offset="0.9032" style="stop-color:#D0E3EA;stop-opacity:0.9" />
<stop offset="1" style="stop-color:#D0E3EA;stop-opacity:0.05" />
</radialGradient>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#real_time_alarm_statistics_2_2_);fill-opacity:0.6;" cx="100" cy="100" r="72.801" />
<path style="fill:#091C38;" d="M100,27.6c-39.984,0-72.4,32.413-72.4,72.4s32.416,72.4,72.4,72.4c39.986,0,72.4-32.413,72.4-72.4S139.986,27.6,100,27.6L100,27.6z" />
<g style="opacity:0.2;">
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="100" y2="29.6" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="81.778" y2="32" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="64.801" y2="39.032" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="50.219" y2="50.219" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="39.032" y2="64.801" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="31.998" y2="81.778" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="29.6" y2="100" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="31.998" y2="118.222" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="39.032" y2="135.199" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="50.219" y2="149.781" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="64.803" y2="160.968" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="81.779" y2="168" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="100" y2="170.399" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="118.221" y2="168" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="135.198" y2="160.967" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="149.781" y2="149.778" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="160.968" y2="135.199" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="168.004" y2="118.222" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="170.4" y2="100" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="168.004" y2="81.777" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="160.967" y2="64.798" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="149.781" y2="50.218" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="135.198" y2="39.032" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="118.221" y2="32" />
</g>
<path style="opacity:0.1;fill:#4196FF;" d="M100,96.434c1.969,0,3.568,1.598,3.568,3.566s-1.6,3.566-3.568,3.566s-3.568-1.598-3.568-3.566S98.031,96.434,100,96.434 M100,95.633c-2.412,0-4.369,1.955-4.369,4.367s1.957,4.367,4.369,4.367s4.367-1.955,4.367-4.367S102.412,95.633,100,95.633L100,95.633z" />
<path style="opacity:0.12;fill:#4196FF;" d="M100,88.18c6.52,0,11.822,5.301,11.822,11.82S106.52,111.82,100,111.82S88.176,106.52,88.176,100S93.48,88.18,100,88.18 M100,87.379c-6.972,0-12.621,5.65-12.621,12.621s5.649,12.621,12.621,12.621s12.621-5.65,12.621-12.621S106.972,87.379,100,87.379L100,87.379z" />
<path style="opacity:0.14;fill:#4196FF;" d="M100,79.924c11.071,0,20.077,9.006,20.077,20.076s-9.006,20.076-20.077,20.076S79.923,111.07,79.923,100S88.929,79.924,100,79.924 M100,79.123c-11.531,0-20.877,9.347-20.877,20.877s9.346,20.876,20.877,20.876c11.529,0,20.877-9.346,20.877-20.876S111.529,79.123,100,79.123L100,79.123z" />
<path style="opacity:0.16;fill:#4196FF;" d="M100,71.67c15.623,0,28.33,12.708,28.33,28.33s-12.707,28.33-28.33,28.33S71.67,115.622,71.67,100S84.377,71.67,100,71.67 M100,70.869c-16.09,0-29.131,13.045-29.131,29.131S83.91,129.131,100,129.131s29.131-13.045,29.131-29.131S116.09,70.869,100,70.869L100,70.869z" />
<path style="opacity:0.18;fill:#4196FF;" d="M100,63.416c20.173,0,36.584,16.412,36.584,36.584c0,20.173-16.411,36.584-36.584,36.584c-20.174,0-36.584-16.411-36.584-36.584C63.416,79.828,79.826,63.416,100,63.416M100,62.615c-20.646,0-37.385,16.738-37.385,37.385c0,20.646,16.738,37.385,37.385,37.385s37.385-16.739,37.385-37.385C137.385,79.354,120.646,62.615,100,62.615L100,62.615z" />
<path style="opacity:0.2;fill:#4196FF;" d="M100,55.163c24.724,0,44.84,20.112,44.84,44.837s-20.116,44.837-44.84,44.837c-24.725,0-44.84-20.112-44.84-44.837S75.275,55.163,100,55.163 M100,54.363c-25.205,0-45.641,20.432-45.641,45.637S74.795,145.637,100,145.637s45.637-20.432,45.637-45.637S125.205,54.363,100,54.363L100,54.363z" />
<path style="opacity:0.22;fill:#4196FF;" d="M100,46.906c29.275,0,53.092,23.818,53.092,53.094S129.275,153.094,100,153.094S46.906,129.275,46.906,100S70.725,46.906,100,46.906 M100,46.109c-29.765,0-53.891,24.127-53.891,53.891c0,29.763,24.126,53.891,53.891,53.891s53.891-24.128,53.891-53.891C153.891,70.236,129.765,46.109,100,46.109L100,46.109z" />
<path style="opacity:0.24;fill:#4196FF;" d="M100,38.654c33.826,0,61.346,27.52,61.346,61.346s-27.52,61.346-61.346,61.346S38.654,133.826,38.654,100S66.174,38.654,100,38.654 M100,37.854c-34.322,0-62.146,27.823-62.146,62.146c0,34.32,27.824,62.146,62.146,62.146S162.146,134.32,162.146,100C162.146,65.677,134.322,37.854,100,37.854L100,37.854z" />
<path style="opacity:0.26;fill:#4196FF;" d="M100,30.4c38.378,0,69.6,31.222,69.6,69.6s-31.222,69.6-69.6,69.6S30.4,138.378,30.4,100S61.622,30.4,100,30.4 M100,29.6c-38.881,0-70.4,31.521-70.4,70.4c0,38.879,31.52,70.4,70.4,70.4c38.883,0,70.4-31.521,70.4-70.4C170.4,61.12,138.883,29.6,100,29.6L100,29.6z" />
<circle style="opacity:0;fill:#F43B42;" cx="100" cy="100" r="0.471" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;" d="M100,8C49.189,8,8,49.189,8,100h20c0-39.768,32.236-72,72-72c39.768,0,72,32.236,72,72h20C192,49.189,150.811,8,100,8z" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;" d="M172,100c0,39.768-32.237,72-72,72c-39.768,0-72-32.236-72-72H8c0,50.811,41.189,92,92,92s92-41.189,92-92H172z" />
<g>
<text transform="matrix(1 0 0 1 88 23)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:12.5001;">{{ urgentName }}</text>
</g>
<g>
<text transform="matrix(1 0 0 1 88 187)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:12.5001;">{{ seriousName }}</text>
</g>
</g>
<!-- <image class="scaner" style="overflow:visible;" width="734" height="734" xlink:href="@/assets/customComponents/RealTimeAlarmStatistics/scanner.png" transform="matrix(0.192 0 0 0.192 29.5996 29.5996)" />-->
<g>
<g>
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;fill-opacity:0.3;" d="M105,132.801c0,2.209-1.791,3.998-4.001,3.998c-2.208,0-3.999-1.789-3.999-3.998c0-2.211,1.791-4.002,3.999-4.002C103.209,128.799,105,130.59,105,132.801z" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;fill-opacity:0.6;" d="M103.4,132.801c0,1.324-1.076,2.398-2.401,2.398c-1.323,0-2.401-1.074-2.401-2.398c0-1.326,1.078-2.4,2.401-2.4C102.324,130.4,103.4,131.475,103.4,132.801z" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#FC8358;" cx="100.999" cy="132.801" r="1.2" />
</g>
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;fill-opacity:0.3;" cx="101" cy="69.6" r="4" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;fill-opacity:0.6;" cx="100.999" cy="69.6" r="2.401" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;" cx="100.999" cy="69.6" r="1.2" />
</g>
<g>
<text transform="matrix(1 0 0 1 96.0938 90.4897)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ alarmMonitorData ? alarmMonitorData["urgent"] : 0 }}</text>
</g>
<g>
<text transform="matrix(1 0 0 1 96.0938 122.2217)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ alarmMonitorData ? alarmMonitorData["serious"] : 0 }}</text>
</g>
</g>
</svg>
<svg v-show="alarmLevelsLength === 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
<g>
<g>
<circle style="opacity:0.2;fill-rule:evenodd;clip-rule:evenodd;fill:#4196FF;" cx="100" cy="100" r="100" />
</g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;fill-opacity:0.6;" cx="100" cy="100" r="92" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;" cx="100" cy="100" r="92" />
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#D0E3EA;" cx="100" cy="100" r="92" />
</g>
<g>
<radialGradient id="real_time_alarm_statistics_1_1_" cx="100" cy="100" r="92" gradientUnits="userSpaceOnUse">
<stop offset="0.836" style="stop-color:#FFFFFF;stop-opacity:0.05" />
<stop offset="1" style="stop-color:#D0E3EA;stop-opacity:0.9" />
</radialGradient>
<path style="fill:url(#real_time_alarm_statistics_1_1_);" d="M100,8C49.189,8,8,49.189,8,100s41.189,92,92,92s92-41.189,92-92S150.811,8,100,8L100,8z" />
</g>
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#091C38;" cx="100" cy="100" r="92" />
</g>
<g>
<g style="opacity:0.5;">
<path style="fill:#FFFFFF;" d="M100,11c49.075,0,89,39.925,89,89c0,49.075-39.925,89-89,89c-49.075,0-89-39.925-89-89C11,50.925,50.925,11,100,11 M100,8C49.189,8,8,49.189,8,100s41.189,92,92,92s92-41.189,92-92S150.811,8,100,8L100,8z" />
</g>
</g>
<radialGradient id="real_time_alarm_statistics_1_2_" cx="100" cy="100" r="72.8008" gradientUnits="userSpaceOnUse">
<stop offset="0.9032" style="stop-color:#D0E3EA;stop-opacity:0.9" />
<stop offset="1" style="stop-color:#D0E3EA;stop-opacity:0.05" />
</radialGradient>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:url(#real_time_alarm_statistics_1_2_);fill-opacity:0.6;" cx="100" cy="100" r="72.801" />
<path style="fill:#091C38;" d="M100,27.6c-39.984,0-72.4,32.413-72.4,72.4s32.416,72.4,72.4,72.4c39.986,0,72.4-32.413,72.4-72.4S139.986,27.6,100,27.6L100,27.6z" />
<g style="opacity:0.2;">
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="100" y2="29.6" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="81.778" y2="32" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="64.801" y2="39.032" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="50.219" y2="50.219" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="39.032" y2="64.801" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="31.998" y2="81.778" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="29.6" y2="100" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="31.998" y2="118.222" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="39.032" y2="135.199" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="50.219" y2="149.781" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="64.803" y2="160.968" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="81.779" y2="168" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="100" y2="170.399" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="118.221" y2="168" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="135.198" y2="160.967" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="149.781" y2="149.778" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="160.968" y2="135.199" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="168.004" y2="118.222" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="170.4" y2="100" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="168.004" y2="81.777" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="160.967" y2="64.798" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="149.781" y2="50.218" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="135.198" y2="39.032" />
<line style="fill:none;stroke:#4196FF;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" x1="100" y1="100" x2="118.221" y2="32" />
</g>
<path style="opacity:0.1;fill:#4196FF;" d="M100,96.434c1.969,0,3.568,1.598,3.568,3.566s-1.6,3.566-3.568,3.566s-3.568-1.598-3.568-3.566S98.031,96.434,100,96.434 M100,95.633c-2.412,0-4.369,1.955-4.369,4.367s1.957,4.367,4.369,4.367s4.367-1.955,4.367-4.367S102.412,95.633,100,95.633L100,95.633z" />
<path style="opacity:0.12;fill:#4196FF;" d="M100,88.18c6.52,0,11.822,5.301,11.822,11.82S106.52,111.82,100,111.82S88.176,106.52,88.176,100S93.48,88.18,100,88.18 M100,87.379c-6.972,0-12.621,5.65-12.621,12.621s5.649,12.621,12.621,12.621s12.621-5.65,12.621-12.621S106.972,87.379,100,87.379L100,87.379z" />
<path style="opacity:0.14;fill:#4196FF;" d="M100,79.924c11.071,0,20.077,9.006,20.077,20.076s-9.006,20.076-20.077,20.076S79.923,111.07,79.923,100S88.929,79.924,100,79.924 M100,79.123c-11.531,0-20.877,9.347-20.877,20.877s9.346,20.876,20.877,20.876c11.529,0,20.877-9.346,20.877-20.876S111.529,79.123,100,79.123L100,79.123z" />
<path style="opacity:0.16;fill:#4196FF;" d="M100,71.67c15.623,0,28.33,12.708,28.33,28.33s-12.707,28.33-28.33,28.33S71.67,115.622,71.67,100S84.377,71.67,100,71.67 M100,70.869c-16.09,0-29.131,13.045-29.131,29.131S83.91,129.131,100,129.131s29.131-13.045,29.131-29.131S116.09,70.869,100,70.869L100,70.869z" />
<path style="opacity:0.18;fill:#4196FF;" d="M100,63.416c20.173,0,36.584,16.412,36.584,36.584c0,20.173-16.411,36.584-36.584,36.584c-20.174,0-36.584-16.411-36.584-36.584C63.416,79.828,79.826,63.416,100,63.416M100,62.615c-20.646,0-37.385,16.738-37.385,37.385c0,20.646,16.738,37.385,37.385,37.385s37.385-16.739,37.385-37.385C137.385,79.354,120.646,62.615,100,62.615L100,62.615z" />
<path style="opacity:0.2;fill:#4196FF;" d="M100,55.163c24.724,0,44.84,20.112,44.84,44.837s-20.116,44.837-44.84,44.837c-24.725,0-44.84-20.112-44.84-44.837S75.275,55.163,100,55.163 M100,54.363c-25.205,0-45.641,20.432-45.641,45.637S74.795,145.637,100,145.637s45.637-20.432,45.637-45.637S125.205,54.363,100,54.363L100,54.363z" />
<path style="opacity:0.22;fill:#4196FF;" d="M100,46.906c29.275,0,53.092,23.818,53.092,53.094S129.275,153.094,100,153.094S46.906,129.275,46.906,100S70.725,46.906,100,46.906 M100,46.109c-29.765,0-53.891,24.127-53.891,53.891c0,29.763,24.126,53.891,53.891,53.891s53.891-24.128,53.891-53.891C153.891,70.236,129.765,46.109,100,46.109L100,46.109z" />
<path style="opacity:0.24;fill:#4196FF;" d="M100,38.654c33.826,0,61.346,27.52,61.346,61.346s-27.52,61.346-61.346,61.346S38.654,133.826,38.654,100S66.174,38.654,100,38.654 M100,37.854c-34.322,0-62.146,27.823-62.146,62.146c0,34.32,27.824,62.146,62.146,62.146S162.146,134.32,162.146,100C162.146,65.677,134.322,37.854,100,37.854L100,37.854z" />
<path style="opacity:0.26;fill:#4196FF;" d="M100,30.4c38.378,0,69.6,31.222,69.6,69.6s-31.222,69.6-69.6,69.6S30.4,138.378,30.4,100S61.622,30.4,100,30.4 M100,29.6c-38.881,0-70.4,31.521-70.4,70.4c0,38.879,31.52,70.4,70.4,70.4c38.883,0,70.4-31.521,70.4-70.4C170.4,61.12,138.883,29.6,100,29.6L100,29.6z" />
<circle style="opacity:0;fill:#F43B42;" cx="100" cy="100" r="0.471" />
<path style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;" d="M100,8C49.189,8,8,49.189,8,100s41.189,92,92,92s92-41.189,92-92S150.811,8,100,8z M100,172c-39.768,0-72-32.236-72-72c0-39.768,32.236-72,72-72c39.768,0,72,32.236,72,72C172,139.768,139.763,172,100,172z" />
</g>
<!-- <image class="scaner" style="overflow:visible;" width="734" height="734" xlink:href="@/assets/customComponents/RealTimeAlarmStatistics/scanner.png" transform="matrix(0.192 0 0 0.192 29.5996 29.5996)" />-->
<g>
<g>
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;fill-opacity:0.3;" cx="101" cy="101.001" r="4" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;fill-opacity:0.6;" cx="100.999" cy="101.001" r="2.401" />
<circle style="fill-rule:evenodd;clip-rule:evenodd;fill:#F43B42;" cx="100.999" cy="101.001" r="1.2" />
</g>
<g>
<text transform="matrix(1 0 0 1 96.0933 121.8906)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ alarmMonitorData ? alarmMonitorData["urgent"] : 0 }}</text>
</g>
<g>
<text transform="matrix(1 0 0 1 86.1982 84)" style="fill:#FFFFFF; font-family:'MicrosoftYaHei'; font-size:14;">{{ urgentName }}</text>
</g>
</g>
</svg>
</div>
</template>
<script lang="ts" setup>
import { toRefs, computed, onMounted, onUnmounted, ref } from 'vue'
import { ResizeObserverELE } from '@/utils/aboutHtml2Canvas'
const props = defineProps(['urgentName', 'seriousName', 'importantName', 'commonName', 'eventName', 'alarmMonitorData', 'alarmLevels'])
const { urgentName, seriousName, importantName, commonName, eventName, alarmMonitorData, alarmLevels } = toRefs(props)
const alarmLevelsLength = computed(() => {
return alarmLevels!.value.length
})
let shorterSide = ref('50px')
const box = ref(null)
const observer = ResizeObserverELE((w, h) => {
shorterSide.value = `${w > h ? h : w}px`
})
onMounted(() => {
observer.observe(box.value!);
})
onUnmounted(() => {
observer.disconnect();
})
</script>
<style lang="scss" scoped>
@keyframes rotate {
from { transform: translate(-50%, -50%) scale(0.71) rotate(0)}
to { transform: translate(-50%, -50%) scale(0.71) rotate(360deg) }
}
.box{
position: relative;
height: 100%;
svg{
height: 100%;
width: 100%;
position: absolute;
//top: 50%;
//transform: translateY(-50%);
z-index: 2;
}
.scaner{
// html2canvas :
//object-fit: contain;
height: 100%;
width: 100%;
position: absolute;
top: 50%;
left: 50%;
animation: rotate linear 5s infinite;
z-index: 3;
//height: 100%;
}
}
</style>

View File

@ -0,0 +1,32 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { RealTimeAlarmStatisticsConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
// import background from '@/assets/customComponents/theme1/backgrond.jpg'
export const option = {
// 图片路径
dataset: '',
// 适应方式
fit: 'contain',
// 圆角
borderRadius: 0
}
export default class Config extends PublicConfigClass implements CreateComponentType
{
constructor() {
super();
this.attr.w = 450
this.attr.h = 300
this.request.requestInterval = 15
}
public key = RealTimeAlarmStatisticsConfig.key
public chartConfig = cloneDeep(RealTimeAlarmStatisticsConfig)
public option = cloneDeep(option)
public customData = cloneDeep({
title: '实时告警统计',
showInterval: true,
space_complete_id: '',
})
}

View File

@ -0,0 +1,67 @@
<template>
<!-- <collapse-item name="属性" :expanded="true">-->
<!-- <setting-item-box name="路径" :alone="true">-->
<!-- <setting-item>-->
<!-- <n-input v-model:value="optionData.dataset" size="small"></n-input>-->
<!-- </setting-item>-->
<!-- </setting-item-box>-->
<!-- <setting-item-box name="样式">-->
<!-- <setting-item name="类型">-->
<!-- <n-select-->
<!-- v-model:value="optionData.fit"-->
<!-- size="small"-->
<!-- :options="fitList"-->
<!-- ></n-select>-->
<!-- </setting-item>-->
<!-- <setting-item name="圆角">-->
<!-- <n-input-number-->
<!-- v-model:value="optionData.borderRadius"-->
<!-- size="small"-->
<!-- :min="0"-->
<!-- placeholder="圆角"-->
<!-- ></n-input-number>-->
<!-- </setting-item>-->
<!-- </setting-item-box>-->
<!-- </collapse-item>-->
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option } from './config'
import {
CollapseItem,
SettingItemBox,
SettingItem,
} from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true,
},
})
//
const fitList = [
{
value: 'fill',
label: 'fill'
},
{
value: 'contain',
label: 'contain'
},
{
value: 'cover',
label: 'cover'
},
{
value: 'scale-down',
label: 'scale-down'
},
{
value: 'none',
label: 'none'
},
]
</script>

View File

@ -0,0 +1,17 @@
<template>
<setting-item-box name="标题" :alone="true">
<n-input v-model:value="props.customData.title" size="small" placeholder="请输入标题"/>
</setting-item-box>
<setting-item-box name="空间ID" :alone="true">
<n-input v-model:value="props.customData.space_complete_id" size="small" placeholder="请输入空间ID"/>
</setting-item-box>
</template>
<script lang="ts" setup>
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
const props = defineProps(['customData', 'request'])
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,18 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum,ChatCategoryEnumName } from '@/packages/components/CUSTOMCOMPONENTS/index.d'
export const RealTimeAlarmStatisticsConfig: ConfigType = {
key: 'RealTimeAlarmStatistics',
chartKey: 'VRealTimeAlarmStatistics',
conKey: 'VCRealTimeAlarmStatistics',
conDataKey: 'VCDRealTimeAlarmStatistics',
title: '实时告警统计',
// category: ChatCategoryEnum.THEMES,
// categoryName: ChatCategoryEnumName.THEMES,
// package: PackagesCategoryEnum.THEMESANDLAYOUTS,
category: ChatCategoryEnum.ALARMDIAGRAM,
categoryName: ChatCategoryEnumName.ALARMDIAGRAM,
package: PackagesCategoryEnum.CUSTOMCOMPONENTS,
chartFrame: ChartFrameEnum.COMMON,
image: 'RealTimeAlarmStatistics.png'
}

View File

@ -0,0 +1,329 @@
<template>
<div :style="getStyle(borderRadius)">
<BorderBox :title="chartConfig?.customData?.title">
<v-chart
ref="vChartRef"
:option="option"
:manual-update="false"
:update-options="{
replaceMerge: ['series', 'xAxis', 'yAxis']
}"
autoresize
style="overflow: visible;width: calc(50% - 10px);margin-right: 20px;"
/>
<div class="box-5-item" style="width: calc(50% - 10px)">
<SvgAll v-bind="nameObj"/>
</div>
</BorderBox>
</div>
</template>
<script setup lang="ts">
import { PropType, watch, toRefs, reactive, onMounted, onUnmounted, nextTick, ref } from 'vue'
import {isPreview} from '@/utils'
import { CreateComponentType } from '@/packages/index.d'
import BorderBox from '../components/BorderBox.vue'
import SvgAll from './Svg.vue'
import {RequestHttpIntervalEnum} from "@/enums/httpEnum";
import { useOriginStore } from '@/store/modules/originStore/originStore'
import { publicInterface } from '@/api/path/business.api'
import {selectTimeOptions} from "@/views/chart/ContentConfigurations/components/ChartData/index.d";
import VChart from 'vue-echarts'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { w, h } = toRefs(props.chartConfig.attr)
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
const getStyle = (radius: number) => {
return {
borderRadius: `${radius}px`,
overflow: 'hidden'
}
}
const nameObj = reactive({
urgentName: '紧急',
seriousName: '严重',
importantName: '重要',
commonName: '一般',
eventName: '事件',
alarmMonitorData: {
urgent: 0,
serious: 0,
important: 0,
secondary: 0,
record: 0
},
alarmLevels: [],
urgentColor: '#cb3f3f',
seriousColor: '#d87855',
importantColor: '#dab42e',
commonColor: '#47acea',
eventColor: '#4fbadb',
})
const originStore = useOriginStore()
const systemConfig = originStore?.getOriginStore?.user?.systemConfig
const systemConstant = originStore?.getOriginStore?.user?.systemConstant
if (systemConfig['active_alarm_level']) {
for (let i:number = 0; i < Number(systemConfig['active_alarm_level']); i++) {
(nameObj.alarmLevels as number[]).push(i + 1)
}
}
nameObj.urgentName = systemConstant['warn_levels'].find((item:any) => item.value === '1') ? systemConstant['warn_levels'].find((item:any) => item.value === '1')['label'] : '紧急'
nameObj.seriousName = systemConstant['warn_levels'].find((item:any) => item.value === '2') ? systemConstant['warn_levels'].find((item:any) => item.value === '2')['label'] : '严重'
nameObj.importantName = systemConstant['warn_levels'].find((item:any) => item.value === '3') ? systemConstant['warn_levels'].find((item:any) => item.value === '3')['label'] : '重要'
nameObj.commonName = systemConstant['warn_levels'].find((item:any) => item.value === '4') ? systemConstant['warn_levels'].find((item:any) => item.value === '4')['label'] : '一般'
nameObj.eventName = systemConstant['warn_levels'].find((item:any) => item.value === '5') ? systemConstant['warn_levels'].find((item:any) => item.value === '5')['label'] : '事件'
nameObj.urgentColor = systemConstant['warn_levels'].find((item:any) => item.value === '1') ? systemConstant['warn_levels'].find((item:any) => item.value === '1')['remark'] : '#cb3f3f'
nameObj.seriousColor = systemConstant['warn_levels'].find((item:any) => item.value === '2') ? systemConstant['warn_levels'].find((item:any) => item.value === '2')['remark'] : '#d87855'
nameObj.importantColor = systemConstant['warn_levels'].find((item:any) => item.value === '3') ? systemConstant['warn_levels'].find((item:any) => item.value === '3')['remark'] : '#dab42e'
nameObj.commonColor = systemConstant['warn_levels'].find((item:any) => item.value === '4') ? systemConstant['warn_levels'].find((item:any) => item.value === '4')['remark'] : '#47acea'
nameObj.eventColor = systemConstant['warn_levels'].find((item:any) => item.value === '5') ? systemConstant['warn_levels'].find((item:any) => item.value === '5')['remark'] : '#4fbadb'
const getData = () => {
const confirm_statuss = systemConfig?.['active_alarm_confirm_status'] ? [...JSON.parse(systemConfig['active_alarm_confirm_status'])] : []
const param = {
confirm_statuss,
space_complete_id: props.chartConfig.customData?.space_complete_id
}
publicInterface('/dcim/dems/devie_active_alarm', 'count_by_level_new', param).then(res => {
if (res && res.data && JSON.stringify(res.data) !== '{}') {
nameObj.alarmMonitorData['urgent'] = res.data['level1'] ? res.data['level1'] : 0
nameObj.alarmMonitorData['serious'] = res.data['level2'] ? res.data['level2'] : 0
nameObj.alarmMonitorData['important'] = res.data['level3'] ? res.data['level3'] : 0
nameObj.alarmMonitorData['secondary'] = res.data['level4'] ? res.data['level4'] : 0
nameObj.alarmMonitorData['record'] = res.data['level5'] ? res.data['level5'] : 0
initChart()
}
})
}
let option = reactive({})
const initChart = () => {
const len = nameObj.alarmLevels.length ? nameObj.alarmLevels.length : 4
const yDataArr = [nameObj.eventName, nameObj.commonName, nameObj.importantName, nameObj.seriousName, nameObj.urgentName].reverse().slice(0, len).reverse()
const dataArr = [nameObj.alarmMonitorData.record, nameObj.alarmMonitorData.secondary, nameObj.alarmMonitorData.important, nameObj.alarmMonitorData.serious, nameObj.alarmMonitorData.urgent].reverse().slice(0, len).reverse()
const yAxisColorList = [
nameObj.eventColor ? nameObj.eventColor : '#4fbadb',
nameObj.commonColor ? nameObj.commonColor : '#47acea',
nameObj.importantColor ? nameObj.importantColor : '#dab42e',
nameObj.seriousColor ? nameObj.seriousColor : '#d87855',
nameObj.urgentColor ? nameObj.urgentColor : '#cb3f3f'
].reverse().slice(0, len).reverse()
const seriesColorList = [
{
// 线
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [{
offset: 0, color: '#47acea00' // 0%
}, {
offset: 1, color: nameObj.eventColor ? nameObj.eventColor : '#4fbadb' // 100%
}],
global: false // false
},
{
// 线
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [{
offset: 0, color: '#47acea00' // 0%
}, {
offset: 1, color: nameObj.commonColor ? nameObj.commonColor : '#47acea' // 100%
}],
global: false // false
},
{
// 线
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [{
offset: 0, color: '#dab42e00' // 0%
}, {
offset: 1, color: nameObj.importantColor ? nameObj.importantColor : '#dab42e' // 100%
}],
global: false // false
},
{
// 线
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [{
offset: 0, color: '#d8785500' // 0%
}, {
offset: 1, color: nameObj.seriousColor ? nameObj.seriousColor : '#d87855' // 100%
}],
global: false // false
},
{
// 线
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [{
offset: 0, color: '#cb3f3f00' // 0%
}, {
offset: 1, color: nameObj.urgentColor ? nameObj.urgentColor : '#cb3f3f' // 100%
}],
global: false // false
}
].reverse().slice(0, len).reverse()
const echart7Options = {
grid: [
{
top: '-3%',
bottom: '-15%',
left: '10%',
right: '0%',
containLabel: true
}
],
xAxis: {
show: false,
// max: 1000,
type: 'value',
axisLine: { show: false },
splitLine: { show: false },
axisTick: { show: false },
data: dataArr
},
yAxis: [
{
type: 'category',
// inverse: true,
axisLine: { show: false },
splitLine: { show: false },
axisTick: { show: false },
axisLabel: {
// inside: true,
// verticalAlign: 'center',
// align: 'center',
color: '#ccc',
// padding: [0, 0, 0, 0],
fontSize: 14
},
data: yDataArr
},
{
type: 'category',
// inverse: true,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: true,
inside: false,
// verticalAlign: 'bottom',
//
padding: [0, 10, 15, 0],
// lineHeight: '40',
textStyle: {
fontSize: 14,
color: (value:unknown, index:number) => {
return yAxisColorList[index]
}
}
},
//
data: dataArr
}
],
series: [
{
label: {
show: false,
fontSize: 16,
fontWeight: 'bold',
// formatter: '使{d}({c})',
formatter: (params:any) => {
return `已使用${(parseFloat(params.value) / 88888 * 100).toFixed(1)}%(${params.value})`
},
position: 'insideLeft',
align: 'left'
},
showBackground: true,
backgroundStyle: {
color: 'rgba(134, 188, 255, 0.2)'
},
barWidth: 10,
barCategoryGap: '30%',
type: 'bar',
data: dataArr,
itemStyle: {
normal: {
//
color: (params:any) => {
return seriesColorList[params.dataIndex]
}
}
}
}
]
}
Object.assign(option, echart7Options)
}
let timer:unknown
watch(() => [props.chartConfig.request.requestInterval, props.chartConfig.request.requestIntervalUnit, props.chartConfig.customData?.space_complete_id].join('&&'), v => {
if(!isPreview()) return
if(props.chartConfig.request.requestInterval) {
if(timer) clearInterval(timer as number)
const obj = selectTimeOptions.find(_ => _.value === props.chartConfig.request.requestIntervalUnit) || {unit: 0}
const unit = obj.unit
const number = unit * props.chartConfig.request.requestInterval
timer = setInterval(() => {
getData()
}, number)
}
})
onMounted(() => {
nextTick(() => {
getData()
})
if(!isPreview()) return
const obj = selectTimeOptions.find(_ => _.value === props.chartConfig.request.requestIntervalUnit) || {unit: 0}
const unit = obj.unit
const number = unit * props.chartConfig.request.requestInterval!
timer = setInterval(() => {
nextTick(() => {
getData()
})
}, number)
})
onUnmounted(() => {
clearInterval(timer as number)
})
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,121 @@
<template>
<BorderBox>
<template #title>
<div class="titleBox">
<div class="mr10">{{title}}</div>
<n-checkbox :checked="checkAll" @update:checked="(v:boolean) => emit('update:checkAll', v)" size="small" class="mr10">全选</n-checkbox>
<n-button strong size="tiny" color="rgba(36,197,231,.5)" text-color="#fff" class="button" @click="clickBatch">
<template #icon>
<AssignmentTurnedInRoundIcon/>
</template>
批量确认
</n-button>
<div style="flex: 1"></div>
<n-checkbox-group v-if="showFilter" :value="select1.value" @update:value="(v:[]) => changeSelect1(v)" class="mr10" size="small">
<n-space item-style="display: flex;" size="small">
<n-checkbox :value="item.value" :label="item.label" v-for="(item, i) in select1.options" :key="i">
<div :style="{color: item.color}" style="display: inline-block">{{item.label}}</div>
<div style="display: inline-block">({{item.number}})</div>
</n-checkbox>
</n-space>
</n-checkbox-group>
<n-checkbox-group v-if="showFilter" :value="select2.value" @update:value="(v:[]) => changeSelect2(v)" class="mr10" size="small">
<n-space item-style="display: flex;">
<n-checkbox :value="item.value" :label="item.label" v-for="(item, i) in select2.options" :key="i">
<div :style="{color: item.color}" style="display: inline-block">{{item.label}}</div>
<div style="display: inline-block">({{item.number}})</div>
</n-checkbox>
</n-space>
</n-checkbox-group>
<div class="more" @click="jumpMore">更多>></div>
</div>
</template>
<template #default>
<slot></slot>
</template>
</BorderBox>
</template>
<script lang="ts" setup>
import { ref, reactive, toRefs, defineEmits } from 'vue'
import BorderBox from '../components/BorderBox.vue'
import { icon } from '@/plugins/icon'
const { AssignmentTurnedInRoundIcon } = icon.material
interface propsType {
title: string,
select1: {
value: number[],
options: { label: string, value: number, number: number, color: string }[],
},
select2: {
value: string[],
options: { label: string, value: string, number: number, color: string }[],
},
checkAll: boolean,
showFilter: boolean,
}
const props = defineProps<propsType>()
const { select1, select2 } = toRefs(props)
const emit = defineEmits(['clickBatch', 'update:select1Value', 'update:select2Value', 'update:checkAll', 'jumpMore'])
const clickBatch = () => {
emit('clickBatch')
}
const changeSelect1 = (v:number[]) => {
emit('update:select1Value', v)
}
const changeSelect2 = (v:number[]) => {
emit('update:select2Value', v)
}
const jumpMore = () => {
emit('jumpMore')
}
// const select1 = reactive({
// value: [1, 2],
// options: [
// { label: '', value: 1, number: 0, color: '#ff0000' },
// { label: '', value: 2, number: 0, color: '#f43b42' },
// { label: '', value: 3, number: 0, color: '#fc8358' },
// { label: '', value: 4, number: 0, color: '#f8ca00' },
// { label: '', value: 5, number: 0, color: '#4fbadb' },
// ]
// })
//
// const select2 = reactive({
// value: [],
// options: [
// { label: '', value: 'ok', number: 0, color: '#4DCA59' },
// { label: '', value: 'not', number: 0, color: '#f5b442' },
// ]
// })
</script>
<style lang="scss" scoped>
.mr10{
margin-right: 10px;
}
.button{
border: 1px solid #4196ff;
//border-color: #4196ff;
}
.n-space{
flex-wrap: nowrap!important;
gap: 4px 2px!important;
}
.titleBox{
display: flex;
align-items: center;
.more{
font-size: 14px;
color: #409eff;
cursor: pointer;
}
}
</style>

View File

@ -0,0 +1,146 @@
<template>
<n-modal
:show="show"
preset="dialog"
class="modal"
title=""
:show-icon="false"
@close="close"
@esc="close"
style="width: 500px"
>
<div class="header">
<div>告警详情</div>
</div>
<div class="box">
<div class="label">告警时间</div>
<div class="value">{{data.generate_time && moment(data.generate_time).format('yyyy-MM-DD HH:mm:ss')}}</div>
<div class="label">告警级别</div>
<div class="value">
<n-tag size="small" :color="{textColor: data.color1, borderColor: data.color1}">
{{select1Options[data.level - 1].label}}
</n-tag>
</div>
<div class="label">告警位置</div>
<div class="value cv">{{data.position}}</div>
<div class="label">设备名称</div>
<div class="value">{{data.device_name}}</div>
<div class="label">告警测点</div>
<div class="value">{{data.node_name}}</div>
<div class="label">告警内容</div>
<div class="value fv">{{data.content}}</div>
<div class="label">是否确认</div>
<div class="value">{{data.confirm_status}}</div>
<div class="label">确认人</div>
<div class="value">{{data.confirm_people}}</div>
<div class="label">确认时间</div>
<div class="value iv">{{data.confirm_time && moment(data.confirm_time).format('yyyy-MM-DD HH:mm:ss')}}</div>
<div class="label">重新确认</div>
<div class="value">{{data.reconfirmation_time_str}}</div>
<div class="label">告警序列号</div>
<div class="value">{{data.serial_no}}</div>
<div class="label">备注</div>
<div class="value lv">{{data.remark}}</div>
</div>
</n-modal>
</template>
<script lang="ts" setup>
import { ref, defineEmits, computed } from 'vue'
import { icon } from '@/plugins/icon'
import { cloneDeep } from 'lodash'
import moment from 'moment'
const { CloseIcon } = icon.ionicons5
const props = defineProps(['show', 'data', 'select1Options'])
const emit = defineEmits(['close', 'update:show'])
const close = () => {
emit('close')
updateShow(false)
}
const updateShow = (flag:boolean) => {
emit('update:show', flag)
}
// const computerData = computed(() => {
// let obj = cloneDeep(props.data)
// return obj
// })
</script>
<style>
.modal{
padding: 0;
background: #121922;
box-sizing: border-box;
}
.modal .n-dialog__content{
margin-top: 0;
}
.modal .n-dialog__close{
margin-top: 7px;
margin-right: 10px;
}
</style>
<style lang="scss" scoped>
.header{
display: flex;
align-items: center;
height: 36px;
line-height: 36px;
padding: 0 10px;;
box-sizing: border-box;
border-left: 1px solid #2f3a49;
border-top: 1px solid #2f3a49;
border-right: 1px solid #2f3a49;
}
.cv{
grid-area: cv;
}
.fv{
grid-area: fv;
}
.iv{
grid-area: iv;
}
.lv{
grid-area: lv;
}
.box{
height: 240px;
display: grid;
grid-template-rows: repeat(8, 1fr);
grid-template-columns: repeat(2, 2fr 3fr);
grid-template-areas: 'a av b bv' 'c cv cv cv' 'd dv e ev' 'f fv fv fv' 'g gv h hv' 'i iv iv iv' 'j jv k kv' 'l lv lv lv';
border-left: 1px solid #2f3a49;
border-top: 1px solid #2f3a49;
box-sizing: border-box;
.label{
padding-left: 10px;
height: 36px;
width: 100%;
background: #242e3b;
line-height: 36px;
font-size: 12px;
border-right: 1px solid #2f3a49;
border-bottom: 1px solid #2f3a49;
box-sizing: border-box;
}
.value{
display: flex;
align-items: center;
padding-left: 10px;
height: 36px;
width: 100%;
background: #121922;
line-height: 14px;
font-size: 12px;
border-right: 1px solid #2f3a49;
border-bottom: 1px solid #2f3a49;
box-sizing: border-box;
}
}
</style>

View File

@ -0,0 +1,143 @@
<template>
<n-modal
:show="show"
preset="dialog"
class="modal"
title=""
:show-icon="false"
@close="close"
@esc="close"
style="width: 500px"
>
<div class="header">
<div>批量确认</div>
</div>
<div class="content">
<n-form
ref="formRef"
:model="data"
:rules="rules"
label-placement="left"
label-width="110px"
label-align="left"
require-mark-placement="right-hanging"
size="small"
:style="{
maxWidth: '640px'
}"
>
<n-form-item label="确认人" path="confirm_people">
<n-input v-model:value="data.confirm_people" readonly placeholder="请输入确认人" />
</n-form-item>
<n-form-item label="是否误报" path="is_misreport">
<n-radio-group v-model:value="data.is_misreport">
<n-radio :value="true"></n-radio>
<n-radio :value="false"></n-radio>
</n-radio-group>
</n-form-item>
<n-form-item label="备注" path="remark">
<n-input
v-model:value="data.remark"
type="textarea"
maxlength="120"
:autosize="{
minRows: 3,
maxRows: 3
}"
placeholder="请输入备注"
/>
</n-form-item>
<n-form-item label="重新确认" path="reconfirmation_time_str">
<n-date-picker v-model:formatted-value="data.reconfirmation_time_str" value-format="yyyy-MM-dd HH:mm:ss" style="width: 100%" type="datetime" clearable />
</n-form-item>
</n-form>
</div>
<div class="footer">
<div style="flex: 1;"></div>
<n-button @click="submitCallback" type="info" size="small" style="margin-right: 5px;color: #fff;">确认</n-button>
<n-button size="small" @click="close">取消</n-button>
</div>
</n-modal>
</template>
<script lang="ts" setup>
import { defineEmits, ref, reactive, watch } from 'vue'
const props = defineProps(['show', 'data'])
const emit = defineEmits(['confirm', 'update:show'])
const submitCallback = () => {
formRef.value.validate((errors:string) => {
if (!errors) {
emit('confirm')
updateShow(false)
}
})
}
const close = () => {
updateShow(false)
}
const formRef:any = ref(null)
const updateShow = (flag:boolean) => {
emit('update:show', flag)
}
console.log(props.data)
const rules = {
confirm_people: {
required: true,
trigger: ['blur', 'input'],
message: '请输入确认人'
},
is_misreport: {
type: 'boolean',
required: true,
trigger: 'change',
message: '请选择'
}
}
</script>
<style>
.modal{
padding: 0;
background: #121922;
box-sizing: border-box;
}
.modal .n-dialog__content{
margin-top: 0;
}
.modal .n-dialog__close{
margin-top: 7px;
margin-right: 10px;
}
</style>
<style lang="scss" scoped>
.header{
display: flex;
align-items: center;
height: 36px;
line-height: 36px;
padding: 0 10px;;
box-sizing: border-box;
border-left: 1px solid #2f3a49;
border-top: 1px solid #2f3a49;
border-right: 1px solid #2f3a49;
}
.content{
padding: 10px;
box-sizing: border-box;
border: 1px solid #2f3a49;
}
.footer{
display: flex;
align-items: center;
padding: 5px 10px;
box-sizing: border-box;
border-left: 1px solid #2f3a49;
border-bottom: 1px solid #2f3a49;
border-right: 1px solid #2f3a49;
}
</style>

View File

@ -0,0 +1,33 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { RealTimeEventConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
// import logo from '@/assets/logo.png'
export const option = {
// 图片路径
dataset: '',
// 适应方式
fit: 'contain',
// 圆角
borderRadius: 0
}
export default class Config extends PublicConfigClass implements CreateComponentType
{
constructor() {
super();
this.attr.w = 950
this.attr.h = 300
this.request.requestInterval = 15
}
public key = RealTimeEventConfig.key
public chartConfig = cloneDeep(RealTimeEventConfig)
public option = cloneDeep(option)
public customData = cloneDeep({
title: '实时事件',
showInterval: true,
showFilter: false,
space_complete_id: '',
})
}

View File

@ -0,0 +1,67 @@
<template>
<!-- <collapse-item name="属性" :expanded="true">-->
<!-- <setting-item-box name="路径" :alone="true">-->
<!-- <setting-item>-->
<!-- <n-input v-model:value="optionData.dataset" size="small"></n-input>-->
<!-- </setting-item>-->
<!-- </setting-item-box>-->
<!-- <setting-item-box name="样式">-->
<!-- <setting-item name="类型">-->
<!-- <n-select-->
<!-- v-model:value="optionData.fit"-->
<!-- size="small"-->
<!-- :options="fitList"-->
<!-- ></n-select>-->
<!-- </setting-item>-->
<!-- <setting-item name="圆角">-->
<!-- <n-input-number-->
<!-- v-model:value="optionData.borderRadius"-->
<!-- size="small"-->
<!-- :min="0"-->
<!-- placeholder="圆角"-->
<!-- ></n-input-number>-->
<!-- </setting-item>-->
<!-- </setting-item-box>-->
<!-- </collapse-item>-->
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option } from './config'
import {
CollapseItem,
SettingItemBox,
SettingItem,
} from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true,
},
})
//
const fitList = [
{
value: 'fill',
label: 'fill'
},
{
value: 'contain',
label: 'contain'
},
{
value: 'cover',
label: 'cover'
},
{
value: 'scale-down',
label: 'scale-down'
},
{
value: 'none',
label: 'none'
},
]
</script>

View File

@ -0,0 +1,23 @@
<template>
<setting-item-box name="标题" :alone="true">
<n-input v-model:value="props.customData.title" size="small" placeholder="请输入"/>
</setting-item-box>
<setting-item-box name="空间ID" :alone="true">
<n-input v-model:value="props.customData.space_complete_id" size="small" placeholder="请输入空间ID"/>
</setting-item-box>
<setting-item-box name="显示筛选条件" :alone="true">
<n-radio-group v-model:value="props.customData.showFilter" size="small" style="margin-top: 2px">
<n-radio :value="true"></n-radio>
<n-radio :value="false"></n-radio>
</n-radio-group>
</setting-item-box>
</template>
<script lang="ts" setup>
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
const props = defineProps(['customData', 'request'])
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,16 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/CustomComponents/index.d'
export const RealTimeEventConfig: ConfigType = {
key: 'RealTimeEvent',
chartKey: 'VRealTimeEvent',
conKey: 'VCRealTimeEvent',
// VCD开头
conDataKey: 'VCDRealTimeEvent',
title: '实时事件',
category: ChatCategoryEnum.ALARMDIAGRAM,
categoryName: ChatCategoryEnumName.ALARMDIAGRAM,
package: PackagesCategoryEnum.CUSTOMCOMPONENTS,
chartFrame: ChartFrameEnum.COMMON,
image: 'RealTimeEvent.png'
}

View File

@ -0,0 +1,394 @@
<template>
<BorderBox
:title="chartConfig?.customData?.title"
:select1="select1"
@update:select1Value="v => select1.value = v"
:select2="select2"
@update:select2Value="v => select2.value = v"
@clickBatch="clickBatch"
v-model:checkAll="checkAll"
@jumpMore="jumpMore"
:showFilter="chartConfig?.customData?.showFilter"
:style="getStyle(borderRadius)"
style="overflow: visible"
>
<div v-if="tableData.length" class="itemBox">
<div class="item" v-for="(item, i) in tableData" :key="i" @click="clickItem(i)">
<n-checkbox :disabled="item.confirm_status === 'ok'" v-model:checked="item.checked" class="mr10" size="small" @click.stop/>
<n-tag class="mr5" size="small" strong :color="{textColor: '#000', color: item.confirm_status === 'ok' ? '#4DCA59' : '#f5b442'}">
{{ item.confirm_status === 'ok'?'已确认':'未确认' }}
</n-tag>
<n-tag class="mr5" size="small" :color="{textColor: item.color1, borderColor: item.color1}">
{{select1.options[item.level - 1].label}}
</n-tag>
<div class="textEllipsis" style="color: rgba(255, 255, 255, 0.82);">{{ item.content }}</div>
<div style="flex: 1"></div>
<div class="mr10 textEllipsis" style="color: #B5BAC3;">{{ moment(item.generate_time).format('yyyy-MM-DD HH:mm:ss') }}</div>
<LocationIcon @click.stop="jumpTo(item)" class="mr10" style="width: 20px;height: 20px;color: #4196ff;"/>
<CheckCircleOutlinedIcon @click.stop="clickSingle(item.id)" v-if="item.confirm_status === 'not'" style="width: 20px;height: 20px;color: #4196ff;"/>
<div v-else style="width: 20px"></div>
</div>
</div>
<div class="emptyBox" v-else>
<img src="@/assets/images/exception/nodata.svg" style="width: 100%;height: 50%" alt="">
<div style="color: #fff;text-align: center">查询结果为空</div>
</div>
<VModal v-model:show="modalObj.show" :data="modalObj.data" :select1Options="select1.options"/>
<VModalV1 v-model:show="modalV1Obj.show" :data="modalV1Obj.data" @confirm="confirm"/>
</BorderBox>
</template>
<script setup lang="ts">
import { PropType, shallowReactive, watch, toRefs, reactive, onMounted, onUnmounted, nextTick, ref } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { publicInterface } from '@/api/path/business.api'
import BorderBox from './BorderBoxV2.vue'
import {isPreview, postMessageToParent} from '@/utils'
import moment from "moment"
import {selectTimeOptions} from "@/views/chart/ContentConfigurations/components/ChartData/index.d";
import {RequestHttpIntervalEnum} from "@/enums/httpEnum";
import {icon} from '@/plugins/icon'
import VModal from './VModal.vue'
import VModalV1 from './VModalV1.vue'
import { useOriginStore } from '@/store/modules/originStore/originStore'
const { LocationIcon } = icon.carbon
const { CheckCircleOutlinedIcon } = icon.material
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { w, h } = toRefs(props.chartConfig.attr)
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
const getStyle = (radius: number) => {
return {
borderRadius: `${radius}px`,
overflow: 'hidden'
}
}
const select1 = reactive({
value: [1, 2],
options: [
{ label: '严重', value: 1, number: 0, color: '#ff0000' },
{ label: '主要', value: 2, number: 0, color: '#f43b42' },
{ label: '次要', value: 3, number: 0, color: '#fc8358' },
{ label: '警告', value: 4, number: 0, color: '#f8ca00' },
{ label: '事件', value: 5, number: 0, color: '#4fbadb' },
]
})
const select2 = reactive({
value: ['not'],
options: [
{ label: '已确认', value: 'ok', number: 0, color: '#4DCA59' },
{ label: '未确认', value: 'not', number: 0, color: '#f5b442' },
]
})
watch(() => select1.value.join('&&') + select2.value.join('&&'), (v) => {
getData()
})
type tableDataItemType = {
id: number,
content: string,
generate_time: string,
checked: boolean,
confirm_status: 'ok' | 'not',
level: number,
color1: string,
color2: string,
position: string,
device_name: string,
node_name: string,
confirm_people: string,
confirm_time: string,
reconfirmation_time_str: string,
serial_no: string,
remark: string,
[k:string]: any,
}
let tableData:tableDataItemType[] = reactive([])
watch(() => tableData.map(_ => _.checked), (v:boolean[]) => {
if(!v.length) checkAll.value = false
else if(v.every(_ => _)) checkAll.value = true
else if(v.every(_ => !_)) checkAll.value = false
})
let checkAll = ref(false)
watch(() => checkAll.value, (v) => {
tableData.forEach(_ => _.checked = v)
})
const getNumber = () => {
const q = {
space_complete_id: props.chartConfig.customData?.space_complete_id,
}
publicInterface('/dcim/dems/devie_active_alarm', 'count_by_level', q).then(res => {
if (res && JSON.stringify(res.data) !== '{}') {
select1.options.forEach((item, i) => {
item.number = res.data[`level${i+1}`]
})
}
})
const param = {
condition: {
id: null,
levels: select1.value,
space_complete_id: props.chartConfig.customData?.space_complete_id,
append_space_to_content: 'complete',
recovery_statuss: ['not'],
}
}
publicInterface('/dcim/dems/devie_active_alarm', 'get_app_alarm_num_by_condition', param).then(res => {
if (res && res.data) {
select2.options[0].number = res.data['confrim_num']
select2.options[1].number = res.data['not_confirm_num']
}
})
}
const getData = () => {
getNumber()
const queryModel = {
condition: {
id: null,
levels: select1.value,
confirm_statuss: select2.value,
space_complete_id: props.chartConfig.customData?.space_complete_id,
append_space_to_content: 'complete',
recovery_statuss: ['not'],
},
page: {
page_size: 10,
page_number: 1
}
}
publicInterface('/dcim/dems/devie_active_alarm', 'get_page', queryModel).then(res => {
if(res && !res.data) {
tableData.splice(0)
return
}
if(res && res.data) {
res.data.item = res.data.item.filter((_: tableDataItemType) => _.level)
const lastTableData = [...tableData]
let arr:tableDataItemType[] = res.data['item'].map((e:any) => ({
...e,
id: e.id,
content: e.content,
generate_time: e.generate_time,
level: e.level,
checked: false,
confirm_status: e.confirm_status,
color1: select1.options.find(_ => _.value === e.level)!.color,
color2: select2.options.find(_ => _.value === e.confirm_status)!.color,
position: e.position,
device_name: e.device_name,
node_name: e?.point?.node_name,
confirm_people: e.confirm_people,
confirm_time: e.confirm_time,
reconfirmation_time_str: e.reconfirmation_time_str,
serial_no: e.serial_no,
remark: e.remark,
}))
if (checkAll.value) {
arr = arr.map((e:any) => ({ ...e, checked: e.confirm_status !== 'ok' }))
} else if (lastTableData.length) {
arr.map(e => {
const lastIndex = lastTableData.findIndex(item => item.id === e.id)
if (lastIndex !== -1) {
e.checked = lastTableData[lastIndex].checked
}
})
}
tableData.splice(0, tableData.length, ...arr)
}
})
}
const modalObj = reactive({
show: false,
data: {}
})
const clickItem = (i:number) => {
const obj = tableData[i]
modalObj.show = true
Object.assign(modalObj, {
show: true,
data: obj
})
}
const originStore = useOriginStore()
const user = originStore.getOriginStore.user.user
const modalV1Obj = reactive({
show: false,
data: {
// confirm_people_id: user.id,
confirm_people: user.name,
is_misreport: false,
remark: '',
reconfirmation_time_str: null,
},
// batch single
type: 'batch',
singleIds: [],
})
const clickBatch = () => {
if(!tableData.filter(_ => _.checked).length) {
window['$message'].warning('请先选择数据')
return
}
Object.assign(modalV1Obj, {
show: true,
data: {
// confirm_people_id: user.id,
confirm_people: user.name,
is_misreport: false,
remark: '',
reconfirmation_time_str: null,
},
type: 'batch',
singleIds: []
})
}
const clickSingle = (id: number) => {
Object.assign(modalV1Obj, {
show: true,
data: {
// confirm_people_id: user.id,
confirm_people: user.name,
is_misreport: false,
remark: '',
reconfirmation_time_str: null,
},
type: 'single',
singleIds: [id]
})
}
const confirm = () => {
const obj = {
id: null,
ids: modalV1Obj.type === 'batch' ? tableData.filter(_ => _.checked).map(_ => _.id) : modalV1Obj.singleIds,
confirm_status: "ok",
...modalV1Obj.data
}
publicInterface('/dcim/dems/devie_active_alarm', 'confirms', obj).then(res => {
window['$message'].success('操作成功')
checkAll.value = false
getData()
})
}
const jumpTo = (row:any) => {
if (row.space && row.space.space_type !== 'device') {
publicInterface('/dcim/space_page', 'get', { space_id: row.space_id, order: 'sort,id asc' }).then(res => {
if (res && res.data && res.data.length) {
postMessageToParent({
type: 'changeRouterV1',
url: `/dynamicRing/schematicDiagram/${res.data[0].id}`
})
}
else {
window['$message'].warning('所选节点没有配置页面')
}
})
}
else {
window['$message'].warning('所选节点没有配置页面')
}
}
const jumpMore = () => {
postMessageToParent({
type: 'changeRouterV1',
url: `/alarmManage/monitorAlarm`
})
}
let timer:unknown
watch(() => [props.chartConfig.request.requestInterval, props.chartConfig.request.requestIntervalUnit, props.chartConfig.customData?.space_complete_id].join('&&'), v => {
if(!isPreview()) return
if(props.chartConfig.request.requestInterval) {
if(timer) clearInterval(timer as number)
const obj = selectTimeOptions.find(_ => _.value === props.chartConfig.request.requestIntervalUnit) || {unit: 0}
const unit = obj.unit
const number = unit * props.chartConfig.request.requestInterval
timer = setInterval(() => {
getData()
}, number)
}
})
onMounted(() => {
nextTick(() => {
getData()
})
if(!isPreview()) return
const obj = selectTimeOptions.find(_ => _.value === props.chartConfig.request.requestIntervalUnit) || {unit: 0}
const unit = obj.unit
const number = unit * props.chartConfig.request.requestInterval!
timer = setInterval(() => {
nextTick(() => {
getData()
})
}, number)
})
onUnmounted(() => {
clearInterval(timer as number)
})
// const option = shallowReactive({
// dataset: ''
// })
// //
// useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
// option.dataset = newData
// })
</script>
<style lang="scss" scoped>
.mr5{
margin-right: 5px;
}
.mr10{
margin-right: 10px;
}
.textEllipsis{
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.emptyBox{
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
}
.itemBox{
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow-y: auto;
.item{
flex: none;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 10px;
margin: 3px 0;
background: rgba(65,150,255,.05);
cursor: pointer;
}
}
</style>

View File

@ -0,0 +1,58 @@
<template>
<div class="box">
<div class="title">
<slot name="title">{{ title }}</slot>
</div>
<div class="content">
<slot></slot>
</div>
</div>
</template>
<script lang="ts" setup>
import { toRefs } from 'vue'
const props = defineProps(['title'])
const { title } = toRefs(props)
</script>
<style lang="scss" scoped>
.box{
height: 100%;
width: 100%;
background: rgba(65,150,255,.04);
.title{
position: relative;
padding: 0 20px;
height: 38px;
line-height: 38px;
font-size: 16px;
color: #fff;
border-top: 1px solid rgba(65,150,255,.5);
border-bottom: 1px solid rgba(65,150,255,.2);
background: linear-gradient(90deg,rgba(65,150,255,.1) 0,rgba(65,150,255,0));
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
&:after{
content: '';
height: 1px;
width: 20px;
background: linear-gradient(90deg,rgba(65,150,255,0) 0,#4196ff);
position: absolute;
bottom: 0;
left: 0;
}
}
.content{
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
height: calc(100% - 40px);
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 7px;
}
}
</style>

View File

@ -0,0 +1,9 @@
import { DeviceAlarmOverviewConfig } from './DeviceAlarmOverview'
import { RealTimeAlarmStatisticsConfig } from './RealTimeAlarmStatistics'
import { RealTimeEventConfig } from './RealTimeEvent'
export default [
DeviceAlarmOverviewConfig,
RealTimeAlarmStatisticsConfig,
RealTimeEventConfig,
]

View File

@ -27,5 +27,6 @@ export default class Config extends PublicConfigClass implements CreateComponent
public customData = cloneDeep({
title: '当前设备告警概况',
showInterval: true,
space_complete_id: '',
})
}

View File

@ -1,67 +1,7 @@
<template>
<!-- <collapse-item name="属性" :expanded="true">-->
<!-- <setting-item-box name="路径" :alone="true">-->
<!-- <setting-item>-->
<!-- <n-input v-model:value="optionData.dataset" size="small"></n-input>-->
<!-- </setting-item>-->
<!-- </setting-item-box>-->
<!-- <setting-item-box name="样式">-->
<!-- <setting-item name="类型">-->
<!-- <n-select-->
<!-- v-model:value="optionData.fit"-->
<!-- size="small"-->
<!-- :options="fitList"-->
<!-- ></n-select>-->
<!-- </setting-item>-->
<!-- <setting-item name="圆角">-->
<!-- <n-input-number-->
<!-- v-model:value="optionData.borderRadius"-->
<!-- size="small"-->
<!-- :min="0"-->
<!-- placeholder="圆角"-->
<!-- ></n-input-number>-->
<!-- </setting-item>-->
<!-- </setting-item-box>-->
<!-- </collapse-item>-->
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option } from './config'
import {
CollapseItem,
SettingItemBox,
SettingItem,
} from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true,
},
})
//
const fitList = [
{
value: 'fill',
label: 'fill'
},
{
value: 'contain',
label: 'contain'
},
{
value: 'cover',
label: 'cover'
},
{
value: 'scale-down',
label: 'scale-down'
},
{
value: 'none',
label: 'none'
},
]
</script>

View File

@ -1,9 +1,10 @@
<template>
<n-space vertical>
<setting-item-box name="标题" :alone="true">
<n-input v-model:value="props.customData.title" size="small" placeholder="请输入"/>
</setting-item-box>
</n-space>
<setting-item-box name="标题" :alone="true">
<n-input v-model:value="props.customData.title" size="small" placeholder="请输入标题"/>
</setting-item-box>
<setting-item-box name="空间ID" :alone="true">
<n-input v-model:value="props.customData.space_complete_id" size="small" placeholder="请输入空间ID"/>
</setting-item-box>
</template>
<script lang="ts" setup>

View File

@ -75,7 +75,10 @@ const obj = reactive({
data4: null as objType
})
const getData = () => {
publicInterface('/dcim/dems/statistic', 'count_device_all', {}).then(res => {
let query = {
space_complete_id: props.chartConfig.customData?.space_complete_id
}
publicInterface('/dcim/dems/statistic', 'count_device_all', query).then(res => {
if (res && res.data) {
let data = res.data as {
active_device_count:number
@ -86,7 +89,7 @@ const getData = () => {
obj.data2 = data.active_device_alarm + data.active_device_offline
}
})
publicInterface('/dcim/dems/statistic', 'count_point_all', {}).then(res => {
publicInterface('/dcim/dems/statistic', 'count_point_all', query).then(res => {
if (res && res.data) {
let data = res.data as {
active_point_count:number
@ -99,7 +102,7 @@ const getData = () => {
}
let timer:unknown
watch(() => [props.chartConfig.request.requestInterval, props.chartConfig.request.requestIntervalUnit].join('&&'), v => {
watch(() => [props.chartConfig.request.requestInterval, props.chartConfig.request.requestIntervalUnit, props.chartConfig.customData?.space_complete_id].join('&&'), v => {
if(!isPreview()) return
if(props.chartConfig.request.requestInterval) {
if(timer) clearInterval(timer as number)

View File

@ -27,5 +27,6 @@ export default class Config extends PublicConfigClass implements CreateComponent
public customData = cloneDeep({
title: '实时告警统计',
showInterval: true,
space_complete_id: '',
})
}

View File

@ -1,9 +1,10 @@
<template>
<n-space vertical>
<setting-item-box name="标题" :alone="true">
<n-input v-model:value="props.customData.title" size="small" placeholder="请输入"/>
</setting-item-box>
</n-space>
<setting-item-box name="标题" :alone="true">
<n-input v-model:value="props.customData.title" size="small" placeholder="请输入标题"/>
</setting-item-box>
<setting-item-box name="空间ID" :alone="true">
<n-input v-model:value="props.customData.space_complete_id" size="small" placeholder="请输入空间ID"/>
</setting-item-box>
</template>
<script lang="ts" setup>

View File

@ -92,7 +92,8 @@ nameObj.eventColor = systemConstant['warn_levels'].find((item:any) => item.value
const getData = () => {
const confirm_statuss = systemConfig?.['active_alarm_confirm_status'] ? [...JSON.parse(systemConfig['active_alarm_confirm_status'])] : []
const param = {
confirm_statuss
confirm_statuss,
space_complete_id: props.chartConfig.customData?.space_complete_id
}
publicInterface('/dcim/dems/devie_active_alarm', 'count_by_level_new', param).then(res => {
@ -290,7 +291,7 @@ const initChart = () => {
}
let timer:unknown
watch(() => [props.chartConfig.request.requestInterval, props.chartConfig.request.requestIntervalUnit].join('&&'), v => {
watch(() => [props.chartConfig.request.requestInterval, props.chartConfig.request.requestIntervalUnit, props.chartConfig.customData?.space_complete_id].join('&&'), v => {
if(!isPreview()) return
if(props.chartConfig.request.requestInterval) {
if(timer) clearInterval(timer as number)

View File

@ -28,5 +28,6 @@ export default class Config extends PublicConfigClass implements CreateComponent
title: '实时事件',
showInterval: true,
showFilter: false,
space_complete_id: '',
})
}

View File

@ -1,15 +1,16 @@
<template>
<n-space vertical>
<setting-item-box name="标题" :alone="true">
<n-input v-model:value="props.customData.title" size="small" placeholder="请输入"/>
</setting-item-box>
<setting-item-box name="显示筛选条件" :alone="true">
<n-radio-group v-model:value="props.customData.showFilter" size="small" style="margin-top: 2px">
<n-radio :value="true"></n-radio>
<n-radio :value="false"></n-radio>
</n-radio-group>
</setting-item-box>
</n-space>
<setting-item-box name="标题" :alone="true">
<n-input v-model:value="props.customData.title" size="small" placeholder="请输入"/>
</setting-item-box>
<setting-item-box name="空间ID" :alone="true">
<n-input v-model:value="props.customData.space_complete_id" size="small" placeholder="请输入空间ID"/>
</setting-item-box>
<setting-item-box name="显示筛选条件" :alone="true">
<n-radio-group v-model:value="props.customData.showFilter" size="small" style="margin-top: 2px">
<n-radio :value="true"></n-radio>
<n-radio :value="false"></n-radio>
</n-radio-group>
</setting-item-box>
</template>
<script lang="ts" setup>

View File

@ -127,7 +127,10 @@ watch(() => checkAll.value, (v) => {
})
const getNumber = () => {
publicInterface('/dcim/dems/devie_active_alarm', 'count_by_level', {}).then(res => {
const q = {
space_complete_id: props.chartConfig.customData?.space_complete_id,
}
publicInterface('/dcim/dems/devie_active_alarm', 'count_by_level', q).then(res => {
if (res && JSON.stringify(res.data) !== '{}') {
select1.options.forEach((item, i) => {
item.number = res.data[`level${i+1}`]
@ -138,7 +141,7 @@ const getNumber = () => {
condition: {
id: null,
levels: select1.value,
space_complete_id: '',
space_complete_id: props.chartConfig.customData?.space_complete_id,
append_space_to_content: 'complete',
recovery_statuss: ['not'],
}
@ -158,7 +161,7 @@ const getData = () => {
id: null,
levels: select1.value,
confirm_statuss: select2.value,
space_complete_id: '',
space_complete_id: props.chartConfig.customData?.space_complete_id,
append_space_to_content: 'complete',
recovery_statuss: ['not'],
},
@ -311,7 +314,7 @@ const jumpMore = () => {
}
let timer:unknown
watch(() => [props.chartConfig.request.requestInterval, props.chartConfig.request.requestIntervalUnit].join('&&'), v => {
watch(() => [props.chartConfig.request.requestInterval, props.chartConfig.request.requestIntervalUnit, props.chartConfig.customData?.space_complete_id].join('&&'), v => {
if(!isPreview()) return
if(props.chartConfig.request.requestInterval) {
if(timer) clearInterval(timer as number)

View File

@ -11,11 +11,11 @@ import { MonitorRealTimeEventsConfig } from './MonitorRealTimeEvents'
export default [
// Theme1Config,
ComprehensivePUEConfig,
DeviceAlarmOverviewConfig,
// DeviceAlarmOverviewConfig,
RealTimeTrafficConfig,
RealTimeAlarmStatisticsConfig,
// RealTimeAlarmStatisticsConfig,
OverviewOfComputingNodesConfig,
RealTimeEventConfig,
// RealTimeEventConfig,
GDMapConfig,
MonitorRealTimeEventsConfig,
]

View File

@ -1,9 +1,11 @@
export enum ChatCategoryEnum {
CUSTOMCOMPONENTS = 'CustomComponents',
BACKGROUNDS = 'Backgrounds',
ALARMDIAGRAM = 'AlarmDiagram',
}
export enum ChatCategoryEnumName {
CUSTOMCOMPONENTS = '自定义',
BACKGROUNDS = '背景'
CUSTOMCOMPONENTS = '其他',
BACKGROUNDS = '背景图',
ALARMDIAGRAM = '告警图'
}

View File

@ -1,4 +1,5 @@
import Backgrounds from './Backgrounds'
import AlarmDiagram from './AlarmDiagram'
import CustomComponents from './CustomComponents'
export const CustomComponentsList = [...Backgrounds, ...CustomComponents]
export const CustomComponentsList = [...Backgrounds, ...AlarmDiagram, ...CustomComponents]

View File

@ -64,6 +64,13 @@ const commonData: commonDataType = {
policy: [],
strategy_ids: [],
dateType: DateTypeEnum.DAY
},
pointRealTime: {
enable: false,
point_uid: [],
limit: 10,
with_device_name: false,
space_complete_name_prefix: false,
}
}

View File

@ -257,7 +257,9 @@ export enum CurrentSourceEnum {
// 能耗历史
ENERGYUSEHISTORY = 'energyUseHistory',
// 记录值历史
RECORDVALUEHISTORY = 'recordValueHistory'
RECORDVALUEHISTORY = 'recordValueHistory',
// 测点实时值
POINTREALTIME = 'pointRealTime'
}
// 测点历史参数
@ -289,12 +291,21 @@ export interface RecordValueHistoryType {
dateType: DateTypeEnum
}
export interface PointRealTimeType {
enable: boolean
point_uid: string[]
limit: number
with_device_name: boolean
space_complete_name_prefix: boolean
}
// 通用组件数据
export interface commonDataType {
currentSource: CurrentSourceEnum,
pointHistory: PointHistoryType,
energyUseHistory: EnergyUseHistoryType,
recordValueHistory: RecordValueHistoryType
pointRealTime: PointRealTimeType
}
// Store 类型

View File

@ -12,7 +12,7 @@
<n-space v-for="(item, i) in computeIds" :key="item.id" align="center" :wrap="false">
<n-input-number
:value="item.value"
@update:value.trim="(v: number) => handleChange(v, i)"
@update:value="(v: number) => handleChange(v, i)"
min="1"
:show-button="false"
placeholder="请输入报表ID"

View File

@ -0,0 +1,104 @@
<template>
<setting-item-box name="启用数据" :alone="true">
<n-space justify="start">
<n-switch v-model:value="pointRealTime.enable" />
</n-space>
</setting-item-box>
<setting-item-box name="标签带空间名" :alone="true">
<n-space justify="start">
<n-switch v-model:value="pointRealTime.space_complete_name_prefix" />
</n-space>
</setting-item-box>
<setting-item-box name="标签带设备名" :alone="true">
<n-space justify="start">
<n-switch v-model:value="pointRealTime.with_device_name" />
</n-space>
</setting-item-box>
<setting-item-box name="测点ID" :alone="true">
<n-space vertical>
<n-space v-for="(item, i) in computeIds" :key="item.id" align="center" :wrap="false">
<n-input
:value="item.value"
@update:value="(v: number) => handleChange(v, i)"
placeholder="请输入测点ID"
size="small"
clearable
/>
<n-button @click="handleDelete(i)" circle size="tiny">
<template #icon>
<n-icon><CloseIcon /></n-icon>
</template>
</n-button>
<n-button v-if="i === computeIds.length - 1" @click="handleAdd" circle size="tiny">
<template #icon>
<n-icon><AddIcon /></n-icon>
</template>
</n-button>
<div v-else style="width: 22px"></div>
</n-space>
</n-space>
</setting-item-box>
<setting-item-box name="测点数量" :alone="true">
<n-input-number
v-model:value="pointRealTime.limit"
min="1"
placeholder="请输入测点数量"
size="small"
clearable
/>
</setting-item-box>
</template>
<script lang="ts" setup>
import { watch, reactive, computed } from 'vue'
import type { Ref } from 'vue'
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
import { useTargetData } from '../../hooks/useTargetData.hook'
import { icon } from '@/plugins/icon'
import { commonDataType, PointRealTimeType } from '@/store/modules/chartEditStore/chartEditStore.d'
const { CloseIcon, AddIcon } = icon.ionicons5
const { targetData } = useTargetData() as { targetData: Ref<{ commonData: commonDataType, id: string }> }
const pointRealTime: Ref<PointRealTimeType> = computed(() => targetData.value.commonData.pointRealTime)
type computeIdsItemType = {
id: string,
value: string
}
const computeIds: computeIdsItemType[] = reactive([])
watch(() => [targetData.value.id, pointRealTime.value.point_uid], () => {
if(!pointRealTime.value.point_uid.length) pointRealTime.value.point_uid.push('')
let arr = pointRealTime.value.point_uid.map((item, i) => {
return {
id: `${targetData.value.id}_${i}`,
value: item
}
})
computeIds.splice(0, computeIds.length, ...arr)
}, {
deep: true,
immediate: true
})
const handleChange = (v: string, i: number) => {
targetData.value.commonData.pointRealTime.point_uid[i] = v
}
const handleAdd = () => {
targetData.value.commonData.pointRealTime.point_uid.push('')
}
const handleDelete = (i: number) => {
targetData.value.commonData.pointRealTime.point_uid.splice(i, 1)
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -15,7 +15,7 @@
<n-space v-for="(item, i) in computeIds" :key="item.id" align="center" :wrap="false">
<n-input-number
:value="item.value"
@update:value.trim="(v: number) => handleChange(v, i)"
@update:value="(v: number) => handleChange(v, i)"
min="1"
:show-button="false"
placeholder="请输入报表ID"

View File

@ -128,4 +128,8 @@ export const sourceOptions: sourceOptionsItemType[] = [
label: '记录值历史',
value: CurrentSourceEnum.RECORDVALUEHISTORY
},
{
label: '测点实时值',
value: CurrentSourceEnum.POINTREALTIME
},
]

View File

@ -5,7 +5,8 @@
</setting-item-box>
<PointHistory v-if="targetData.commonData.currentSource === CurrentSourceEnum.POINTHISTORY"/>
<EnergyUseHistory v-else-if="targetData.commonData.currentSource === CurrentSourceEnum.ENERGYUSEHISTORY"/>
<RecordValueHistoryType v-else-if="targetData.commonData.currentSource === CurrentSourceEnum.RECORDVALUEHISTORY"/>
<RecordValueHistory v-else-if="targetData.commonData.currentSource === CurrentSourceEnum.RECORDVALUEHISTORY"/>
<PointRealTime v-else-if="targetData.commonData.currentSource === CurrentSourceEnum.POINTREALTIME"/>
<setting-item-box name="更新间隔" :alone="true">
<n-input-group>
<n-input-number
@ -48,7 +49,8 @@
<script setup lang="ts">
import PointHistory from './components/PointHistory.vue'
import EnergyUseHistory from './components/EnergyUseHistory.vue'
import RecordValueHistoryType from './components/RecordValueHistory.vue'
import RecordValueHistory from './components/RecordValueHistory.vue'
import PointRealTime from './components/PointRealTime.vue'
import type { Ref } from 'vue'
import { loadAsyncComponent } from '@/utils'
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'