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
ae342d87bb
commit
890d303b65
@ -21,8 +21,6 @@
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/keymaster": "^1.6.30",
|
||||
"@types/lodash": "^4.14.184",
|
||||
"@vicons/fluent": "^0.12.0",
|
||||
"@vicons/tabler": "^0.12.0",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^1.4.0",
|
||||
"color": "^4.2.3",
|
||||
@ -60,7 +58,10 @@
|
||||
"@typescript-eslint/eslint-plugin": "^5.18.0",
|
||||
"@typescript-eslint/parser": "^5.18.0",
|
||||
"@vicons/carbon": "^0.12.0",
|
||||
"@vicons/fluent": "^0.12.0",
|
||||
"@vicons/ionicons5": "~0.11.0",
|
||||
"@vicons/material": "^0.12.0",
|
||||
"@vicons/tabler": "^0.12.0",
|
||||
"@vitejs/plugin-vue": "^4.2.3",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.1",
|
||||
"@vue/compiler-sfc": "^3.2.31",
|
||||
|
31
src/App.vue
31
src/App.vue
@ -19,26 +19,27 @@ import { GoAppProvider } from '@/components/GoAppProvider'
|
||||
import { I18n } from '@/components/I18n'
|
||||
import { useSystemInit, useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
|
||||
import { getToken } from '@/api/path'
|
||||
import { onMounted, onUnmounted } from 'vue'
|
||||
import { useRouterStore } from '@/store/modules/routerStore/routerStore'
|
||||
import { useOriginStore } from '@/store/modules/originStore/originStore'
|
||||
import { useGetMessageByParent } from '@/utils/utils'
|
||||
|
||||
const {getMessageByParent} = useGetMessageByParent()
|
||||
|
||||
const routerStore = useRouterStore()
|
||||
let handleMessage = function(event:{data:string}) {
|
||||
const {data}:{data:any} = event
|
||||
if(data.page === 'customLargeScreen' && data.type === 'setCallByParent') {
|
||||
routerStore.setCallByParent(data.callByParent)
|
||||
getMessageByParent('setCallByParent', (e) => {
|
||||
if(e.data.type === 'setCallByParent' && e.data.page === 'customLargeScreen') {
|
||||
const {data}:{data:any} = e
|
||||
if(data.page === 'customLargeScreen' && data.type === 'setCallByParent') {
|
||||
routerStore.setCallByParent(data.callByParent)
|
||||
}
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
window.addEventListener('message', handleMessage);
|
||||
let obj = {
|
||||
page: 'customLargeScreen',
|
||||
type: 'bindPostMessageEvent'
|
||||
}
|
||||
window.parent.postMessage(JSON.stringify(obj), '*');
|
||||
})
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('message', handleMessage);
|
||||
|
||||
const originStore = useOriginStore()
|
||||
getMessageByParent('getStore', (e) => {
|
||||
if(e.data.type === 'getStore' && e.data.page === 'customLargeScreen') {
|
||||
originStore.setOriginStore(e.data.data, false)
|
||||
}
|
||||
})
|
||||
|
||||
getToken()
|
||||
|
@ -2,10 +2,15 @@
|
||||
import { http } from "@/api/http";
|
||||
import { RequestHttpEnum } from "@/enums/httpEnum";
|
||||
import { httpErrorHandle } from '@/utils'
|
||||
import moment from 'moment'
|
||||
|
||||
export function getToken() {
|
||||
const storage_access_token = localStorage.getItem('access_token')
|
||||
if(storage_access_token) return storage_access_token
|
||||
const storage_access_token = localStorage.getItem('access_token_obj')
|
||||
if(storage_access_token) {
|
||||
const obj = JSON.parse(storage_access_token)
|
||||
const { access_token, expiration } = obj
|
||||
if(expiration >= moment().format('x')) return access_token
|
||||
}
|
||||
let queryStr = window.location.href
|
||||
queryStr = queryStr.split('?')[1]
|
||||
if(queryStr && queryStr.indexOf('#') > -1) queryStr = queryStr.split('#')[0]
|
||||
@ -13,7 +18,11 @@ export function getToken() {
|
||||
queryStr && queryStr.split('&').forEach((item:string) => {
|
||||
query[item.split('=')[0]] = item.split('=')[1]
|
||||
})
|
||||
if(query.access_token) localStorage.setItem('access_token', query.access_token)
|
||||
const obj = {
|
||||
access_token: query.access_token,
|
||||
expiration: 86400000 + moment().format('x')
|
||||
}
|
||||
if(query.access_token) localStorage.setItem('access_token_obj', JSON.stringify(obj))
|
||||
return query.access_token
|
||||
}
|
||||
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 116 KiB |
BIN
src/assets/images/chart/customponents/RealTimeEvent.png
Normal file
BIN
src/assets/images/chart/customponents/RealTimeEvent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 191 KiB |
@ -45,7 +45,7 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
Object.assign(props.chartConfig.attr, { w: 380, h: 250 })
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
if(!props.chartConfig.request.requestInterval) 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)
|
||||
@ -58,7 +58,7 @@ const getStyle = (radius: number) => {
|
||||
}
|
||||
|
||||
const value = reactive([
|
||||
{label: '实时PUE', value: '0.000'},
|
||||
{label: '实时PUE', value: '1.000'},
|
||||
{label: '昨日PUE', value: '0.000'},
|
||||
{label: '上周PUE', value: '0.000'},
|
||||
{label: '上月PUE', value: '0.000'},
|
||||
|
@ -53,7 +53,7 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
Object.assign(props.chartConfig.attr, { w: 380, h: 250 })
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
if(!props.chartConfig.request.requestInterval) 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)
|
||||
|
@ -0,0 +1,25 @@
|
||||
import { PublicConfigClass } from '@/packages/public'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { OverviewOfComputingNodesConfig } 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 = OverviewOfComputingNodesConfig.key
|
||||
public chartConfig = cloneDeep(OverviewOfComputingNodesConfig)
|
||||
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 OverviewOfComputingNodesConfig: ConfigType = {
|
||||
key: 'OverviewOfComputingNodes',
|
||||
chartKey: 'VOverviewOfComputingNodes',
|
||||
conKey: 'VCOverviewOfComputingNodes',
|
||||
// VCD开头
|
||||
conDataKey: 'VCDOverviewOfComputingNodes',
|
||||
title: '计算节点运行概况',
|
||||
category: ChatCategoryEnum.CUSTOMCOMPONENTS,
|
||||
categoryName: ChatCategoryEnumName.CUSTOMCOMPONENTS,
|
||||
package: PackagesCategoryEnum.CUSTOMCOMPONENTS,
|
||||
chartFrame: ChartFrameEnum.COMMON,
|
||||
image: 'OverviewOfComputingNodes.png'
|
||||
}
|
@ -0,0 +1,214 @@
|
||||
<template>
|
||||
<BorderBox :title="props.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">
|
||||
<stop offset="0" stop-color="aqua" stop-opacity="0.3" />
|
||||
<stop offset="1" stop-color="aqua" stop-opacity="0.1" />
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-compute-node-2" x1="301" y1="176" x2="301" y2="120" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#999" stop-opacity="0.3" />
|
||||
<stop offset="1" stop-color="#999" stop-opacity="0.1" />
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-compute-node-3" x1="99" y1="236" x2="99" y2="180" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#f43b42" stop-opacity="0.3" />
|
||||
<stop offset="1" stop-color="#f43b42" stop-opacity="0.1" />
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-compute-node-4" x1="301" y1="236" x2="301" y2="180" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#f5b442" stop-opacity="0.3" />
|
||||
<stop offset="1" stop-color="#f5b442" stop-opacity="0.1" />
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-compute-node-5" x1="1" y1="100" x2="401" y2="100" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#4196ff" stop-opacity="0.1" />
|
||||
<stop offset="1" stop-color="#4196ff" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-compute-node-6" x1="1" y1="115.5" x2="21" y2="115.5" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#4196ff" stop-opacity="0" />
|
||||
<stop offset="1" stop-color="#4196ff" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g>
|
||||
<rect y="120" width="198" height="56" style="fill:url(#linear-gradient-compute-node)" />
|
||||
<!-- <text transform="translate(160 155.6)" style="font-size:20px;fill:aqua;font-family:SourceHanSansCN-Bold, SourceHanSansCN Bold-GBpc-EUC-H;font-weight:700">{{ computeNodeData.sever_count }}</text> -->
|
||||
<text transform="translate(160 155.6)" style="font-size:20px;fill:aqua;font-weight:700">{{ computeNodeData.sever_count }}</text>
|
||||
<rect y="174" width="198" height="2" style="fill:aqua" />
|
||||
<text transform="translate(28 152)" style="font-size:12px;fill:#fff;font-family:PingFang-SC-Regular, PingFang SC-Regular">服务总数</text>
|
||||
<rect x="6" y="140" width="16" height="16" style="fill:#fff;opacity:0" />
|
||||
<path d="M14,142a6,6,0,1,1-6,6,6,6,0,0,1,6-6m0-1a7,7,0,1,0,7,7,7,7,0,0,0-7-7Z" style="fill:#fff" />
|
||||
<polyline points="20 148 14 148 14 142" style="fill:none;stroke:#fff;stroke-miterlimit:10" />
|
||||
<rect x="202" y="120" width="198" height="56" style="fill:url(#linear-gradient-compute-node-2)" />
|
||||
<text transform="translate(362 155.6)" style="font-size:20px;fill:#999;font-weight:700">{{ computeNodeData.offline_server_count }}</text>
|
||||
<rect x="202" y="174" width="198" height="2" style="fill:#999" />
|
||||
<text transform="translate(230 152)" style="font-size:12px;fill:#fff;font-family:PingFang-SC-Regular, PingFang SC-Regular">离线服务</text>
|
||||
<rect x="208" y="140" width="16" height="16" style="fill:#fff;opacity:0" />
|
||||
<line x1="219" y1="149" x2="213" y2="155" style="fill:none;stroke:#fff;stroke-miterlimit:10" />
|
||||
<line x1="213" y1="149" x2="219" y2="155" style="fill:none;stroke:#fff;stroke-miterlimit:10" />
|
||||
<path d="M216,144a5,5,0,0,0-4.65,3.18l.93.36a4,4,0,0,1,7.43,0l.93-.36A5,5,0,0,0,216,144Z" style="fill:#fff" />
|
||||
<path d="M216,141a8,8,0,0,0-7.45,5.09l.93.36a7,7,0,0,1,13,0l.93-.36A8,8,0,0,0,216,141Z" style="fill:#fff" />
|
||||
<rect y="180" width="198" height="56" style="fill:url(#linear-gradient-compute-node-3)" />
|
||||
<text transform="translate(165 215.6)" style="font-size:20px;fill:#f43b42;font-weight:700">{{ computeNodeData.busy_server_count }}</text>
|
||||
<rect y="234" width="198" height="2" style="fill:#f43b42" />
|
||||
<text transform="translate(28 212)" style="font-size:12px;fill:#fff;font-family:PingFang-SC-Regular, PingFang SC-Regular">拥堵服务</text>
|
||||
<rect x="6" y="200" width="16" height="16" style="fill:#fff;opacity:0" />
|
||||
<path d="M14,202a6,6,0,1,1-6,6,6,6,0,0,1,6-6m0-1a7,7,0,1,0,7,7,7,7,0,0,0-7-7Z" style="fill:#fff" />
|
||||
<line x1="21" y1="208" x2="7" y2="208" style="fill:none;stroke:#fff;stroke-miterlimit:10" />
|
||||
<line x1="21" y1="208" x2="10" y2="203" style="fill:none;stroke:#fff;stroke-miterlimit:10" />
|
||||
<line x1="21" y1="208" x2="10" y2="213" style="fill:none;stroke:#fff;stroke-miterlimit:10" />
|
||||
<rect x="202" y="180" width="198" height="56" style="fill:url(#linear-gradient-compute-node-4)" />
|
||||
<text transform="translate(367 215.6)" style="font-size:20px;fill:#f5b442;font-weight:700">{{ computeNodeData.loss_server_count }}</text>
|
||||
<rect x="202" y="234" width="198" height="2" style="fill:#f5b442" />
|
||||
<text transform="translate(230 212)" style="font-size:12px;fill:#fff;font-family:PingFang-SC-Regular, PingFang SC-Regular">缺失服务</text>
|
||||
<rect x="208" y="200" width="16" height="16" style="fill:#fff;opacity:0" />
|
||||
<path d="M216,202a6,6,0,1,1-6,6,6,6,0,0,1,6-6m0-1a7,7,0,1,0,7,7,7,7,0,0,0-7-7Z" style="fill:#fff" />
|
||||
<line x1="220.95" y1="203.05" x2="211.05" y2="212.95" style="fill:none;stroke:#fff;stroke-miterlimit:10" />
|
||||
<rect x="1" y="84" width="400" height="32" style="fill:url(#linear-gradient-compute-node-5)" />
|
||||
<rect x="1" y="115" width="20" height="1" style="fill:url(#linear-gradient-compute-node-6)" />
|
||||
<text transform="translate(11 105)" style="font-size:14px;fill:#fff;font-family:PingFang-SC-Bold, PingFang SC-Bold;font-weight:700">计算节点服务统计</text>
|
||||
<rect x="1" width="400" height="68" style="fill:#4196ff;fill-opacity:0.08" />
|
||||
<rect x="101" y="14" width="1" height="40" style="fill:#4196ff;fill-opacity:0.08" />
|
||||
<rect x="201" y="14" width="1" height="40" style="fill:#4196ff;fill-opacity:0.08" />
|
||||
<rect x="301" y="14" width="1" height="40" style="fill:#4196ff;fill-opacity:0.08" />
|
||||
<text transform="translate(27 30)" style="font-size:20px;fill:aqua;font-weight:700">{{ computeNodeData.node_count }}</text>
|
||||
<text transform="translate(27 51)" style="font-size:12px;fill:#fff;font-family:PingFang-SC-Regular, PingFang SC-Regular">计算节点</text>
|
||||
<text transform="translate(133 51)" style="font-size:12px;fill:#fff;font-family:PingFang-SC-Regular, PingFang SC-Regular">待更新</text>
|
||||
<text transform="translate(227 51)" style="font-size:12px;fill:#fff;font-family:PingFang-SC-Regular, PingFang SC-Regular">异常节点</text>
|
||||
<text transform="translate(327 51)" style="font-size:12px;fill:#fff;font-family:PingFang-SC-Regular, PingFang SC-Regular">异常服务</text>
|
||||
<text transform="translate(133 30)" style="font-size:20px;fill:#fff;font-weight:700">{{ computeNodeData.need_updated_count }}</text>
|
||||
<text transform="translate(228 30)" style="font-size:20px;fill:#f43b42;font-weight:700">{{ computeNodeData.abnormal_count }}</text>
|
||||
<text transform="translate(327 30)" style="font-size:20px;fill:#fc8358;font-weight:700">{{ computeNodeData.abnormal_server_count }}</text>
|
||||
</g>
|
||||
</svg>
|
||||
</BorderBox>
|
||||
</template>
|
||||
|
||||
<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";
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
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 })
|
||||
|
||||
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 computeNodeData:{[k:string]: number} = reactive({
|
||||
abnormal_count: 0,
|
||||
abnormal_server_count: 0,
|
||||
busy_server_count: 0,
|
||||
loss_server_count: 0,
|
||||
need_updated_count: 0,
|
||||
node_count: 0,
|
||||
offline_server_count: 0,
|
||||
sever_count: 0
|
||||
})
|
||||
const getData = () => {
|
||||
publicInterface('/dcim/dems/statistic', 'count_node', {}).then(res => {
|
||||
if (res && res.data) {
|
||||
for (const key in computeNodeData) {
|
||||
computeNodeData[key] = res.data[key]
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
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>
|
||||
.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: 60px;
|
||||
}
|
||||
.right{
|
||||
margin-left: 10px;
|
||||
.label{
|
||||
color: #fff;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.value{
|
||||
color: #0ff;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
font-size: 20px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
.leftRed{
|
||||
color: #f43b42;
|
||||
}
|
||||
.rightRed{
|
||||
.value{
|
||||
color: #f43b42;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,12 @@
|
||||
<template>
|
||||
<div :style="getStyle(borderRadius)">
|
||||
<BorderBox :title="props.chartConfig.customData.title">
|
||||
<div ref="echart7" class="box-5-item" style="width: 50%"></div>
|
||||
<v-chart
|
||||
ref="vChartRef"
|
||||
:option="option"
|
||||
:manual-update="false"
|
||||
:update-options="{
|
||||
replaceMerge: ['series', 'xAxis']
|
||||
replaceMerge: ['series', 'xAxis', 'yAxis']
|
||||
}"
|
||||
autoresize
|
||||
style="overflow: visible;width: 50%"
|
||||
@ -20,16 +19,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { PropType, shallowReactive, watch, toRefs, reactive, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { requireErrorImg } from '@/utils'
|
||||
import { useChartDataFetch } from '@/hooks'
|
||||
import { PropType, watch, toRefs, reactive, onMounted, onUnmounted, nextTick, ref } from 'vue'
|
||||
import {isPreview} from '@/utils'
|
||||
import { CreateComponentType } from '@/packages/index.d'
|
||||
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
|
||||
import moment from 'moment'
|
||||
import BorderBox from '../components/BorderBox.vue'
|
||||
import SvgAll from './Svg.vue'
|
||||
import {RequestHttpIntervalEnum} from "@/enums/httpEnum";
|
||||
import {postMessageToParent, useGetMessageByParent} from '@/utils/utils'
|
||||
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: {
|
||||
@ -39,7 +38,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
Object.assign(props.chartConfig.attr, {w: 380, h: 250})
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
if(!props.chartConfig.request.requestInterval) 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)
|
||||
@ -64,43 +63,269 @@ const nameObj = reactive({
|
||||
secondary: 0,
|
||||
record: 0
|
||||
},
|
||||
alarmLevels: []
|
||||
alarmLevels: [],
|
||||
urgentColor: '#cb3f3f',
|
||||
seriousColor: '#d87855',
|
||||
importantColor: '#dab42e',
|
||||
commonColor: '#47acea',
|
||||
eventColor: '#4fbadb',
|
||||
})
|
||||
|
||||
const option = reactive({
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
postMessageToParent({type: 'getStore', data: 'user'})
|
||||
// const userStore = reactive({})
|
||||
const {getMessageByParent} = useGetMessageByParent()
|
||||
getMessageByParent('getStore', (e) => {
|
||||
console.log(e)
|
||||
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
|
||||
}
|
||||
|
||||
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].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>
|
||||
.Theme1{
|
||||
position: relative;
|
||||
.full-screen-btn {
|
||||
border: #4396fd 1px solid;
|
||||
border-radius: 3px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 3px 10px;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 9.6%;
|
||||
color: #4396fd;
|
||||
font-size: 14px;
|
||||
.full-screen {
|
||||
font-size: 16px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -0,0 +1,25 @@
|
||||
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
|
||||
{
|
||||
public key = RealTimeEventConfig.key
|
||||
public chartConfig = cloneDeep(RealTimeEventConfig)
|
||||
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 RealTimeEventConfig: ConfigType = {
|
||||
key: 'RealTimeEvent',
|
||||
chartKey: 'VRealTimeEvent',
|
||||
conKey: 'VCRealTimeEvent',
|
||||
// VCD开头
|
||||
conDataKey: 'VCDRealTimeEvent',
|
||||
title: '实时事件',
|
||||
category: ChatCategoryEnum.CUSTOMCOMPONENTS,
|
||||
categoryName: ChatCategoryEnumName.CUSTOMCOMPONENTS,
|
||||
package: PackagesCategoryEnum.CUSTOMCOMPONENTS,
|
||||
chartFrame: ChartFrameEnum.COMMON,
|
||||
image: 'RealTimeEvent.png'
|
||||
}
|
@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<BorderBox ref="refBorderBox" :title="props.chartConfig.customData.title" :select1="select1" :select2="select2" :style="getStyle(borderRadius)" style="overflow: visible">
|
||||
<div class="itemBox">
|
||||
<div class="item" v-for="(item, i) in tableData" :key="i">
|
||||
<n-checkbox class="mr10" size="small"/>
|
||||
<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 style="flex: 1"></div>
|
||||
<div class="mr10" style="color: #B5BAC3;">{{ moment(item.generate_time).format('yyyy-MM-DD HH:mm:ss') }}</div>
|
||||
<LocationIcon class="mr10" style="width: 20px;height: 20px;color: #4196ff;"/>
|
||||
<CheckCircleOutlinedIcon v-if="item.confirm_status === 'not'" style="width: 20px;height: 20px;color: #4196ff;"/>
|
||||
<div v-else style="width: 20px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</BorderBox>
|
||||
</template>
|
||||
|
||||
<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/BorderBoxV2.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";
|
||||
import {icon} from '@/plugins/icon'
|
||||
|
||||
const { LocationIcon } = icon.carbon
|
||||
const { CheckCircleOutlinedIcon } = icon.material
|
||||
|
||||
const props = defineProps({
|
||||
chartConfig: {
|
||||
type: Object as PropType<CreateComponentType>,
|
||||
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 })
|
||||
|
||||
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' },
|
||||
]
|
||||
})
|
||||
type tableDataType = {
|
||||
id: number,
|
||||
content: string,
|
||||
generate_time: string,
|
||||
checked: boolean,
|
||||
confirm_status: 'ok' | 'not',
|
||||
level: number,
|
||||
color1: string,
|
||||
color2: string,
|
||||
}[]
|
||||
let tableData:tableDataType = reactive([])
|
||||
let checkAll = ref(false)
|
||||
const refBorderBox = ref(null)
|
||||
const getData = () => {
|
||||
console.log(refBorderBox.value)
|
||||
const queryModel = {
|
||||
condition: {
|
||||
id: null,
|
||||
levels: select1.value,
|
||||
confirm_statuss: select2.value,
|
||||
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) {
|
||||
const lastTableData = [...tableData]
|
||||
let arr = res.data['item'].map((e:any) => ({
|
||||
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,
|
||||
}))
|
||||
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
|
||||
}
|
||||
})
|
||||
}
|
||||
arr = arr.concat(Array(10).fill({}).map(_ => ({
|
||||
id: 1234,
|
||||
content: '1234',
|
||||
generate_time: moment().format('x'),
|
||||
level: 2,
|
||||
checked: false,
|
||||
confirm_status: 'ok',
|
||||
color1: 'green',
|
||||
color2: 'green',
|
||||
})))
|
||||
tableData.splice(0, tableData.length, ...arr)
|
||||
console.log(tableData)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
.itemBox{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
.item{
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 10px;
|
||||
margin: 3px 0;
|
||||
background: rgba(65,150,255,.05);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -38,7 +38,7 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
Object.assign(props.chartConfig.attr, { w: 380, h: 250 })
|
||||
Object.assign(props.chartConfig.request, { requestInterval: 15, requestIntervalUnit: RequestHttpIntervalEnum.SECOND })
|
||||
if(!props.chartConfig.request.requestInterval) 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)
|
||||
|
@ -22,7 +22,7 @@ const { title } = toRefs(props)
|
||||
background: rgba(65,150,255,.04);
|
||||
.title{
|
||||
position: relative;
|
||||
padding-left: 20px;
|
||||
padding: 0 20px;
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
font-size: 16px;
|
||||
|
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<BorderBox>
|
||||
<template #title>
|
||||
<div class="titleBox">
|
||||
<div class="mr10">{{title}}</div>
|
||||
<n-checkbox v-model:checked="checkAll" size="small" class="mr10">全选</n-checkbox>
|
||||
<n-button strong size="tiny" color="rgba(36,197,231,.5)" text-color="#fff" class="button">
|
||||
<template #icon><AssignmentTurnedInRoundIcon/></template>
|
||||
批量确认
|
||||
</n-button>
|
||||
<div style="flex: 1"></div>
|
||||
<n-checkbox-group v-model:value="select1.value" 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-model:value="select2.value" 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">更多>></div>
|
||||
</div>
|
||||
</template>
|
||||
<template #default>
|
||||
<slot></slot>
|
||||
</template>
|
||||
</BorderBox>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, toRefs } from 'vue'
|
||||
import BorderBox from './BorderBox.vue'
|
||||
import { icon } from '@/plugins/icon'
|
||||
|
||||
const { AssignmentTurnedInRoundIcon } = icon.material
|
||||
|
||||
|
||||
const props = defineProps(['title', 'select1', 'select2'])
|
||||
|
||||
const { select1, select2 } = toRefs(props)
|
||||
|
||||
const checkAll = ref(false)
|
||||
|
||||
// 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;
|
||||
}
|
||||
.titleBox{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.more{
|
||||
color: #409eff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -3,5 +3,15 @@ import { ComprehensivePUEConfig } from './ComprehensivePUE'
|
||||
import { DeviceAlarmOverviewConfig } from './DeviceAlarmOverview'
|
||||
import { RealTimeTrafficConfig } from './RealTimeTraffic'
|
||||
import { RealTimeAlarmStatisticsConfig } from './RealTimeAlarmStatistics'
|
||||
import { OverviewOfComputingNodesConfig } from './OverviewOfComputingNodes'
|
||||
import { RealTimeEventConfig } from './RealTimeEvent'
|
||||
|
||||
export default [ Theme1Config, ComprehensivePUEConfig, DeviceAlarmOverviewConfig, RealTimeTrafficConfig, RealTimeAlarmStatisticsConfig ]
|
||||
export default [
|
||||
Theme1Config,
|
||||
ComprehensivePUEConfig,
|
||||
DeviceAlarmOverviewConfig,
|
||||
RealTimeTrafficConfig,
|
||||
RealTimeAlarmStatisticsConfig,
|
||||
OverviewOfComputingNodesConfig,
|
||||
RealTimeEventConfig
|
||||
]
|
||||
|
@ -105,12 +105,18 @@ import {
|
||||
FilterEdit as FilterEditIcon,
|
||||
Laptop as LaptopIcon,
|
||||
AreaCustom as AreaCustomIcon,
|
||||
Location as LocationIcon
|
||||
} from '@vicons/carbon'
|
||||
|
||||
import {
|
||||
Apps20Regular as Apps20RegularIcon
|
||||
} from '@vicons/fluent'
|
||||
|
||||
import {
|
||||
AssignmentTurnedInRound as AssignmentTurnedInRoundIcon,
|
||||
CheckCircleOutlined as CheckCircleOutlinedIcon
|
||||
} from '@vicons/material'
|
||||
|
||||
const ionicons5 = {
|
||||
// 新增
|
||||
AddIcon,
|
||||
@ -311,6 +317,8 @@ const carbon = {
|
||||
LaptopIcon,
|
||||
// 自定义
|
||||
AreaCustomIcon,
|
||||
// 地点
|
||||
LocationIcon,
|
||||
}
|
||||
|
||||
const fluent = {
|
||||
@ -318,10 +326,18 @@ const fluent = {
|
||||
Apps20RegularIcon
|
||||
}
|
||||
|
||||
const material = {
|
||||
// 批量确认
|
||||
AssignmentTurnedInRoundIcon,
|
||||
// 圆圈 勾
|
||||
CheckCircleOutlinedIcon
|
||||
}
|
||||
|
||||
// https://www.xicons.org/#/ 还有很多
|
||||
|
||||
export const icon = {
|
||||
ionicons5,
|
||||
carbon,
|
||||
fluent
|
||||
fluent,
|
||||
material
|
||||
}
|
||||
|
24
src/store/modules/originStore/originStore.ts
Normal file
24
src/store/modules/originStore/originStore.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { cloneDeep } from 'lodash'
|
||||
|
||||
export const useOriginStore = defineStore({
|
||||
id: 'useOriginStore',
|
||||
state: () => ({
|
||||
originStore: {}
|
||||
}),
|
||||
getters: {
|
||||
getOriginStore():{[k:string]: any} {
|
||||
return this.originStore
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setOriginStore(originStore: {[k:string]: any}, merge: boolean = true) {
|
||||
if(merge) {
|
||||
this.originStore = cloneDeep(originStore)
|
||||
}
|
||||
else {
|
||||
Object.assign(this.originStore, originStore)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
@ -356,25 +356,25 @@ export const addWindowUnload = () => {
|
||||
/**
|
||||
* 向父页面发送消息
|
||||
*/
|
||||
export const postMessageToParent = (obj = {}) => {
|
||||
const routerStore:any = useRouterStore()
|
||||
if (routerStore && routerStore.getCallByParent) {
|
||||
// 获取父页面的 window 对象
|
||||
var parentWindow = window.parent;
|
||||
const message = {
|
||||
// 属于哪个页面
|
||||
page: 'customLargeScreen',
|
||||
// 属于什么类型
|
||||
// type: 'goHome',
|
||||
...obj
|
||||
}
|
||||
parentWindow.postMessage(JSON.stringify(message), '*');
|
||||
return
|
||||
}
|
||||
}
|
||||
// export const postMessageToParent = (obj = {}) => {
|
||||
// const routerStore:any = useRouterStore()
|
||||
// if (routerStore && routerStore.getCallByParent) {
|
||||
// // 获取父页面的 window 对象
|
||||
// var parentWindow = window.parent;
|
||||
// const message = {
|
||||
// // 属于哪个页面
|
||||
// page: 'customLargeScreen',
|
||||
// // 属于什么类型
|
||||
// // type: 'goHome',
|
||||
// ...obj
|
||||
// }
|
||||
// parentWindow.postMessage(JSON.stringify(message), '*');
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 从父页面接收消息
|
||||
* 从父页面发送并接收消息
|
||||
*/
|
||||
export const useGetMessageByParent = () => {
|
||||
const getMessageByParent = (type = '', cb = (e:any) => {}) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user