mirror of
https://gitee.com/dromara/go-view.git
synced 2025-06-30 00:29:16 +08:00
feat: 新增组件
This commit is contained in:
parent
7dcbe34de8
commit
e85eda9b4f
BIN
src/assets/images/chart/customponents/GDMap.png
Normal file
BIN
src/assets/images/chart/customponents/GDMap.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 840 KiB |
BIN
src/assets/images/chart/customponents/MonitorRealTimeEvents.png
Normal file
BIN
src/assets/images/chart/customponents/MonitorRealTimeEvents.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div :style="getStyle(borderRadius)" style="overflow: visible;">
|
||||
<BorderBox :title="props.chartConfig.customData.title">
|
||||
<BorderBox :title="chartConfig?.customData?.title">
|
||||
<div class="inner">
|
||||
<div class="left">
|
||||
<VCircle :value="value" style="height: 100%"/>
|
||||
<VCircle :value="value" style="height: 100%;width: 100%"/>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="item" v-for="(item, i) in rightArr" :key="i">
|
||||
<Svg v-if="i === 0" class="leftBox" style="position: absolute;width: 60px;height: 37%;"/>
|
||||
<Svg v-if="i === 0" class="leftBox" style="position: absolute;width: 65px;height: 37%;"/>
|
||||
<v-chart class="leftBox" :option="item.option" :update-options="{ notMerge: true, replaceMerge: ['series'] }"/>
|
||||
<div class="rightBox">
|
||||
<div>{{item.label}}</div>
|
||||
@ -44,8 +44,10 @@ const props = defineProps({
|
||||
required: true
|
||||
}
|
||||
})
|
||||
Object.assign(props.chartConfig.attr, { w: 380, h: 250 })
|
||||
if(!props.chartConfig.request.requestInterval) Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
if(!isPreview()) {
|
||||
Object.assign(props.chartConfig.attr, { w: 450, h: 300 })
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
}
|
||||
|
||||
const { w, h } = toRefs(props.chartConfig.attr)
|
||||
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
|
||||
@ -498,6 +500,7 @@ onUnmounted(() => {
|
||||
display: flex;
|
||||
.left{
|
||||
flex: 6;
|
||||
min-width: 60%;
|
||||
.circle{
|
||||
|
||||
}
|
||||
@ -510,20 +513,30 @@ onUnmounted(() => {
|
||||
.right{
|
||||
flex: 4;
|
||||
.item{
|
||||
box-sizing: border-box;
|
||||
height: 33.3%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding: 5px 0;
|
||||
.leftBox{
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
height: 70px;
|
||||
width: 70px;
|
||||
}
|
||||
.rightBox{
|
||||
width: 66.6%;
|
||||
height: 100%;
|
||||
color: #fff;
|
||||
width: calc(100% - 60px);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-evenly;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div :style="getStyle(borderRadius)">
|
||||
<BorderBox :title="props.chartConfig.customData.title">
|
||||
<BorderBox :title="chartConfig?.customData?.title">
|
||||
<div class="item">
|
||||
<BareMetalServerIcon class="left"/>
|
||||
<div class="right">
|
||||
@ -52,8 +52,10 @@ const props = defineProps({
|
||||
required: true
|
||||
}
|
||||
})
|
||||
Object.assign(props.chartConfig.attr, { w: 380, h: 250 })
|
||||
if(!props.chartConfig.request.requestInterval) Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
if(!isPreview()) {
|
||||
Object.assign(props.chartConfig.attr, { w: 450, h: 300 })
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
}
|
||||
|
||||
const { w, h } = toRefs(props.chartConfig.attr)
|
||||
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
|
||||
@ -154,22 +156,33 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
|
||||
justify-content: center;
|
||||
.left{
|
||||
color: #0ff;
|
||||
height: 60px;
|
||||
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;
|
||||
margin-top: 8px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
.leftRed{
|
||||
|
@ -0,0 +1,25 @@
|
||||
import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { GDMapConfig } 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
|
||||
{
|
||||
public key = GDMapConfig.key
|
||||
public chartConfig = cloneDeep(GDMapConfig)
|
||||
public option = cloneDeep(option)
|
||||
public customData = cloneDeep({
|
||||
showInterval: true,
|
||||
mapId: null
|
||||
})
|
||||
}
|
@ -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>
|
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<n-space vertical>
|
||||
<setting-item-box name="地图ID" :alone="true">
|
||||
<n-input-number v-model:value="props.customData.mapId" size="small" placeholder="请输入地图ID"/>
|
||||
</setting-item-box>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
const props = defineProps(['customData', 'request'])
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
@ -0,0 +1,16 @@
|
||||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/CustomComponents/index.d'
|
||||
|
||||
export const GDMapConfig: ConfigType = {
|
||||
key: 'GDMap',
|
||||
chartKey: 'VGDMap',
|
||||
conKey: 'VCGDMap',
|
||||
// VCD开头
|
||||
conDataKey: 'VCDGDMap',
|
||||
title: '站点概况',
|
||||
category: ChatCategoryEnum.CUSTOMCOMPONENTS,
|
||||
categoryName: ChatCategoryEnumName.CUSTOMCOMPONENTS,
|
||||
package: PackagesCategoryEnum.CUSTOMCOMPONENTS,
|
||||
chartFrame: ChartFrameEnum.COMMON,
|
||||
image: 'GDMap.png'
|
||||
}
|
@ -0,0 +1,278 @@
|
||||
<template>
|
||||
<div :style="getStyle(borderRadius)" class="box" style="overflow: visible;position: relative">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 120 141.16"
|
||||
style="width: 180px; height: 142px; position: absolute; z-index: 99;"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="statistics_76" y1="862.16" x2="120" y2="862.16" gradientTransform="matrix(1, 0, 0, -1, 0, 890.33)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="aqua" stop-opacity="0.5" />
|
||||
<stop offset="1" stop-color="aqua" stop-opacity="0.1" />
|
||||
</linearGradient>
|
||||
<linearGradient id="statistics_77" y1="818.16" x2="120" y2="818.16" gradientTransform="matrix(1, 0, 0, -1, 0, 890.33)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#4dca59" stop-opacity="0.5" />
|
||||
<stop offset="1" stop-color="#4dca59" stop-opacity="0.1" />
|
||||
</linearGradient>
|
||||
<linearGradient id="statistics_78" y1="774.16" x2="120" y2="774.16" gradientTransform="matrix(1, 0, 0, -1, 0, 890.33)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#f43b42" stop-opacity="0.5" />
|
||||
<stop offset="1" stop-color="#f43b42" stop-opacity="0.1" />
|
||||
</linearGradient>
|
||||
<linearGradient id="statistics_79" y1="730.16" x2="120" y2="730.16" gradientTransform="matrix(1, 0, 0, -1, 0, 890.33)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#999" stop-opacity="0.5" />
|
||||
<stop offset="1" stop-color="#999" stop-opacity="0.1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g>
|
||||
<rect y="27.16" width="120" height="2" style="fill:url(#statistics_76)" />
|
||||
<rect y="27.16" width="14" height="2" style="fill:aqua" />
|
||||
<g id="正常点-22">
|
||||
<path d="M7,3.16a6,6,0,1,1-6,6,6,6,0,0,1,6-6m0-1a7,7,0,1,0,7,7A7,7,0,0,0,7,2.16Z" style="fill:aqua" />
|
||||
<circle cx="7" cy="9.16" r="3" style="fill:aqua" />
|
||||
</g>
|
||||
<!-- <text transform="translate(24 14.16)" style="isolation:isolate;font-size:12px;fill:#ccc;font-family:AdobeSongStd-Light-GBpc-EUC-H, Adobe Song Std">全部站点</text> -->
|
||||
<text transform="translate(24 14.16)" style="isolation:isolate;font-size:12px;fill:#ccc">全部站点</text>
|
||||
<text transform="translate(95.48 17.16)" style="isolation:isolate;font-size:20px;fill:aqua;font-family:ArialMT, Arial">{{ allNumber }}</text>
|
||||
<rect y="33.16" width="120" height="40" style="fill:#4dca59;fill-opacity:0" />
|
||||
<rect y="71.16" width="120" height="2" style="fill:url(#statistics_77)" />
|
||||
<rect y="71.16" width="14" height="2" style="fill:#4dca59" />
|
||||
<g id="正常点-23">
|
||||
<path d="M7,47.16a6,6,0,1,1-6,6,6,6,0,0,1,6-6m0-1a7,7,0,1,0,7,7A7,7,0,0,0,7,46.16Z" style="fill:#4dca59" />
|
||||
<circle cx="7" cy="53.16" r="3" style="fill:#4dca59" />
|
||||
</g>
|
||||
<text transform="translate(24 58.16)" style="isolation:isolate;font-size:12px;fill:#ccc">正常站点</text>
|
||||
<text transform="translate(95.48 61.16)" style="isolation:isolate;font-size:20px;fill:#4dca59;font-family:ArialMT, Arial">{{ normalNumber }}</text>
|
||||
<rect y="77.16" width="120" height="40" style="fill:#f43b42;fill-opacity:0" />
|
||||
<rect y="115.16" width="120" height="2" style="fill:url(#statistics_78)" />
|
||||
<rect y="115.16" width="14" height="2" style="fill:#f43b42" />
|
||||
<g id="正常点-24">
|
||||
<path d="M7,91.16a6,6,0,1,1-6,6,6,6,0,0,1,6-6m0-1a7,7,0,1,0,7,7A7,7,0,0,0,7,90.16Z" style="fill:#f43b42" />
|
||||
<circle cx="7" cy="97.16" r="3" style="fill:#f43b42" />
|
||||
</g>
|
||||
<text transform="translate(24 102.16)" style="isolation:isolate;font-size:12px;fill:#ccc">告警站点</text>
|
||||
<text transform="translate(95.48 105.16)" style="isolation:isolate;font-size:20px;fill:#f43b42;font-family:ArialMT, Arial">{{ abnormalNumber }}</text>
|
||||
</g>
|
||||
</svg>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 423.5 40"
|
||||
style="height: 29px; position: absolute; left: 50%;transform: translateX(-50%); z-index: 99;"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="linear-gradient-staqyxts" x1="212.5" y1="40" x2="212.5" y2="30" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#4196ff" stop-opacity="0.5" />
|
||||
<stop offset="1" stop-color="#4196ff" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="图层_2" data-name="图层 2">
|
||||
<g id="内容">
|
||||
<polygon points="161.68 39.5 157 35.76 157 5.21 161.71 0.5 183.29 0.5 188 5.21 188 35.76 183.32 39.5 161.68 39.5" style="fill:#171e28;opacity:0.8" />
|
||||
<path d="M183.09,1l4.41,4.41V35.52L183.15,39h-21.3l-4.35-3.48V5.41L161.91,1h21.17m.41-1h-22l-5,5V36l5,4h22l5-4V5l-5-5Z" style="fill:#27558e" />
|
||||
<polygon points="201.68 39.5 197 35.76 197 5.21 201.71 0.5 223.29 0.5 228 5.21 228 35.76 223.32 39.5 201.68 39.5" style="fill:#171e28;opacity:0.8" />
|
||||
<path d="M223.09,1l4.41,4.41V35.52L223.15,39h-21.3l-4.35-3.48V5.41L201.91,1h21.17m.41-1h-22l-5,5V36l5,4h22l5-4V5l-5-5Z" style="fill:#27558e" />
|
||||
<polygon points="241.68 39.5 237 35.76 237 5.21 241.71 0.5 263.29 0.5 268 5.21 268 35.76 263.32 39.5 241.68 39.5" style="fill:#171e28;opacity:0.8" />
|
||||
<path d="M263.09,1l4.41,4.41V35.52L263.15,39h-21.3l-4.35-3.48V5.41L241.91,1h21.17m.41-1h-22l-5,5V36l5,4h22l5-4V5l-5-5Z" style="fill:#27558e" />
|
||||
<polygon points="281.68 39.5 277 35.76 277 5.21 281.71 0.5 303.29 0.5 308 5.21 308 35.76 303.32 39.5 281.68 39.5" style="fill:#171e28;opacity:0.8" />
|
||||
<path d="M303.09,1l4.41,4.41V35.52L303.15,39h-21.3l-4.35-3.48V5.41L281.91,1h21.17m.41-1h-22l-5,5V36l5,4h22l5-4V5l-5-5Z" style="fill:#27558e" />
|
||||
<polygon points="321.68 39.5 317 35.76 317 5.21 321.71 0.5 343.29 0.5 348 5.21 348 35.76 343.32 39.5 321.68 39.5" style="fill:#171e28;opacity:0.8" />
|
||||
<path d="M343.09,1l4.41,4.41V35.52L343.15,39h-21.3l-4.35-3.48V5.41L321.91,1h21.17m.41-1h-22l-5,5V36l5,4h22l5-4V5l-5-5Z" style="fill:#27558e" />
|
||||
<polygon points="361.68 39.5 357 35.76 357 5.21 361.71 0.5 383.29 0.5 388 5.21 388 35.76 383.32 39.5 361.68 39.5" style="fill:#171e28;opacity:0.8" />
|
||||
<path d="M383.09,1l4.41,4.41V35.52L383.15,39h-21.3l-4.35-3.48V5.41L361.91,1h21.17m.41-1h-22l-5,5V36l5,4h22l5-4V5l-5-5Z" style="fill:#27558e" />
|
||||
<rect x="2.5" y="30" width="420" height="10" style="fill:url(#linear-gradient-staqyxts)" />
|
||||
<text transform="translate(166.36 30)" style="font-size:24px;fill:aqua;font-family:LCDUltra, LCDUltra">{{ safeDaysList[0] }}</text>
|
||||
<text transform="translate(206.34 30)" style="font-size:24px;fill:aqua;font-family:LCDUltra, LCDUltra">{{ safeDaysList[1] }}</text>
|
||||
<text transform="translate(246.34 30)" style="font-size:24px;fill:aqua;font-family:LCDUltra, LCDUltra">{{ safeDaysList[2] }}</text>
|
||||
<text transform="translate(286.34 30)" style="font-size:24px;fill:aqua;font-family:LCDUltra, LCDUltra">{{ safeDaysList[3] }}</text>
|
||||
<text transform="translate(326.34 30)" style="font-size:24px;fill:aqua;font-family:LCDUltra, LCDUltra">{{ safeDaysList[4] }}</text>
|
||||
<text transform="translate(366.34 30)" style="font-size:24px;fill:aqua;font-family:LCDUltra, LCDUltra">{{ safeDaysList[5] }}</text>
|
||||
<text transform="translate(0 29.12)" style="font-size:24px;fill:#fff;font-weight:700">系统安全运行</text>
|
||||
<text transform="translate(399.5 29.12)" style="font-size:24px;fill:#fff;font-weight:700">天</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<img :src="gdMap.propValue" :style="{transform: `scale(${scale(w, 870)}, ${scale(h - 100,560)})`}" style="position: absolute;top: 100px;width: 870px;height: 560px;transform-origin: left top"/>
|
||||
<div :style="{transform: `scale(${scale(w, 870)}, ${scale(h - 100,560)})`}" style="position: absolute;top: 100px;width: 870px;height: 560px;transform-origin: left top">
|
||||
<svg
|
||||
v-for="(item, i) in point"
|
||||
:key="i"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
style="position: absolute;outline: none;width: 22px;height: 22px;"
|
||||
:style="{
|
||||
top: `${pxToPercentTop(item.style.top + 20, 911)}`,
|
||||
left: `${pxToPercentLeft(item.style.left - 220, 1400)}`,
|
||||
}"
|
||||
>
|
||||
<g transform="translate(0, 0) scale(1, 1)">
|
||||
<g>
|
||||
<circle cx="11" cy="11" r="6.5" style="fill:#4dca59;opacity:0.5;isolation:isolate"></circle>
|
||||
<path d="M11,5a6,6,0,1,1-6,6,6,6,0,0,1,6-6m0-1a7,7,0,1,0,7,7A7,7,0,0,0,11,4Z" style="fill:#4dca59"></path>
|
||||
<g style="opacity:0.5">
|
||||
<path d="M11,1A10,10,0,1,1,1,11,10,10,0,0,1,11,1m0-1A11,11,0,1,0,22,11,11,11,0,0,0,11,0Z" style="fill:#4dca59"></path>
|
||||
</g>
|
||||
<circle cx="11" cy="11" r="3" style="fill:#4dca59"></circle>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<div
|
||||
v-for="(item, i) in text"
|
||||
:key="i"
|
||||
style="position: absolute;color: #fff;"
|
||||
:style="{top: `${pxToPercentTop(item.style.top + 20, 911)}`, left: `${pxToPercentLeft(item.style.left - 220, 1400)}`}"
|
||||
>
|
||||
{{item.propValue}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, shallowReactive, watch, toRefs, reactive, onMounted, onUnmounted, nextTick, ref, computed } from 'vue'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { publicInterface } from '@/api/path/business.api'
|
||||
import {isPreview} from '@/utils'
|
||||
import {selectTimeOptions} from "@/views/chart/ContentConfigurations/components/ChartData/index.d";
|
||||
import {RequestHttpIntervalEnum} from "@/enums/httpEnum";
|
||||
import { useOriginStore } from '@/store/modules/originStore/originStore'
|
||||
import moment from 'moment'
|
||||
import { debounce } from "lodash";
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
if(!isPreview()) {
|
||||
Object.assign(props.chartConfig.attr, { w: 950, h: 620 })
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
}
|
||||
// Object.assign(props.chartConfig.attr, { w: 870, h: 560 })
|
||||
|
||||
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 originStore = useOriginStore()
|
||||
const systemConfig = originStore.getOriginStore.user.systemConfig
|
||||
|
||||
const scale = (a:number, b:number) => {
|
||||
return a / b
|
||||
}
|
||||
const pxToPercentLeft = (left:number, w:number) => {
|
||||
return `calc(${left * 100 / w}% - 11px)`
|
||||
}
|
||||
const pxToPercentTop = (top:number, h:number) => {
|
||||
return `calc(${top * 100 / h}% - 11px)`
|
||||
}
|
||||
let gdMap: { [k: string]: any } = reactive({})
|
||||
let text: { style: { [k: string]: any }, propValue: string }[] = reactive([])
|
||||
let point: { color: string, node_status: number, style: { [k: string]: any } }[] = reactive([])
|
||||
|
||||
const allNumber = computed(() => point.length)
|
||||
const normalNumber = computed(() => point.filter(_ => _.color !== '#f00').length)
|
||||
const abnormalNumber = computed(() => point.filter(_ => _.color === '#f00').length)
|
||||
|
||||
let safeDaysList = reactive(['0', '0', '0', '0', '0', '0'])
|
||||
|
||||
const getData = () => {
|
||||
safeDaysList.splice(0, safeDaysList.length, ...(moment().diff(moment(systemConfig.overview_dglt_idc_operation_date), 'days') + 1).toString().padStart(6, '0').split(''))
|
||||
publicInterface('/dcim/space_page', 'get_one_no_permission', { id: props.chartConfig.customData!.mapId }).then(res => {
|
||||
if(res && res.data){
|
||||
const arr:[] = JSON.parse(res.data.canvas_data)
|
||||
gdMap = arr.find((_:any) => _.component === 'Picture') || {}
|
||||
Object.assign(gdMap, arr.find((_:any) => _.component === 'Picture') || {})
|
||||
text.splice(0, text.length, ...arr.filter((_:any) => _.component === 'v-text'))
|
||||
point.splice(0, text.length, ...arr.filter((_:any) => _.component === 'svg-shape'))
|
||||
|
||||
const activeAlarmData = {
|
||||
levels: [],
|
||||
confirm_statuses: []
|
||||
}
|
||||
if (systemConfig.active_alarm_confirm_status) {
|
||||
activeAlarmData.confirm_statuses.splice(0, activeAlarmData.confirm_statuses.length, ...JSON.parse(systemConfig.active_alarm_confirm_status) as [])
|
||||
}
|
||||
if (systemConfig['active_alarm_level']) {
|
||||
for (let i = 0; i < Number(systemConfig['active_alarm_level']); i++) {
|
||||
(activeAlarmData.levels as number[]).push(i + 1)
|
||||
}
|
||||
}
|
||||
const param = {
|
||||
ids: point.filter((_:any) => _.dataBind.monitorIds.length).map((_:any) => Number(_.dataBind.monitorIds[0])),
|
||||
...activeAlarmData,
|
||||
}
|
||||
const idMap:{[k:string]: number} = {}
|
||||
param.ids.forEach((item, i) => {
|
||||
idMap[item] = i
|
||||
})
|
||||
publicInterface('/dcim/dems/device', 'get_space_tree_with_status_v3', param).then(res => {
|
||||
if(res && res.data) {
|
||||
res.data.forEach((item:any) => {
|
||||
if(item.node_status !== 0) {
|
||||
point[idMap[item.id]].color = '#f00'
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let timer:unknown
|
||||
watch(() => [props.chartConfig.request.requestInterval, props.chartConfig.request.requestIntervalUnit].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)
|
||||
}
|
||||
})
|
||||
const fn = debounce(() => {
|
||||
getData()
|
||||
}, 200)
|
||||
watch(() => props.chartConfig.customData!.mapId, fn)
|
||||
|
||||
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>
|
||||
.box{
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<BorderBox>
|
||||
<template #title>
|
||||
<div class="titleBox">
|
||||
<div class="mr10 nowrap">{{title}}</div>
|
||||
<n-checkbox :checked="checkAll" @update:checked="(v:boolean) => emit('update:checkAll', v)" size="small" class="mr10 nowrap">全选</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>
|
||||
<div class="more nowrap" @click="jumpMore">更多>></div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default>
|
||||
<slot></slot>
|
||||
</template>
|
||||
</BorderBox>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineEmits } from 'vue'
|
||||
import BorderBox from '../components/BorderBox.vue'
|
||||
import { icon } from '@/plugins/icon'
|
||||
|
||||
const { AssignmentTurnedInRoundIcon } = icon.material
|
||||
|
||||
interface propsType {
|
||||
title: string,
|
||||
checkAll: boolean,
|
||||
}
|
||||
const props = defineProps<propsType>()
|
||||
|
||||
|
||||
const emit = defineEmits(['clickBatch', 'update:checkAll', 'jumpMore'])
|
||||
const clickBatch = () => {
|
||||
emit('clickBatch')
|
||||
}
|
||||
|
||||
const jumpMore = () => {
|
||||
emit('jumpMore')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mr10{
|
||||
margin-right: 10px;
|
||||
}
|
||||
.button{
|
||||
border: 1px solid #4196ff;
|
||||
//border-color: #4196ff;
|
||||
}
|
||||
.nowrap{
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.titleBox{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
.more{
|
||||
font-size: 14px;
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,142 @@
|
||||
<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)
|
||||
}
|
||||
|
||||
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>
|
@ -0,0 +1,25 @@
|
||||
import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { MonitorRealTimeEventsConfig } 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
|
||||
{
|
||||
public key = MonitorRealTimeEventsConfig.key
|
||||
public chartConfig = cloneDeep(MonitorRealTimeEventsConfig)
|
||||
public option = cloneDeep(option)
|
||||
public customData = cloneDeep({
|
||||
title: '自监控实时事件',
|
||||
showInterval: true,
|
||||
})
|
||||
}
|
@ -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>
|
@ -0,0 +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>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
|
||||
|
||||
const props = defineProps(['customData', 'request'])
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
@ -0,0 +1,16 @@
|
||||
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
|
||||
import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/CustomComponents/index.d'
|
||||
|
||||
export const MonitorRealTimeEventsConfig: ConfigType = {
|
||||
key: 'MonitorRealTimeEvents',
|
||||
chartKey: 'VMonitorRealTimeEvents',
|
||||
conKey: 'VCMonitorRealTimeEvents',
|
||||
// VCD开头
|
||||
conDataKey: 'VCDMonitorRealTimeEvents',
|
||||
title: '自监控实时事件',
|
||||
category: ChatCategoryEnum.CUSTOMCOMPONENTS,
|
||||
categoryName: ChatCategoryEnumName.CUSTOMCOMPONENTS,
|
||||
package: PackagesCategoryEnum.CUSTOMCOMPONENTS,
|
||||
chartFrame: ChartFrameEnum.COMMON,
|
||||
image: 'MonitorRealTimeEvents.png'
|
||||
}
|
@ -0,0 +1,271 @@
|
||||
<template>
|
||||
<div :style="getStyle(borderRadius)" style="overflow: visible">
|
||||
<BorderBox
|
||||
:title="chartConfig?.customData?.title"
|
||||
v-model:checkAll="checkAll"
|
||||
@clickBatch="clickBatch('batch')"
|
||||
@jumpMore="jumpMore"
|
||||
>
|
||||
<div class="itemBox">
|
||||
<div class="item" v-for="(item, i) in tableData" :key="i">
|
||||
<div class="row1">
|
||||
<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: levelToOption(item.level).remark, borderColor: levelToOption(item.level).remark}">
|
||||
{{levelToOption(item.level).label}}
|
||||
</n-tag>
|
||||
<div class="content">{{ item.content }}</div>
|
||||
</div>
|
||||
<div class="row2">
|
||||
<div class="mr10 nowrap" style="color: #B5BAC3;">{{ moment(item.generate_time).format('yyyy-MM-DD HH:mm:ss') }}</div>
|
||||
<div style="flex: 1;"></div>
|
||||
<CheckCircleOutlinedIcon @click="clickBatch('single', item.id)" style="width: 20px;height: 20px;color: #4196ff;"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BorderBox>
|
||||
<VModalV1 v-model:show="modalV1Obj.show" :data="modalV1Obj.data" @confirm="confirm"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, 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 {selectTimeOptions} from "@/views/chart/ContentConfigurations/components/ChartData/index.d";
|
||||
import {RequestHttpIntervalEnum} from "@/enums/httpEnum";
|
||||
import {icon} from "@/plugins";
|
||||
import moment from 'moment'
|
||||
import { useOriginStore } from '@/store/modules/originStore/originStore'
|
||||
import VModalV1 from './VModalV1.vue'
|
||||
|
||||
const { CheckCircleOutlinedIcon } = icon.material
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
if(!isPreview()){
|
||||
Object.assign(props.chartConfig.attr, { w: 450, h: 300 })
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
}
|
||||
|
||||
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 originStore = useOriginStore()
|
||||
const user = originStore.getOriginStore.user.user
|
||||
const modalV1Obj = reactive({
|
||||
show: false,
|
||||
data: {
|
||||
confirm_people: user.name,
|
||||
is_misreport: false,
|
||||
remark: '',
|
||||
reconfirmation_time_str: null,
|
||||
},
|
||||
// batch 批量 single 单个
|
||||
type: 'batch',
|
||||
singleIds: [],
|
||||
})
|
||||
const clickBatch = (type = 'batch', id?:number) => {
|
||||
if(type === 'batch' && !tableData.filter(_ => _.checked).length) {
|
||||
window['$message'].warning('请先选择数据')
|
||||
return
|
||||
}
|
||||
let singleIds:number[] = []
|
||||
if(type === 'single' && id) singleIds = [id]
|
||||
Object.assign(modalV1Obj, {
|
||||
show: true,
|
||||
data: {
|
||||
confirm_people: user.name,
|
||||
is_misreport: false,
|
||||
remark: '',
|
||||
reconfirmation_time_str: null,
|
||||
},
|
||||
type,
|
||||
singleIds
|
||||
})
|
||||
}
|
||||
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 jumpMore = () => {
|
||||
postMessageToParent({
|
||||
type: 'changeRouterV1',
|
||||
url: `/alarmManage/monitorAlarm`
|
||||
})
|
||||
}
|
||||
type tableDataItemType = {
|
||||
id: number,
|
||||
content: string,
|
||||
generate_time: string,
|
||||
checked: boolean,
|
||||
confirm_status: 'ok' | 'not',
|
||||
level: number
|
||||
}
|
||||
|
||||
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)
|
||||
})
|
||||
|
||||
type levelItem = { [k:string]: string | number }
|
||||
const warnLevelOption = originStore.getOriginStore.user.systemConstant['warn_levels'].filter((item: levelItem) => item.value !== '').map((item: levelItem) => {
|
||||
return { label: item.label, value: Number(item.value), remark: item.remark }
|
||||
})
|
||||
|
||||
const levelToOption = (level:number) => {
|
||||
return warnLevelOption.find((_:levelItem) => _.value === level) || { label: '其他', remark: '#989898' }
|
||||
}
|
||||
|
||||
const getData = () => {
|
||||
const queryModel = {
|
||||
condition: {
|
||||
id: null,
|
||||
levels: [],
|
||||
confirm_statuss: ['not'],
|
||||
trigger_source: 1 // 1:IOT服务告警,0:设备测点告警
|
||||
},
|
||||
page: {
|
||||
page_size: 6,
|
||||
page_number: 1
|
||||
}
|
||||
}
|
||||
publicInterface('/dcim/dems/devie_active_alarm', 'get_page', queryModel).then(res => {
|
||||
if(res && res.data && res.data.item) {
|
||||
const lastTableData = [...tableData]
|
||||
tableData.splice(0, tableData.length, ...res.data.item.map((e:any) => ({ ...e, checked: false })))
|
||||
if (checkAll.value) {
|
||||
tableData.splice(0, tableData.length, ...tableData.map(e => ({ ...e, checked: e.confirm_status !== 'ok' })))
|
||||
} else if (lastTableData.length) {
|
||||
tableData.forEach(e => {
|
||||
const lastIndex = lastTableData.findIndex(item => item.id === e.id)
|
||||
if (lastIndex !== -1) {
|
||||
e.checked = lastTableData[lastIndex].checked
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let timer:unknown
|
||||
watch(() => [props.chartConfig.request.requestInterval, props.chartConfig.request.requestIntervalUnit].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;
|
||||
}
|
||||
.nowrap{
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.itemBox{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
.item{
|
||||
flex: none;
|
||||
height: 60px;
|
||||
padding: 5px 10px;
|
||||
box-sizing: border-box;
|
||||
margin: 3px 0;
|
||||
background: rgba(65,150,255,.05);
|
||||
cursor: pointer;
|
||||
.row1{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.content{
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.82)
|
||||
}
|
||||
}
|
||||
.row2{
|
||||
margin-top: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<BorderBox :title="props.chartConfig.customData.title" :style="getStyle(borderRadius)" style="overflow: visible">
|
||||
<BorderBox :title="chartConfig?.customData?.title" :style="getStyle(borderRadius)" style="overflow: visible">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 401 236" style="width: 100%;height: 100%">
|
||||
<defs>
|
||||
<linearGradient id="linear-gradient-compute-node" x1="99" y1="176" x2="99" y2="120" gradientUnits="userSpaceOnUse">
|
||||
@ -102,8 +102,10 @@ const props = defineProps({
|
||||
required: true
|
||||
}
|
||||
})
|
||||
Object.assign(props.chartConfig.attr, { w: 380, h: 250 })
|
||||
if(!props.chartConfig.request.requestInterval) Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
if(!isPreview()) {
|
||||
Object.assign(props.chartConfig.attr, { w: 450, h: 300 })
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
}
|
||||
|
||||
const { w, h } = toRefs(props.chartConfig.attr)
|
||||
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<img class="scaner" src="@/assets/customComponents/RealTimeAlarmStatistics/scanner.png" alt="">
|
||||
<svg v-show="alarmLevels.length === 5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
|
||||
<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" />
|
||||
@ -133,7 +133,7 @@
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<svg v-show="alarmLevels.length === 4 || alarmLevels.length === 0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
|
||||
<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" />
|
||||
@ -219,7 +219,7 @@
|
||||
<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="alarmLevels.length === 3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
|
||||
<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" />
|
||||
@ -327,7 +327,7 @@
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<svg v-show="alarmLevels.length === 2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
|
||||
<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" />
|
||||
@ -423,7 +423,7 @@
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<svg v-show="alarmLevels.length === 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 200 200">
|
||||
<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" />
|
||||
@ -511,25 +511,41 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { toRefs } from 'vue'
|
||||
import { toRefs, computed } from 'vue'
|
||||
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
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@keyframes rotate {
|
||||
from { transform: scale(0.69) rotate(0);}
|
||||
to { transform: scale(0.69) rotate(360deg);}
|
||||
from { transform: translateY(-50%) scale(0.71) rotate(0)}
|
||||
to { transform: translateY(-50%) scale(0.71) rotate(360deg) }
|
||||
}
|
||||
.box{
|
||||
position: relative;
|
||||
.scaner{
|
||||
height: 100%;
|
||||
svg{
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: -1.5%;
|
||||
left: -0.5%;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 2;
|
||||
}
|
||||
.scaner{
|
||||
object-fit: contain;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
animation: rotate linear 5s infinite;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 3;
|
||||
//height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div :style="getStyle(borderRadius)">
|
||||
<BorderBox :title="props.chartConfig.customData.title">
|
||||
<BorderBox :title="chartConfig?.customData?.title">
|
||||
<v-chart
|
||||
ref="vChartRef"
|
||||
:option="option"
|
||||
@ -9,9 +9,9 @@
|
||||
replaceMerge: ['series', 'xAxis', 'yAxis']
|
||||
}"
|
||||
autoresize
|
||||
style="overflow: visible;width: 50%"
|
||||
style="overflow: visible;width: calc(50% - 10px);margin-right: 20px;"
|
||||
/>
|
||||
<div class="box-5-item" style="width: 50%">
|
||||
<div class="box-5-item" style="width: calc(50% - 10px)">
|
||||
<SvgAll v-bind="nameObj"/>
|
||||
</div>
|
||||
</BorderBox>
|
||||
@ -37,8 +37,10 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
Object.assign(props.chartConfig.attr, {w: 380, h: 250})
|
||||
if(!props.chartConfig.request.requestInterval) Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
if(!isPreview()) {
|
||||
Object.assign(props.chartConfig.attr, {w: 450, h: 300})
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
}
|
||||
|
||||
const { w, h } = toRefs(props.chartConfig.attr)
|
||||
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
|
||||
@ -75,8 +77,8 @@ const originStore = useOriginStore()
|
||||
const systemConfig = originStore?.getOriginStore?.user?.systemConfig
|
||||
const systemConstant = originStore?.getOriginStore?.user?.systemConstant
|
||||
if (systemConfig['active_alarm_level']) {
|
||||
for (let i = 0; i < Number(systemConfig['active_alarm_level']); i++) {
|
||||
nameObj.alarmLevels.push(i + 1)
|
||||
for (let i:number = 0; i < Number(systemConfig['active_alarm_level']); i++) {
|
||||
(nameObj.alarmLevels as number[]).push(i + 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
<template #title>
|
||||
<div class="titleBox">
|
||||
<div class="mr10">{{title}}</div>
|
||||
<n-checkbox :checked="checkAll" @update:checked="v => emit('update:checkAll', v)" size="small" class="mr10">全选</n-checkbox>
|
||||
<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/>
|
||||
@ -11,7 +11,7 @@
|
||||
批量确认
|
||||
</n-button>
|
||||
<div style="flex: 1"></div>
|
||||
<n-checkbox-group :value="select1.value" @update:value="v => changeSelect1(v)" class="mr10" size="small">
|
||||
<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>
|
||||
@ -19,7 +19,7 @@
|
||||
</n-checkbox>
|
||||
</n-space>
|
||||
</n-checkbox-group>
|
||||
<n-checkbox-group :value="select2.value" @update:value="v => changeSelect2(v)" class="mr10" size="small">
|
||||
<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>
|
||||
@ -40,12 +40,24 @@
|
||||
import { ref, reactive, toRefs, defineEmits } from 'vue'
|
||||
import BorderBox from '../components/BorderBox.vue'
|
||||
import { icon } from '@/plugins/icon'
|
||||
import VModal from './VModalV1.vue'
|
||||
|
||||
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 props = defineProps(['title', 'select1', 'select2', 'checkAll'])
|
||||
|
||||
const { select1, select2 } = toRefs(props)
|
||||
|
||||
@ -93,6 +105,10 @@ const jumpMore = () => {
|
||||
border: 1px solid #4196ff;
|
||||
//border-color: #4196ff;
|
||||
}
|
||||
.n-space{
|
||||
flex-wrap: nowrap!important;
|
||||
gap: 4px 2px!important;
|
||||
}
|
||||
.titleBox{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -21,5 +21,6 @@ export default class Config extends PublicConfigClass implements CreateComponent
|
||||
public customData = cloneDeep({
|
||||
title: '实时事件',
|
||||
showInterval: true,
|
||||
showFilter: false,
|
||||
})
|
||||
}
|
||||
|
@ -3,6 +3,12 @@
|
||||
<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>
|
||||
</template>
|
||||
|
||||
|
@ -1,33 +1,38 @@
|
||||
<template>
|
||||
<BorderBox
|
||||
:title="props.chartConfig.customData.title"
|
||||
:title="chartConfig?.customData?.title"
|
||||
:select1="select1"
|
||||
@update:select1Value="v => select1.value = v"
|
||||
:select2="select2"
|
||||
@update:select2Value="v => select2.value = v"
|
||||
:style="getStyle(borderRadius)"
|
||||
@clickBatch="clickBatch"
|
||||
v-model:checkAll="checkAll"
|
||||
@jumpMore="jumpMore"
|
||||
:showFilter="chartConfig?.customData?.showFilter"
|
||||
:style="getStyle(borderRadius)"
|
||||
style="overflow: visible"
|
||||
>
|
||||
<div class="itemBox">
|
||||
<div class="item" v-for="(item, i) in tableData" :key="i" @click="clickItem(i)">
|
||||
<n-checkbox :disabled="item.checked" v-model:checked="item.checked" class="mr10" size="small" @click.stop/>
|
||||
<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 style="color: rgba(255, 255, 255, 0.82);">{{ item.content }}</div>
|
||||
<div class="textEllipsis" style="color: rgba(255, 255, 255, 0.82);">{{ item.content }}</div>
|
||||
<div style="flex: 1"></div>
|
||||
<div class="mr10" style="color: #B5BAC3;">{{ moment(item.generate_time).format('yyyy-MM-DD HH:mm:ss') }}</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>
|
||||
@ -35,15 +40,10 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, shallowReactive, watch, toRefs, reactive, onMounted, onUnmounted, nextTick, ref } from 'vue'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { publicInterface } from '@/api/path/business.api'
|
||||
import BorderBox from './BorderBoxV2.vue'
|
||||
import VChart from 'vue-echarts'
|
||||
import {isPreview, postMessageToParent} from '@/utils'
|
||||
import {graphic} from "echarts";
|
||||
import {cloneDeep} from 'lodash'
|
||||
import moment from "moment"
|
||||
import {selectTimeOptions} from "@/views/chart/ContentConfigurations/components/ChartData/index.d";
|
||||
import {RequestHttpIntervalEnum} from "@/enums/httpEnum";
|
||||
@ -61,8 +61,11 @@ const props = defineProps({
|
||||
required: true
|
||||
}
|
||||
})
|
||||
Object.assign(props.chartConfig.attr, { w: 1000, h: 250 })
|
||||
if(!props.chartConfig.request.requestInterval) Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
if(!isPreview()){
|
||||
Object.assign(props.chartConfig.attr, { w: 950, h: 300 })
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
}
|
||||
|
||||
|
||||
const { w, h } = toRefs(props.chartConfig.attr)
|
||||
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
|
||||
@ -276,7 +279,7 @@ const confirm = () => {
|
||||
const obj = {
|
||||
id: null,
|
||||
ids: modalV1Obj.type === 'batch' ? tableData.filter(_ => _.checked).map(_ => _.id) : modalV1Obj.singleIds,
|
||||
confirm_status: "not",
|
||||
confirm_status: "ok",
|
||||
...modalV1Obj.data
|
||||
}
|
||||
publicInterface('/dcim/dems/devie_active_alarm', 'confirms', obj).then(res => {
|
||||
@ -359,6 +362,19 @@ onUnmounted(() => {
|
||||
.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%;
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div :style="getStyle(borderRadius)" style="overflow: visible">
|
||||
<BorderBox :title="props.chartConfig.customData.title">
|
||||
<BorderBox :title="chartConfig?.customData?.title">
|
||||
<v-chart
|
||||
ref="vChartRef"
|
||||
:option="option"
|
||||
@ -18,15 +18,12 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, shallowReactive, watch, toRefs, reactive, onMounted, onUnmounted, nextTick, ref } from 'vue'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import { publicInterface } from '@/api/path/business.api'
|
||||
import BorderBox from '../components/BorderBox.vue'
|
||||
import VChart from 'vue-echarts'
|
||||
import {isPreview} from '@/utils'
|
||||
import {graphic} from "echarts";
|
||||
import {cloneDeep} from 'lodash'
|
||||
import moment from "moment"
|
||||
import {selectTimeOptions} from "@/views/chart/ContentConfigurations/components/ChartData/index.d";
|
||||
import {RequestHttpIntervalEnum} from "@/enums/httpEnum";
|
||||
@ -37,8 +34,10 @@ const props = defineProps({
|
||||
required: true
|
||||
}
|
||||
})
|
||||
Object.assign(props.chartConfig.attr, { w: 380, h: 250 })
|
||||
if(!props.chartConfig.request.requestInterval) Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
if(!isPreview()) {
|
||||
Object.assign(props.chartConfig.attr, { w: 450, h: 300 })
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
}
|
||||
|
||||
const { w, h } = toRefs(props.chartConfig.attr)
|
||||
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
|
||||
|
@ -90,7 +90,7 @@
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<div style="font: 30px PingFang-SC-Bold;color: #fff;width: 1920px;height: 60px;line-height: 60px;text-align: center;position: absolute;top: 0;">{{props.chartConfig.customData.title}}</div>
|
||||
<div style="font: 30px PingFang-SC-Bold;color: #fff;width: 1920px;height: 60px;line-height: 60px;text-align: center;position: absolute;top: 0;">{{chartConfig?.customData?.title}}</div>
|
||||
<n-image
|
||||
:object-fit="fit"
|
||||
preview-disabled
|
||||
@ -104,14 +104,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, shallowReactive, watch, toRefs, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { PropType, shallowReactive, watch, toRefs, onMounted, onUnmounted, ref, computed } from 'vue'
|
||||
import { requireErrorImg } from '@/utils'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import moment from 'moment'
|
||||
import background from '@/assets/customComponents/theme1/backgrond.jpg'
|
||||
import { isPreview } from '@/utils/router'
|
||||
import { postMessageToParent } from "@/utils";
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
@ -120,9 +119,7 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
props.chartConfig.attr.w = 1920
|
||||
props.chartConfig.attr.h = 1080
|
||||
Object.assign(props.chartConfig.attr, {w: 1920, h: 1080, x: 0, y: 0})
|
||||
if(!isPreview()) Object.assign(props.chartConfig.attr, {w: 1920, h: 1080, x: 0, y: 0})
|
||||
|
||||
const { w, h } = toRefs(props.chartConfig.attr)
|
||||
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
|
||||
@ -145,17 +142,20 @@ onUnmounted(() => {
|
||||
const showMoreMenuBts = ref(true)
|
||||
// 切换全屏函数
|
||||
function toggleFullscreen() {
|
||||
showMoreMenuBts.value = !showMoreMenuBts.value
|
||||
if (document.fullscreenElement) {
|
||||
// 如果当前已经是全屏状态,则退出全屏
|
||||
document.exitFullscreen();
|
||||
} else {
|
||||
// 否则,进入全屏
|
||||
document.documentElement.requestFullscreen()
|
||||
.catch(err => {
|
||||
console.error('Error attempting to enable full-screen mode:', err);
|
||||
});
|
||||
}
|
||||
postMessageToParent({type: 'fullScreen'})
|
||||
// console.log(document.documentElement)
|
||||
// showMoreMenuBts.value = !showMoreMenuBts.value
|
||||
//
|
||||
// if (document.fullscreenElement) {
|
||||
// // 如果当前已经是全屏状态,则退出全屏
|
||||
// document.exitFullscreen();
|
||||
// } else {
|
||||
// // 否则,进入全屏
|
||||
// document.documentElement.requestFullscreen()
|
||||
// .catch(err => {
|
||||
// console.error('Error attempting to enable full-screen mode:', err);
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
const option = shallowReactive({
|
||||
@ -202,6 +202,7 @@ const getStyle = (radius: number) => {
|
||||
.Theme1{
|
||||
position: relative;
|
||||
.full-screen-btn {
|
||||
z-index: 999;
|
||||
border: #4396fd 1px solid;
|
||||
border-radius: 3px;
|
||||
display: flex;
|
||||
|
@ -30,6 +30,9 @@ const { title } = toRefs(props)
|
||||
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;
|
||||
@ -41,6 +44,9 @@ const { title } = toRefs(props)
|
||||
}
|
||||
}
|
||||
.content{
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
height: calc(100% - 40px);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
|
@ -5,6 +5,8 @@ import { RealTimeTrafficConfig } from './RealTimeTraffic'
|
||||
import { RealTimeAlarmStatisticsConfig } from './RealTimeAlarmStatistics'
|
||||
import { OverviewOfComputingNodesConfig } from './OverviewOfComputingNodes'
|
||||
import { RealTimeEventConfig } from './RealTimeEvent'
|
||||
import { GDMapConfig } from './GDMap'
|
||||
import { MonitorRealTimeEventsConfig } from './MonitorRealTimeEvents'
|
||||
|
||||
export default [
|
||||
Theme1Config,
|
||||
@ -13,5 +15,7 @@ export default [
|
||||
RealTimeTrafficConfig,
|
||||
RealTimeAlarmStatisticsConfig,
|
||||
OverviewOfComputingNodesConfig,
|
||||
RealTimeEventConfig
|
||||
RealTimeEventConfig,
|
||||
GDMapConfig,
|
||||
MonitorRealTimeEventsConfig,
|
||||
]
|
||||
|
2
src/packages/index.d.ts
vendored
2
src/packages/index.d.ts
vendored
@ -46,6 +46,8 @@ export type ConfigType = {
|
||||
icon?: string
|
||||
// 事件
|
||||
configEvents?: { [T: string]: Function }
|
||||
// 自定义数据配置
|
||||
customData?: { [T: string]: any }
|
||||
}
|
||||
|
||||
// 数据请求
|
||||
|
@ -12,7 +12,7 @@
|
||||
</div>
|
||||
<div v-if="targetData && targetData.chartConfig.conDataKey">
|
||||
<component :is="targetData.chartConfig.conDataKey" :customData="targetData.customData" :request="targetData.request"></component>
|
||||
<setting-item-box v-if="targetData.customData.showInterval" name="更新间隔" :alone="true">
|
||||
<setting-item-box v-if="targetData?.customData?.showInterval" name="更新间隔" :alone="true">
|
||||
<n-input-group>
|
||||
<n-input-number
|
||||
v-model:value.trim="targetData.request.requestInterval"
|
||||
|
Loading…
x
Reference in New Issue
Block a user