冀北问题修改
This commit is contained in:
@@ -54,6 +54,24 @@
|
||||
<div class="content unicode" style="display: block;">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">停运事件管理</div>
|
||||
<div class="code-name">&#xe65d;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">在运设备</div>
|
||||
<div class="code-name">&#xe604;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">异常类_14非智能表在运异常</div>
|
||||
<div class="code-name">&#xe666;</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont"></span>
|
||||
<div class="name">综合评价</div>
|
||||
@@ -234,9 +252,9 @@
|
||||
<pre><code class="language-css"
|
||||
>@font-face {
|
||||
font-family: 'iconfont';
|
||||
src: url('iconfont.woff2?t=1744179175277') format('woff2'),
|
||||
url('iconfont.woff?t=1744179175277') format('woff'),
|
||||
url('iconfont.ttf?t=1744179175277') format('truetype');
|
||||
src: url('iconfont.woff2?t=1764826411334') format('woff2'),
|
||||
url('iconfont.woff?t=1764826411334') format('woff'),
|
||||
url('iconfont.ttf?t=1764826411334') format('truetype');
|
||||
}
|
||||
</code></pre>
|
||||
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
|
||||
@@ -262,6 +280,33 @@
|
||||
<div class="content font-class">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-tingyunshijianguanli"></span>
|
||||
<div class="name">
|
||||
停运事件管理
|
||||
</div>
|
||||
<div class="code-name">.icon-tingyunshijianguanli
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-zaiyunshebei"></span>
|
||||
<div class="name">
|
||||
在运设备
|
||||
</div>
|
||||
<div class="code-name">.icon-zaiyunshebei
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-yichanglei_14feizhinengbiaozaiyunyichang"></span>
|
||||
<div class="name">
|
||||
异常类_14非智能表在运异常
|
||||
</div>
|
||||
<div class="code-name">.icon-yichanglei_14feizhinengbiaozaiyunyichang
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<span class="icon iconfont icon-zonghepingjia1"></span>
|
||||
<div class="name">
|
||||
@@ -532,6 +577,30 @@
|
||||
<div class="content symbol">
|
||||
<ul class="icon_lists dib-box">
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-tingyunshijianguanli"></use>
|
||||
</svg>
|
||||
<div class="name">停运事件管理</div>
|
||||
<div class="code-name">#icon-tingyunshijianguanli</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-zaiyunshebei"></use>
|
||||
</svg>
|
||||
<div class="name">在运设备</div>
|
||||
<div class="code-name">#icon-zaiyunshebei</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-yichanglei_14feizhinengbiaozaiyunyichang"></use>
|
||||
</svg>
|
||||
<div class="name">异常类_14非智能表在运异常</div>
|
||||
<div class="code-name">#icon-yichanglei_14feizhinengbiaozaiyunyichang</div>
|
||||
</li>
|
||||
|
||||
<li class="dib">
|
||||
<svg class="icon svg-icon" aria-hidden="true">
|
||||
<use xlink:href="#icon-zonghepingjia1"></use>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 3482754 */
|
||||
src: url('iconfont.woff2?t=1744179175277') format('woff2'),
|
||||
url('iconfont.woff?t=1744179175277') format('woff'),
|
||||
url('iconfont.ttf?t=1744179175277') format('truetype');
|
||||
font-family: 'iconfont';
|
||||
src: url('/src/assets/font/iconfont.woff2?t=1764826411334') format('woff2'),
|
||||
url('/src/assets/font/iconfont.woff?t=1764826411334') format('woff'),
|
||||
url('/src/assets/font/iconfont.ttf?t=1764826411334') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
@@ -13,6 +12,18 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-tingyunshijianguanli:before {
|
||||
content: "\e65d";
|
||||
}
|
||||
|
||||
.icon-zaiyunshebei:before {
|
||||
content: "\e604";
|
||||
}
|
||||
|
||||
.icon-yichanglei_14feizhinengbiaozaiyunyichang:before {
|
||||
content: "\e666";
|
||||
}
|
||||
|
||||
.icon-zonghepingjia1:before {
|
||||
content: "\e82f";
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -5,6 +5,27 @@
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "25458995",
|
||||
"name": "停运事件管理",
|
||||
"font_class": "tingyunshijianguanli",
|
||||
"unicode": "e65d",
|
||||
"unicode_decimal": 58973
|
||||
},
|
||||
{
|
||||
"icon_id": "35341056",
|
||||
"name": "在运设备",
|
||||
"font_class": "zaiyunshebei",
|
||||
"unicode": "e604",
|
||||
"unicode_decimal": 58884
|
||||
},
|
||||
{
|
||||
"icon_id": "22630860",
|
||||
"name": "异常类_14非智能表在运异常",
|
||||
"font_class": "yichanglei_14feizhinengbiaozaiyunyichang",
|
||||
"unicode": "e666",
|
||||
"unicode_decimal": 58982
|
||||
},
|
||||
{
|
||||
"icon_id": "32402696",
|
||||
"name": "综合评价",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -6,7 +6,7 @@
|
||||
</div> -->
|
||||
<TableHeader :showSearch="false">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="日期">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef" :nextFlag="false" :theCurrentTime="true"></DatePicker>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
@@ -1,491 +1,491 @@
|
||||
<template>
|
||||
<div class="panel-tab__content">
|
||||
<el-table :data="elementListenersList" size="small" border>
|
||||
<el-table-column label="序号" width="80px" type="index" />
|
||||
<el-table-column
|
||||
label="事件类型"
|
||||
min-width="80px"
|
||||
show-overflow-tooltip
|
||||
:formatter="(row) => listenerEventTypeObject[row.event]"
|
||||
/>
|
||||
<el-table-column label="事件id" min-width="80px" prop="id" show-overflow-tooltip />
|
||||
<el-table-column
|
||||
label="监听器类型"
|
||||
min-width="80px"
|
||||
show-overflow-tooltip
|
||||
:formatter="(row) => listenerTypeObject[row.listenerType]"
|
||||
/>
|
||||
<el-table-column label="操作" width="90px">
|
||||
<template #default="scope">
|
||||
<el-button size="small" link @click="openListenerForm(scope.row, scope.$index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
size="small"
|
||||
link
|
||||
style="color: #ff4d4f"
|
||||
@click="removeListener(scope.row, scope.$index)"
|
||||
>移除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="element-drawer__button">
|
||||
<XButton
|
||||
size="small"
|
||||
type="primary"
|
||||
preIcon="ep:plus"
|
||||
title="添加监听器"
|
||||
@click="openListenerForm(null)"
|
||||
/>
|
||||
<XButton
|
||||
type="success"
|
||||
preIcon="ep:select"
|
||||
title="选择监听器"
|
||||
size="small"
|
||||
@click="openProcessListenerDialog"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 监听器 编辑/创建 部分 -->
|
||||
<el-drawer
|
||||
v-model="listenerFormModelVisible"
|
||||
title="任务监听器"
|
||||
:size="`${width}px`"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form size="small" :model="listenerForm" label-width="96px" ref="listenerFormRef">
|
||||
<el-form-item
|
||||
label="事件类型"
|
||||
prop="event"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-select v-model="listenerForm.event">
|
||||
<el-option
|
||||
v-for="i in Object.keys(listenerEventTypeObject)"
|
||||
:key="i"
|
||||
:label="listenerEventTypeObject[i]"
|
||||
:value="i"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="监听器ID"
|
||||
prop="id"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerForm.id" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="监听器类型"
|
||||
prop="listenerType"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-select v-model="listenerForm.listenerType">
|
||||
<el-option
|
||||
v-for="i in Object.keys(listenerTypeObject)"
|
||||
:key="i"
|
||||
:label="listenerTypeObject[i]"
|
||||
:value="i"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerForm.listenerType === 'classListener'"
|
||||
label="Java类"
|
||||
prop="class"
|
||||
key="listener-class"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerForm.class" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerForm.listenerType === 'expressionListener'"
|
||||
label="表达式"
|
||||
prop="expression"
|
||||
key="listener-expression"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerForm.expression" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerForm.listenerType === 'delegateExpressionListener'"
|
||||
label="代理表达式"
|
||||
prop="delegateExpression"
|
||||
key="listener-delegate"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerForm.delegateExpression" clearable />
|
||||
</el-form-item>
|
||||
<template v-if="listenerForm.listenerType === 'scriptListener'">
|
||||
<el-form-item
|
||||
label="脚本格式"
|
||||
prop="scriptFormat"
|
||||
key="listener-script-format"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本格式' }"
|
||||
>
|
||||
<el-input v-model="listenerForm.scriptFormat" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="脚本类型"
|
||||
prop="scriptType"
|
||||
key="listener-script-type"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请选择脚本类型' }"
|
||||
>
|
||||
<el-select v-model="listenerForm.scriptType">
|
||||
<el-option label="内联脚本" value="inlineScript" />
|
||||
<el-option label="外部脚本" value="externalScript" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerForm.scriptType === 'inlineScript'"
|
||||
label="脚本内容"
|
||||
prop="value"
|
||||
key="listener-script"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本内容' }"
|
||||
>
|
||||
<el-input v-model="listenerForm.value" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerForm.scriptType === 'externalScript'"
|
||||
label="资源地址"
|
||||
prop="resource"
|
||||
key="listener-resource"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写资源地址' }"
|
||||
>
|
||||
<el-input v-model="listenerForm.resource" clearable />
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-if="listenerForm.event === 'timeout'">
|
||||
<el-form-item label="定时器类型" prop="eventDefinitionType" key="eventDefinitionType">
|
||||
<el-select v-model="listenerForm.eventDefinitionType">
|
||||
<el-option label="日期" value="date" />
|
||||
<el-option label="持续时长" value="duration" />
|
||||
<el-option label="循环" value="cycle" />
|
||||
<el-option label="无" value="null" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="!!listenerForm.eventDefinitionType && listenerForm.eventDefinitionType !== 'null'"
|
||||
label="定时器"
|
||||
prop="eventTimeDefinitions"
|
||||
key="eventTimeDefinitions"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写定时器配置' }"
|
||||
>
|
||||
<el-input v-model="listenerForm.eventTimeDefinitions" clearable />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
|
||||
<el-divider />
|
||||
<p class="listener-filed__title">
|
||||
<span><Icon icon="ep:menu" />注入字段:</span>
|
||||
<el-button size="small" type="primary" @click="openListenerFieldForm(null)"
|
||||
>添加字段</el-button
|
||||
>
|
||||
</p>
|
||||
<el-table
|
||||
:data="fieldsListOfListener"
|
||||
size="small"
|
||||
max-height="240"
|
||||
fit
|
||||
border
|
||||
style="flex: none"
|
||||
>
|
||||
<el-table-column label="序号" width="80px" type="index" />
|
||||
<el-table-column label="字段名称" min-width="100px" prop="name" />
|
||||
<el-table-column
|
||||
label="字段类型"
|
||||
min-width="80px"
|
||||
show-overflow-tooltip
|
||||
:formatter="(row) => fieldTypeObject[row.fieldType]"
|
||||
/>
|
||||
<el-table-column
|
||||
label="字段值/表达式"
|
||||
min-width="100px"
|
||||
show-overflow-tooltip
|
||||
:formatter="(row) => row.string || row.expression"
|
||||
/>
|
||||
<el-table-column label="操作" width="100px">
|
||||
<template #default="scope">
|
||||
<el-button size="small" link @click="openListenerFieldForm(scope.row, scope.$index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
size="small"
|
||||
link
|
||||
style="color: #ff4d4f"
|
||||
@click="removeListenerField(scope.row, scope.$index)"
|
||||
>移除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="element-drawer__button">
|
||||
<el-button size="small" @click="listenerFormModelVisible = false">取 消</el-button>
|
||||
<el-button size="small" type="primary" @click="saveListenerConfig">保 存</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<!-- 注入西段 编辑/创建 部分 -->
|
||||
<el-dialog
|
||||
title="字段配置"
|
||||
v-model="listenerFieldFormModelVisible"
|
||||
width="600px"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
:model="listenerFieldForm"
|
||||
size="small"
|
||||
label-width="96px"
|
||||
ref="listenerFieldFormRef"
|
||||
style="height: 136px"
|
||||
>
|
||||
<el-form-item
|
||||
label="字段名称:"
|
||||
prop="name"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerFieldForm.name" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="字段类型:"
|
||||
prop="fieldType"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-select v-model="listenerFieldForm.fieldType">
|
||||
<el-option
|
||||
v-for="i in Object.keys(fieldTypeObject)"
|
||||
:key="i"
|
||||
:label="fieldTypeObject[i]"
|
||||
:value="i"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerFieldForm.fieldType === 'string'"
|
||||
label="字段值:"
|
||||
prop="string"
|
||||
key="field-string"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerFieldForm.string" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerFieldForm.fieldType === 'expression'"
|
||||
label="表达式:"
|
||||
prop="expression"
|
||||
key="field-expression"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerFieldForm.expression" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button size="small" @click="listenerFieldFormModelVisible = false">取 消</el-button>
|
||||
<el-button size="small" type="primary" @click="saveListenerFiled">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<!-- 选择弹窗 -->
|
||||
<ProcessListenerDialog ref="processListenerDialogRef" @select="selectProcessListener" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { createListenerObject, updateElementExtensions } from '../../utils'
|
||||
import {
|
||||
initListenerForm,
|
||||
initListenerType,
|
||||
eventType,
|
||||
listenerType,
|
||||
fieldType,
|
||||
initListenerForm2
|
||||
} from './utilSelf'
|
||||
import ProcessListenerDialog from '@/components/bpmnProcessDesigner/package/penal/listeners/ProcessListenerDialog.vue'
|
||||
|
||||
defineOptions({ name: 'UserTaskListeners' })
|
||||
|
||||
const props = defineProps({
|
||||
id: String,
|
||||
type: String
|
||||
})
|
||||
const prefix = inject('prefix')
|
||||
const width = inject('width')
|
||||
const elementListenersList = ref<any[]>([])
|
||||
const listenerEventTypeObject = ref(eventType)
|
||||
const listenerTypeObject = ref(listenerType)
|
||||
const listenerFormModelVisible = ref(false)
|
||||
const listenerForm = ref<any>({})
|
||||
const fieldTypeObject = ref(fieldType)
|
||||
const fieldsListOfListener = ref<any[]>([])
|
||||
const listenerFieldFormModelVisible = ref(false) // 监听器 注入字段表单弹窗 显示状态
|
||||
const editingListenerIndex = ref(-1) // 监听器所在下标,-1 为新增
|
||||
const editingListenerFieldIndex = ref(-1) // 字段所在下标,-1 为新增
|
||||
const listenerFieldForm = ref<any>({}) // 监听器 注入字段 详情表单
|
||||
const bpmnElement = ref()
|
||||
const bpmnElementListeners = ref()
|
||||
const otherExtensionList = ref()
|
||||
const listenerFormRef = ref()
|
||||
const listenerFieldFormRef = ref()
|
||||
const bpmnInstances = () => (window as any)?.bpmnInstances
|
||||
|
||||
const resetListenersList = () => {
|
||||
// console.log(
|
||||
// bpmnInstances().bpmnElement,
|
||||
// 'window.bpmnInstances.bpmnElementwindow.bpmnInstances.bpmnElementwindow.bpmnInstances.bpmnElementwindow.bpmnInstances.bpmnElementwindow.bpmnInstances.bpmnElementwindow.bpmnInstances.bpmnElement'
|
||||
// )
|
||||
bpmnElement.value = bpmnInstances().bpmnElement
|
||||
otherExtensionList.value = []
|
||||
bpmnElementListeners.value =
|
||||
bpmnElement.value.businessObject?.extensionElements?.values.filter(
|
||||
(ex) => ex.$type === `${prefix}:TaskListener`
|
||||
) ?? []
|
||||
elementListenersList.value = bpmnElementListeners.value.map((listener) =>
|
||||
initListenerType(listener)
|
||||
)
|
||||
}
|
||||
const openListenerForm = (listener, index?) => {
|
||||
if (listener) {
|
||||
listenerForm.value = initListenerForm(listener)
|
||||
editingListenerIndex.value = index
|
||||
} else {
|
||||
listenerForm.value = {}
|
||||
editingListenerIndex.value = -1 // 标记为新增
|
||||
}
|
||||
if (listener && listener.fields) {
|
||||
fieldsListOfListener.value = listener.fields.map((field) => ({
|
||||
...field,
|
||||
fieldType: field.string ? 'string' : 'expression'
|
||||
}))
|
||||
} else {
|
||||
fieldsListOfListener.value = []
|
||||
listenerForm.value['fields'] = []
|
||||
}
|
||||
// 打开侧边栏并清楚验证状态
|
||||
listenerFormModelVisible.value = true
|
||||
nextTick(() => {
|
||||
if (listenerFormRef.value) listenerFormRef.value.clearValidate()
|
||||
})
|
||||
}
|
||||
// 移除监听器
|
||||
const removeListener = (listener, index?) => {
|
||||
console.log(listener, 'listener')
|
||||
ElMessageBox.confirm('确认移除该监听器吗?', '提示', {
|
||||
confirmButtonText: '确 认',
|
||||
cancelButtonText: '取 消'
|
||||
})
|
||||
.then(() => {
|
||||
bpmnElementListeners.value.splice(index, 1)
|
||||
elementListenersList.value.splice(index, 1)
|
||||
updateElementExtensions(
|
||||
bpmnElement.value,
|
||||
otherExtensionList.value.concat(bpmnElementListeners.value)
|
||||
)
|
||||
})
|
||||
.catch(() => console.info('操作取消'))
|
||||
}
|
||||
// 保存监听器
|
||||
const saveListenerConfig = async () => {
|
||||
let validateStatus = await listenerFormRef.value.validate()
|
||||
if (!validateStatus) return // 验证不通过直接返回
|
||||
const listenerObject = createListenerObject(listenerForm.value, true, prefix)
|
||||
if (editingListenerIndex.value === -1) {
|
||||
bpmnElementListeners.value.push(listenerObject)
|
||||
elementListenersList.value.push(listenerForm.value)
|
||||
} else {
|
||||
bpmnElementListeners.value.splice(editingListenerIndex.value, 1, listenerObject)
|
||||
elementListenersList.value.splice(editingListenerIndex.value, 1, listenerForm.value)
|
||||
}
|
||||
// 保存其他配置
|
||||
otherExtensionList.value =
|
||||
bpmnElement.value.businessObject?.extensionElements?.values?.filter(
|
||||
(ex) => ex.$type !== `${prefix}:TaskListener`
|
||||
) ?? []
|
||||
updateElementExtensions(
|
||||
bpmnElement.value,
|
||||
otherExtensionList.value.concat(bpmnElementListeners.value)
|
||||
)
|
||||
// 4. 隐藏侧边栏
|
||||
listenerFormModelVisible.value = false
|
||||
listenerForm.value = {}
|
||||
}
|
||||
// 打开监听器字段编辑弹窗
|
||||
const openListenerFieldForm = (field, index?) => {
|
||||
listenerFieldForm.value = field ? JSON.parse(JSON.stringify(field)) : {}
|
||||
editingListenerFieldIndex.value = field ? index : -1
|
||||
listenerFieldFormModelVisible.value = true
|
||||
nextTick(() => {
|
||||
if (listenerFieldFormRef.value) listenerFieldFormRef.value.clearValidate()
|
||||
})
|
||||
}
|
||||
// 保存监听器注入字段
|
||||
const saveListenerFiled = async () => {
|
||||
let validateStatus = await listenerFieldFormRef.value.validate()
|
||||
if (!validateStatus) return // 验证不通过直接返回
|
||||
if (editingListenerFieldIndex.value === -1) {
|
||||
fieldsListOfListener.value.push(listenerFieldForm.value)
|
||||
listenerForm.value.fields.push(listenerFieldForm.value)
|
||||
} else {
|
||||
fieldsListOfListener.value.splice(editingListenerFieldIndex.value, 1, listenerFieldForm.value)
|
||||
listenerForm.value.fields.splice(editingListenerFieldIndex.value, 1, listenerFieldForm.value)
|
||||
}
|
||||
listenerFieldFormModelVisible.value = false
|
||||
nextTick(() => {
|
||||
listenerFieldForm.value = {}
|
||||
})
|
||||
}
|
||||
// 移除监听器字段
|
||||
const removeListenerField = (field, index) => {
|
||||
console.log(field, 'field')
|
||||
ElMessageBox.confirm('确认移除该字段吗?', '提示', {
|
||||
confirmButtonText: '确 认',
|
||||
cancelButtonText: '取 消'
|
||||
})
|
||||
.then(() => {
|
||||
fieldsListOfListener.value.splice(index, 1)
|
||||
listenerForm.value.fields.splice(index, 1)
|
||||
})
|
||||
.catch(() => console.info('操作取消'))
|
||||
}
|
||||
|
||||
// 打开监听器弹窗
|
||||
const processListenerDialogRef = ref()
|
||||
const openProcessListenerDialog = async () => {
|
||||
processListenerDialogRef.value.open('task')
|
||||
}
|
||||
const selectProcessListener = (listener) => {
|
||||
const listenerForm = initListenerForm2(listener)
|
||||
const listenerObject = createListenerObject(listenerForm, true, prefix)
|
||||
bpmnElementListeners.value.push(listenerObject)
|
||||
elementListenersList.value.push(listenerForm)
|
||||
|
||||
// 保存其他配置
|
||||
otherExtensionList.value =
|
||||
bpmnElement.value.businessObject?.extensionElements?.values?.filter(
|
||||
(ex) => ex.$type !== `${prefix}:TaskListener`
|
||||
) ?? []
|
||||
updateElementExtensions(
|
||||
bpmnElement.value,
|
||||
otherExtensionList.value.concat(bpmnElementListeners.value)
|
||||
)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.id,
|
||||
(val) => {
|
||||
val &&
|
||||
val.length &&
|
||||
nextTick(() => {
|
||||
resetListenersList()
|
||||
})
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
</script>
|
||||
<template>
|
||||
<div class="panel-tab__content">
|
||||
<el-table :data="elementListenersList" size="small" border>
|
||||
<el-table-column label="序号" width="80px" type="index" />
|
||||
<el-table-column
|
||||
label="事件类型"
|
||||
min-width="80px"
|
||||
show-overflow-tooltip
|
||||
:formatter="(row) => listenerEventTypeObject[row.event]"
|
||||
/>
|
||||
<el-table-column label="事件id" min-width="80px" prop="id" show-overflow-tooltip />
|
||||
<el-table-column
|
||||
label="监听器类型"
|
||||
min-width="80px"
|
||||
show-overflow-tooltip
|
||||
:formatter="(row) => listenerTypeObject[row.listenerType]"
|
||||
/>
|
||||
<el-table-column label="操作" width="90px">
|
||||
<template #default="scope">
|
||||
<el-button size="small" link @click="openListenerForm(scope.row, scope.$index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
size="small"
|
||||
link
|
||||
style="color: #ff4d4f"
|
||||
@click="removeListener(scope.row, scope.$index)"
|
||||
>移除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="element-drawer__button">
|
||||
<XButton
|
||||
size="small"
|
||||
type="primary"
|
||||
preIcon="ep:plus"
|
||||
title="添加监听器"
|
||||
@click="openListenerForm(null)"
|
||||
/>
|
||||
<XButton
|
||||
type="success"
|
||||
preIcon="ep:select"
|
||||
title="选择监听器"
|
||||
size="small"
|
||||
@click="openProcessListenerDialog"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 监听器 编辑/创建 部分 -->
|
||||
<el-drawer
|
||||
v-model="listenerFormModelVisible"
|
||||
title="任务监听器"
|
||||
:size="`${width}px`"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form size="small" :model="listenerForm" label-width="96px" ref="listenerFormRef">
|
||||
<el-form-item
|
||||
label="事件类型"
|
||||
prop="event"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-select v-model="listenerForm.event">
|
||||
<el-option
|
||||
v-for="i in Object.keys(listenerEventTypeObject)"
|
||||
:key="i"
|
||||
:label="listenerEventTypeObject[i]"
|
||||
:value="i"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="监听器ID"
|
||||
prop="id"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerForm.id" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="监听器类型"
|
||||
prop="listenerType"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-select v-model="listenerForm.listenerType">
|
||||
<el-option
|
||||
v-for="i in Object.keys(listenerTypeObject)"
|
||||
:key="i"
|
||||
:label="listenerTypeObject[i]"
|
||||
:value="i"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerForm.listenerType === 'classListener'"
|
||||
label="Java类"
|
||||
prop="class"
|
||||
key="listener-class"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerForm.class" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerForm.listenerType === 'expressionListener'"
|
||||
label="表达式"
|
||||
prop="expression"
|
||||
key="listener-expression"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerForm.expression" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerForm.listenerType === 'delegateExpressionListener'"
|
||||
label="代理表达式"
|
||||
prop="delegateExpression"
|
||||
key="listener-delegate"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerForm.delegateExpression" clearable />
|
||||
</el-form-item>
|
||||
<template v-if="listenerForm.listenerType === 'scriptListener'">
|
||||
<el-form-item
|
||||
label="脚本格式"
|
||||
prop="scriptFormat"
|
||||
key="listener-script-format"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本格式' }"
|
||||
>
|
||||
<el-input v-model="listenerForm.scriptFormat" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="脚本类型"
|
||||
prop="scriptType"
|
||||
key="listener-script-type"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请选择脚本类型' }"
|
||||
>
|
||||
<el-select v-model="listenerForm.scriptType">
|
||||
<el-option label="内联脚本" value="inlineScript" />
|
||||
<el-option label="外部脚本" value="externalScript" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerForm.scriptType === 'inlineScript'"
|
||||
label="脚本内容"
|
||||
prop="value"
|
||||
key="listener-script"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写脚本内容' }"
|
||||
>
|
||||
<el-input v-model="listenerForm.value" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerForm.scriptType === 'externalScript'"
|
||||
label="资源地址"
|
||||
prop="resource"
|
||||
key="listener-resource"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写资源地址' }"
|
||||
>
|
||||
<el-input v-model="listenerForm.resource" clearable />
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-if="listenerForm.event === 'timeout'">
|
||||
<el-form-item label="定时器类型" prop="eventDefinitionType" key="eventDefinitionType">
|
||||
<el-select v-model="listenerForm.eventDefinitionType">
|
||||
<el-option label="统计时间" value="date" />
|
||||
<el-option label="持续时长" value="duration" />
|
||||
<el-option label="循环" value="cycle" />
|
||||
<el-option label="无" value="null" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="!!listenerForm.eventDefinitionType && listenerForm.eventDefinitionType !== 'null'"
|
||||
label="定时器"
|
||||
prop="eventTimeDefinitions"
|
||||
key="eventTimeDefinitions"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'], message: '请填写定时器配置' }"
|
||||
>
|
||||
<el-input v-model="listenerForm.eventTimeDefinitions" clearable />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
|
||||
<el-divider />
|
||||
<p class="listener-filed__title">
|
||||
<span><Icon icon="ep:menu" />注入字段:</span>
|
||||
<el-button size="small" type="primary" @click="openListenerFieldForm(null)"
|
||||
>添加字段</el-button
|
||||
>
|
||||
</p>
|
||||
<el-table
|
||||
:data="fieldsListOfListener"
|
||||
size="small"
|
||||
max-height="240"
|
||||
fit
|
||||
border
|
||||
style="flex: none"
|
||||
>
|
||||
<el-table-column label="序号" width="80px" type="index" />
|
||||
<el-table-column label="字段名称" min-width="100px" prop="name" />
|
||||
<el-table-column
|
||||
label="字段类型"
|
||||
min-width="80px"
|
||||
show-overflow-tooltip
|
||||
:formatter="(row) => fieldTypeObject[row.fieldType]"
|
||||
/>
|
||||
<el-table-column
|
||||
label="字段值/表达式"
|
||||
min-width="100px"
|
||||
show-overflow-tooltip
|
||||
:formatter="(row) => row.string || row.expression"
|
||||
/>
|
||||
<el-table-column label="操作" width="100px">
|
||||
<template #default="scope">
|
||||
<el-button size="small" link @click="openListenerFieldForm(scope.row, scope.$index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-divider direction="vertical" />
|
||||
<el-button
|
||||
size="small"
|
||||
link
|
||||
style="color: #ff4d4f"
|
||||
@click="removeListenerField(scope.row, scope.$index)"
|
||||
>移除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="element-drawer__button">
|
||||
<el-button size="small" @click="listenerFormModelVisible = false">取 消</el-button>
|
||||
<el-button size="small" type="primary" @click="saveListenerConfig">保 存</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<!-- 注入西段 编辑/创建 部分 -->
|
||||
<el-dialog
|
||||
title="字段配置"
|
||||
v-model="listenerFieldFormModelVisible"
|
||||
width="600px"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form
|
||||
:model="listenerFieldForm"
|
||||
size="small"
|
||||
label-width="96px"
|
||||
ref="listenerFieldFormRef"
|
||||
style="height: 136px"
|
||||
>
|
||||
<el-form-item
|
||||
label="字段名称:"
|
||||
prop="name"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerFieldForm.name" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="字段类型:"
|
||||
prop="fieldType"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-select v-model="listenerFieldForm.fieldType">
|
||||
<el-option
|
||||
v-for="i in Object.keys(fieldTypeObject)"
|
||||
:key="i"
|
||||
:label="fieldTypeObject[i]"
|
||||
:value="i"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerFieldForm.fieldType === 'string'"
|
||||
label="字段值:"
|
||||
prop="string"
|
||||
key="field-string"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerFieldForm.string" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="listenerFieldForm.fieldType === 'expression'"
|
||||
label="表达式:"
|
||||
prop="expression"
|
||||
key="field-expression"
|
||||
:rules="{ required: true, trigger: ['blur', 'change'] }"
|
||||
>
|
||||
<el-input v-model="listenerFieldForm.expression" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button size="small" @click="listenerFieldFormModelVisible = false">取 消</el-button>
|
||||
<el-button size="small" type="primary" @click="saveListenerFiled">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<!-- 选择弹窗 -->
|
||||
<ProcessListenerDialog ref="processListenerDialogRef" @select="selectProcessListener" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ElMessageBox } from 'element-plus'
|
||||
import { createListenerObject, updateElementExtensions } from '../../utils'
|
||||
import {
|
||||
initListenerForm,
|
||||
initListenerType,
|
||||
eventType,
|
||||
listenerType,
|
||||
fieldType,
|
||||
initListenerForm2
|
||||
} from './utilSelf'
|
||||
import ProcessListenerDialog from '@/components/bpmnProcessDesigner/package/penal/listeners/ProcessListenerDialog.vue'
|
||||
|
||||
defineOptions({ name: 'UserTaskListeners' })
|
||||
|
||||
const props = defineProps({
|
||||
id: String,
|
||||
type: String
|
||||
})
|
||||
const prefix = inject('prefix')
|
||||
const width = inject('width')
|
||||
const elementListenersList = ref<any[]>([])
|
||||
const listenerEventTypeObject = ref(eventType)
|
||||
const listenerTypeObject = ref(listenerType)
|
||||
const listenerFormModelVisible = ref(false)
|
||||
const listenerForm = ref<any>({})
|
||||
const fieldTypeObject = ref(fieldType)
|
||||
const fieldsListOfListener = ref<any[]>([])
|
||||
const listenerFieldFormModelVisible = ref(false) // 监听器 注入字段表单弹窗 显示状态
|
||||
const editingListenerIndex = ref(-1) // 监听器所在下标,-1 为新增
|
||||
const editingListenerFieldIndex = ref(-1) // 字段所在下标,-1 为新增
|
||||
const listenerFieldForm = ref<any>({}) // 监听器 注入字段 详情表单
|
||||
const bpmnElement = ref()
|
||||
const bpmnElementListeners = ref()
|
||||
const otherExtensionList = ref()
|
||||
const listenerFormRef = ref()
|
||||
const listenerFieldFormRef = ref()
|
||||
const bpmnInstances = () => (window as any)?.bpmnInstances
|
||||
|
||||
const resetListenersList = () => {
|
||||
// console.log(
|
||||
// bpmnInstances().bpmnElement,
|
||||
// 'window.bpmnInstances.bpmnElementwindow.bpmnInstances.bpmnElementwindow.bpmnInstances.bpmnElementwindow.bpmnInstances.bpmnElementwindow.bpmnInstances.bpmnElementwindow.bpmnInstances.bpmnElement'
|
||||
// )
|
||||
bpmnElement.value = bpmnInstances().bpmnElement
|
||||
otherExtensionList.value = []
|
||||
bpmnElementListeners.value =
|
||||
bpmnElement.value.businessObject?.extensionElements?.values.filter(
|
||||
(ex) => ex.$type === `${prefix}:TaskListener`
|
||||
) ?? []
|
||||
elementListenersList.value = bpmnElementListeners.value.map((listener) =>
|
||||
initListenerType(listener)
|
||||
)
|
||||
}
|
||||
const openListenerForm = (listener, index?) => {
|
||||
if (listener) {
|
||||
listenerForm.value = initListenerForm(listener)
|
||||
editingListenerIndex.value = index
|
||||
} else {
|
||||
listenerForm.value = {}
|
||||
editingListenerIndex.value = -1 // 标记为新增
|
||||
}
|
||||
if (listener && listener.fields) {
|
||||
fieldsListOfListener.value = listener.fields.map((field) => ({
|
||||
...field,
|
||||
fieldType: field.string ? 'string' : 'expression'
|
||||
}))
|
||||
} else {
|
||||
fieldsListOfListener.value = []
|
||||
listenerForm.value['fields'] = []
|
||||
}
|
||||
// 打开侧边栏并清楚验证状态
|
||||
listenerFormModelVisible.value = true
|
||||
nextTick(() => {
|
||||
if (listenerFormRef.value) listenerFormRef.value.clearValidate()
|
||||
})
|
||||
}
|
||||
// 移除监听器
|
||||
const removeListener = (listener, index?) => {
|
||||
console.log(listener, 'listener')
|
||||
ElMessageBox.confirm('确认移除该监听器吗?', '提示', {
|
||||
confirmButtonText: '确 认',
|
||||
cancelButtonText: '取 消'
|
||||
})
|
||||
.then(() => {
|
||||
bpmnElementListeners.value.splice(index, 1)
|
||||
elementListenersList.value.splice(index, 1)
|
||||
updateElementExtensions(
|
||||
bpmnElement.value,
|
||||
otherExtensionList.value.concat(bpmnElementListeners.value)
|
||||
)
|
||||
})
|
||||
.catch(() => console.info('操作取消'))
|
||||
}
|
||||
// 保存监听器
|
||||
const saveListenerConfig = async () => {
|
||||
let validateStatus = await listenerFormRef.value.validate()
|
||||
if (!validateStatus) return // 验证不通过直接返回
|
||||
const listenerObject = createListenerObject(listenerForm.value, true, prefix)
|
||||
if (editingListenerIndex.value === -1) {
|
||||
bpmnElementListeners.value.push(listenerObject)
|
||||
elementListenersList.value.push(listenerForm.value)
|
||||
} else {
|
||||
bpmnElementListeners.value.splice(editingListenerIndex.value, 1, listenerObject)
|
||||
elementListenersList.value.splice(editingListenerIndex.value, 1, listenerForm.value)
|
||||
}
|
||||
// 保存其他配置
|
||||
otherExtensionList.value =
|
||||
bpmnElement.value.businessObject?.extensionElements?.values?.filter(
|
||||
(ex) => ex.$type !== `${prefix}:TaskListener`
|
||||
) ?? []
|
||||
updateElementExtensions(
|
||||
bpmnElement.value,
|
||||
otherExtensionList.value.concat(bpmnElementListeners.value)
|
||||
)
|
||||
// 4. 隐藏侧边栏
|
||||
listenerFormModelVisible.value = false
|
||||
listenerForm.value = {}
|
||||
}
|
||||
// 打开监听器字段编辑弹窗
|
||||
const openListenerFieldForm = (field, index?) => {
|
||||
listenerFieldForm.value = field ? JSON.parse(JSON.stringify(field)) : {}
|
||||
editingListenerFieldIndex.value = field ? index : -1
|
||||
listenerFieldFormModelVisible.value = true
|
||||
nextTick(() => {
|
||||
if (listenerFieldFormRef.value) listenerFieldFormRef.value.clearValidate()
|
||||
})
|
||||
}
|
||||
// 保存监听器注入字段
|
||||
const saveListenerFiled = async () => {
|
||||
let validateStatus = await listenerFieldFormRef.value.validate()
|
||||
if (!validateStatus) return // 验证不通过直接返回
|
||||
if (editingListenerFieldIndex.value === -1) {
|
||||
fieldsListOfListener.value.push(listenerFieldForm.value)
|
||||
listenerForm.value.fields.push(listenerFieldForm.value)
|
||||
} else {
|
||||
fieldsListOfListener.value.splice(editingListenerFieldIndex.value, 1, listenerFieldForm.value)
|
||||
listenerForm.value.fields.splice(editingListenerFieldIndex.value, 1, listenerFieldForm.value)
|
||||
}
|
||||
listenerFieldFormModelVisible.value = false
|
||||
nextTick(() => {
|
||||
listenerFieldForm.value = {}
|
||||
})
|
||||
}
|
||||
// 移除监听器字段
|
||||
const removeListenerField = (field, index) => {
|
||||
console.log(field, 'field')
|
||||
ElMessageBox.confirm('确认移除该字段吗?', '提示', {
|
||||
confirmButtonText: '确 认',
|
||||
cancelButtonText: '取 消'
|
||||
})
|
||||
.then(() => {
|
||||
fieldsListOfListener.value.splice(index, 1)
|
||||
listenerForm.value.fields.splice(index, 1)
|
||||
})
|
||||
.catch(() => console.info('操作取消'))
|
||||
}
|
||||
|
||||
// 打开监听器弹窗
|
||||
const processListenerDialogRef = ref()
|
||||
const openProcessListenerDialog = async () => {
|
||||
processListenerDialogRef.value.open('task')
|
||||
}
|
||||
const selectProcessListener = (listener) => {
|
||||
const listenerForm = initListenerForm2(listener)
|
||||
const listenerObject = createListenerObject(listenerForm, true, prefix)
|
||||
bpmnElementListeners.value.push(listenerObject)
|
||||
elementListenersList.value.push(listenerForm)
|
||||
|
||||
// 保存其他配置
|
||||
otherExtensionList.value =
|
||||
bpmnElement.value.businessObject?.extensionElements?.values?.filter(
|
||||
(ex) => ex.$type !== `${prefix}:TaskListener`
|
||||
) ?? []
|
||||
updateElementExtensions(
|
||||
bpmnElement.value,
|
||||
otherExtensionList.value.concat(bpmnElementListeners.value)
|
||||
)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.id,
|
||||
(val) => {
|
||||
val &&
|
||||
val.length &&
|
||||
nextTick(() => {
|
||||
resetListenersList()
|
||||
})
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -364,6 +364,7 @@ watch(
|
||||
)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
.monitoringPoints {
|
||||
display: flex;
|
||||
.statistics {
|
||||
|
||||
@@ -340,6 +340,7 @@ watch(
|
||||
)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
.monitoringPoints {
|
||||
display: flex;
|
||||
.statistics {
|
||||
|
||||
@@ -177,7 +177,9 @@ const tableStore: any = new TableStore({
|
||||
monitoringPoints.value.runNum = tableStore.table.data.totalNum
|
||||
monitoringPoints.value.abnormalNum = tableStore.table.data.belowNum
|
||||
monitoringPoints.value.totalOnlineRate = tableStore.table.data.totalOnlineRate - 0
|
||||
abnormal.value = tableStore.table.data.citDetailList
|
||||
abnormal.value = tableStore.table.data.citDetailList.filter(
|
||||
(k: any) => k.citName != '上送国网' && k.citName != '非上送国网'
|
||||
)
|
||||
}
|
||||
})
|
||||
tableStore.table.params.deptIndex = dictData.state.area[0].id
|
||||
@@ -338,6 +340,7 @@ watch(
|
||||
)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
.monitoringPoints {
|
||||
display: flex;
|
||||
.statistics {
|
||||
|
||||
@@ -18,24 +18,48 @@
|
||||
>
|
||||
<div style="flex: 1">
|
||||
<div class="title">终端统计</div>
|
||||
<div style="height: 135px" class="box1">
|
||||
<div class="boxDiv hexagon">
|
||||
<div style="color: #fff">{{ statisticsList.allNum }}</div>
|
||||
<div class="mt10 divBot">总数</div>
|
||||
<div
|
||||
class="box1"
|
||||
:style="{
|
||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px - 30px )`,
|
||||
overflow: 'auto'
|
||||
}"
|
||||
>
|
||||
<div class="statistics">
|
||||
<div class="divBox div1">
|
||||
<span class="iconfont icon-qiyezongshu" style="color: #57bc6e"></span>
|
||||
<span class="divBox_title">终端总数</span>
|
||||
<span class="divBox_num text-style" style="color: #57bc6e">
|
||||
{{ statisticsList.allNum }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="divBox div2">
|
||||
<span class="iconfont icon-zaiyunshebei" style="color: #67c23a"></span>
|
||||
<span class="divBox_title">在运终端数</span>
|
||||
<span class="divBox_num text-style" style="color: #67c23a">
|
||||
{{ statisticsList.runNum }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="boxDiv hexagon hexagon1">
|
||||
<div style="color: #fff">{{ statisticsList.runNum }}</div>
|
||||
<div class="mt10 divBot">在运</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 135px" class="box1">
|
||||
<div class="boxDiv hexagon hexagon2">
|
||||
<div style="color: #fff">{{ statisticsList.checkNum }}</div>
|
||||
<div class="mt10 divBot">调试</div>
|
||||
</div>
|
||||
<div class="boxDiv hexagon hexagon3">
|
||||
<div style="color: #fff">{{ statisticsList.stopRunNum }}</div>
|
||||
<div class="mt10 divBot">停运</div>
|
||||
|
||||
<div class="statistics">
|
||||
<div class="divBox div3">
|
||||
<span
|
||||
class="iconfont icon-yichanglei_14feizhinengbiaozaiyunyichang"
|
||||
style="color: #ffbf00"
|
||||
></span>
|
||||
<span class="divBox_title">调试终端数</span>
|
||||
<span class="divBox_num text-style" style="color: #ffbf00">
|
||||
{{ statisticsList.checkNum }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="divBox div4">
|
||||
<span class="iconfont icon-tingyunshijianguanli" style="color: #f56c6c"></span>
|
||||
<span class="divBox_title">停运终端数</span>
|
||||
<span class="divBox_num text-style" style="color: #f56c6c">
|
||||
{{ statisticsList.stopRunNum }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,7 +89,7 @@
|
||||
<span style="width: 90px">终端总数</span>
|
||||
<span style="flex: 1">完整性(%)</span>
|
||||
<span style="flex: 1">在线率(%)</span>
|
||||
<span style="flex: 1">合格率(%)</span>
|
||||
<span style="flex: 1">异常率(%)</span>
|
||||
</div>
|
||||
<div
|
||||
:style="{
|
||||
@@ -205,7 +229,7 @@ const tableStore: any = new TableStore({
|
||||
statisticsList.value.checkNum = totalData.value.filter(item => item.runFlag === '调试').length
|
||||
statisticsList.value.stopRunNum = totalData.value.filter(item => item.runFlag === '停运').length
|
||||
|
||||
abnormal.value = tableStore.table.data
|
||||
abnormal.value = tableStore.table.data.filter((k: any) => k.name != '上送国网' && k.name != '非上送国网')
|
||||
}
|
||||
})
|
||||
tableStore.table.params.deptIndex = dictData.state.area[0].id
|
||||
@@ -234,6 +258,7 @@ watch(
|
||||
)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
.monitoringPoints {
|
||||
display: flex;
|
||||
}
|
||||
@@ -344,32 +369,7 @@ watch(
|
||||
color: #fff;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.box1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
.boxDiv {
|
||||
// flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
margin: 0 5px;
|
||||
|
||||
div:nth-child(1) {
|
||||
position: absolute;
|
||||
font-size: 30px;
|
||||
top: -10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.divBot {
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
}
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.hexagon {
|
||||
position: relative;
|
||||
width: 100px;
|
||||
@@ -427,4 +427,44 @@ watch(
|
||||
border-top: 27.5px solid #a52a2a;
|
||||
}
|
||||
}
|
||||
.statistics {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
.divBox {
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
.iconfont {
|
||||
font-size: 40px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.divBox_title {
|
||||
font-weight: 550;
|
||||
}
|
||||
.divBox_num {
|
||||
font-size: 20px;
|
||||
font-weight: 550;
|
||||
margin-left: auto;
|
||||
font-family: AlimamaDongFangDaKai;
|
||||
}
|
||||
align-items: center;
|
||||
// text-align: center;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.div1 {
|
||||
background-color: #eef8f0;
|
||||
}
|
||||
.div2 {
|
||||
background-color: #67c23a24;
|
||||
}
|
||||
.div3 {
|
||||
background-color: #ffbf0024;
|
||||
}
|
||||
.div4 {
|
||||
background-color: #f56c6c24;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
>
|
||||
<el-form-item v-if="datePicker" style="grid-column: span 2; max-width: 630px">
|
||||
<template #label>
|
||||
<el-checkbox v-if="showTimeAll" v-model="timeAll" label="时间" />
|
||||
<el-checkbox v-if="showTimeAll" v-model="timeAll" label="统计时间" />
|
||||
<span v-else>{{ dateLabel }}</span>
|
||||
</template>
|
||||
<DatePicker
|
||||
@@ -111,7 +111,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
showReset: true,
|
||||
showExport: false,
|
||||
showTimeAll: false,
|
||||
dateLabel: '时间'
|
||||
dateLabel: '统计日期'
|
||||
})
|
||||
// 动态计算table高度
|
||||
const resizeObserver = new ResizeObserver(entries => {
|
||||
|
||||
@@ -362,3 +362,4 @@ export function getTimeOfTheMonth(key: string): [string, string] {
|
||||
throw new Error('Invalid key')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<pane style="background: #fff">
|
||||
<TableHeader :showSearch="false" v-show="props.rowList.id == undefined">
|
||||
<template #select>
|
||||
<el-form-item label="时间">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="default-main">
|
||||
<TableHeader :showSearch="false" v-show="flag">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="日期">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker
|
||||
ref="datePickerRef"
|
||||
:nextFlag="false"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</div> -->
|
||||
<TableHeader :showSearch="false">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="日期">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef" :nextFlag="false" :theCurrentTime="true"></DatePicker>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="default-main">
|
||||
<TableHeader :showSearch="false" v-show="flag">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="日期">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker
|
||||
ref="datePickerRef"
|
||||
:nextFlag="false"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<TableHeader date-picker ref="TableHeaderRef" :dateLabel="`数据统计时间`">
|
||||
<TableHeader date-picker ref="TableHeaderRef" >
|
||||
<template v-slot:select>
|
||||
<el-form-item label="运行状态">
|
||||
<el-select v-model="tableStore.table.params.lineRunFlag" clearable placeholder="请选择运行状态">
|
||||
@@ -474,6 +474,7 @@ tableStore.table.params.name = ''
|
||||
provide('tableStore', tableStore)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
.card-list {
|
||||
display: flex;
|
||||
.monitoringPoints {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<TableHeader date-picker ref="TableHeaderRef" :dateLabel="`数据统计时间`">
|
||||
<TableHeader date-picker ref="TableHeaderRef">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="运行状态">
|
||||
<el-select v-model="tableStore.table.params.lineRunFlag" clearable placeholder="请选择运行状态">
|
||||
@@ -34,7 +34,11 @@
|
||||
<div class="divBox">
|
||||
<span class="iconfont icon-qiyezongshu" style="color: #57bc6e"></span>
|
||||
<span class="divBox_title">终端总数</span>
|
||||
<span class="divBox_num text-style" style="color: #57bc6e" @click="totalTable(100001, '')">
|
||||
<span
|
||||
class="divBox_num text-style"
|
||||
style="color: #57bc6e"
|
||||
@click="totalTable(100001, '')"
|
||||
>
|
||||
{{ monitoringPoints.runNum }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -200,6 +204,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import '@/assets/font/iconfont.css'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
@@ -262,10 +267,13 @@ const tableStore = new TableStore({
|
||||
monitoringPoints.value.runNum = tableStore.table.data.totalNum
|
||||
monitoringPoints.value.abnormalNum = tableStore.table.data.belowNum
|
||||
monitoringPoints.value.totalOnlineRate = tableStore.table.data.totalOnlineRate - 0
|
||||
abnormal.value = tableStore.table.data.citDetailList
|
||||
abnormal.value = tableStore.table.data.citDetailList.filter(
|
||||
(k: any) => k.citName != '上送国网' && k.citName != '非上送国网'
|
||||
)
|
||||
// 合并子集数据 并去重
|
||||
totalData.value = Array.from(
|
||||
tableStore.table.data.citDetailList
|
||||
|
||||
.map((item: any) => item.detailList)
|
||||
.flat()
|
||||
.reduce((map: any, item: any) => {
|
||||
@@ -470,6 +478,7 @@ tableStore.table.params.name = ''
|
||||
provide('tableStore', tableStore)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
.card-list {
|
||||
display: flex;
|
||||
.monitoringPoints {
|
||||
|
||||
@@ -1,430 +1,430 @@
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%; position: relative">
|
||||
<el-form :inline="true">
|
||||
<el-form-item label="多监测点">
|
||||
<el-checkbox v-model="checked" @change="checkChange" />
|
||||
</el-form-item>
|
||||
<el-form-item label="日期">
|
||||
<DatePicker ref="datePickerRef" ></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item label="指标类型:">
|
||||
<el-select
|
||||
v-model="formData.condition"
|
||||
multiple
|
||||
collapse-tags
|
||||
:multiple-limit="5"
|
||||
filterable
|
||||
placeholder="请选择指标"
|
||||
@change="conditionChange"
|
||||
>
|
||||
<el-option-group v-for="group in indexOptions" :key="group.label" :label="group.label">
|
||||
<el-option
|
||||
v-for="item in group.options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="谐波次数:" v-if="showXieBoCiShu">
|
||||
<el-select style="width: 100%" v-model="formData.harmonic" placeholder="请选择谐波">
|
||||
<el-option
|
||||
v-for="item in harmonicOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="showJianXieBoCiShu" label="间谐波次数:">
|
||||
<el-select style="width: 100%" v-model="formData.inHarmonic" placeholder="请选择间谐波">
|
||||
<el-option
|
||||
v-for="item in inharmonicOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="flex: 1; overflow: hidden" class="mt10" v-loading="loading">
|
||||
<vxe-table height="auto" v-bind="defaultAttribute" :data="tableData">
|
||||
<vxe-column field="subName" title="变电站" min-width="120px"></vxe-column>
|
||||
<vxe-column field="lineName" title="监测点名称" min-width="120px"></vxe-column>
|
||||
<vxe-column field="targetName" title="指标类型" min-width="120px"></vxe-column>
|
||||
<vxe-column field="phaseType" title="相别" min-width="100px"></vxe-column>
|
||||
<vxe-column field="scale" title="电压等级" min-width="100px"></vxe-column>
|
||||
<vxe-column field="timeId" title="时间" min-width="130px"></vxe-column>
|
||||
<vxe-column field="unit" title="单位" min-width="100px"></vxe-column>
|
||||
<vxe-column field="maxData" title="最大值(%)" min-width="100px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
@click="showCharts(scope.row, 3, '最大值')"
|
||||
:style="{ color: scope.row.statisticalType === 3 ? '#A52a2a' : '#07d75a' }"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.maxData }}
|
||||
</el-button>
|
||||
<el-button v-if="scope.row.statisticalType === 3.14159">/</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="minData" title="最小值(%)" min-width="100px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
@click="showCharts(scope.row, 2, '最小值')"
|
||||
:style="{ color: scope.row.statisticalType === 2 ? '#A52a2a' : '#07d75a' }"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.minData }}
|
||||
</el-button>
|
||||
<el-button v-if="scope.row.statisticalType === 3.14159">/</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="avgData" title="平均值(%)" min-width="100px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
@click="showCharts(scope.row, 1, '平均值')"
|
||||
:style="{ color: scope.row.statisticalType === 1 ? '#A52a2a' : '#07d75a' }"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.avgData }}
|
||||
</el-button>
|
||||
<el-button v-if="scope.row.statisticalType === 3.14159">/</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="cp95Data" title="CP95值(%)" min-width="100px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
@click="showCharts(scope.row, 4, 'CP95值')"
|
||||
:style="{ color: scope.row.statisticalType === 4 ? '#A52a2a' : '#07d75a' }"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.cp95Data }}
|
||||
</el-button>
|
||||
<el-button v-if="scope.row.statisticalType === 3.14159">/</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<SecondSheet v-if="options" style="background: #fff; z-index: 10">
|
||||
<el-button
|
||||
style="position: absolute; right: 0; top: 0; cursor: pointer; z-index: 3"
|
||||
icon="el-icon-Back"
|
||||
size="small"
|
||||
@click="close"
|
||||
>
|
||||
返回
|
||||
</el-button>
|
||||
<MyEChart :options="options"></MyEChart>
|
||||
</SecondSheet>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import { Close } from '@element-plus/icons-vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { indexOptions, harmonicOptions, inharmonicOptions } from '@/utils/dictionary'
|
||||
import { getHistoryTableData, getHistoryLineData } from '@/api/harmonic-boot/normLimit'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import SecondSheet from '@/components/secondSheet/index.vue'
|
||||
import MyEChart from '@/components/echarts/MyEchart.vue'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const checked = ref(monitoringPoint.state.showCheckBox)
|
||||
const formData = reactive<{
|
||||
lineId: string[]
|
||||
searchBeginTime: string
|
||||
searchEndTime: string
|
||||
condition: string[]
|
||||
harmonic: number
|
||||
inHarmonic: number
|
||||
}>({
|
||||
lineId: [],
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
condition: ['10', '11', '12'],
|
||||
harmonic: 2,
|
||||
inHarmonic: 1
|
||||
})
|
||||
const tableData = ref([])
|
||||
const showXieBoCiShu = ref(false)
|
||||
const showJianXieBoCiShu = ref(false)
|
||||
const options = ref<any>(null)
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.lineId = checked.value ? monitoringPoint.state.lineIds : [monitoringPoint.state.lineId]
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
getHistoryTableData(formData).then((res: any) => {
|
||||
tableData.value = res.data.map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
maxData: item.maxData.toFixed(2),
|
||||
minData: item.minData.toFixed(2),
|
||||
avgData: item.avgData.toFixed(2),
|
||||
cp95Data: item.cp95Data.toFixed(2)
|
||||
}
|
||||
})
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
const checkChange = () => {
|
||||
if (checked.value) {
|
||||
monitoringPoint.setShowCheckBox(true)
|
||||
} else {
|
||||
monitoringPoint.setShowCheckBox(false)
|
||||
init()
|
||||
}
|
||||
}
|
||||
const close = () => {
|
||||
console.log('====================================')
|
||||
console.log(2123123)
|
||||
console.log('====================================')
|
||||
options.value = null
|
||||
}
|
||||
const showCharts = (row: any, valueType: number, name: string) => {
|
||||
getHistoryLineData({
|
||||
lineId: row.lineId,
|
||||
number: row.number,
|
||||
phaseType: row.phaseType,
|
||||
searchTime: row.timeId,
|
||||
targetCode: row.targetCode,
|
||||
valueType
|
||||
}).then(res => {
|
||||
options.value = {
|
||||
title: {
|
||||
text: row.subName + ' ' + row.lineName + ' ' + row.targetName + ' ' + row.phaseType + '相' + name
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
name: '时间',
|
||||
data: res.data[0]?.value.map((item: any[]) => item[0])
|
||||
},
|
||||
yAxis: {
|
||||
name: '%',
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: name,
|
||||
data: res.data[0]?.value.map((item: any[]) => item[1]),
|
||||
type: 'line'
|
||||
}
|
||||
],
|
||||
options: {
|
||||
grid: {
|
||||
top: '50px',
|
||||
left: '40px',
|
||||
right: '60px',
|
||||
bottom: '10px',
|
||||
containLabel: true
|
||||
},
|
||||
dataZoom: null
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
const conditionChange = () => {
|
||||
//判断一个指标时
|
||||
if (formData.condition.length == 1) {
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
//判断2个指标时
|
||||
if (formData.condition.length == 2) {
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
(formData.condition.includes('45') && formData.condition.includes('46')) ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
showJianXieBoCiShu.value = true
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
//判断3个指标时
|
||||
if (formData.condition.length == 3) {
|
||||
if (
|
||||
(formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')) &&
|
||||
(formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49'))
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
//判断4个指标时
|
||||
if (formData.condition.length == 4) {
|
||||
if (
|
||||
(formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')) &&
|
||||
(formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49'))
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
//判断5个指标时
|
||||
if (formData.condition.length == 5) {
|
||||
if (
|
||||
(formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')) &&
|
||||
(formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49'))
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
//判断无指标时
|
||||
if (formData.condition.length == 0) {
|
||||
showJianXieBoCiShu.value = false
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%; position: relative">
|
||||
<el-form :inline="true">
|
||||
<el-form-item label="多监测点">
|
||||
<el-checkbox v-model="checked" @change="checkChange" />
|
||||
</el-form-item>
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef" ></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item label="指标类型:">
|
||||
<el-select
|
||||
v-model="formData.condition"
|
||||
multiple
|
||||
collapse-tags
|
||||
:multiple-limit="5"
|
||||
filterable
|
||||
placeholder="请选择指标"
|
||||
@change="conditionChange"
|
||||
>
|
||||
<el-option-group v-for="group in indexOptions" :key="group.label" :label="group.label">
|
||||
<el-option
|
||||
v-for="item in group.options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="谐波次数:" v-if="showXieBoCiShu">
|
||||
<el-select style="width: 100%" v-model="formData.harmonic" placeholder="请选择谐波">
|
||||
<el-option
|
||||
v-for="item in harmonicOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="showJianXieBoCiShu" label="间谐波次数:">
|
||||
<el-select style="width: 100%" v-model="formData.inHarmonic" placeholder="请选择间谐波">
|
||||
<el-option
|
||||
v-for="item in inharmonicOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="flex: 1; overflow: hidden" class="mt10" v-loading="loading">
|
||||
<vxe-table height="auto" v-bind="defaultAttribute" :data="tableData">
|
||||
<vxe-column field="subName" title="变电站" min-width="120px"></vxe-column>
|
||||
<vxe-column field="lineName" title="监测点名称" min-width="120px"></vxe-column>
|
||||
<vxe-column field="targetName" title="指标类型" min-width="120px"></vxe-column>
|
||||
<vxe-column field="phaseType" title="相别" min-width="100px"></vxe-column>
|
||||
<vxe-column field="scale" title="电压等级" min-width="100px"></vxe-column>
|
||||
<vxe-column field="timeId" title="时间" min-width="130px"></vxe-column>
|
||||
<vxe-column field="unit" title="单位" min-width="100px"></vxe-column>
|
||||
<vxe-column field="maxData" title="最大值(%)" min-width="100px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
@click="showCharts(scope.row, 3, '最大值')"
|
||||
:style="{ color: scope.row.statisticalType === 3 ? '#A52a2a' : '#07d75a' }"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.maxData }}
|
||||
</el-button>
|
||||
<el-button v-if="scope.row.statisticalType === 3.14159">/</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="minData" title="最小值(%)" min-width="100px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
@click="showCharts(scope.row, 2, '最小值')"
|
||||
:style="{ color: scope.row.statisticalType === 2 ? '#A52a2a' : '#07d75a' }"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.minData }}
|
||||
</el-button>
|
||||
<el-button v-if="scope.row.statisticalType === 3.14159">/</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="avgData" title="平均值(%)" min-width="100px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
@click="showCharts(scope.row, 1, '平均值')"
|
||||
:style="{ color: scope.row.statisticalType === 1 ? '#A52a2a' : '#07d75a' }"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.avgData }}
|
||||
</el-button>
|
||||
<el-button v-if="scope.row.statisticalType === 3.14159">/</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="cp95Data" title="CP95值(%)" min-width="100px">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
@click="showCharts(scope.row, 4, 'CP95值')"
|
||||
:style="{ color: scope.row.statisticalType === 4 ? '#A52a2a' : '#07d75a' }"
|
||||
type="text"
|
||||
size="small"
|
||||
>
|
||||
{{ scope.row.cp95Data }}
|
||||
</el-button>
|
||||
<el-button v-if="scope.row.statisticalType === 3.14159">/</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<SecondSheet v-if="options" style="background: #fff; z-index: 10">
|
||||
<el-button
|
||||
style="position: absolute; right: 0; top: 0; cursor: pointer; z-index: 3"
|
||||
icon="el-icon-Back"
|
||||
size="small"
|
||||
@click="close"
|
||||
>
|
||||
返回
|
||||
</el-button>
|
||||
<MyEChart :options="options"></MyEChart>
|
||||
</SecondSheet>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import { Close } from '@element-plus/icons-vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { indexOptions, harmonicOptions, inharmonicOptions } from '@/utils/dictionary'
|
||||
import { getHistoryTableData, getHistoryLineData } from '@/api/harmonic-boot/normLimit'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import SecondSheet from '@/components/secondSheet/index.vue'
|
||||
import MyEChart from '@/components/echarts/MyEchart.vue'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const checked = ref(monitoringPoint.state.showCheckBox)
|
||||
const formData = reactive<{
|
||||
lineId: string[]
|
||||
searchBeginTime: string
|
||||
searchEndTime: string
|
||||
condition: string[]
|
||||
harmonic: number
|
||||
inHarmonic: number
|
||||
}>({
|
||||
lineId: [],
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
condition: ['10', '11', '12'],
|
||||
harmonic: 2,
|
||||
inHarmonic: 1
|
||||
})
|
||||
const tableData = ref([])
|
||||
const showXieBoCiShu = ref(false)
|
||||
const showJianXieBoCiShu = ref(false)
|
||||
const options = ref<any>(null)
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.lineId = checked.value ? monitoringPoint.state.lineIds : [monitoringPoint.state.lineId]
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
getHistoryTableData(formData).then((res: any) => {
|
||||
tableData.value = res.data.map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
maxData: item.maxData.toFixed(2),
|
||||
minData: item.minData.toFixed(2),
|
||||
avgData: item.avgData.toFixed(2),
|
||||
cp95Data: item.cp95Data.toFixed(2)
|
||||
}
|
||||
})
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
const checkChange = () => {
|
||||
if (checked.value) {
|
||||
monitoringPoint.setShowCheckBox(true)
|
||||
} else {
|
||||
monitoringPoint.setShowCheckBox(false)
|
||||
init()
|
||||
}
|
||||
}
|
||||
const close = () => {
|
||||
console.log('====================================')
|
||||
console.log(2123123)
|
||||
console.log('====================================')
|
||||
options.value = null
|
||||
}
|
||||
const showCharts = (row: any, valueType: number, name: string) => {
|
||||
getHistoryLineData({
|
||||
lineId: row.lineId,
|
||||
number: row.number,
|
||||
phaseType: row.phaseType,
|
||||
searchTime: row.timeId,
|
||||
targetCode: row.targetCode,
|
||||
valueType
|
||||
}).then(res => {
|
||||
options.value = {
|
||||
title: {
|
||||
text: row.subName + ' ' + row.lineName + ' ' + row.targetName + ' ' + row.phaseType + '相' + name
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
name: '时间',
|
||||
data: res.data[0]?.value.map((item: any[]) => item[0])
|
||||
},
|
||||
yAxis: {
|
||||
name: '%',
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: name,
|
||||
data: res.data[0]?.value.map((item: any[]) => item[1]),
|
||||
type: 'line'
|
||||
}
|
||||
],
|
||||
options: {
|
||||
grid: {
|
||||
top: '50px',
|
||||
left: '40px',
|
||||
right: '60px',
|
||||
bottom: '10px',
|
||||
containLabel: true
|
||||
},
|
||||
dataZoom: null
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
const conditionChange = () => {
|
||||
//判断一个指标时
|
||||
if (formData.condition.length == 1) {
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
//判断2个指标时
|
||||
if (formData.condition.length == 2) {
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
(formData.condition.includes('45') && formData.condition.includes('46')) ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
showJianXieBoCiShu.value = true
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
//判断3个指标时
|
||||
if (formData.condition.length == 3) {
|
||||
if (
|
||||
(formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')) &&
|
||||
(formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49'))
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
//判断4个指标时
|
||||
if (formData.condition.length == 4) {
|
||||
if (
|
||||
(formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')) &&
|
||||
(formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49'))
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
//判断5个指标时
|
||||
if (formData.condition.length == 5) {
|
||||
if (
|
||||
(formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')) &&
|
||||
(formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49'))
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('46') ||
|
||||
// formData.condition.includes('47') ||
|
||||
// formData.condition.includes('48') ||
|
||||
formData.condition.includes('49')
|
||||
) {
|
||||
showJianXieBoCiShu.value = true
|
||||
} else {
|
||||
showJianXieBoCiShu.value = false
|
||||
}
|
||||
if (
|
||||
formData.condition.includes('40') ||
|
||||
formData.condition.includes('43') ||
|
||||
formData.condition.includes('44') ||
|
||||
formData.condition.includes('45')
|
||||
) {
|
||||
showXieBoCiShu.value = true
|
||||
} else {
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
//判断无指标时
|
||||
if (formData.condition.length == 0) {
|
||||
showJianXieBoCiShu.value = false
|
||||
showXieBoCiShu.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<el-form-item label="多监测点">
|
||||
<el-checkbox v-model="checked" @change="checkChange" />
|
||||
</el-form-item>
|
||||
<el-form-item label="日期">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef" :theCurrentTime="true"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item label="指标类型:">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,315 +1,315 @@
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<TableHeader ref="TableHeaderRef" :showSearch="false">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="日期">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item label="对比">
|
||||
<el-select v-model="searchType" clearable placeholder="可选择同比、环比">
|
||||
<el-option
|
||||
v-for="item in searchTypeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-slot:operation>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
|
||||
<div style="flex: 1" class="mt10" v-loading="loading">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getSteadyData } from '@/api/harmonic-boot/pollution'
|
||||
import { gradeColor3 } from '@/components/echarts/color'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
const tableStore = new TableStore({
|
||||
url: '',
|
||||
method: 'POST',
|
||||
column: []
|
||||
})
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
id: '',
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
periodBeginTime: '',
|
||||
periodEndTime: ''
|
||||
})
|
||||
const options = ref({})
|
||||
const searchType = ref('')
|
||||
const searchTypeOptions = [
|
||||
{
|
||||
label: '同比',
|
||||
value: '1'
|
||||
},
|
||||
{
|
||||
label: '环比',
|
||||
value: '2'
|
||||
}
|
||||
]
|
||||
const gradeNames = ['优质', '良好', '一般', '较差', '极差']
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.id = monitoringPoint.state.lineId
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
if (searchType.value == '1') {
|
||||
;[formData.periodBeginTime, formData.periodEndTime] = datePickerRef.value.getYearOnYear(
|
||||
formData.searchBeginTime,
|
||||
formData.searchEndTime
|
||||
)
|
||||
} else if (searchType.value == '2') {
|
||||
;[formData.periodBeginTime, formData.periodEndTime] = datePickerRef.value.getMonthOnMonth(
|
||||
formData.searchBeginTime,
|
||||
formData.searchEndTime
|
||||
)
|
||||
} else {
|
||||
formData.periodBeginTime = ''
|
||||
formData.periodEndTime = ''
|
||||
}
|
||||
getSteadyData(formData).then((res: any) => {
|
||||
const { steadyInfoData, steadyInfoList } = res.data
|
||||
let yData = [],
|
||||
yData2 = []
|
||||
for (let i = 0; i < steadyInfoList.length; i++) {
|
||||
// if (steadyInfoList[i] == 3.1415) {
|
||||
// steadyInfoList[i] = 1
|
||||
// yData.push(steadyInfoList[i])
|
||||
// } else if (steadyInfoList[i] == 3.14159) {
|
||||
// steadyInfoList[i] = 1
|
||||
// yData.push(steadyInfoList[i])
|
||||
// } else if (steadyInfoList[i] !== 3.14159) {
|
||||
yData.push(steadyInfoList[i])
|
||||
// }
|
||||
}
|
||||
for (let i = 0; i < steadyInfoData.length; i++) {
|
||||
yData2.push(steadyInfoData[i])
|
||||
// if (steadyInfoData[i] == 3.14159) {
|
||||
// steadyInfoData[i] = 0
|
||||
// yData2.push(steadyInfoData[i])
|
||||
// } else if (steadyInfoData[i] == 3.14159) {
|
||||
// steadyInfoData[i] = 0
|
||||
// yData2.push(steadyInfoData[i])
|
||||
// } else if (steadyInfoData[i] !== 3.14159) {
|
||||
// yData2.push(steadyInfoData[i])
|
||||
// }
|
||||
}
|
||||
let series: any[] = [
|
||||
{
|
||||
name: formData.searchBeginTime + '至' + formData.searchEndTime,
|
||||
type: 'bar',
|
||||
barMaxWidth: 30,
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
distance: 2,
|
||||
color: '#fff',
|
||||
fontWeight: 'bolder'
|
||||
},
|
||||
data: yData,
|
||||
markLine: {
|
||||
silent: false,
|
||||
symbol: 'circle',
|
||||
data: [
|
||||
{
|
||||
name: '',
|
||||
yAxis: 100,
|
||||
lineStyle: {
|
||||
color: gradeColor3[0]
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '优质',
|
||||
color: gradeColor3[0]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
yAxis: 90,
|
||||
lineStyle: {
|
||||
color: gradeColor3[1]
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
color: gradeColor3[1],
|
||||
formatter: '良好'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
yAxis: 60,
|
||||
lineStyle: {
|
||||
color: gradeColor3[2]
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
color: gradeColor3[2],
|
||||
formatter: '合格'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
itemStyle: {
|
||||
color: (params: any) => {
|
||||
if (params.value > 90) {
|
||||
return gradeColor3[0]
|
||||
} else if (params.value > 60) {
|
||||
return gradeColor3[1]
|
||||
} else if (params.value == 3.14159) {
|
||||
return '#ccc'
|
||||
} else {
|
||||
return gradeColor3[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
if (searchType.value) {
|
||||
series.push({
|
||||
name: formData.periodBeginTime + '至' + formData.periodEndTime,
|
||||
type: 'bar',
|
||||
barMaxWidth: 30,
|
||||
// label: {
|
||||
// show: true,
|
||||
// position: 'top',
|
||||
// distance: 2,
|
||||
// color: '#fff',
|
||||
// fontWeight: 'bolder'
|
||||
// },
|
||||
data: yData2,
|
||||
itemStyle: {
|
||||
color: (params: any) => {
|
||||
if (params.value > 90) {
|
||||
return gradeColor3[0]
|
||||
} else if (params.value > 60) {
|
||||
return gradeColor3[1]
|
||||
} else if (params.value == 3.14159) {
|
||||
return '#ccc'
|
||||
} else {
|
||||
return gradeColor3[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
options.value = {
|
||||
title: {
|
||||
text: '稳态指标合格率'
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
formatter: function (params: any) {
|
||||
//console.log(params)
|
||||
let msg = ''
|
||||
msg += params[0].name + '<br/>'
|
||||
for (let i in params) {
|
||||
if (params[i].data == 3.14159) {
|
||||
msg +=params[i].marker+ params[i].seriesName + ': 暂无数据<br/>'
|
||||
} else {
|
||||
msg += params[i].marker+ params[i].seriesName + ': ' + params[i].data + '<br/>'
|
||||
}
|
||||
}
|
||||
return msg
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
name: '指标类型',
|
||||
type: 'category',
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1
|
||||
},
|
||||
symbol: ['none', 'arrow']
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
fontFamily: 'dinproRegular'
|
||||
}
|
||||
},
|
||||
data: [
|
||||
'频率偏差',
|
||||
'闪变',
|
||||
'三相电压不平衡',
|
||||
'谐波电压',
|
||||
'谐波电流',
|
||||
'电压偏差',
|
||||
'负序电流',
|
||||
'间谐波电压含有率'
|
||||
]
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
name: '%',
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 100,
|
||||
position: 'left',
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1
|
||||
},
|
||||
symbol: ['none', 'arrow']
|
||||
}
|
||||
},
|
||||
{
|
||||
position: 'left',
|
||||
axisLine: {
|
||||
show: true,
|
||||
symbol: ['none', 'arrow']
|
||||
},
|
||||
splitLine: {
|
||||
//分割线配置
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
provide('tableStore', tableStore)
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<TableHeader ref="TableHeaderRef" :showSearch="false">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item label="对比">
|
||||
<el-select v-model="searchType" clearable placeholder="可选择同比、环比">
|
||||
<el-option
|
||||
v-for="item in searchTypeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-slot:operation>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
|
||||
<div style="flex: 1" class="mt10" v-loading="loading">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getSteadyData } from '@/api/harmonic-boot/pollution'
|
||||
import { gradeColor3 } from '@/components/echarts/color'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
const tableStore = new TableStore({
|
||||
url: '',
|
||||
method: 'POST',
|
||||
column: []
|
||||
})
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
id: '',
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
periodBeginTime: '',
|
||||
periodEndTime: ''
|
||||
})
|
||||
const options = ref({})
|
||||
const searchType = ref('')
|
||||
const searchTypeOptions = [
|
||||
{
|
||||
label: '同比',
|
||||
value: '1'
|
||||
},
|
||||
{
|
||||
label: '环比',
|
||||
value: '2'
|
||||
}
|
||||
]
|
||||
const gradeNames = ['优质', '良好', '一般', '较差', '极差']
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.id = monitoringPoint.state.lineId
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
if (searchType.value == '1') {
|
||||
;[formData.periodBeginTime, formData.periodEndTime] = datePickerRef.value.getYearOnYear(
|
||||
formData.searchBeginTime,
|
||||
formData.searchEndTime
|
||||
)
|
||||
} else if (searchType.value == '2') {
|
||||
;[formData.periodBeginTime, formData.periodEndTime] = datePickerRef.value.getMonthOnMonth(
|
||||
formData.searchBeginTime,
|
||||
formData.searchEndTime
|
||||
)
|
||||
} else {
|
||||
formData.periodBeginTime = ''
|
||||
formData.periodEndTime = ''
|
||||
}
|
||||
getSteadyData(formData).then((res: any) => {
|
||||
const { steadyInfoData, steadyInfoList } = res.data
|
||||
let yData = [],
|
||||
yData2 = []
|
||||
for (let i = 0; i < steadyInfoList.length; i++) {
|
||||
// if (steadyInfoList[i] == 3.1415) {
|
||||
// steadyInfoList[i] = 1
|
||||
// yData.push(steadyInfoList[i])
|
||||
// } else if (steadyInfoList[i] == 3.14159) {
|
||||
// steadyInfoList[i] = 1
|
||||
// yData.push(steadyInfoList[i])
|
||||
// } else if (steadyInfoList[i] !== 3.14159) {
|
||||
yData.push(steadyInfoList[i])
|
||||
// }
|
||||
}
|
||||
for (let i = 0; i < steadyInfoData.length; i++) {
|
||||
yData2.push(steadyInfoData[i])
|
||||
// if (steadyInfoData[i] == 3.14159) {
|
||||
// steadyInfoData[i] = 0
|
||||
// yData2.push(steadyInfoData[i])
|
||||
// } else if (steadyInfoData[i] == 3.14159) {
|
||||
// steadyInfoData[i] = 0
|
||||
// yData2.push(steadyInfoData[i])
|
||||
// } else if (steadyInfoData[i] !== 3.14159) {
|
||||
// yData2.push(steadyInfoData[i])
|
||||
// }
|
||||
}
|
||||
let series: any[] = [
|
||||
{
|
||||
name: formData.searchBeginTime + '至' + formData.searchEndTime,
|
||||
type: 'bar',
|
||||
barMaxWidth: 30,
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
distance: 2,
|
||||
color: '#fff',
|
||||
fontWeight: 'bolder'
|
||||
},
|
||||
data: yData,
|
||||
markLine: {
|
||||
silent: false,
|
||||
symbol: 'circle',
|
||||
data: [
|
||||
{
|
||||
name: '',
|
||||
yAxis: 100,
|
||||
lineStyle: {
|
||||
color: gradeColor3[0]
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '优质',
|
||||
color: gradeColor3[0]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
yAxis: 90,
|
||||
lineStyle: {
|
||||
color: gradeColor3[1]
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
color: gradeColor3[1],
|
||||
formatter: '良好'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
yAxis: 60,
|
||||
lineStyle: {
|
||||
color: gradeColor3[2]
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
color: gradeColor3[2],
|
||||
formatter: '合格'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
itemStyle: {
|
||||
color: (params: any) => {
|
||||
if (params.value > 90) {
|
||||
return gradeColor3[0]
|
||||
} else if (params.value > 60) {
|
||||
return gradeColor3[1]
|
||||
} else if (params.value == 3.14159) {
|
||||
return '#ccc'
|
||||
} else {
|
||||
return gradeColor3[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
if (searchType.value) {
|
||||
series.push({
|
||||
name: formData.periodBeginTime + '至' + formData.periodEndTime,
|
||||
type: 'bar',
|
||||
barMaxWidth: 30,
|
||||
// label: {
|
||||
// show: true,
|
||||
// position: 'top',
|
||||
// distance: 2,
|
||||
// color: '#fff',
|
||||
// fontWeight: 'bolder'
|
||||
// },
|
||||
data: yData2,
|
||||
itemStyle: {
|
||||
color: (params: any) => {
|
||||
if (params.value > 90) {
|
||||
return gradeColor3[0]
|
||||
} else if (params.value > 60) {
|
||||
return gradeColor3[1]
|
||||
} else if (params.value == 3.14159) {
|
||||
return '#ccc'
|
||||
} else {
|
||||
return gradeColor3[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
options.value = {
|
||||
title: {
|
||||
text: '稳态指标合格率'
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
formatter: function (params: any) {
|
||||
//console.log(params)
|
||||
let msg = ''
|
||||
msg += params[0].name + '<br/>'
|
||||
for (let i in params) {
|
||||
if (params[i].data == 3.14159) {
|
||||
msg +=params[i].marker+ params[i].seriesName + ': 暂无数据<br/>'
|
||||
} else {
|
||||
msg += params[i].marker+ params[i].seriesName + ': ' + params[i].data + '<br/>'
|
||||
}
|
||||
}
|
||||
return msg
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
name: '指标类型',
|
||||
type: 'category',
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1
|
||||
},
|
||||
symbol: ['none', 'arrow']
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
fontFamily: 'dinproRegular'
|
||||
}
|
||||
},
|
||||
data: [
|
||||
'频率偏差',
|
||||
'闪变',
|
||||
'三相电压不平衡',
|
||||
'谐波电压',
|
||||
'谐波电流',
|
||||
'电压偏差',
|
||||
'负序电流',
|
||||
'间谐波电压含有率'
|
||||
]
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
name: '%',
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 100,
|
||||
position: 'left',
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 1
|
||||
},
|
||||
symbol: ['none', 'arrow']
|
||||
}
|
||||
},
|
||||
{
|
||||
position: 'left',
|
||||
axisLine: {
|
||||
show: true,
|
||||
symbol: ['none', 'arrow']
|
||||
},
|
||||
splitLine: {
|
||||
//分割线配置
|
||||
lineStyle: {
|
||||
color: '#fff'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
provide('tableStore', tableStore)
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
@@ -1,212 +1,212 @@
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<el-form :inline="true">
|
||||
<el-form-item label="日期">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="flex: 1" class="mt10">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getQualityAssessData } from '@/api/harmonic-boot/asses'
|
||||
import { gradeColor5 } from '@/components/echarts/color'
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
id: '',
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
periodBeginTime: '',
|
||||
periodEndTime: ''
|
||||
})
|
||||
const options = ref({})
|
||||
const gradeNames = ['优质', '良好', '一般', '较差', '极差']
|
||||
const grade = gradeColor5.map((item, index) => {
|
||||
return {
|
||||
name: gradeNames[index],
|
||||
color: item
|
||||
}
|
||||
})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
if (!monitoringPoint.state.lineId) {
|
||||
return
|
||||
}
|
||||
formData.id = monitoringPoint.state.lineId
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
getQualityAssessData(formData).then((res: any) => {
|
||||
let data = res.data.syn[0]
|
||||
if (data == 3.14159) {
|
||||
data = 0.25
|
||||
} else if (data == 3.1415) {
|
||||
data = 0.15
|
||||
}
|
||||
options.value = {
|
||||
title: {
|
||||
text: '稳态综合评估',
|
||||
x: 'center',
|
||||
y: '0%'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
borderColor: '#fff',
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
formatter: function (params: any) {
|
||||
if (params.value >= 5) {
|
||||
return params.name + ' : ' + '优质'
|
||||
} else if (params.value > 4 && params.value <= 5) {
|
||||
return params.name + ' : ' + '良好'
|
||||
} else if (params.value > 3 && params.value <= 4) {
|
||||
return params.name + ' : ' + '合格'
|
||||
} else if (params.value > 2 && params.value <= 3) {
|
||||
return params.name + ' : ' + '较差'
|
||||
} else if (params.value <= 2 && params.value >= 1) {
|
||||
return params.name + ' : ' + '极差'
|
||||
} else if (params.value >= 0.25 && params.value < 1) {
|
||||
return params.name + ' : ' + '暂无数据'
|
||||
} else if (params.value <= 0.15 && params.value >= 0) {
|
||||
return params.name + ' : ' + '/'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
name: '指标',
|
||||
type: 'category',
|
||||
data: ['稳态综合评估'],
|
||||
axisLabel: {
|
||||
margin: 10
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
symbol: ['none', 'arrow']
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: {
|
||||
name: '等级',
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 5,
|
||||
axisLabel: {
|
||||
show: true,
|
||||
// 这里重新定义就可以
|
||||
formatter: function (value: number) {
|
||||
var texts = []
|
||||
if (value === 1) {
|
||||
texts.push('1级')
|
||||
} else if (value === 2) {
|
||||
texts.push('2级')
|
||||
} else if (value === 3) {
|
||||
texts.push('3级')
|
||||
} else if (value === 4) {
|
||||
texts.push('4级')
|
||||
} else if (value === 5) {
|
||||
texts.push('5级')
|
||||
}
|
||||
return texts
|
||||
}
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
symbol: ['none', 'arrow']
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '综合评估',
|
||||
type: 'bar',
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
distance: 2,
|
||||
color: '#fff',
|
||||
fontWeight: 'bolder'
|
||||
},
|
||||
barWidth: '45',
|
||||
data: [
|
||||
{
|
||||
value: data
|
||||
}
|
||||
],
|
||||
markLine: {
|
||||
silent: false,
|
||||
symbol: 'circle',
|
||||
data: grade.map((item, index) => {
|
||||
return {
|
||||
yAxis: grade.length - index,
|
||||
name: item.name,
|
||||
lineStyle: {
|
||||
color: item.color
|
||||
},
|
||||
label: {
|
||||
color: item.color,
|
||||
formatter: item.name
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
itemStyle: {
|
||||
color: (params: any) => {
|
||||
if (params.value > 5) {
|
||||
return gradeColor5[0]
|
||||
} else if (params.value > 4) {
|
||||
return gradeColor5[1]
|
||||
} else if (params.value > 3) {
|
||||
return gradeColor5[2]
|
||||
} else if (params.value > 2) {
|
||||
return gradeColor5[3]
|
||||
} else {
|
||||
return gradeColor5[4]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
options: {
|
||||
dataZoom: null
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<el-form :inline="true">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="flex: 1" class="mt10">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getQualityAssessData } from '@/api/harmonic-boot/asses'
|
||||
import { gradeColor5 } from '@/components/echarts/color'
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
id: '',
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
periodBeginTime: '',
|
||||
periodEndTime: ''
|
||||
})
|
||||
const options = ref({})
|
||||
const gradeNames = ['优质', '良好', '一般', '较差', '极差']
|
||||
const grade = gradeColor5.map((item, index) => {
|
||||
return {
|
||||
name: gradeNames[index],
|
||||
color: item
|
||||
}
|
||||
})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
if (!monitoringPoint.state.lineId) {
|
||||
return
|
||||
}
|
||||
formData.id = monitoringPoint.state.lineId
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
getQualityAssessData(formData).then((res: any) => {
|
||||
let data = res.data.syn[0]
|
||||
if (data == 3.14159) {
|
||||
data = 0.25
|
||||
} else if (data == 3.1415) {
|
||||
data = 0.15
|
||||
}
|
||||
options.value = {
|
||||
title: {
|
||||
text: '稳态综合评估',
|
||||
x: 'center',
|
||||
y: '0%'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
borderColor: '#fff',
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
formatter: function (params: any) {
|
||||
if (params.value >= 5) {
|
||||
return params.name + ' : ' + '优质'
|
||||
} else if (params.value > 4 && params.value <= 5) {
|
||||
return params.name + ' : ' + '良好'
|
||||
} else if (params.value > 3 && params.value <= 4) {
|
||||
return params.name + ' : ' + '合格'
|
||||
} else if (params.value > 2 && params.value <= 3) {
|
||||
return params.name + ' : ' + '较差'
|
||||
} else if (params.value <= 2 && params.value >= 1) {
|
||||
return params.name + ' : ' + '极差'
|
||||
} else if (params.value >= 0.25 && params.value < 1) {
|
||||
return params.name + ' : ' + '暂无数据'
|
||||
} else if (params.value <= 0.15 && params.value >= 0) {
|
||||
return params.name + ' : ' + '/'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
name: '指标',
|
||||
type: 'category',
|
||||
data: ['稳态综合评估'],
|
||||
axisLabel: {
|
||||
margin: 10
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
symbol: ['none', 'arrow']
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: {
|
||||
name: '等级',
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 5,
|
||||
axisLabel: {
|
||||
show: true,
|
||||
// 这里重新定义就可以
|
||||
formatter: function (value: number) {
|
||||
var texts = []
|
||||
if (value === 1) {
|
||||
texts.push('1级')
|
||||
} else if (value === 2) {
|
||||
texts.push('2级')
|
||||
} else if (value === 3) {
|
||||
texts.push('3级')
|
||||
} else if (value === 4) {
|
||||
texts.push('4级')
|
||||
} else if (value === 5) {
|
||||
texts.push('5级')
|
||||
}
|
||||
return texts
|
||||
}
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
symbol: ['none', 'arrow']
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '综合评估',
|
||||
type: 'bar',
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
distance: 2,
|
||||
color: '#fff',
|
||||
fontWeight: 'bolder'
|
||||
},
|
||||
barWidth: '45',
|
||||
data: [
|
||||
{
|
||||
value: data
|
||||
}
|
||||
],
|
||||
markLine: {
|
||||
silent: false,
|
||||
symbol: 'circle',
|
||||
data: grade.map((item, index) => {
|
||||
return {
|
||||
yAxis: grade.length - index,
|
||||
name: item.name,
|
||||
lineStyle: {
|
||||
color: item.color
|
||||
},
|
||||
label: {
|
||||
color: item.color,
|
||||
formatter: item.name
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
itemStyle: {
|
||||
color: (params: any) => {
|
||||
if (params.value > 5) {
|
||||
return gradeColor5[0]
|
||||
} else if (params.value > 4) {
|
||||
return gradeColor5[1]
|
||||
} else if (params.value > 3) {
|
||||
return gradeColor5[2]
|
||||
} else if (params.value > 2) {
|
||||
return gradeColor5[3]
|
||||
} else {
|
||||
return gradeColor5[4]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
options: {
|
||||
dataZoom: null
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
@@ -1,136 +1,136 @@
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<TableHeader ref="TableHeaderRef" :showSearch="false">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="日期">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item label="指标">
|
||||
<el-radio-group v-model="formData.harmState">
|
||||
<el-radio-button :label="0">谐波电压含有率</el-radio-button>
|
||||
<el-radio-button :label="1">谐波电流幅值</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-slot:operation>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
|
||||
<vxe-table :data="analysisData" v-bind="defaultAttribute">
|
||||
<vxe-column field="name" title="指标" width="140px"></vxe-column>
|
||||
<vxe-column
|
||||
:field="index.toString()"
|
||||
:title="item + 1 + '次'"
|
||||
v-for="(item, index) in 49"
|
||||
width="80px"
|
||||
></vxe-column>
|
||||
</vxe-table>
|
||||
<div style="flex: 1" class="mt10" v-loading="loading">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getHarmInHarmData } from '@/api/harmonic-boot/inHarm'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
const tableStore = new TableStore({
|
||||
url: '',
|
||||
method: 'POST',
|
||||
column: []
|
||||
})
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
id: monitoringPoint.state.lineId,
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
harmState: 0
|
||||
})
|
||||
const analysisData = ref<any>([])
|
||||
const options = ref({})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.id = monitoringPoint.state.lineId
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
getHarmInHarmData(formData).then((res: any) => {
|
||||
let xName = ''
|
||||
analysisData.value = []
|
||||
if (formData.harmState === 1) {
|
||||
xName = 'A'
|
||||
analysisData.value.push(
|
||||
{
|
||||
name: '谐波电流幅值(A)',
|
||||
originData: res.data.harmInHarmValue.map((item: number) =>
|
||||
item == null || item == 3.14159 ? 0.14159 : Math.floor(item * 1000) / 1000
|
||||
),
|
||||
...res.data.harmInHarmValue.map((item: number) =>
|
||||
item == null || item == 3.14159 ? '/' : Math.floor(item * 1000) / 1000
|
||||
)
|
||||
},
|
||||
{
|
||||
name: '国标限值(A)',
|
||||
originData: res.data.harmInOverLimit,
|
||||
...res.data.harmInOverLimit
|
||||
}
|
||||
)
|
||||
} else {
|
||||
xName = '%'
|
||||
analysisData.value.push(
|
||||
{
|
||||
name: '谐波电压含有率(%)',
|
||||
originData: res.data.harmInHarmValue.map((item: number) =>
|
||||
item == null || item == 3.14159 ? 0.14159 : Math.floor(item * 1000) / 1000
|
||||
),
|
||||
...res.data.harmInHarmValue.map((item: number) =>
|
||||
item == null || item == 3.14159 ? '/' : Math.floor(item * 1000) / 1000
|
||||
)
|
||||
},
|
||||
{
|
||||
name: '国标限值(%)',
|
||||
originData: res.data.harmInOverLimit,
|
||||
...res.data.harmInOverLimit
|
||||
}
|
||||
)
|
||||
}
|
||||
options.value = {
|
||||
xAxis: {
|
||||
name: '次数',
|
||||
type: 'category',
|
||||
data: Array.from({ length: 49 }, (_, i) => `${i + 2}次`)
|
||||
},
|
||||
yAxis: {
|
||||
name: xName,
|
||||
type: 'value'
|
||||
},
|
||||
color: ['#2E8B57', '#DAA520'],
|
||||
series: analysisData.value.map((item: any) => {
|
||||
return {
|
||||
name: item.name,
|
||||
data: item.originData,
|
||||
type: 'bar'
|
||||
}
|
||||
}),
|
||||
options: {
|
||||
// dataZoom: null
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
provide('tableStore', tableStore)
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<TableHeader ref="TableHeaderRef" :showSearch="false">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item label="指标">
|
||||
<el-radio-group v-model="formData.harmState">
|
||||
<el-radio-button :label="0">谐波电压含有率</el-radio-button>
|
||||
<el-radio-button :label="1">谐波电流幅值</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-slot:operation>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
|
||||
<vxe-table :data="analysisData" v-bind="defaultAttribute">
|
||||
<vxe-column field="name" title="指标" width="140px"></vxe-column>
|
||||
<vxe-column
|
||||
:field="index.toString()"
|
||||
:title="item + 1 + '次'"
|
||||
v-for="(item, index) in 49"
|
||||
width="80px"
|
||||
></vxe-column>
|
||||
</vxe-table>
|
||||
<div style="flex: 1" class="mt10" v-loading="loading">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getHarmInHarmData } from '@/api/harmonic-boot/inHarm'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
const tableStore = new TableStore({
|
||||
url: '',
|
||||
method: 'POST',
|
||||
column: []
|
||||
})
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
id: monitoringPoint.state.lineId,
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
harmState: 0
|
||||
})
|
||||
const analysisData = ref<any>([])
|
||||
const options = ref({})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.id = monitoringPoint.state.lineId
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
getHarmInHarmData(formData).then((res: any) => {
|
||||
let xName = ''
|
||||
analysisData.value = []
|
||||
if (formData.harmState === 1) {
|
||||
xName = 'A'
|
||||
analysisData.value.push(
|
||||
{
|
||||
name: '谐波电流幅值(A)',
|
||||
originData: res.data.harmInHarmValue.map((item: number) =>
|
||||
item == null || item == 3.14159 ? 0.14159 : Math.floor(item * 1000) / 1000
|
||||
),
|
||||
...res.data.harmInHarmValue.map((item: number) =>
|
||||
item == null || item == 3.14159 ? '/' : Math.floor(item * 1000) / 1000
|
||||
)
|
||||
},
|
||||
{
|
||||
name: '国标限值(A)',
|
||||
originData: res.data.harmInOverLimit,
|
||||
...res.data.harmInOverLimit
|
||||
}
|
||||
)
|
||||
} else {
|
||||
xName = '%'
|
||||
analysisData.value.push(
|
||||
{
|
||||
name: '谐波电压含有率(%)',
|
||||
originData: res.data.harmInHarmValue.map((item: number) =>
|
||||
item == null || item == 3.14159 ? 0.14159 : Math.floor(item * 1000) / 1000
|
||||
),
|
||||
...res.data.harmInHarmValue.map((item: number) =>
|
||||
item == null || item == 3.14159 ? '/' : Math.floor(item * 1000) / 1000
|
||||
)
|
||||
},
|
||||
{
|
||||
name: '国标限值(%)',
|
||||
originData: res.data.harmInOverLimit,
|
||||
...res.data.harmInOverLimit
|
||||
}
|
||||
)
|
||||
}
|
||||
options.value = {
|
||||
xAxis: {
|
||||
name: '次数',
|
||||
type: 'category',
|
||||
data: Array.from({ length: 49 }, (_, i) => `${i + 2}次`)
|
||||
},
|
||||
yAxis: {
|
||||
name: xName,
|
||||
type: 'value'
|
||||
},
|
||||
color: ['#2E8B57', '#DAA520'],
|
||||
series: analysisData.value.map((item: any) => {
|
||||
return {
|
||||
name: item.name,
|
||||
data: item.originData,
|
||||
type: 'bar'
|
||||
}
|
||||
}),
|
||||
options: {
|
||||
// dataZoom: null
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
provide('tableStore', tableStore)
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<TableHeader ref="TableHeaderRef" :showSearch="false">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="日期">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item label="对比">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,277 +1,277 @@
|
||||
<template>
|
||||
<div class="panorama" :style="height">
|
||||
<div class="mapBox" v-show="lineInfo">
|
||||
<DatePicker ref="datePickerRef" style="display: none" theCurrentTime />
|
||||
<el-form :inline="true" :model="form" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<Area ref="areaRef" :show-all-levels="false" v-model="form.orgNo" style="width: 100px"
|
||||
@changeValue="changeValue" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="form.isUpToGrid" style="width: 100px" @change="info">
|
||||
<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div class="Icon" @click="reset">
|
||||
<Icon name="fa fa-refresh" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 地图 -->
|
||||
<Map v-if="VITE_FLAG" ref="mapRef" @changeValue="changeValue" :lineInfo="lineInfo" @drop="drop"
|
||||
@show="infoShow" />
|
||||
<div v-show="lineInfo">
|
||||
<!-- 省级 -->
|
||||
<div v-show="control == 1">
|
||||
<mapL ref="mapLRef" class="mapL" @LookMap="LookMap" @GridDiagram="GridDiagram" />
|
||||
<mapR ref="mapRRef" class="mapR" />
|
||||
</div>
|
||||
<!-- 市级 -->
|
||||
<!-- <div v-show="control == 4"> -->
|
||||
<div v-show="control == 2">
|
||||
<cityMapL ref="cityMapLRef" class="mapL" @LookMap="LookMap" @GridDiagram="GridDiagram" />
|
||||
<cityMapR ref="cityMapRRef" class="mapR" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Info v-if="!lineInfo" ref="InfoRef" @back="lineInfo = true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, nextTick, ref, provide } from 'vue'
|
||||
import Area from '@/components/form/area/index.vue'
|
||||
import Map from './components/map.vue'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { Search, Refresh } from '@element-plus/icons-vue'
|
||||
import mapL from './components/mapL.vue'
|
||||
import mapR from './components/mapR.vue'
|
||||
import cityMapL from './components/cityMapL.vue'
|
||||
import cityMapR from './components/cityMapR.vue'
|
||||
import Info from './components/line/info.vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
const VITE_FLAG = import.meta.env.VITE_NAME == 'jibei'
|
||||
|
||||
const dictData = useDictData()
|
||||
defineOptions({
|
||||
name: 'panorama'
|
||||
})
|
||||
|
||||
const datePickerRef = ref()
|
||||
const areaRef = ref()
|
||||
const lineInfo = ref(true)
|
||||
const mapRef = ref()
|
||||
const mapLRef = ref()
|
||||
const InfoRef = ref()
|
||||
const mapRRef = ref()
|
||||
const cityMapLRef = ref()
|
||||
const cityMapRRef = ref()
|
||||
|
||||
// const list: any = [dictData.state.area[0], ...dictData.state.area[0].children]
|
||||
const options: any = ref([
|
||||
{
|
||||
name: dictData.state.area[0].name,
|
||||
id: 0
|
||||
},
|
||||
{
|
||||
name: '上送网公司',
|
||||
id: 1
|
||||
}
|
||||
])
|
||||
const control = ref(1)
|
||||
const form: any = ref({
|
||||
name: '',
|
||||
orgNo: dictData.state.area[0].id,
|
||||
areaName: dictData.state.area[0]?.name,
|
||||
isUpToGrid: 0
|
||||
})
|
||||
|
||||
const height = mainHeight(10)
|
||||
// 获取区域名称
|
||||
const changeValue = (e: any) => {
|
||||
VITE_FLAG ? mapRef.value.locatePositions(e) : ''
|
||||
form.value.orgNo = e.data.id //list.filter((item: any) => item.code == e.orgId)[0]?.id || dictData.state.area[0].id
|
||||
form.value.areaName = e.data.name
|
||||
options.value[0].name = e.data.areaName
|
||||
|
||||
control.value = e.data.level
|
||||
|
||||
info()
|
||||
}
|
||||
//点击监测点详情
|
||||
const drop = (id: string) => {
|
||||
lineInfo.value = false
|
||||
nextTick(() => {
|
||||
InfoRef.value.open(id)
|
||||
})
|
||||
}
|
||||
// 关闭左右数据展示
|
||||
const infoShow = (e: boolean) => {
|
||||
mapLRef.value.show = e
|
||||
mapRRef.value.show = e
|
||||
cityMapLRef.value.show = e
|
||||
cityMapRRef.value.show = e
|
||||
}
|
||||
// 地图控制图层
|
||||
const LookMap = (row: any, key?: any) => {
|
||||
VITE_FLAG ? mapRef.value.addMarkers({ ...row, type: 1 }, key) : ''
|
||||
}
|
||||
const LngLat = [
|
||||
{
|
||||
name: '唐山',
|
||||
LngLat: [118.335849137, 39.7513593355],
|
||||
zoom: 8
|
||||
},
|
||||
{
|
||||
name: '张家口',
|
||||
LngLat: [115.032504679, 40.8951549951],
|
||||
zoom: 7
|
||||
},
|
||||
{
|
||||
name: '秦皇岛',
|
||||
LngLat: [119.185113833, 40.1179119754],
|
||||
zoom: 8.3
|
||||
},
|
||||
{
|
||||
name: '承德',
|
||||
LngLat: [117.548498365, 41.3775890632],
|
||||
zoom: 7.3
|
||||
},
|
||||
{
|
||||
name: '廊坊',
|
||||
LngLat: [116.628004129, 39.0589378611],
|
||||
zoom: 8
|
||||
},
|
||||
{
|
||||
name: '超高压',
|
||||
LngLat: [116.84428600000001, 40.57707185292256],
|
||||
zoom: 6.709267680647425
|
||||
},
|
||||
{
|
||||
name: '风光储',
|
||||
LngLat: [116.84428600000001, 40.57707185292256],
|
||||
zoom: 6.709267680647425
|
||||
}
|
||||
]
|
||||
//区域统计展示切换
|
||||
const GridDiagram = (k?: number, num?: number) => {
|
||||
VITE_FLAG ? mapRef.value.radiusPop(k) : ''
|
||||
if (num == 3) {
|
||||
// form.value.areaName
|
||||
let value = LngLat.filter(item => item.name == form.value.areaName)[0]
|
||||
|
||||
if (value) VITE_FLAG ? mapRef.value.flyTo({ coordinate: value.LngLat }, value.zoom) : ''
|
||||
} else {
|
||||
VITE_FLAG ? mapRef.value.flyTo({ coordinate: [116.84428600000001, 40.57707185292256] }, 6.709267680647425) : ''
|
||||
}
|
||||
}
|
||||
const info = () => {
|
||||
form.value.startTime = datePickerRef.value.timeValue[0]
|
||||
form.value.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
form.value.endTime = datePickerRef.value.timeValue[1]
|
||||
form.value.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
|
||||
form.value.type = datePickerRef.value.interval
|
||||
|
||||
VITE_FLAG ? mapRef.value.grids(form.value) : ''
|
||||
if (control.value == 1) {
|
||||
mapLRef.value.info(form.value)
|
||||
mapRRef.value.info(form.value)
|
||||
} else {
|
||||
cityMapRRef.value.info(form.value)
|
||||
cityMapLRef.value.info(form.value)
|
||||
}
|
||||
}
|
||||
// 重置
|
||||
const reset = () => {
|
||||
form.value = {
|
||||
name: '',
|
||||
orgNo: dictData.state.area[0].id,
|
||||
areaName: dictData.state.area[0]?.name,
|
||||
isUpToGrid: 0
|
||||
}
|
||||
changeValue({ data: dictData.state.area[0] })
|
||||
}
|
||||
onMounted(() => {
|
||||
// info()
|
||||
changeValue({ data: dictData.state.area[0] })
|
||||
// aaa()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.mapBox) {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: calc(50% + 45px);
|
||||
|
||||
z-index: 1;
|
||||
|
||||
.el-select {
|
||||
min-width: 100px;
|
||||
|
||||
.el-select__wrapper {
|
||||
height: 46px !important;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.Icon {
|
||||
height: 46px;
|
||||
width: 46px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
cursor: pointer;
|
||||
|
||||
.fa-refresh {
|
||||
color: var(--el-color-primary) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__wrapper {
|
||||
height: 46px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.mapL {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
// z-index: 1;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.mapR {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
// z-index: 1;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.panorama {
|
||||
margin: 10px 0 0 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.el-button:focus {
|
||||
color: var(--color);
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.el-button:hover {
|
||||
color: var(--el-color-white);
|
||||
border-color: var(--el-button-hover-bg-color);
|
||||
background-color: var(--el-button-hover-bg-color);
|
||||
outline: 0;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="panorama" :style="height">
|
||||
<div class="mapBox" v-show="lineInfo">
|
||||
<DatePicker ref="datePickerRef" style="display: none" theCurrentTime />
|
||||
<el-form :inline="true" :model="form" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<Area ref="areaRef" :show-all-levels="false" v-model="form.orgNo" style="width: 100px"
|
||||
@changeValue="changeValue" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select v-model="form.isUpToGrid" style="width: 100px" @change="info">
|
||||
<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<div class="Icon" @click="reset">
|
||||
<Icon name="fa fa-refresh" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!-- 地图 -->
|
||||
<Map v-if="VITE_FLAG" ref="mapRef" @changeValue="changeValue" :lineInfo="lineInfo" @drop="drop"
|
||||
@show="infoShow" />
|
||||
<div v-show="lineInfo">
|
||||
<!-- 省级 -->
|
||||
<div v-show="control == 1">
|
||||
<mapL ref="mapLRef" class="mapL" @LookMap="LookMap" @GridDiagram="GridDiagram" />
|
||||
<mapR ref="mapRRef" class="mapR" />
|
||||
</div>
|
||||
<!-- 市级 -->
|
||||
<!-- <div v-show="control == 4"> -->
|
||||
<div v-show="control == 2">
|
||||
<cityMapL ref="cityMapLRef" class="mapL" @LookMap="LookMap" @GridDiagram="GridDiagram" />
|
||||
<cityMapR ref="cityMapRRef" class="mapR" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Info v-if="!lineInfo" ref="InfoRef" @back="lineInfo = true" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, nextTick, ref, provide } from 'vue'
|
||||
import Area from '@/components/form/area/index.vue'
|
||||
import Map from './components/map.vue'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { Search, Refresh } from '@element-plus/icons-vue'
|
||||
import mapL from './components/mapL.vue'
|
||||
import mapR from './components/mapR.vue'
|
||||
import cityMapL from './components/cityMapL.vue'
|
||||
import cityMapR from './components/cityMapR.vue'
|
||||
import Info from './components/line/info.vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
const VITE_FLAG = import.meta.env.VITE_NAME == 'jibei'
|
||||
|
||||
const dictData = useDictData()
|
||||
defineOptions({
|
||||
name: 'panorama'
|
||||
})
|
||||
|
||||
const datePickerRef = ref()
|
||||
const areaRef = ref()
|
||||
const lineInfo = ref(true)
|
||||
const mapRef = ref()
|
||||
const mapLRef = ref()
|
||||
const InfoRef = ref()
|
||||
const mapRRef = ref()
|
||||
const cityMapLRef = ref()
|
||||
const cityMapRRef = ref()
|
||||
|
||||
// const list: any = [dictData.state.area[0], ...dictData.state.area[0].children]
|
||||
const options: any = ref([
|
||||
{
|
||||
name: dictData.state.area[0].name,
|
||||
id: 0
|
||||
},
|
||||
{
|
||||
name: '上送网公司',
|
||||
id: 1
|
||||
}
|
||||
])
|
||||
const control = ref(1)
|
||||
const form: any = ref({
|
||||
name: '',
|
||||
orgNo: dictData.state.area[0].id,
|
||||
areaName: dictData.state.area[0]?.name,
|
||||
isUpToGrid: 0
|
||||
})
|
||||
|
||||
const height = mainHeight(10)
|
||||
// 获取区域名称
|
||||
const changeValue = (e: any) => {
|
||||
VITE_FLAG ? mapRef.value.locatePositions(e) : ''
|
||||
form.value.orgNo = e.data.id //list.filter((item: any) => item.code == e.orgId)[0]?.id || dictData.state.area[0].id
|
||||
form.value.areaName = e.data.name
|
||||
options.value[0].name = e.data.areaName
|
||||
|
||||
control.value = e.data.level
|
||||
|
||||
info()
|
||||
}
|
||||
//点击监测点详情
|
||||
const drop = (id: string) => {
|
||||
lineInfo.value = false
|
||||
nextTick(() => {
|
||||
InfoRef.value.open(id)
|
||||
})
|
||||
}
|
||||
// 关闭左右数据展示
|
||||
const infoShow = (e: boolean) => {
|
||||
mapLRef.value.show = e
|
||||
mapRRef.value.show = e
|
||||
cityMapLRef.value.show = e
|
||||
cityMapRRef.value.show = e
|
||||
}
|
||||
// 地图控制图层
|
||||
const LookMap = (row: any, key?: any) => {
|
||||
VITE_FLAG ? mapRef.value.addMarkers({ ...row, type: 1 }, key) : ''
|
||||
}
|
||||
const LngLat = [
|
||||
{
|
||||
name: '唐山',
|
||||
LngLat: [118.335849137, 39.7513593355],
|
||||
zoom: 8
|
||||
},
|
||||
{
|
||||
name: '张家口',
|
||||
LngLat: [115.032504679, 40.8951549951],
|
||||
zoom: 7
|
||||
},
|
||||
{
|
||||
name: '秦皇岛',
|
||||
LngLat: [119.185113833, 40.1179119754],
|
||||
zoom: 8.3
|
||||
},
|
||||
{
|
||||
name: '承德',
|
||||
LngLat: [117.548498365, 41.3775890632],
|
||||
zoom: 7.3
|
||||
},
|
||||
{
|
||||
name: '廊坊',
|
||||
LngLat: [116.628004129, 39.0589378611],
|
||||
zoom: 8
|
||||
},
|
||||
{
|
||||
name: '超高压',
|
||||
LngLat: [116.84428600000001, 40.57707185292256],
|
||||
zoom: 6.709267680647425
|
||||
},
|
||||
{
|
||||
name: '风光储',
|
||||
LngLat: [116.84428600000001, 40.57707185292256],
|
||||
zoom: 6.709267680647425
|
||||
}
|
||||
]
|
||||
//区域统计展示切换
|
||||
const GridDiagram = (k?: number, num?: number) => {
|
||||
VITE_FLAG ? mapRef.value.radiusPop(k) : ''
|
||||
if (num == 3) {
|
||||
// form.value.areaName
|
||||
let value = LngLat.filter(item => item.name == form.value.areaName)[0]
|
||||
|
||||
if (value) VITE_FLAG ? mapRef.value.flyTo({ coordinate: value.LngLat }, value.zoom) : ''
|
||||
} else {
|
||||
VITE_FLAG ? mapRef.value.flyTo({ coordinate: [116.84428600000001, 40.57707185292256] }, 6.709267680647425) : ''
|
||||
}
|
||||
}
|
||||
const info = () => {
|
||||
form.value.startTime = datePickerRef.value.timeValue[0]
|
||||
form.value.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
form.value.endTime = datePickerRef.value.timeValue[1]
|
||||
form.value.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
|
||||
form.value.type = datePickerRef.value.interval
|
||||
|
||||
VITE_FLAG ? mapRef.value.grids(form.value) : ''
|
||||
if (control.value == 1) {
|
||||
mapLRef.value.info(form.value)
|
||||
mapRRef.value.info(form.value)
|
||||
} else {
|
||||
cityMapRRef.value.info(form.value)
|
||||
cityMapLRef.value.info(form.value)
|
||||
}
|
||||
}
|
||||
// 重置
|
||||
const reset = () => {
|
||||
form.value = {
|
||||
name: '',
|
||||
orgNo: dictData.state.area[0].id,
|
||||
areaName: dictData.state.area[0]?.name,
|
||||
isUpToGrid: 0
|
||||
}
|
||||
changeValue({ data: dictData.state.area[0] })
|
||||
}
|
||||
onMounted(() => {
|
||||
// info()
|
||||
changeValue({ data: dictData.state.area[0] })
|
||||
// aaa()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.mapBox) {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: calc(50% + 45px);
|
||||
|
||||
z-index: 1;
|
||||
|
||||
.el-select {
|
||||
min-width: 100px;
|
||||
|
||||
.el-select__wrapper {
|
||||
height: 46px !important;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.Icon {
|
||||
height: 46px;
|
||||
width: 46px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
cursor: pointer;
|
||||
|
||||
.fa-refresh {
|
||||
color: var(--el-color-primary) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-input__wrapper {
|
||||
height: 46px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.mapL {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
// z-index: 1;
|
||||
left: 10px;
|
||||
}
|
||||
|
||||
.mapR {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
// z-index: 1;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
.panorama {
|
||||
margin: 10px 0 0 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.el-button:focus {
|
||||
color: var(--color);
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.el-button:hover {
|
||||
color: var(--el-color-white);
|
||||
border-color: var(--el-button-hover-bg-color);
|
||||
background-color: var(--el-button-hover-bg-color);
|
||||
outline: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -476,6 +476,7 @@ tableStore.table.params.name = ''
|
||||
provide('tableStore', tableStore)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
.card-list {
|
||||
display: flex;
|
||||
.monitoringPoints {
|
||||
|
||||
@@ -518,6 +518,7 @@ tableStore.table.params.name = ''
|
||||
provide('tableStore', tableStore)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
.card-list {
|
||||
display: flex;
|
||||
.monitoringPoints {
|
||||
|
||||
@@ -1,137 +1,170 @@
|
||||
<template>
|
||||
<el-dialog draggable width="1550px" class="cn-operate-dialog" v-model="dialogVisible" :title="title">
|
||||
<div style="display: flex">
|
||||
<div :style="height1" class="mr10 box" style="width: 600px">
|
||||
<vxe-table
|
||||
height="auto"
|
||||
:data="TableData"
|
||||
v-bind="defaultAttribute"
|
||||
ref="tableRef"
|
||||
:row-config="{ isCurrent: true, isHover: true }"
|
||||
@current-change="currentChangeEvent"
|
||||
>
|
||||
<vxe-column type="seq" title="序号" width="60px"></vxe-column>
|
||||
<vxe-column field="date" title="日期"></vxe-column>
|
||||
<vxe-column field="bdName" title="所属电站(场站)" width="120px"></vxe-column>
|
||||
<vxe-column field="monitorName" title="监测点名称" width="120px"></vxe-column>
|
||||
<vxe-column field="timeSum" title="异常时间(分钟)" width="80px"></vxe-column>
|
||||
<vxe-column field="errCount" title="异常次数" width="80px"></vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
|
||||
<div :style="height" style="width: 920px" v-loading="loading1">
|
||||
<vxe-table
|
||||
height="auto"
|
||||
:data="TableData1.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
|
||||
v-bind="defaultAttribute"
|
||||
>
|
||||
<vxe-column type="seq" title="序号" width="80px">
|
||||
<template #default="{ rowIndex }">
|
||||
<span>{{ (pageNum - 1) * pageSize + rowIndex + 1 }}</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="time" title="时间" width="150px"></vxe-column>
|
||||
<vxe-column field="targetName" title="指标类型" min-width="80px"></vxe-column>
|
||||
<vxe-column field="phaseType" title="相别" width="60px">
|
||||
<template v-slot="{ row }">
|
||||
{{ row.phaseType=='T'?'/':row.phaseType }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="rangeDesc" title="合理范围" min-width="90px"></vxe-column>
|
||||
<vxe-column field="max" title="最大" width="85px" :formatter="formatter"></vxe-column>
|
||||
<vxe-column field="min" title="最小" width="85px" :formatter="formatter"></vxe-column>
|
||||
<vxe-column field="avg" title="平均" width="85px" :formatter="formatter"></vxe-column>
|
||||
<vxe-column field="cp95" title="CP95" width="85px" :formatter="formatter"></vxe-column>
|
||||
</vxe-table>
|
||||
<div class="table-pagination">
|
||||
<el-pagination
|
||||
v-model:currentPage="pageNum"
|
||||
v-model:page-size="pageSize"
|
||||
:page-sizes="[10, 20, 50, 100, 200]"
|
||||
background
|
||||
layout="sizes,total, ->, prev, pager, next, jumper"
|
||||
:total="TableData1.length"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, inject } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { monitorAbnormalTable, monitorAbnormalTableDetail } from '@/api/device-boot/dataVerify'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
const dialogVisible = ref(false)
|
||||
const height1 = mainHeight(-110, 2)
|
||||
const height = mainHeight(10, 2)
|
||||
const tableRef = ref()
|
||||
const title = ref('')
|
||||
const loading1 = ref(false)
|
||||
const TableData = ref([])
|
||||
const TableData1 = ref([])
|
||||
const pageNum = ref(1)
|
||||
const pageSize = ref(20)
|
||||
const numKey = ref(0)
|
||||
const targetKey = ref('')
|
||||
const open = (data: anyObj, time: string[], num: number) => {
|
||||
// title.value = (num == 0 ? data.targetName : data.monitorName) + '_异常监测点详情'
|
||||
title.value ='异常监测点详情'
|
||||
TableData.value = []
|
||||
numKey.value = num
|
||||
targetKey.value = data.key
|
||||
monitorAbnormalTable({
|
||||
monitorIds: num == 0 ? data.ids : [data.monitorId],
|
||||
targetKey: num == 0 ? data.key : '',
|
||||
searchBeginTime: time[0],
|
||||
searchEndTime: time[1]
|
||||
}).then(res => {
|
||||
TableData.value = res.data
|
||||
tableRef.value.setCurrentRow(TableData.value[0])
|
||||
currentChangeEvent()
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
const currentChangeEvent = () => {
|
||||
loading1.value = true
|
||||
let data = tableRef.value.getCurrentRecord()
|
||||
TableData1.value = []
|
||||
monitorAbnormalTableDetail({
|
||||
monitorIds: [data.monitorId],
|
||||
searchBeginTime: data.date,
|
||||
targetKey: numKey.value == 0 ? targetKey.value : ''
|
||||
})
|
||||
.then(res => {
|
||||
TableData1.value = res.data
|
||||
loading1.value = false
|
||||
pageNum.value = 1
|
||||
})
|
||||
.catch(() => {
|
||||
loading1.value = false
|
||||
})
|
||||
}
|
||||
const formatter = (row: any) => {
|
||||
return row.cellValue == null ? '/' : (row.cellValue - 0).toFixed(2)
|
||||
}
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.table-pagination {
|
||||
height: 58px;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
background-color: var(--ba-bg-color-overlay);
|
||||
padding: 13px 15px;
|
||||
border-left: 1px solid #e4e7e9;
|
||||
border-right: 1px solid #e4e7e9;
|
||||
border-bottom: 1px solid #e4e7e9;
|
||||
}
|
||||
:deep(.box) {
|
||||
.row--current {
|
||||
background-color: var(--el-color-primary-light-8) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<el-dialog draggable width="1550px" class="cn-operate-dialog" v-model="dialogVisible" :title="title">
|
||||
<div style="display: flex">
|
||||
<div :style="height1" class="mr10 box" style="width: 600px">
|
||||
<vxe-table
|
||||
height="auto"
|
||||
:data="TableData"
|
||||
v-bind="defaultAttribute"
|
||||
ref="tableRef"
|
||||
:row-config="{ isCurrent: true, isHover: true }"
|
||||
@current-change="currentChangeEvent"
|
||||
>
|
||||
<vxe-column type="seq" title="序号" width="60px"></vxe-column>
|
||||
<vxe-column field="date" title="日期"></vxe-column>
|
||||
<vxe-column field="bdName" title="所属电站(场站)" width="120px"></vxe-column>
|
||||
<vxe-column field="monitorName" title="监测点名称" width="120px"></vxe-column>
|
||||
<vxe-column field="timeSum" title="异常时间(分钟)" width="80px"></vxe-column>
|
||||
<vxe-column field="errCount" title="异常次数" width="80px"></vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
|
||||
<div :style="height" style="width: 920px" v-loading="loading1">
|
||||
<vxe-table
|
||||
height="auto"
|
||||
:data="TableData1.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
|
||||
v-bind="defaultAttribute"
|
||||
>
|
||||
<vxe-column type="seq" title="序号" width="80px">
|
||||
<template #default="{ rowIndex }">
|
||||
<span>{{ (pageNum - 1) * pageSize + rowIndex + 1 }}</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="time" title="时间" width="150px"></vxe-column>
|
||||
<vxe-column field="targetName" title="指标类型" min-width="80px"></vxe-column>
|
||||
<vxe-column field="phaseType" title="相别" width="60px">
|
||||
<template v-slot="{ row }">
|
||||
{{ row.phaseType == 'T' ? '/' : row.phaseType }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="rangeDesc" title="合理范围" min-width="90px"></vxe-column>
|
||||
<vxe-column
|
||||
field="max"
|
||||
title="最大"
|
||||
width="85px"
|
||||
:formatter="formatter"
|
||||
v-if="showColumn"
|
||||
></vxe-column>
|
||||
<vxe-column
|
||||
field="min"
|
||||
title="最小"
|
||||
width="85px"
|
||||
:formatter="formatter"
|
||||
v-if="showColumn"
|
||||
></vxe-column>
|
||||
<vxe-column
|
||||
field="avg"
|
||||
title="平均"
|
||||
width="85px"
|
||||
:formatter="formatter"
|
||||
v-if="showColumn"
|
||||
></vxe-column>
|
||||
<vxe-column
|
||||
field="cp95"
|
||||
title="CP95"
|
||||
width="85px"
|
||||
:formatter="formatter"
|
||||
v-if="showColumn"
|
||||
></vxe-column>
|
||||
<vxe-column
|
||||
field="featureAmplitude"
|
||||
title="幅值"
|
||||
width="85px"
|
||||
:formatter="formatter"
|
||||
v-if="!showColumn"
|
||||
></vxe-column>
|
||||
</vxe-table>
|
||||
<div class="table-pagination">
|
||||
<el-pagination
|
||||
v-model:currentPage="pageNum"
|
||||
v-model:page-size="pageSize"
|
||||
:page-sizes="[10, 20, 50, 100, 200]"
|
||||
background
|
||||
layout="sizes,total, ->, prev, pager, next, jumper"
|
||||
:total="TableData1.length"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, inject } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { monitorAbnormalTable, monitorAbnormalTableDetail } from '@/api/device-boot/dataVerify'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
const dialogVisible = ref(false)
|
||||
const height1 = mainHeight(-110, 2)
|
||||
const height = mainHeight(10, 2)
|
||||
const tableRef = ref()
|
||||
const title = ref('')
|
||||
const loading1 = ref(false)
|
||||
const TableData = ref([])
|
||||
const TableData1 = ref([])
|
||||
const pageNum = ref(1)
|
||||
const pageSize = ref(20)
|
||||
const numKey = ref(0)
|
||||
const targetKey = ref('')
|
||||
const showColumn = ref(true)
|
||||
const open = (data: anyObj, time: string[], num: number) => {
|
||||
// title.value = (num == 0 ? data.targetName : data.monitorName) + '_异常监测点详情'
|
||||
title.value = '异常监测点详情'
|
||||
TableData.value = []
|
||||
numKey.value = num
|
||||
targetKey.value = data.key
|
||||
monitorAbnormalTable({
|
||||
monitorIds: num == 0 ? data.ids : [data.monitorId],
|
||||
targetKey: num == 0 ? data.key : '',
|
||||
searchBeginTime: time[0],
|
||||
searchEndTime: time[1]
|
||||
}).then(res => {
|
||||
TableData.value = res.data
|
||||
tableRef.value.setCurrentRow(TableData.value[0])
|
||||
currentChangeEvent()
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
const currentChangeEvent = () => {
|
||||
loading1.value = true
|
||||
let data = tableRef.value.getCurrentRecord()
|
||||
TableData1.value = []
|
||||
monitorAbnormalTableDetail({
|
||||
monitorIds: [data.monitorId],
|
||||
searchBeginTime: data.date,
|
||||
targetKey: numKey.value == 0 ? targetKey.value : ''
|
||||
})
|
||||
.then(res => {
|
||||
TableData1.value = res.data
|
||||
showColumn.value = res.data[0]?.featureAmplitude == null ? true : false
|
||||
loading1.value = false
|
||||
pageNum.value = 1
|
||||
})
|
||||
.catch(() => {
|
||||
loading1.value = false
|
||||
})
|
||||
}
|
||||
const formatter = (row: any) => {
|
||||
return row.cellValue == null ? '/' : (row.cellValue - 0).toFixed(2)
|
||||
}
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.table-pagination {
|
||||
height: 58px;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
background-color: var(--ba-bg-color-overlay);
|
||||
padding: 13px 15px;
|
||||
border-left: 1px solid #e4e7e9;
|
||||
border-right: 1px solid #e4e7e9;
|
||||
border-bottom: 1px solid #e4e7e9;
|
||||
}
|
||||
:deep(.box) {
|
||||
.row--current {
|
||||
background-color: var(--el-color-primary-light-8) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
121
src/views/pqs/runManage/runEvaluate/components/statistics_JB.vue
Normal file
121
src/views/pqs/runManage/runEvaluate/components/statistics_JB.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div style="height: 145px" class="box1">
|
||||
<!-- <div class="boxDiv hexagon">
|
||||
<div class="text-style" @click="change('')">{{ props.params.allNum }}</div>
|
||||
<div class="mt10 divBot">总数</div>
|
||||
</div>
|
||||
<div class="boxDiv hexagon hexagon1">
|
||||
<div class="text-style" @click="change('运行')">{{ props.params.runNum }}</div>
|
||||
<div class="mt10 divBot">在运</div>
|
||||
</div>
|
||||
<div class="boxDiv hexagon hexagon2">
|
||||
<div class="text-style" @click="change('调试')">{{ props.params.checkNum }}</div>
|
||||
<div class="mt10 divBot">调试</div>
|
||||
</div>
|
||||
<div class="boxDiv hexagon hexagon3">
|
||||
<div class="text-style" @click="change('停运')">{{ props.params.stopRunNum }}</div>
|
||||
<div class="mt10 divBot">停运</div>
|
||||
</div> -->
|
||||
<div class="statistics">
|
||||
<div class="divBox div1">
|
||||
<span class="iconfont icon-qiyezongshu" style="color: #57bc6e"></span>
|
||||
<span class="divBox_title">终端总数</span>
|
||||
<span class="divBox_num text-style" style="color: #57bc6e" @click="change('')">
|
||||
{{ props.params.allNum }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="divBox div2" style="width: 210px">
|
||||
<span class="iconfont icon-zaiyunshebei" style="color: #67c23a"></span>
|
||||
<span class="divBox_title">在运终端数</span>
|
||||
<span class="divBox_num text-style" style="color: #67c23a" @click="change('运行')">
|
||||
{{ props.params.runNum }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="statistics">
|
||||
<div class="divBox div3">
|
||||
<span class="iconfont icon-yichanglei_14feizhinengbiaozaiyunyichang" style="color: #ffbf00"></span>
|
||||
<span class="divBox_title">调试终端数</span>
|
||||
<span class="divBox_num text-style" style="color: #ffbf00" @click="change('调试')">
|
||||
{{ props.params.checkNum }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="divBox div4" style="width: 210px">
|
||||
<span class="iconfont icon-tingyunshijianguanli" style="color: #f56c6c"></span>
|
||||
<span class="divBox_title">停运终端数</span>
|
||||
<span class="divBox_num text-style" style="color: #f56c6c" @click="change('停运')">
|
||||
{{ props.params.stopRunNum }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import MyEChart from '@/components/echarts/MyEchart.vue'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { color } from '@/components/echarts/color'
|
||||
const emit = defineEmits(['change'])
|
||||
const height = mainHeight(330, 3)
|
||||
const props = defineProps({
|
||||
params: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
})
|
||||
const change = (e: string) => {
|
||||
emit('change', e)
|
||||
}
|
||||
const info = () => {}
|
||||
onMounted(() => {
|
||||
info()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
.statistics {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
.divBox {
|
||||
width: 210px;
|
||||
height: 70px;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
|
||||
.iconfont {
|
||||
font-size: 40px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
.divBox_title {
|
||||
font-weight: 550;
|
||||
}
|
||||
.divBox_num {
|
||||
font-size: 20px;
|
||||
font-weight: 550;
|
||||
margin-left: auto;
|
||||
font-family: AlimamaDongFangDaKai;
|
||||
}
|
||||
align-items: center;
|
||||
// text-align: center;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.div1 {
|
||||
background-color: #eef8f0;
|
||||
}
|
||||
.div2 {
|
||||
background-color: #67c23a24;
|
||||
}
|
||||
.div3 {
|
||||
background-color: #ffbf0024;
|
||||
}
|
||||
.div4 {
|
||||
background-color: #f56c6c24;
|
||||
}
|
||||
}
|
||||
.text-style {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<TableHeader date-picker ref="TableHeaderRef" :dateLabel="`数据统计时间`">
|
||||
<TableHeader date-picker ref="TableHeaderRef" >
|
||||
<template v-slot:select>
|
||||
<el-form-item label="运行状态">
|
||||
<el-select v-model="tableStore.table.params.lineRunFlag" clearable placeholder="请选择运行状态">
|
||||
@@ -23,7 +23,7 @@
|
||||
</TableHeader>
|
||||
<div class="card-list pt10" v-loading="tableStore.table.loading">
|
||||
<div class="monitoringPoints">
|
||||
<el-card style="height: 200px">
|
||||
<el-card style="height: 215px">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>终端统计</span>
|
||||
@@ -68,7 +68,7 @@
|
||||
<span style="width: 90px">终端总数</span>
|
||||
<span style="flex: 1">完整性(%)</span>
|
||||
<span style="width: 80px">在线率(%)</span>
|
||||
<span style="width: 80px">合格率(%)</span>
|
||||
<span style="width: 80px">异常率(%)</span>
|
||||
</div>
|
||||
<div :style="indicatorHeight" style="overflow-y: auto">
|
||||
<div v-for="o in abnormal" class="abnormal mb10">
|
||||
@@ -165,7 +165,7 @@
|
||||
</vxe-column>
|
||||
<vxe-column field="integrityRate" title="完整性(%)" width="100px"></vxe-column>
|
||||
<vxe-column field="onLineRate" title="在线率(%)" width="100px"></vxe-column>
|
||||
<vxe-column field="passRate" title="合格率(%)" width="100px"></vxe-column>
|
||||
<vxe-column field="passRate" title="异常率(%)" width="100px"></vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
<div class="table-pagination">
|
||||
@@ -191,7 +191,7 @@ import { onMounted, provide, ref } from 'vue'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import statistics from './components/statistics.vue'
|
||||
import statistics from './components/statistics_JB.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { getMonitorVerifyDay } from '@/api/device-boot/dataVerify'
|
||||
defineOptions({
|
||||
@@ -201,7 +201,7 @@ defineOptions({
|
||||
const dictData = useDictData()
|
||||
//字典获取监督对象类型
|
||||
const pageHeight = mainHeight(97)
|
||||
const indicatorHeight = mainHeight(447)
|
||||
const indicatorHeight = mainHeight(462)
|
||||
const monitoringPoints = ref({
|
||||
runNum: 0,
|
||||
abnormalNum: 0,
|
||||
@@ -269,7 +269,9 @@ const tableStore = new TableStore({
|
||||
statisticsList.value.checkNum = totalData.value.filter(item => item.runFlag === '调试').length
|
||||
statisticsList.value.stopRunNum = totalData.value.filter(item => item.runFlag === '停运').length
|
||||
|
||||
abnormal.value = tableStore.table.data
|
||||
abnormal.value = tableStore.table.data.filter(
|
||||
(k: any) => k.name != '上送国网' && k.name != '非上送国网'
|
||||
)
|
||||
// 合并子集数据 并去重
|
||||
|
||||
totalTable(101, '')
|
||||
@@ -484,7 +486,7 @@ provide('tableStore', tableStore)
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
.divBox {
|
||||
width: 200px;
|
||||
width: 215x;
|
||||
height: 70px;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
|
||||
@@ -195,16 +195,16 @@ const tableStore = new TableStore({
|
||||
render: 'buttons',
|
||||
fixed: 'right',
|
||||
buttons: [
|
||||
// {
|
||||
// name: 'edit',
|
||||
// title: '人工维护',
|
||||
// type: 'primary',
|
||||
// icon: 'el-icon-Plus',
|
||||
// render: 'basicButton',
|
||||
// click: async row => {
|
||||
// addFormRef.value.open(row)
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: 'edit',
|
||||
title: '人工维护',
|
||||
type: 'primary',
|
||||
icon: 'el-icon-Plus',
|
||||
render: 'basicButton',
|
||||
click: async row => {
|
||||
addFormRef.value.open(row)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'edit',
|
||||
title: '波形分析',
|
||||
|
||||
@@ -1,332 +1,332 @@
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%" v-loading="loading">
|
||||
<el-form :inline="true" class="fx-jcsb">
|
||||
<el-form-item label="日期">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-descriptions class="mt2" direction="vertical" :column="4" border>
|
||||
<el-descriptions-item align="center" label="名称">{{ data.name }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="可容忍">{{ data.krr }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="不可容忍">{{ data.bkrr }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div style="flex: 1" class="mt10">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getPlot } from '@/api/event-boot/monitor'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const loading = ref(true)
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const formData = reactive({
|
||||
lineIndex: monitoringPoint.state.lineId,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
})
|
||||
const data = reactive({
|
||||
name: '事件个数',
|
||||
gs: 0,
|
||||
krr: 0,
|
||||
bkrr: 0
|
||||
})
|
||||
const options = ref({})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.lineIndex = monitoringPoint.state.lineId
|
||||
formData.startTime = datePickerRef.value.timeValue[0]
|
||||
formData.endTime = datePickerRef.value.timeValue[1]
|
||||
getPlot(formData).then((res: any) => {
|
||||
const gongData = gongfunction(res.data.voltageToleranceCurveDataList)
|
||||
data.gs = res.data.voltageToleranceCurveDataList.length
|
||||
data.krr = gongData.pointI.length
|
||||
data.bkrr = gongData.pointIun.length
|
||||
console.log(gongData)
|
||||
options.value = {
|
||||
// backgroundColor: "#f9f9f9", //地图背景色深蓝
|
||||
title: {
|
||||
// text: `ITIC曲线(总统计:${gongData.pointI.length + gongData.pointIun.length}个,可容忍:${gongData.pointI.length}个,不可容忍:${gongData.pointIun.length}个)`
|
||||
text: `ITIC曲线`
|
||||
},
|
||||
legend: {
|
||||
data: ['上限', '下限', '可容忍事件', '不可容忍事件']
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
show: true,
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0,
|
||||
formatter: function (a: any) {
|
||||
var relVal = ''
|
||||
relVal = "<font style='color:" + "'>发生时间:" + a.value[2] + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>持续时间:" + a.value[0] + 's</font><br/>'
|
||||
relVal += "<font style='color:" + "'>特征幅值:" + a.value[1].toFixed(2) + '%</font>'
|
||||
return relVal
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'log',
|
||||
min: 0.001,
|
||||
max: 1000,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
name: 's'
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitNumber: 10,
|
||||
minInterval: 3,
|
||||
name: '%'
|
||||
}
|
||||
],
|
||||
color: ['#FF8C00', '#00BFFF', 'green', 'red'],
|
||||
options: {
|
||||
dataZoom: null,
|
||||
series: [
|
||||
{
|
||||
name: '上限',
|
||||
type: 'line',
|
||||
data: [
|
||||
[0.001, 200],
|
||||
[0.003, 140],
|
||||
[0.003, 120],
|
||||
[0.5, 120],
|
||||
[0.5, 110],
|
||||
[10, 110],
|
||||
[1000, 110]
|
||||
],
|
||||
showSymbol: false,
|
||||
tooltips: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '下限',
|
||||
type: 'line',
|
||||
data: [
|
||||
[0.02, 0],
|
||||
[0.02, 70],
|
||||
[0.5, 70],
|
||||
[0.5, 80],
|
||||
[10, 80],
|
||||
[10, 90],
|
||||
[1000, 90]
|
||||
],
|
||||
showSymbol: false,
|
||||
tooltips: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
data: gongData.pointI
|
||||
},
|
||||
{
|
||||
name: '不可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
data: gongData.pointIun
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function gongfunction(arr: any) {
|
||||
let standI = 0
|
||||
let unstandI = 0
|
||||
let standF = 0
|
||||
let unstandF = 0
|
||||
let total = 0
|
||||
let pointIun = []
|
||||
let pointI = []
|
||||
let pointF = []
|
||||
let pointFun = []
|
||||
total = arr.length
|
||||
if (total == 0) {
|
||||
} else {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let point = []
|
||||
let xx = arr[i].persistTime
|
||||
let yy = arr[i].eventValue
|
||||
let time = arr[i].time
|
||||
let eventId = arr[i].eventId
|
||||
// let index =arr[i].eventDetailIndex;
|
||||
point = [xx, yy, time, eventId]
|
||||
|
||||
if (xx <= 0.003) {
|
||||
let line = 0
|
||||
line = 250 - 30000 * xx
|
||||
if (yy > line) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 0.02) {
|
||||
if (yy > 120) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 0.5) {
|
||||
if (yy > 120 || yy < 70) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 10) {
|
||||
if (yy > 110 || yy < 80) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (yy > 110 || yy < 90) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (xx < 0.05) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else if (xx < 0.2) {
|
||||
if (yy > 50) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
} else if (xx < 0.5) {
|
||||
if (yy > 70) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (yy > 80) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
standI,
|
||||
unstandI,
|
||||
pointI,
|
||||
pointIun,
|
||||
standF,
|
||||
unstandF,
|
||||
pointF,
|
||||
pointFun
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%" v-loading="loading">
|
||||
<el-form :inline="true" class="fx-jcsb">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-descriptions class="mt2" direction="vertical" :column="4" border>
|
||||
<el-descriptions-item align="center" label="名称">{{ data.name }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="可容忍">{{ data.krr }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="不可容忍">{{ data.bkrr }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div style="flex: 1" class="mt10">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getPlot } from '@/api/event-boot/monitor'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const loading = ref(true)
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const formData = reactive({
|
||||
lineIndex: monitoringPoint.state.lineId,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
})
|
||||
const data = reactive({
|
||||
name: '事件个数',
|
||||
gs: 0,
|
||||
krr: 0,
|
||||
bkrr: 0
|
||||
})
|
||||
const options = ref({})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.lineIndex = monitoringPoint.state.lineId
|
||||
formData.startTime = datePickerRef.value.timeValue[0]
|
||||
formData.endTime = datePickerRef.value.timeValue[1]
|
||||
getPlot(formData).then((res: any) => {
|
||||
const gongData = gongfunction(res.data.voltageToleranceCurveDataList)
|
||||
data.gs = res.data.voltageToleranceCurveDataList.length
|
||||
data.krr = gongData.pointI.length
|
||||
data.bkrr = gongData.pointIun.length
|
||||
console.log(gongData)
|
||||
options.value = {
|
||||
// backgroundColor: "#f9f9f9", //地图背景色深蓝
|
||||
title: {
|
||||
// text: `ITIC曲线(总统计:${gongData.pointI.length + gongData.pointIun.length}个,可容忍:${gongData.pointI.length}个,不可容忍:${gongData.pointIun.length}个)`
|
||||
text: `ITIC曲线`
|
||||
},
|
||||
legend: {
|
||||
data: ['上限', '下限', '可容忍事件', '不可容忍事件']
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
show: true,
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0,
|
||||
formatter: function (a: any) {
|
||||
var relVal = ''
|
||||
relVal = "<font style='color:" + "'>发生时间:" + a.value[2] + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>持续时间:" + a.value[0] + 's</font><br/>'
|
||||
relVal += "<font style='color:" + "'>特征幅值:" + a.value[1].toFixed(2) + '%</font>'
|
||||
return relVal
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'log',
|
||||
min: 0.001,
|
||||
max: 1000,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
name: 's'
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitNumber: 10,
|
||||
minInterval: 3,
|
||||
name: '%'
|
||||
}
|
||||
],
|
||||
color: ['#FF8C00', '#00BFFF', 'green', 'red'],
|
||||
options: {
|
||||
dataZoom: null,
|
||||
series: [
|
||||
{
|
||||
name: '上限',
|
||||
type: 'line',
|
||||
data: [
|
||||
[0.001, 200],
|
||||
[0.003, 140],
|
||||
[0.003, 120],
|
||||
[0.5, 120],
|
||||
[0.5, 110],
|
||||
[10, 110],
|
||||
[1000, 110]
|
||||
],
|
||||
showSymbol: false,
|
||||
tooltips: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '下限',
|
||||
type: 'line',
|
||||
data: [
|
||||
[0.02, 0],
|
||||
[0.02, 70],
|
||||
[0.5, 70],
|
||||
[0.5, 80],
|
||||
[10, 80],
|
||||
[10, 90],
|
||||
[1000, 90]
|
||||
],
|
||||
showSymbol: false,
|
||||
tooltips: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
data: gongData.pointI
|
||||
},
|
||||
{
|
||||
name: '不可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
data: gongData.pointIun
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function gongfunction(arr: any) {
|
||||
let standI = 0
|
||||
let unstandI = 0
|
||||
let standF = 0
|
||||
let unstandF = 0
|
||||
let total = 0
|
||||
let pointIun = []
|
||||
let pointI = []
|
||||
let pointF = []
|
||||
let pointFun = []
|
||||
total = arr.length
|
||||
if (total == 0) {
|
||||
} else {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let point = []
|
||||
let xx = arr[i].persistTime
|
||||
let yy = arr[i].eventValue
|
||||
let time = arr[i].time
|
||||
let eventId = arr[i].eventId
|
||||
// let index =arr[i].eventDetailIndex;
|
||||
point = [xx, yy, time, eventId]
|
||||
|
||||
if (xx <= 0.003) {
|
||||
let line = 0
|
||||
line = 250 - 30000 * xx
|
||||
if (yy > line) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 0.02) {
|
||||
if (yy > 120) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 0.5) {
|
||||
if (yy > 120 || yy < 70) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 10) {
|
||||
if (yy > 110 || yy < 80) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (yy > 110 || yy < 90) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (xx < 0.05) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else if (xx < 0.2) {
|
||||
if (yy > 50) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
} else if (xx < 0.5) {
|
||||
if (yy > 70) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (yy > 80) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
standI,
|
||||
unstandI,
|
||||
pointI,
|
||||
pointIun,
|
||||
standF,
|
||||
unstandF,
|
||||
pointF,
|
||||
pointFun
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
@@ -1,320 +1,320 @@
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<el-form :inline="true" class="fx-jcsb">
|
||||
<el-form-item label="日期">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-descriptions class="mt2" direction="vertical" :column="4" border>
|
||||
<el-descriptions-item align="center" label="名称">{{ data.name }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="可容忍">{{ data.krr }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="不可容忍">{{ data.bkrr }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div style="flex: 1" class="mt10">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getPlot } from '@/api/event-boot/monitor'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
lineIndex: monitoringPoint.state.lineId,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
})
|
||||
const data = reactive({
|
||||
name: '事件个数',
|
||||
gs: 0,
|
||||
krr: 0,
|
||||
bkrr: 0
|
||||
})
|
||||
const options = ref({})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.lineIndex = monitoringPoint.state.lineId
|
||||
formData.startTime = datePickerRef.value.timeValue[0]
|
||||
formData.endTime = datePickerRef.value.timeValue[1]
|
||||
getPlot(formData).then((res: any) => {
|
||||
const gongData = gongfunction(res.data.voltageToleranceCurveDataList)
|
||||
data.gs = res.data.voltageToleranceCurveDataList.length
|
||||
data.krr = gongData.pointI.length
|
||||
data.bkrr = gongData.pointIun.length
|
||||
console.log(gongData)
|
||||
options.value = {
|
||||
// backgroundColor: "#f9f9f9", //地图背景色深蓝
|
||||
title: {
|
||||
text: `SEMI F47曲线`
|
||||
},
|
||||
legend: {
|
||||
data: ['上限', '下限', '可容忍事件', '不可容忍事件']
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
show: true,
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0,
|
||||
formatter: function (a: any) {
|
||||
var relVal = ''
|
||||
relVal = "<font style='color:" + "'>发生时间:" + a.value[2] + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>持续时间:" + a.value[0] + 's</font><br/>'
|
||||
relVal += "<font style='color:" + "'>特征幅值:" + a.value[1].toFixed(2) + '%</font>'
|
||||
return relVal
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'log',
|
||||
min: 0.001,
|
||||
max: 1000,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
name: 's'
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
max: function (value: any) {
|
||||
return value.max + 20
|
||||
},
|
||||
splitNumber: 10,
|
||||
minInterval: 0.1,
|
||||
name: '%'
|
||||
}
|
||||
],
|
||||
color: ['#DAA520', 'green', 'red'],
|
||||
options: {
|
||||
dataZoom: null,
|
||||
series: [
|
||||
{
|
||||
name: '边界线',
|
||||
type: 'line',
|
||||
data: [
|
||||
[0.05, 0],
|
||||
[0.05, 50],
|
||||
[0.2, 50],
|
||||
[0.2, 70],
|
||||
[0.5, 70],
|
||||
[0.5, 80],
|
||||
[10, 80],
|
||||
[1000, 80]
|
||||
],
|
||||
showSymbol: false,
|
||||
tooltips: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
data: gongData.pointF
|
||||
},
|
||||
{
|
||||
name: '不可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
data: gongData.pointFun
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function gongfunction(arr: any) {
|
||||
let standI = 0
|
||||
let unstandI = 0
|
||||
let standF = 0
|
||||
let unstandF = 0
|
||||
let total = 0
|
||||
let pointIun = []
|
||||
let pointI = []
|
||||
let pointF = []
|
||||
let pointFun = []
|
||||
total = arr.length
|
||||
if (total == 0) {
|
||||
} else {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let point = []
|
||||
let xx = arr[i].persistTime
|
||||
let yy = arr[i].eventValue
|
||||
let time = arr[i].time
|
||||
let eventId = arr[i].eventId
|
||||
// let index =arr[i].eventDetailIndex;
|
||||
point = [xx, yy, time, eventId]
|
||||
|
||||
if (xx <= 0.003) {
|
||||
let line = 0
|
||||
line = 250 - 30000 * xx
|
||||
if (yy > line) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 0.02) {
|
||||
if (yy > 120) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 0.5) {
|
||||
|
||||
|
||||
if (yy > 120 || yy < 70) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 10) {
|
||||
if (yy > 110 || yy < 80) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (yy > 110 || yy < 90) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (xx < 0.05) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else if (xx < 0.2) {
|
||||
if (yy > 50) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
} else if (xx < 0.5) {
|
||||
if (yy > 70) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (yy > 80) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
standI,
|
||||
unstandI,
|
||||
pointI,
|
||||
pointIun,
|
||||
standF,
|
||||
unstandF,
|
||||
pointF,
|
||||
pointFun
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<el-form :inline="true" class="fx-jcsb">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-descriptions class="mt2" direction="vertical" :column="4" border>
|
||||
<el-descriptions-item align="center" label="名称">{{ data.name }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="可容忍">{{ data.krr }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="不可容忍">{{ data.bkrr }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div style="flex: 1" class="mt10">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getPlot } from '@/api/event-boot/monitor'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
lineIndex: monitoringPoint.state.lineId,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
})
|
||||
const data = reactive({
|
||||
name: '事件个数',
|
||||
gs: 0,
|
||||
krr: 0,
|
||||
bkrr: 0
|
||||
})
|
||||
const options = ref({})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.lineIndex = monitoringPoint.state.lineId
|
||||
formData.startTime = datePickerRef.value.timeValue[0]
|
||||
formData.endTime = datePickerRef.value.timeValue[1]
|
||||
getPlot(formData).then((res: any) => {
|
||||
const gongData = gongfunction(res.data.voltageToleranceCurveDataList)
|
||||
data.gs = res.data.voltageToleranceCurveDataList.length
|
||||
data.krr = gongData.pointI.length
|
||||
data.bkrr = gongData.pointIun.length
|
||||
console.log(gongData)
|
||||
options.value = {
|
||||
// backgroundColor: "#f9f9f9", //地图背景色深蓝
|
||||
title: {
|
||||
text: `SEMI F47曲线`
|
||||
},
|
||||
legend: {
|
||||
data: ['上限', '下限', '可容忍事件', '不可容忍事件']
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
show: true,
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0,
|
||||
formatter: function (a: any) {
|
||||
var relVal = ''
|
||||
relVal = "<font style='color:" + "'>发生时间:" + a.value[2] + '</font><br/>'
|
||||
relVal += "<font style='color:" + "'>持续时间:" + a.value[0] + 's</font><br/>'
|
||||
relVal += "<font style='color:" + "'>特征幅值:" + a.value[1].toFixed(2) + '%</font>'
|
||||
return relVal
|
||||
}
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'log',
|
||||
min: 0.001,
|
||||
max: 1000,
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
name: 's'
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
max: function (value: any) {
|
||||
return value.max + 20
|
||||
},
|
||||
splitNumber: 10,
|
||||
minInterval: 0.1,
|
||||
name: '%'
|
||||
}
|
||||
],
|
||||
color: ['#DAA520', 'green', 'red'],
|
||||
options: {
|
||||
dataZoom: null,
|
||||
series: [
|
||||
{
|
||||
name: '边界线',
|
||||
type: 'line',
|
||||
data: [
|
||||
[0.05, 0],
|
||||
[0.05, 50],
|
||||
[0.2, 50],
|
||||
[0.2, 70],
|
||||
[0.5, 70],
|
||||
[0.5, 80],
|
||||
[10, 80],
|
||||
[1000, 80]
|
||||
],
|
||||
showSymbol: false,
|
||||
tooltips: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
data: gongData.pointF
|
||||
},
|
||||
{
|
||||
name: '不可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'circle',
|
||||
data: gongData.pointFun
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function gongfunction(arr: any) {
|
||||
let standI = 0
|
||||
let unstandI = 0
|
||||
let standF = 0
|
||||
let unstandF = 0
|
||||
let total = 0
|
||||
let pointIun = []
|
||||
let pointI = []
|
||||
let pointF = []
|
||||
let pointFun = []
|
||||
total = arr.length
|
||||
if (total == 0) {
|
||||
} else {
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let point = []
|
||||
let xx = arr[i].persistTime
|
||||
let yy = arr[i].eventValue
|
||||
let time = arr[i].time
|
||||
let eventId = arr[i].eventId
|
||||
// let index =arr[i].eventDetailIndex;
|
||||
point = [xx, yy, time, eventId]
|
||||
|
||||
if (xx <= 0.003) {
|
||||
let line = 0
|
||||
line = 250 - 30000 * xx
|
||||
if (yy > line) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 0.02) {
|
||||
if (yy > 120) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 0.5) {
|
||||
|
||||
|
||||
if (yy > 120 || yy < 70) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else if (xx <= 10) {
|
||||
if (yy > 110 || yy < 80) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (yy > 110 || yy < 90) {
|
||||
unstandI++
|
||||
pointIun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
} else {
|
||||
standI++
|
||||
pointI.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (xx < 0.05) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else if (xx < 0.2) {
|
||||
if (yy > 50) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
} else if (xx < 0.5) {
|
||||
if (yy > 70) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (yy > 80) {
|
||||
standF++
|
||||
pointF.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'green' } }
|
||||
})
|
||||
} else {
|
||||
unstandF++
|
||||
pointFun.push({
|
||||
value: point,
|
||||
itemStyle: { normal: { color: 'red' } }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
standI,
|
||||
unstandI,
|
||||
pointI,
|
||||
pointIun,
|
||||
standF,
|
||||
unstandF,
|
||||
pointF,
|
||||
pointFun
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
@@ -1,171 +1,171 @@
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<el-form :inline="true" class="fx-jcsb">
|
||||
<el-form-item label="日期">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="flex: 1" class="mt10">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getProbabilityDistribution } from '@/api/event-boot/monitor'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
lineIndex: monitoringPoint.state.lineId,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
})
|
||||
const options = ref({})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.lineIndex = monitoringPoint.state.lineId
|
||||
formData.startTime = datePickerRef.value.timeValue[0]
|
||||
formData.endTime = datePickerRef.value.timeValue[1]
|
||||
getProbabilityDistribution(formData).then((res: any) => {
|
||||
let data = res.data
|
||||
let sisttime = data.sisttime
|
||||
let persisttime = data.persisttime
|
||||
options.value = {
|
||||
backgroundColor: '#fff', //背景色,
|
||||
title: {
|
||||
text: '持续时间的概率分布函数',
|
||||
x: 'center'
|
||||
},
|
||||
legend: {
|
||||
top: 0,
|
||||
show: true,
|
||||
data: ['概率分布', '占比'],
|
||||
|
||||
textStyle: {
|
||||
rich: {
|
||||
a: {
|
||||
verticalAlign: 'middle'
|
||||
}
|
||||
},
|
||||
|
||||
padding: [2, 0, 0, 0] //[上、右、下、左]
|
||||
}
|
||||
},
|
||||
toolbox: {
|
||||
top: -10
|
||||
},
|
||||
tooltip: {
|
||||
//提示框组件
|
||||
trigger: 'axis',
|
||||
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0
|
||||
},
|
||||
calculable: true,
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
name: '持续时间',
|
||||
nameGap: 10,
|
||||
nameTextStyle: {
|
||||
fontSize: 12
|
||||
},
|
||||
data: ['0.01', '0.1', '0.25', '0.5', '1', '3', '20', '60', '180']
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '概率分布',
|
||||
nameTextStyle: {
|
||||
fontSize: 15
|
||||
},
|
||||
axisLabel: {
|
||||
formatter: '{value}%'
|
||||
},
|
||||
axisLine: {
|
||||
show: true
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
// 使用深浅的间隔色
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '占比',
|
||||
|
||||
nameTextStyle: {
|
||||
fontSize: 15
|
||||
},
|
||||
axisLine: {
|
||||
show: true
|
||||
},
|
||||
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '概率分布',
|
||||
type: 'line',
|
||||
data: sisttime,
|
||||
itemStyle: {
|
||||
normal: { show: true }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '占比',
|
||||
type: 'bar',
|
||||
data: persisttime,
|
||||
barWidth: 30,
|
||||
itemStyle: {
|
||||
normal: { show: true }
|
||||
}
|
||||
}
|
||||
],
|
||||
options: {
|
||||
dataZoom: null
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<el-form :inline="true" class="fx-jcsb">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="flex: 1" class="mt10">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getProbabilityDistribution } from '@/api/event-boot/monitor'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
lineIndex: monitoringPoint.state.lineId,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
})
|
||||
const options = ref({})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.lineIndex = monitoringPoint.state.lineId
|
||||
formData.startTime = datePickerRef.value.timeValue[0]
|
||||
formData.endTime = datePickerRef.value.timeValue[1]
|
||||
getProbabilityDistribution(formData).then((res: any) => {
|
||||
let data = res.data
|
||||
let sisttime = data.sisttime
|
||||
let persisttime = data.persisttime
|
||||
options.value = {
|
||||
backgroundColor: '#fff', //背景色,
|
||||
title: {
|
||||
text: '持续时间的概率分布函数',
|
||||
x: 'center'
|
||||
},
|
||||
legend: {
|
||||
top: 0,
|
||||
show: true,
|
||||
data: ['概率分布', '占比'],
|
||||
|
||||
textStyle: {
|
||||
rich: {
|
||||
a: {
|
||||
verticalAlign: 'middle'
|
||||
}
|
||||
},
|
||||
|
||||
padding: [2, 0, 0, 0] //[上、右、下、左]
|
||||
}
|
||||
},
|
||||
toolbox: {
|
||||
top: -10
|
||||
},
|
||||
tooltip: {
|
||||
//提示框组件
|
||||
trigger: 'axis',
|
||||
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0
|
||||
},
|
||||
calculable: true,
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
name: '持续时间',
|
||||
nameGap: 10,
|
||||
nameTextStyle: {
|
||||
fontSize: 12
|
||||
},
|
||||
data: ['0.01', '0.1', '0.25', '0.5', '1', '3', '20', '60', '180']
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '概率分布',
|
||||
nameTextStyle: {
|
||||
fontSize: 15
|
||||
},
|
||||
axisLabel: {
|
||||
formatter: '{value}%'
|
||||
},
|
||||
axisLine: {
|
||||
show: true
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
// 使用深浅的间隔色
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '占比',
|
||||
|
||||
nameTextStyle: {
|
||||
fontSize: 15
|
||||
},
|
||||
axisLine: {
|
||||
show: true
|
||||
},
|
||||
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '概率分布',
|
||||
type: 'line',
|
||||
data: sisttime,
|
||||
itemStyle: {
|
||||
normal: { show: true }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '占比',
|
||||
type: 'bar',
|
||||
data: persisttime,
|
||||
barWidth: 30,
|
||||
itemStyle: {
|
||||
normal: { show: true }
|
||||
}
|
||||
}
|
||||
],
|
||||
options: {
|
||||
dataZoom: null
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
@@ -1,304 +1,304 @@
|
||||
<template>
|
||||
<div v-loading="loading" class="dianyazanjiangbaojimidu">
|
||||
<el-form :inline="true" class="fx-jcsb">
|
||||
<el-form-item label="日期">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="mt10 dianyazanjiang">
|
||||
<div class="first">
|
||||
<div class="mb10">DISDIP表格(国际发配电联盟UNIPEDE)</div>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<vxe-table v-bind="defaultAttribute" height="420px" size="mini" :data="firstData">
|
||||
<vxe-colgroup title="剩余电压" field="name" width="80px"></vxe-colgroup>
|
||||
<vxe-colgroup title="持续时间">
|
||||
<vxe-column field="twentyMs" title="20ms" :formatter="formatter" />
|
||||
<vxe-column field="oneHundredMs" title="100ms" :formatter="formatter" />
|
||||
<vxe-column field="fiveHundredMs" title="500ms" :formatter="formatter" />
|
||||
<vxe-column field="oneS" title="1s" :formatter="formatter" />
|
||||
<vxe-column field="threeS" title="2s" :formatter="formatter" />
|
||||
<vxe-column field="twentyS" title="20s" :formatter="formatter" />
|
||||
<vxe-column field="sixtyS" title="60s" :formatter="formatter" />
|
||||
<vxe-column field="oneEightyS" title="180s" :formatter="formatter" />
|
||||
</vxe-colgroup>
|
||||
</vxe-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="second">
|
||||
<div class="mb10">EC61000-4-11(用电终端的电压暂降抗度)</div>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<vxe-table v-bind="defaultAttribute" height="220px" size="mini" :data="secondData">
|
||||
<vxe-colgroup title="剩余电压" field="name" width="80px"></vxe-colgroup>
|
||||
<vxe-colgroup title="持续时间">
|
||||
<vxe-column field="tenTwentyMs" title="10-20ms" :formatter="formatter" />
|
||||
<vxe-column field="twentyOneHundredMs" title="20-100ms" :formatter="formatter" />
|
||||
<vxe-column field="zeroPiontOneTwoS" title="0.1-0.2s" :formatter="formatter" />
|
||||
<vxe-column field="zeroPiontFive1S" title="0.2-0.5s" :formatter="formatter" />
|
||||
<vxe-column field="zeroPiontTwoFiveS" title="0.5-1s" :formatter="formatter" />
|
||||
<vxe-column field="greater1S" title=">1s" :formatter="formatter" />
|
||||
</vxe-colgroup>
|
||||
</vxe-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="third">
|
||||
<div class="mb10">IEC61000-2-8(公共用电暂降测量统计)</div>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<vxe-table v-bind="defaultAttribute" height="100%" size="mini" :data="thirdData">
|
||||
<vxe-colgroup title="剩余电压" field="name" width="120px"></vxe-colgroup>
|
||||
<vxe-colgroup title="持续时间">
|
||||
<vxe-column field="q" title="0.01-0.1s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="w" title="0.1-0.25s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="e" title="0.25-0.5s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="r" title="0.5-1s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="t" title="1-3s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="y" title="3-20s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="u" title="20-60s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="i" title="60-180s" align="center" :formatter="formatter" />
|
||||
</vxe-colgroup>
|
||||
</vxe-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="charts" id="charts">
|
||||
<MyEchart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { eventDisdip, getCoords, IEC28, IEC411 } from '@/api/event-boot/monitor'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const loading = ref(true)
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const formData = reactive({
|
||||
lineIndex: monitoringPoint.state.lineId,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
})
|
||||
const options = ref({})
|
||||
const firstData = ref([])
|
||||
const secondData = ref([])
|
||||
const thirdData = ref([])
|
||||
const chartsData = ref([])
|
||||
const formatter = (row: any) => {
|
||||
return row.cellValue == 0 ? '/' : row.cellValue
|
||||
}
|
||||
const init = () => {
|
||||
formData.lineIndex = monitoringPoint.state.lineId
|
||||
formData.startTime = datePickerRef.value.timeValue[0]
|
||||
formData.endTime = datePickerRef.value.timeValue[1]
|
||||
loading.value = true
|
||||
Promise.all([eventDisdip(formData), IEC411(formData), IEC28(formData), getCoords(formData)]).then(res => {
|
||||
firstData.value = res[0].data
|
||||
secondData.value = res[1].data
|
||||
thirdData.value = res[2].data
|
||||
chartsData.value = res[3].data
|
||||
options.value = {
|
||||
options: {
|
||||
xAxis: null,
|
||||
yAxis: null,
|
||||
dataZoom: null,
|
||||
backgroundColor: '#fff',
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
title: {
|
||||
text: '暂降密度图',
|
||||
x: 'center'
|
||||
},
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
// dataView: { show: true },
|
||||
// dataZoom: { show: true },
|
||||
//restore: { show: true },
|
||||
// saveAsImage: { show: true },
|
||||
myFull: {
|
||||
show: true,
|
||||
title: '全屏查看',
|
||||
icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
|
||||
onclick: () => {
|
||||
let element = document.getElementById('charts') as HTMLElement
|
||||
// 全屏,如果已经全屏,则退出全屏
|
||||
if (document.fullscreenElement) {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen()
|
||||
}
|
||||
} else {
|
||||
if (element.requestFullscreen) {
|
||||
element.requestFullscreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
visualMap: {
|
||||
max: 20,
|
||||
show: false,
|
||||
inRange: {
|
||||
color: ['#313695', '#00BB00', '#ff8000', '#a50026']
|
||||
}
|
||||
},
|
||||
xAxis3D: {
|
||||
type: 'category',
|
||||
name: '剩余电压(%)',
|
||||
data: ['0-10', '10-20', '20-30', '30-40', '40-50', '50-60', '60-70', '70-80', '80-90', '90-100'],
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#111'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#111'
|
||||
}
|
||||
},
|
||||
yAxis3D: {
|
||||
type: 'category',
|
||||
name: '持续时间(cyc)',
|
||||
data: ['1cyc', '2cyc', '3cyc', '4cyc', '5cyc', '6~10cyc', '10~20cyc', '20~30cyc', '30~60cyc'],
|
||||
nameTextStyle: {
|
||||
color: '#111'
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#111'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#111'
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
// 使用深浅的间隔色
|
||||
color: ['#111'],
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
zAxis3D: {
|
||||
type: 'value',
|
||||
splitNumber: 10,
|
||||
minInterval: 10,
|
||||
name: '次数'
|
||||
},
|
||||
grid3D: {
|
||||
viewControl: {
|
||||
projection: 'perspective',
|
||||
distance: 250
|
||||
},
|
||||
boxWidth: 200,
|
||||
boxDepth: 80,
|
||||
light: {
|
||||
main: {
|
||||
intensity: 1.2
|
||||
},
|
||||
ambient: {
|
||||
intensity: 0.3
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'bar3D',
|
||||
data: chartsData.value.map(function (item: any) {
|
||||
return {
|
||||
value: [item['x'], item['y'], item['z']]
|
||||
}
|
||||
}),
|
||||
shading: 'realistic',
|
||||
label: {
|
||||
show: false,
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
borderWidth: 1
|
||||
}
|
||||
},
|
||||
|
||||
itemStyle: {
|
||||
opacity: 1
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
textStyle: {
|
||||
fontSize: 20,
|
||||
color: '#900'
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#900'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.dianyazanjiangbaojimidu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
|
||||
.dianyazanjiang {
|
||||
flex: 1;
|
||||
min-width: 1200px;
|
||||
min-height: 800px;
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
'first charts'
|
||||
'second charts'
|
||||
'third third '
|
||||
'third third ';
|
||||
grid-template-rows: 1fr 1fr 1fr 1fr;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 10px;
|
||||
|
||||
.first {
|
||||
grid-area: first;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
height: 280px;
|
||||
}
|
||||
|
||||
.second {
|
||||
grid-area: second;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
height: 210px;
|
||||
}
|
||||
|
||||
.third {
|
||||
grid-area: third;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
height: 720px;
|
||||
}
|
||||
|
||||
.charts {
|
||||
grid-area: charts;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div v-loading="loading" class="dianyazanjiangbaojimidu">
|
||||
<el-form :inline="true" class="fx-jcsb">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="mt10 dianyazanjiang">
|
||||
<div class="first">
|
||||
<div class="mb10">DISDIP表格(国际发配电联盟UNIPEDE)</div>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<vxe-table v-bind="defaultAttribute" height="420px" size="mini" :data="firstData">
|
||||
<vxe-colgroup title="剩余电压" field="name" width="80px"></vxe-colgroup>
|
||||
<vxe-colgroup title="持续时间">
|
||||
<vxe-column field="twentyMs" title="20ms" :formatter="formatter" />
|
||||
<vxe-column field="oneHundredMs" title="100ms" :formatter="formatter" />
|
||||
<vxe-column field="fiveHundredMs" title="500ms" :formatter="formatter" />
|
||||
<vxe-column field="oneS" title="1s" :formatter="formatter" />
|
||||
<vxe-column field="threeS" title="2s" :formatter="formatter" />
|
||||
<vxe-column field="twentyS" title="20s" :formatter="formatter" />
|
||||
<vxe-column field="sixtyS" title="60s" :formatter="formatter" />
|
||||
<vxe-column field="oneEightyS" title="180s" :formatter="formatter" />
|
||||
</vxe-colgroup>
|
||||
</vxe-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="second">
|
||||
<div class="mb10">EC61000-4-11(用电终端的电压暂降抗度)</div>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<vxe-table v-bind="defaultAttribute" height="220px" size="mini" :data="secondData">
|
||||
<vxe-colgroup title="剩余电压" field="name" width="80px"></vxe-colgroup>
|
||||
<vxe-colgroup title="持续时间">
|
||||
<vxe-column field="tenTwentyMs" title="10-20ms" :formatter="formatter" />
|
||||
<vxe-column field="twentyOneHundredMs" title="20-100ms" :formatter="formatter" />
|
||||
<vxe-column field="zeroPiontOneTwoS" title="0.1-0.2s" :formatter="formatter" />
|
||||
<vxe-column field="zeroPiontFive1S" title="0.2-0.5s" :formatter="formatter" />
|
||||
<vxe-column field="zeroPiontTwoFiveS" title="0.5-1s" :formatter="formatter" />
|
||||
<vxe-column field="greater1S" title=">1s" :formatter="formatter" />
|
||||
</vxe-colgroup>
|
||||
</vxe-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="third">
|
||||
<div class="mb10">IEC61000-2-8(公共用电暂降测量统计)</div>
|
||||
<div style="flex: 1; overflow: hidden">
|
||||
<vxe-table v-bind="defaultAttribute" height="100%" size="mini" :data="thirdData">
|
||||
<vxe-colgroup title="剩余电压" field="name" width="120px"></vxe-colgroup>
|
||||
<vxe-colgroup title="持续时间">
|
||||
<vxe-column field="q" title="0.01-0.1s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="w" title="0.1-0.25s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="e" title="0.25-0.5s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="r" title="0.5-1s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="t" title="1-3s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="y" title="3-20s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="u" title="20-60s" align="center" :formatter="formatter" />
|
||||
<vxe-column field="i" title="60-180s" align="center" :formatter="formatter" />
|
||||
</vxe-colgroup>
|
||||
</vxe-table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="charts" id="charts">
|
||||
<MyEchart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { eventDisdip, getCoords, IEC28, IEC411 } from '@/api/event-boot/monitor'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const loading = ref(true)
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const formData = reactive({
|
||||
lineIndex: monitoringPoint.state.lineId,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
})
|
||||
const options = ref({})
|
||||
const firstData = ref([])
|
||||
const secondData = ref([])
|
||||
const thirdData = ref([])
|
||||
const chartsData = ref([])
|
||||
const formatter = (row: any) => {
|
||||
return row.cellValue == 0 ? '/' : row.cellValue
|
||||
}
|
||||
const init = () => {
|
||||
formData.lineIndex = monitoringPoint.state.lineId
|
||||
formData.startTime = datePickerRef.value.timeValue[0]
|
||||
formData.endTime = datePickerRef.value.timeValue[1]
|
||||
loading.value = true
|
||||
Promise.all([eventDisdip(formData), IEC411(formData), IEC28(formData), getCoords(formData)]).then(res => {
|
||||
firstData.value = res[0].data
|
||||
secondData.value = res[1].data
|
||||
thirdData.value = res[2].data
|
||||
chartsData.value = res[3].data
|
||||
options.value = {
|
||||
options: {
|
||||
xAxis: null,
|
||||
yAxis: null,
|
||||
dataZoom: null,
|
||||
backgroundColor: '#fff',
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
title: {
|
||||
text: '暂降密度图',
|
||||
x: 'center'
|
||||
},
|
||||
toolbox: {
|
||||
show: true,
|
||||
feature: {
|
||||
// dataView: { show: true },
|
||||
// dataZoom: { show: true },
|
||||
//restore: { show: true },
|
||||
// saveAsImage: { show: true },
|
||||
myFull: {
|
||||
show: true,
|
||||
title: '全屏查看',
|
||||
icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
|
||||
onclick: () => {
|
||||
let element = document.getElementById('charts') as HTMLElement
|
||||
// 全屏,如果已经全屏,则退出全屏
|
||||
if (document.fullscreenElement) {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen()
|
||||
}
|
||||
} else {
|
||||
if (element.requestFullscreen) {
|
||||
element.requestFullscreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
visualMap: {
|
||||
max: 20,
|
||||
show: false,
|
||||
inRange: {
|
||||
color: ['#313695', '#00BB00', '#ff8000', '#a50026']
|
||||
}
|
||||
},
|
||||
xAxis3D: {
|
||||
type: 'category',
|
||||
name: '剩余电压(%)',
|
||||
data: ['0-10', '10-20', '20-30', '30-40', '40-50', '50-60', '60-70', '70-80', '80-90', '90-100'],
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#111'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#111'
|
||||
}
|
||||
},
|
||||
yAxis3D: {
|
||||
type: 'category',
|
||||
name: '持续时间(cyc)',
|
||||
data: ['1cyc', '2cyc', '3cyc', '4cyc', '5cyc', '6~10cyc', '10~20cyc', '20~30cyc', '30~60cyc'],
|
||||
nameTextStyle: {
|
||||
color: '#111'
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#111'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#111'
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
// 使用深浅的间隔色
|
||||
color: ['#111'],
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
zAxis3D: {
|
||||
type: 'value',
|
||||
splitNumber: 10,
|
||||
minInterval: 10,
|
||||
name: '次数'
|
||||
},
|
||||
grid3D: {
|
||||
viewControl: {
|
||||
projection: 'perspective',
|
||||
distance: 250
|
||||
},
|
||||
boxWidth: 200,
|
||||
boxDepth: 80,
|
||||
light: {
|
||||
main: {
|
||||
intensity: 1.2
|
||||
},
|
||||
ambient: {
|
||||
intensity: 0.3
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'bar3D',
|
||||
data: chartsData.value.map(function (item: any) {
|
||||
return {
|
||||
value: [item['x'], item['y'], item['z']]
|
||||
}
|
||||
}),
|
||||
shading: 'realistic',
|
||||
label: {
|
||||
show: false,
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
borderWidth: 1
|
||||
}
|
||||
},
|
||||
|
||||
itemStyle: {
|
||||
opacity: 1
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
textStyle: {
|
||||
fontSize: 20,
|
||||
color: '#900'
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#900'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.dianyazanjiangbaojimidu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
|
||||
.dianyazanjiang {
|
||||
flex: 1;
|
||||
min-width: 1200px;
|
||||
min-height: 800px;
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
'first charts'
|
||||
'second charts'
|
||||
'third third '
|
||||
'third third ';
|
||||
grid-template-rows: 1fr 1fr 1fr 1fr;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 10px;
|
||||
|
||||
.first {
|
||||
grid-area: first;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
height: 280px;
|
||||
}
|
||||
|
||||
.second {
|
||||
grid-area: second;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
height: 210px;
|
||||
}
|
||||
|
||||
.third {
|
||||
grid-area: third;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
height: 720px;
|
||||
}
|
||||
|
||||
.charts {
|
||||
grid-area: charts;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,51 +1,59 @@
|
||||
<template>
|
||||
<el-tabs v-model='activeName' type='border-card' class='event-statistics' tab-position='left' :style='height'>
|
||||
<el-tab-pane lazy label='ITIC曲线分析' name='1'>
|
||||
<ITICquxianfenxi />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label='SEMI F47 分析' name='2'>
|
||||
<SEMIF47fenxi />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label='电压暂降表及密度' name='3'>
|
||||
<Dianyazanjiangbiaojimidu />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label='暂降分布统计' name='4'>
|
||||
<Zanjiangfenbutongji />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label='暂降幅值概率分布' name='5'>
|
||||
<Zanjiangfuzhigailvfenbu />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label='持续时间概率分布' name='6'>
|
||||
<Chixushijiangailvfenbu />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
<script setup lang='ts'>
|
||||
import { ref } from 'vue'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import ITICquxianfenxi from './ITICquxianfenxi/index.vue'
|
||||
import SEMIF47fenxi from './SEMIF47fenxi/index.vue'
|
||||
import Dianyazanjiangbiaojimidu from './dianyazanjiangbiaojimidu/index.vue'
|
||||
import Zanjiangfenbutongji from './zanjiangfenbutongji/index.vue'
|
||||
import Zanjiangfuzhigailvfenbu from './zanjiangfuzhigailvfenbu/index.vue'
|
||||
import Chixushijiangailvfenbu from './chixushijiangailvfenbu/index.vue'
|
||||
|
||||
const activeName = ref('1')
|
||||
const height = mainHeight(84)
|
||||
|
||||
</script>
|
||||
<style lang='scss'>
|
||||
.event-statistics {
|
||||
.el-tabs__header.is-left {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.el-tabs__content {
|
||||
height: 100%;
|
||||
|
||||
.el-tab-pane {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<el-tabs v-model="activeName" type="border-card" class="event-statistics" tab-position="left" :style="height">
|
||||
<el-tab-pane lazy label="ITIC曲线分析" name="1">
|
||||
<ITICquxianfenxi />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label="SEMI F47 分析" name="2">
|
||||
<SEMIF47fenxi />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label="电压暂降表及密度" name="3">
|
||||
<Dianyazanjiangbiaojimidu />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label="暂降分布统计" name="4">
|
||||
<Zanjiangfenbutongji />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label="暂降幅值概率分布" name="5">
|
||||
<Zanjiangfuzhigailvfenbu />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane lazy label="持续时间概率分布" name="6">
|
||||
<Chixushijiangailvfenbu />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import ITICquxianfenxi from './ITICquxianfenxi/index.vue'
|
||||
import SEMIF47fenxi from './SEMIF47fenxi/index.vue'
|
||||
import Dianyazanjiangbiaojimidu from './dianyazanjiangbiaojimidu/index.vue'
|
||||
import Zanjiangfenbutongji from './zanjiangfenbutongji/index.vue'
|
||||
import Zanjiangfuzhigailvfenbu from './zanjiangfuzhigailvfenbu/index.vue'
|
||||
import Chixushijiangailvfenbu from './chixushijiangailvfenbu/index.vue'
|
||||
const props = defineProps({
|
||||
externalHeight: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
const activeName = ref('1')
|
||||
const height = ref(mainHeight(84 + props.externalHeight))
|
||||
// onMounted(() => {
|
||||
// height.value = mainHeight(84 + props.externalHeight)
|
||||
// console.log("🚀 ~ 84 + props.externalHeight:", 84 + props.externalHeight)
|
||||
// })
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.event-statistics {
|
||||
.el-tabs__header.is-left {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.el-tabs__content {
|
||||
height: 100%;
|
||||
|
||||
.el-tab-pane {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,172 +1,172 @@
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<el-form :inline="true" class="fx-jcsb">
|
||||
<el-form-item label="日期">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="flex: 1" class="mt10">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getProbabilityDistribution } from '@/api/event-boot/monitor'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
lineIndex: monitoringPoint.state.lineId,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
})
|
||||
const options = ref({})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.lineIndex = monitoringPoint.state.lineId
|
||||
formData.startTime = datePickerRef.value.timeValue[0]
|
||||
formData.endTime = datePickerRef.value.timeValue[1]
|
||||
getProbabilityDistribution(formData).then((res: any) => {
|
||||
let data = res.data
|
||||
let eventValue = data.eventvalue
|
||||
let pereventValue = data.pereventvalue
|
||||
options.value = {
|
||||
backgroundColor: '#fff', //背景色,
|
||||
title: {
|
||||
text: '暂降幅值的概率分布函数',
|
||||
x: 'center'
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
top: 0,
|
||||
data: ['概率分布', '占比'],
|
||||
|
||||
textStyle: {
|
||||
rich: {
|
||||
a: {
|
||||
verticalAlign: 'middle'
|
||||
}
|
||||
},
|
||||
|
||||
padding: [2, 0, 0, 0] //[上、右、下、左]
|
||||
}
|
||||
},
|
||||
toolbox: {
|
||||
top: -10
|
||||
},
|
||||
|
||||
tooltip: {
|
||||
//提示框组件
|
||||
trigger: 'axis',
|
||||
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0
|
||||
},
|
||||
calculable: true,
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
name: '暂降幅值',
|
||||
nameGap: 10,
|
||||
nameTextStyle: {
|
||||
fontSize: 12
|
||||
},
|
||||
data: ['0', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%']
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '概率分布',
|
||||
nameTextStyle: {
|
||||
fontSize: 15
|
||||
},
|
||||
axisLabel: {
|
||||
formatter: '{value}%'
|
||||
},
|
||||
axisLine: {
|
||||
show: true
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
// 使用深浅的间隔色
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '占比',
|
||||
|
||||
nameTextStyle: {
|
||||
fontSize: 15
|
||||
},
|
||||
axisLine: {
|
||||
show: true
|
||||
},
|
||||
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '占比',
|
||||
type: 'bar',
|
||||
data: pereventValue,
|
||||
barWidth: 30,
|
||||
itemStyle: {
|
||||
normal: { show: true }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '概率分布',
|
||||
type: 'line',
|
||||
data: eventValue,
|
||||
itemStyle: {
|
||||
normal: { show: true }
|
||||
}
|
||||
}
|
||||
],
|
||||
options: {
|
||||
dataZoom: null
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
<template>
|
||||
<div style="display: flex; flex-direction: column; height: 100%">
|
||||
<el-form :inline="true" class="fx-jcsb">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="flex: 1" class="mt10">
|
||||
<my-echart :options="options" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { getProbabilityDistribution } from '@/api/event-boot/monitor'
|
||||
|
||||
const datePickerRef = ref()
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
lineIndex: monitoringPoint.state.lineId,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
})
|
||||
const options = ref({})
|
||||
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.lineIndex = monitoringPoint.state.lineId
|
||||
formData.startTime = datePickerRef.value.timeValue[0]
|
||||
formData.endTime = datePickerRef.value.timeValue[1]
|
||||
getProbabilityDistribution(formData).then((res: any) => {
|
||||
let data = res.data
|
||||
let eventValue = data.eventvalue
|
||||
let pereventValue = data.pereventvalue
|
||||
options.value = {
|
||||
backgroundColor: '#fff', //背景色,
|
||||
title: {
|
||||
text: '暂降幅值的概率分布函数',
|
||||
x: 'center'
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
top: 0,
|
||||
data: ['概率分布', '占比'],
|
||||
|
||||
textStyle: {
|
||||
rich: {
|
||||
a: {
|
||||
verticalAlign: 'middle'
|
||||
}
|
||||
},
|
||||
|
||||
padding: [2, 0, 0, 0] //[上、右、下、左]
|
||||
}
|
||||
},
|
||||
toolbox: {
|
||||
top: -10
|
||||
},
|
||||
|
||||
tooltip: {
|
||||
//提示框组件
|
||||
trigger: 'axis',
|
||||
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0
|
||||
},
|
||||
calculable: true,
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
name: '暂降幅值',
|
||||
nameGap: 10,
|
||||
nameTextStyle: {
|
||||
fontSize: 12
|
||||
},
|
||||
data: ['0', '10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%']
|
||||
}
|
||||
],
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '概率分布',
|
||||
nameTextStyle: {
|
||||
fontSize: 15
|
||||
},
|
||||
axisLabel: {
|
||||
formatter: '{value}%'
|
||||
},
|
||||
axisLine: {
|
||||
show: true
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
// 使用深浅的间隔色
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '占比',
|
||||
|
||||
nameTextStyle: {
|
||||
fontSize: 15
|
||||
},
|
||||
axisLine: {
|
||||
show: true
|
||||
},
|
||||
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '占比',
|
||||
type: 'bar',
|
||||
data: pereventValue,
|
||||
barWidth: 30,
|
||||
itemStyle: {
|
||||
normal: { show: true }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '概率分布',
|
||||
type: 'line',
|
||||
data: eventValue,
|
||||
itemStyle: {
|
||||
normal: { show: true }
|
||||
}
|
||||
}
|
||||
],
|
||||
options: {
|
||||
dataZoom: null
|
||||
}
|
||||
}
|
||||
nextTick(() => {
|
||||
loading.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
@@ -1,162 +1,171 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-show="view">
|
||||
<!-- 表头 -->
|
||||
<TableHeader date-picker showExport>
|
||||
<template v-slot:operation>
|
||||
<el-button :icon='Download' type='primary' @click='download'>下载波形</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<!-- 表格 -->
|
||||
<Table ref='tableRef' :checkboxConfig='checkboxConfig' />
|
||||
|
||||
</div>
|
||||
<div :style="{ height: pageHeight.height }" style="padding: 10px; overflow: hidden" v-if="!view">
|
||||
<waveForm ref="waveFormRef" senior @backbxlb="backbxlb" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang='ts'>
|
||||
import { Download } from '@element-plus/icons-vue'
|
||||
import { ref, onMounted, provide, reactive } from 'vue'
|
||||
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { checkUser } from '@/api/user-boot/user'
|
||||
import waveForm from '@/components/echarts/waveForm.vue'
|
||||
import { VxeTablePropTypes } from 'vxe-table'
|
||||
import { downloadWaveFile, getMonitorEventAnalyseWave } from '@/api/event-boot/transient'
|
||||
const view = ref(true)
|
||||
const waveFormRef = ref()
|
||||
const view2 = ref(false)
|
||||
const pageHeight = mainHeight(20)
|
||||
const dictData = useDictData()
|
||||
const eventTypeOptions = dictData.getBasicData('Event_Statis')
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const tableStore = new TableStore({
|
||||
publicHeight: 60,
|
||||
url: '/event-boot/monitor/getMonitorEventAnalyseQuery',
|
||||
method: 'POST',
|
||||
column: [
|
||||
{ width: '60', type: 'checkbox' },
|
||||
{
|
||||
title: '序号', width: 80, formatter: (row: any) => {
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '变电站名称', field: 'subName', minWidth: '140' },
|
||||
{ title: '监测点名称', field: 'lineName', minWidth: '130' },
|
||||
{ title: '网络参数', field: 'ip', minWidth: '130' },
|
||||
{ title: '电压等级(kV)', field: 'voltageScale', width: '120' },
|
||||
{ title: '暂降发生时刻', field: 'startTime', width: '200' },
|
||||
// { title: '暂降类型', field: 'advanceType', minWidth: '130' },
|
||||
{ title: '暂降原因', field: 'advanceReason', minWidth: '130' },
|
||||
{
|
||||
title: '触发类型', field: 'eventType', minWidth: '80', formatter: (row: any) => {
|
||||
return eventTypeOptions.find(item => item.id === row.cellValue)?.name || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '暂降(骤升)幅值(%)', field: 'featureAmplitude', minWidth: '140',
|
||||
|
||||
formatter: (row: any) => {
|
||||
return (row.cellValue * 100).toFixed(2)
|
||||
},
|
||||
|
||||
},
|
||||
{ title: '持续时间(s)', field: 'duration', minWidth: '100' },
|
||||
// { title: '严重度', field: 'severity', minWidth: '80' },
|
||||
{
|
||||
title: '操作',
|
||||
width: '180',
|
||||
render: 'buttons',
|
||||
fixed: 'right',
|
||||
buttons: [
|
||||
{
|
||||
name: 'edit',
|
||||
title: '波形分析',
|
||||
type: 'primary',
|
||||
icon: 'el-icon-Lock',
|
||||
render: 'basicButton',
|
||||
disabled: row => {
|
||||
return row.fileFlag === 0
|
||||
},
|
||||
click: row => {
|
||||
// getMonitorEventAnalyseWave({
|
||||
// id: row.eventId,
|
||||
// systemType: 0,
|
||||
// type: 0
|
||||
// }).then(res => {
|
||||
// console.log(res)
|
||||
// ElMessage.error('暂无可下载的波形文件!')
|
||||
// })
|
||||
view.value = false
|
||||
setTimeout(() => {
|
||||
waveFormRef.value.open(row)
|
||||
}, 100)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'edit',
|
||||
title: '暂无波形',
|
||||
type: '',
|
||||
disabled: row => {
|
||||
return row.fileFlag != 0
|
||||
},
|
||||
icon: 'el-icon-Plus',
|
||||
render: 'basicButton'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.lineId = monitoringPoint.state.lineId
|
||||
console.log('beforeSearchFun')
|
||||
},
|
||||
loadCallback: () => {
|
||||
|
||||
}
|
||||
})
|
||||
provide('tableStore', tableStore)
|
||||
tableStore.table.params.searchState = 0
|
||||
onMounted(() => {
|
||||
// 加载数据
|
||||
tableStore.index()
|
||||
})
|
||||
const checkboxConfig = reactive<VxeTablePropTypes.CheckboxConfig<any>>({
|
||||
checkMethod: ({ row }) => {
|
||||
return row.fileFlag === 1
|
||||
}
|
||||
})
|
||||
const backbxlb = () => {
|
||||
view.value = true
|
||||
view2.value = false
|
||||
}
|
||||
const download = () => {
|
||||
if (!tableStore.table.selection.length) {
|
||||
ElMessage.warning('请选择数据')
|
||||
return
|
||||
}
|
||||
downloadWaveFile({
|
||||
lineId: tableStore.table.selection.map((item: any) => item.eventId)
|
||||
}).then((res: any) => {
|
||||
if (res.type == 'application/json') {
|
||||
ElMessage.warning('暂无可下载的波形文件!')
|
||||
return
|
||||
}
|
||||
ElMessage.info('下载中......')
|
||||
let blob = new Blob([res], { type: 'application/zip' }) // console.log(blob) // var href = window.URL.createObjectURL(blob); //创建下载的链接
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a') // 创建a标签
|
||||
link.href = url
|
||||
link.download = '波形分析下载' // 设置下载的文件名
|
||||
document.body.appendChild(link)
|
||||
link.click() //执行下载
|
||||
document.body.removeChild(link) //释放标签
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<div v-show="view">
|
||||
<!-- 表头 -->
|
||||
<TableHeader date-picker showExport>
|
||||
<template v-slot:operation>
|
||||
<el-button :icon="Download" type="primary" @click="download">下载波形</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<!-- 表格 -->
|
||||
<Table ref="tableRef" :checkboxConfig="checkboxConfig" />
|
||||
</div>
|
||||
<div :style="{ height: pageHeight.height }" style="padding: 10px; overflow: hidden" v-if="!view">
|
||||
<waveForm ref="waveFormRef" senior @backbxlb="backbxlb" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { Download } from '@element-plus/icons-vue'
|
||||
import { ref, onMounted, provide, reactive } from 'vue'
|
||||
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { checkUser } from '@/api/user-boot/user'
|
||||
import waveForm from '@/components/echarts/waveForm.vue'
|
||||
import { VxeTablePropTypes } from 'vxe-table'
|
||||
import { downloadWaveFile, getMonitorEventAnalyseWave } from '@/api/event-boot/transient'
|
||||
const props = defineProps({
|
||||
externalHeight: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
})
|
||||
const view = ref(true)
|
||||
const waveFormRef = ref()
|
||||
const view2 = ref(false)
|
||||
const pageHeight = mainHeight(20)
|
||||
const dictData = useDictData()
|
||||
const eventTypeOptions = dictData.getBasicData('Event_Statis')
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const tableStore = new TableStore({
|
||||
publicHeight: 60 + props.externalHeight,
|
||||
url: '/event-boot/monitor/getMonitorEventAnalyseQuery',
|
||||
method: 'POST',
|
||||
column: [
|
||||
{ width: '60', type: 'checkbox' },
|
||||
{
|
||||
title: '序号',
|
||||
width: 80,
|
||||
formatter: (row: any) => {
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '变电站名称', field: 'subName', minWidth: '140' },
|
||||
{ title: '监测点名称', field: 'lineName', minWidth: '130' },
|
||||
{ title: '网络参数', field: 'ip', minWidth: '130' },
|
||||
{ title: '电压等级(kV)', field: 'voltageScale', width: '120' },
|
||||
{ title: '暂降发生时刻', field: 'startTime', width: '200' },
|
||||
// { title: '暂降类型', field: 'advanceType', minWidth: '130' },
|
||||
{ title: '暂降原因', field: 'advanceReason', minWidth: '130' },
|
||||
{
|
||||
title: '触发类型',
|
||||
field: 'eventType',
|
||||
minWidth: '80',
|
||||
formatter: (row: any) => {
|
||||
return eventTypeOptions.find(item => item.id === row.cellValue)?.name || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '暂降(骤升)幅值(%)',
|
||||
field: 'featureAmplitude',
|
||||
minWidth: '140',
|
||||
|
||||
formatter: (row: any) => {
|
||||
return (row.cellValue * 100).toFixed(2)
|
||||
}
|
||||
},
|
||||
{ title: '持续时间(s)', field: 'duration', minWidth: '100' },
|
||||
// { title: '严重度', field: 'severity', minWidth: '80' },
|
||||
{
|
||||
title: '操作',
|
||||
width: '180',
|
||||
render: 'buttons',
|
||||
fixed: 'right',
|
||||
buttons: [
|
||||
{
|
||||
name: 'edit',
|
||||
title: '波形分析',
|
||||
type: 'primary',
|
||||
icon: 'el-icon-Lock',
|
||||
render: 'basicButton',
|
||||
disabled: row => {
|
||||
return row.fileFlag === 0
|
||||
},
|
||||
click: row => {
|
||||
// getMonitorEventAnalyseWave({
|
||||
// id: row.eventId,
|
||||
// systemType: 0,
|
||||
// type: 0
|
||||
// }).then(res => {
|
||||
// console.log(res)
|
||||
// ElMessage.error('暂无可下载的波形文件!')
|
||||
// })
|
||||
view.value = false
|
||||
setTimeout(() => {
|
||||
waveFormRef.value.open(row)
|
||||
}, 100)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'edit',
|
||||
title: '暂无波形',
|
||||
type: '',
|
||||
disabled: row => {
|
||||
return row.fileFlag != 0
|
||||
},
|
||||
icon: 'el-icon-Plus',
|
||||
render: 'basicButton'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.lineId = monitoringPoint.state.lineId
|
||||
console.log('beforeSearchFun')
|
||||
},
|
||||
loadCallback: () => {}
|
||||
})
|
||||
provide('tableStore', tableStore)
|
||||
tableStore.table.params.searchState = 0
|
||||
onMounted(() => {
|
||||
// 加载数据
|
||||
tableStore.index()
|
||||
})
|
||||
const checkboxConfig = reactive<VxeTablePropTypes.CheckboxConfig<any>>({
|
||||
checkMethod: ({ row }) => {
|
||||
return row.fileFlag === 1
|
||||
}
|
||||
})
|
||||
const backbxlb = () => {
|
||||
view.value = true
|
||||
view2.value = false
|
||||
}
|
||||
const download = () => {
|
||||
if (!tableStore.table.selection.length) {
|
||||
ElMessage.warning('请选择数据')
|
||||
return
|
||||
}
|
||||
downloadWaveFile({
|
||||
lineId: tableStore.table.selection.map((item: any) => item.eventId)
|
||||
}).then((res: any) => {
|
||||
if (res.type == 'application/json') {
|
||||
ElMessage.warning('暂无可下载的波形文件!')
|
||||
return
|
||||
}
|
||||
ElMessage.info('下载中......')
|
||||
let blob = new Blob([res], { type: 'application/zip' }) // console.log(blob) // var href = window.URL.createObjectURL(blob); //创建下载的链接
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a') // 创建a标签
|
||||
link.href = url
|
||||
link.download = '波形分析下载' // 设置下载的文件名
|
||||
document.body.appendChild(link)
|
||||
link.click() //执行下载
|
||||
document.body.removeChild(link) //释放标签
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -27,7 +27,6 @@ import EventStatistics from './eventStatistics/index.vue'
|
||||
import EventStudy from './eventStudy/index.vue'
|
||||
import RunningCondition from './runningCondition/index.vue'
|
||||
import TransientReport from './transientReport/index.vue'
|
||||
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import router from '@/router'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
|
||||
130
src/views/pqs/voltageSags/monitoringPoint/online/index_JB.vue
Normal file
130
src/views/pqs/voltageSags/monitoringPoint/online/index_JB.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div class="default-main" style="padding: 10px">
|
||||
<splitpanes :style="height" class="default-theme" id="navigation-splitpanes">
|
||||
<pane :size="size">
|
||||
<PointTree
|
||||
ref="pointTree"
|
||||
:default-expand-all="false"
|
||||
:default-expanded-keys="monitoringPoint.state.lineId ? [monitoringPoint.state.lineId] : []"
|
||||
:current-node-key="monitoringPoint.state.lineId"
|
||||
:show-checkbox="monitoringPoint.state.showCheckBox"
|
||||
:default-checked-keys="monitoringPoint.state.lineIds"
|
||||
@check="handleCheckChange"
|
||||
@node-click="handleNodeClick"
|
||||
@init="handleNodeClick"
|
||||
></PointTree>
|
||||
</pane>
|
||||
<pane>
|
||||
<div style="position: relative; height: 100%">
|
||||
<el-tabs
|
||||
v-model="activeName"
|
||||
type="border-card"
|
||||
class="demo-tabs"
|
||||
style="height: 100%"
|
||||
@tab-change="handleTabChange"
|
||||
>
|
||||
<el-tab-pane label="事件分析" name="3" lazy v-if="!isReload">
|
||||
<EventStudy :externalHeight='20'/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="事件统计" name="2" lazy v-if="!isReload">
|
||||
<EventStatistics :externalHeight='20'/>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="运行情况" name="4" lazy :style="height" v-if="!isReload">
|
||||
<RunningCondition :externalHeight='20'/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="暂态报告" name="5" lazy v-if="!isReload">
|
||||
<TransientReport />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</pane>
|
||||
</splitpanes>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { defineOptions, watch, onMounted, ref, nextTick } from 'vue'
|
||||
import 'splitpanes/dist/splitpanes.css'
|
||||
import { Splitpanes, Pane } from 'splitpanes'
|
||||
import PointTree from '@/components/tree/pqs/pointTree.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import Navigation from './navigation/index.vue'
|
||||
import EventStatistics from './eventStatistics/index.vue'
|
||||
import EventStudy from './eventStudy/index.vue'
|
||||
import RunningCondition from './runningCondition/index.vue'
|
||||
import TransientReport from './transientReport/index.vue'
|
||||
const VITE_FLAG = import.meta.env.VITE_NAME == 'jibei'
|
||||
import router from '@/router'
|
||||
|
||||
defineOptions({
|
||||
name: 'harmonic-boot/monitor/online'
|
||||
})
|
||||
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const pointTree = ref()
|
||||
const size = ref(0)
|
||||
const isReload = ref(false)
|
||||
const height = mainHeight(40)
|
||||
const activeName = ref('3')
|
||||
onMounted(() => {
|
||||
const dom = document.getElementById('navigation-splitpanes')
|
||||
if (dom) {
|
||||
size.value = Math.round((180 / dom.offsetHeight) * 100)
|
||||
}
|
||||
})
|
||||
const handleNodeClick = (data: any, node: any) => {
|
||||
if (data.level === 6) {
|
||||
monitoringPoint.setValue('lineId', data.id)
|
||||
monitoringPoint.setValue('pid', data.pids)
|
||||
monitoringPoint.setValue('lineName', data.alias)
|
||||
monitoringPoint.setValue('comFlag', data.comFlag)
|
||||
}
|
||||
}
|
||||
const handleCheckChange = (data: any, node: any) => {
|
||||
monitoringPoint.setValue(
|
||||
'lineIds',
|
||||
node.checkedNodes.filter((item: any) => item.level === 6).map((item: any) => item.id)
|
||||
)
|
||||
}
|
||||
const handleTabChange = () => {
|
||||
monitoringPoint.setShowCheckBox(false)
|
||||
}
|
||||
watch(
|
||||
() => router.currentRoute.value.query.lineId,
|
||||
(newLineId, oldLineId) => {
|
||||
if (!newLineId) return
|
||||
// 在这里处理 lineId 的变化
|
||||
monitoringPoint.setValue('lineId', router.currentRoute.value.query.lineId)
|
||||
monitoringPoint.setValue('lineName', router.currentRoute.value.query.lineName)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
watch(
|
||||
() => monitoringPoint.state.lineId,
|
||||
() => {
|
||||
// 刷新页面
|
||||
isReload.value = true
|
||||
nextTick(() => {
|
||||
isReload.value = false
|
||||
})
|
||||
}
|
||||
)
|
||||
const changeTab = (e: string) => {
|
||||
activeName.value = e
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.splitpanes.default-theme .splitpanes__pane {
|
||||
background: #eaeef1;
|
||||
}
|
||||
|
||||
.monitoring-point {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 10px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div v-loading="loading" class="running-condition">
|
||||
<el-form :inline="true" class="fx-jcsb">
|
||||
<el-form-item label="日期">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
<template>
|
||||
<div :style="height">
|
||||
<splitpanes style="height: 100%" class="default-theme" id="navigation-splitpanes">
|
||||
<pane :size="size">
|
||||
<PointTree
|
||||
:default-expand-all="false"
|
||||
:default-expanded-keys="monitoringPoint.state.lineId ? [monitoringPoint.state.lineId] : []"
|
||||
:current-node-key="monitoringPoint.state.lineId"
|
||||
@node-click="handleNodeClick"
|
||||
@init="handleNodeClick"
|
||||
></PointTree>
|
||||
</pane>
|
||||
<pane style="background: #fff" :style="height">
|
||||
<!-- <div :style="height"></div> -->
|
||||
<TableHeader ref="TableHeaderRef" date-picker :show-search="false">
|
||||
@@ -29,7 +20,7 @@
|
||||
<el-button icon="el-icon-Download" type="primary" @click="exportEvent">生成报告</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<div class="box" :style="`height: calc(${tableStore.table.height} + 45px)`">
|
||||
<div class="box" :style="`height: calc(${tableStore.table.height} + 65px)`">
|
||||
<el-row>
|
||||
<el-col :span="12" class="mTop">
|
||||
<div class="grid-content">
|
||||
@@ -140,6 +131,7 @@ import { mainHeight } from '@/utils/layout'
|
||||
import { getLineExport, getList, selectReleation } from '@/api/event-boot/report'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
defineOptions({
|
||||
name: 'TransientReport/monitoringpointReport'
|
||||
})
|
||||
@@ -174,6 +166,7 @@ const formd: any = ref({
|
||||
|
||||
const templatePolicy: any = ref([])
|
||||
const tableStore = new TableStore({
|
||||
publicHeight: 80,
|
||||
url: '',
|
||||
method: 'post',
|
||||
column: []
|
||||
@@ -185,58 +178,7 @@ onMounted(() => {
|
||||
size.value = Math.round((180 / dom.offsetHeight) * 100)
|
||||
}
|
||||
})
|
||||
// getList({
|
||||
// pageNum: 1,
|
||||
// pageSize: 100,
|
||||
// type: 0
|
||||
// }).then(res => {
|
||||
// templatePolicy.value = res.data.records
|
||||
// // 默认选中第一个
|
||||
// if (res.data.records && res.data.records.length > 0) {
|
||||
// value.value = res.data.records[0].id
|
||||
// // 触发 change 事件,加载对应的配置
|
||||
// changeFn(res.data.records[0].id)
|
||||
// }
|
||||
// })
|
||||
const handleNodeClick = (data: any, node: any) => {
|
||||
if (data.level === 6) {
|
||||
dotList.value = data
|
||||
monitoringPoint.setValue('lineId', data.id)
|
||||
}
|
||||
}
|
||||
const changeFn = (val: any) => {
|
||||
formd.value = {
|
||||
xq: false,
|
||||
lb: false,
|
||||
mdbg: false,
|
||||
mdtx: false,
|
||||
sjdITIC: false,
|
||||
sjdF47: false,
|
||||
glfbfz: false,
|
||||
glfbsj: false,
|
||||
tjbg: false,
|
||||
tjtx: false,
|
||||
yybg: false,
|
||||
yytx: false,
|
||||
lxbg: false,
|
||||
lxtx: false,
|
||||
type: 0
|
||||
}
|
||||
let data = {
|
||||
id: val
|
||||
}
|
||||
|
||||
selectReleation(data).then(res => {
|
||||
res.data.forEach((item: any) => {
|
||||
for (let k in formd.value) {
|
||||
if (item.name == k) {
|
||||
formd.value[k] = true
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
const exportEvent = () => {
|
||||
if (dotList.value.level != 6) {
|
||||
return ElMessage({
|
||||
@@ -246,8 +188,8 @@ const exportEvent = () => {
|
||||
}
|
||||
let a = ''
|
||||
|
||||
formd.value.lineId = dotList.value.id
|
||||
formd.value.lineName = dotList.value.name
|
||||
formd.value.lineId = monitoringPoint.state.lineId
|
||||
formd.value.lineName = monitoringPoint.state.lineName.split('>').at(-1)
|
||||
formd.value.searchBeginTime = TableHeaderRef.value.datePickerRef.timeValue[0]
|
||||
formd.value.searchEndTime = TableHeaderRef.value.datePickerRef.timeValue[1]
|
||||
formd.value.flag = TableHeaderRef.value.datePickerRef.interval
|
||||
|
||||
@@ -1,134 +1,134 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form :inline="true" class="formFlex">
|
||||
<el-form-item label="日期">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item class="mr5">
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
<el-button icon="el-icon-Download" type="primary" @click="exportEvent">导出</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div v-loading="loading" style="display: flex; overflow: hidden" :style="{ height: height }">
|
||||
<vxe-table style="flex: 1" v-bind="defaultAttribute" height="100%" :data="region">
|
||||
<vxe-table-colgroup title="暂态统计(按区域统计)">
|
||||
<vxe-table-column field="name" title="区域"></vxe-table-column>
|
||||
<vxe-table-colgroup title="监测点数量">
|
||||
<vxe-table-column field="onLine" title="在线"></vxe-table-column>
|
||||
<vxe-table-column field="offLine" title="离线"></vxe-table-column>
|
||||
</vxe-table-colgroup>
|
||||
<vxe-table-column field="sagsCount" title="暂降次数"></vxe-table-column>
|
||||
<vxe-table-column field="breakCount" title="中断次数"></vxe-table-column>
|
||||
<vxe-table-column field="upCount" title="暂升次数"></vxe-table-column>
|
||||
</vxe-table-colgroup>
|
||||
</vxe-table>
|
||||
<vxe-table style="flex: 1" class="ml10" v-bind="defaultAttribute" height="100%" :data="voltage">
|
||||
<vxe-table-colgroup title="暂态统计(按电压等级统计)">
|
||||
<vxe-table-column field="name" title="电压等级"></vxe-table-column>
|
||||
<vxe-table-colgroup title="监测点数量">
|
||||
<vxe-table-column field="onLine" title="在线"></vxe-table-column>
|
||||
<vxe-table-column field="offLine" title="离线"></vxe-table-column>
|
||||
</vxe-table-colgroup>
|
||||
<vxe-table-column field="sagsCount" title="暂降次数"></vxe-table-column>
|
||||
<vxe-table-column field="breakCount" title="中断次数"></vxe-table-column>
|
||||
<vxe-table-column field="upCount" title="暂升次数"></vxe-table-column>
|
||||
</vxe-table-colgroup>
|
||||
</vxe-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { getVoltage, getGeneralSituation, getExport } from '@/api/event-boot/report'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
const dictData = useDictData()
|
||||
const datePickerRef = ref()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
deptIndex: dictData.state.area[0].id,
|
||||
monitorFlag: 2,
|
||||
powerFlag: 2,
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
serverName: 'event-boot'
|
||||
})
|
||||
const height = mainHeight(145).height
|
||||
const region = ref([])
|
||||
const voltage = ref([])
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
|
||||
Promise.all([
|
||||
getGeneralSituation({
|
||||
...formData,
|
||||
statisticalType: dictData.getBasicData('Statistical_Type', [
|
||||
'Report_Type',
|
||||
'Manufacturer',
|
||||
|
||||
'Voltage_Level',
|
||||
'Load_Type'
|
||||
])[0]
|
||||
}),
|
||||
getVoltage({
|
||||
...formData,
|
||||
statisticalType: dictData.getBasicData('Statistical_Type', [
|
||||
'Report_Type',
|
||||
'Power_Network',
|
||||
'Manufacturer',
|
||||
'Load_Type'
|
||||
])[0]
|
||||
})
|
||||
]).then(res => {
|
||||
loading.value = false
|
||||
region.value = res[0].data
|
||||
voltage.value = res[1].data
|
||||
})
|
||||
}
|
||||
const exportEvent = () => {
|
||||
ElMessage({
|
||||
message: '正在导出中'
|
||||
})
|
||||
getExport({
|
||||
...formData,
|
||||
|
||||
statisticalType: dictData.getBasicData('Statistical_Type', [
|
||||
'Report_Type',
|
||||
'Manufacturer',
|
||||
|
||||
'Voltage_Level',
|
||||
'Load_Type'
|
||||
])[0]
|
||||
}).then(res => {
|
||||
const link = document.createElement('a')
|
||||
let blob = new Blob([res], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'
|
||||
})
|
||||
link.style.display = 'none'
|
||||
link.href = URL.createObjectURL(blob)
|
||||
link.setAttribute('download', '暂态总体概况.xlsx') // 文件名可自定义
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
ElMessage({
|
||||
message: '导出成功',
|
||||
type: 'success'
|
||||
})
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.formFlex {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<el-form :inline="true" class="formFlex">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item class="mr5">
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
<el-button icon="el-icon-Download" type="primary" @click="exportEvent">导出</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div v-loading="loading" style="display: flex; overflow: hidden" :style="{ height: height }">
|
||||
<vxe-table style="flex: 1" v-bind="defaultAttribute" height="100%" :data="region">
|
||||
<vxe-table-colgroup title="暂态统计(按区域统计)">
|
||||
<vxe-table-column field="name" title="区域"></vxe-table-column>
|
||||
<vxe-table-colgroup title="监测点数量">
|
||||
<vxe-table-column field="onLine" title="在线"></vxe-table-column>
|
||||
<vxe-table-column field="offLine" title="离线"></vxe-table-column>
|
||||
</vxe-table-colgroup>
|
||||
<vxe-table-column field="sagsCount" title="暂降次数"></vxe-table-column>
|
||||
<vxe-table-column field="breakCount" title="中断次数"></vxe-table-column>
|
||||
<vxe-table-column field="upCount" title="暂升次数"></vxe-table-column>
|
||||
</vxe-table-colgroup>
|
||||
</vxe-table>
|
||||
<vxe-table style="flex: 1" class="ml10" v-bind="defaultAttribute" height="100%" :data="voltage">
|
||||
<vxe-table-colgroup title="暂态统计(按电压等级统计)">
|
||||
<vxe-table-column field="name" title="电压等级"></vxe-table-column>
|
||||
<vxe-table-colgroup title="监测点数量">
|
||||
<vxe-table-column field="onLine" title="在线"></vxe-table-column>
|
||||
<vxe-table-column field="offLine" title="离线"></vxe-table-column>
|
||||
</vxe-table-colgroup>
|
||||
<vxe-table-column field="sagsCount" title="暂降次数"></vxe-table-column>
|
||||
<vxe-table-column field="breakCount" title="中断次数"></vxe-table-column>
|
||||
<vxe-table-column field="upCount" title="暂升次数"></vxe-table-column>
|
||||
</vxe-table-colgroup>
|
||||
</vxe-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { getVoltage, getGeneralSituation, getExport } from '@/api/event-boot/report'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
const dictData = useDictData()
|
||||
const datePickerRef = ref()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
deptIndex: dictData.state.area[0].id,
|
||||
monitorFlag: 2,
|
||||
powerFlag: 2,
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
serverName: 'event-boot'
|
||||
})
|
||||
const height = mainHeight(145).height
|
||||
const region = ref([])
|
||||
const voltage = ref([])
|
||||
const init = () => {
|
||||
loading.value = true
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
|
||||
Promise.all([
|
||||
getGeneralSituation({
|
||||
...formData,
|
||||
statisticalType: dictData.getBasicData('Statistical_Type', [
|
||||
'Report_Type',
|
||||
'Manufacturer',
|
||||
|
||||
'Voltage_Level',
|
||||
'Load_Type'
|
||||
])[0]
|
||||
}),
|
||||
getVoltage({
|
||||
...formData,
|
||||
statisticalType: dictData.getBasicData('Statistical_Type', [
|
||||
'Report_Type',
|
||||
'Power_Network',
|
||||
'Manufacturer',
|
||||
'Load_Type'
|
||||
])[0]
|
||||
})
|
||||
]).then(res => {
|
||||
loading.value = false
|
||||
region.value = res[0].data
|
||||
voltage.value = res[1].data
|
||||
})
|
||||
}
|
||||
const exportEvent = () => {
|
||||
ElMessage({
|
||||
message: '正在导出中'
|
||||
})
|
||||
getExport({
|
||||
...formData,
|
||||
|
||||
statisticalType: dictData.getBasicData('Statistical_Type', [
|
||||
'Report_Type',
|
||||
'Manufacturer',
|
||||
|
||||
'Voltage_Level',
|
||||
'Load_Type'
|
||||
])[0]
|
||||
}).then(res => {
|
||||
const link = document.createElement('a')
|
||||
let blob = new Blob([res], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8'
|
||||
})
|
||||
link.style.display = 'none'
|
||||
link.href = URL.createObjectURL(blob)
|
||||
link.setAttribute('download', '暂态总体概况.xlsx') // 文件名可自定义
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
ElMessage({
|
||||
message: '导出成功',
|
||||
type: 'success'
|
||||
})
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.formFlex {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,292 +1,292 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-form :inline="true" class="formFlex">
|
||||
<el-form-item label="日期">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item class="mr5">
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div v-loading="loading" :style="{ height: height }">
|
||||
<div style="display: flex">
|
||||
<my-echart class="bars_w" :options="options1" />
|
||||
<my-echart class="bars_w" :options="options2" />
|
||||
</div>
|
||||
<div style="display: flex">
|
||||
<my-echart class="bars_w" :options="options3" />
|
||||
<my-echart class="bars_w" :options="options4" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { getVoltage, getGeneralSituation } from '@/api/event-boot/report'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
const dictData = useDictData()
|
||||
const datePickerRef = ref()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
deptIndex: dictData.state.area[0].id,
|
||||
monitorFlag: 2,
|
||||
powerFlag: 2,
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
serverName: 'event-boot'
|
||||
})
|
||||
const height = mainHeight(145).height
|
||||
const options1 = ref({})
|
||||
const options2 = ref({})
|
||||
const options3 = ref({})
|
||||
const options4 = ref({})
|
||||
|
||||
const init = () => {
|
||||
let label = {
|
||||
normal: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
//数值样式
|
||||
color: '#fff',
|
||||
fontSize: 14
|
||||
}
|
||||
}
|
||||
}
|
||||
loading.value = true
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
|
||||
Promise.all([
|
||||
getGeneralSituation({
|
||||
...formData,
|
||||
statisticalType: dictData.getBasicData('Statistical_Type', [
|
||||
'Report_Type',
|
||||
'Manufacturer',
|
||||
|
||||
'Voltage_Level',
|
||||
'Load_Type'
|
||||
])[0]
|
||||
}),
|
||||
getVoltage({
|
||||
...formData,
|
||||
statisticalType: dictData.getBasicData('Statistical_Type', [
|
||||
'Report_Type',
|
||||
'Power_Network',
|
||||
'Manufacturer',
|
||||
'Load_Type'
|
||||
])[0]
|
||||
})
|
||||
]).then(res => {
|
||||
// region.value = res[0].data
|
||||
// voltage.value = res[1].data
|
||||
|
||||
let area = []
|
||||
let onlineData = []
|
||||
let offlineData = []
|
||||
res[0].data.forEach(item => {
|
||||
area.push(item.name)
|
||||
onlineData.push(item.onLine)
|
||||
offlineData.push(item.offLine)
|
||||
})
|
||||
options1.value = {
|
||||
title: {
|
||||
text: '终端运行情况',
|
||||
subtext: '区域统计'
|
||||
},
|
||||
|
||||
legend: {
|
||||
data: ['在线', '离线']
|
||||
},
|
||||
|
||||
xAxis: {
|
||||
name: '(区域)',
|
||||
data: res[0].data.map(item => item.name)
|
||||
},
|
||||
yAxis: {
|
||||
name: '个' // 给X轴加单位
|
||||
},
|
||||
color: ['#07CCCA', '#FFBF00'],
|
||||
options: {
|
||||
series: [
|
||||
{
|
||||
name: '在线',
|
||||
type: 'bar',
|
||||
barMaxWidth: 20,
|
||||
stack: 'account',
|
||||
|
||||
// color: 'green',
|
||||
data: res[0].data.map(item => item.onLine)
|
||||
},
|
||||
{
|
||||
name: '离线',
|
||||
type: 'bar',
|
||||
barMaxWidth: 20,
|
||||
stack: 'account',
|
||||
|
||||
// color: 'orange',
|
||||
data: res[0].data.map(item => item.offLine)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
options2.value = {
|
||||
title: {
|
||||
text: '终端运行情况',
|
||||
subtext: '电压等级统计'
|
||||
},
|
||||
|
||||
legend: {
|
||||
data: ['在线', '离线']
|
||||
},
|
||||
|
||||
xAxis: {
|
||||
name: '电压\n等级',
|
||||
data: res[1].data.map(item => item.name)
|
||||
},
|
||||
yAxis: {
|
||||
name: '个' // 给X轴加单位
|
||||
},
|
||||
color: ['#07CCCA', '#FFBF00'],
|
||||
options: {
|
||||
series: [
|
||||
{
|
||||
name: '在线',
|
||||
type: 'bar',
|
||||
barMaxWidth: 20,
|
||||
stack: 'account',
|
||||
|
||||
// color: 'green',
|
||||
data: res[1].data.map(item => item.onLine)
|
||||
},
|
||||
{
|
||||
name: '离线',
|
||||
type: 'bar',
|
||||
barMaxWidth: 20,
|
||||
stack: 'account',
|
||||
|
||||
// color: 'orange',
|
||||
data: res[1].data.map(item => item.offLine)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
options3.value = {
|
||||
title: {
|
||||
text: '暂态事件次数',
|
||||
subtext: '区域统计'
|
||||
},
|
||||
|
||||
legend: {
|
||||
data: ['暂降次数', '中断次数', '暂升次数']
|
||||
},
|
||||
|
||||
xAxis: {
|
||||
name: '(区域)',
|
||||
data: res[0].data.map(item => item.name)
|
||||
},
|
||||
yAxis: {
|
||||
name: '次' // 给X轴加单位
|
||||
},
|
||||
color: ['#07CCCA', '#FFBF00', '#77DA63'],
|
||||
options: {
|
||||
series: [
|
||||
{
|
||||
name: '暂降次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
|
||||
barWidth: 20,
|
||||
|
||||
data: res[0].data.map(item => item.sagsCount)
|
||||
},
|
||||
{
|
||||
name: '中断次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
|
||||
barWidth: 20,
|
||||
|
||||
data: res[0].data.map(item => item.breakCount)
|
||||
},
|
||||
{
|
||||
name: '暂升次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
|
||||
barWidth: 20,
|
||||
|
||||
data: res[0].data.map(item => item.upCount)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
options4.value = {
|
||||
title: {
|
||||
text: '暂态事件次数',
|
||||
subtext: '电压等级统计'
|
||||
},
|
||||
|
||||
legend: {
|
||||
data: ['暂降次数', '中断次数', '暂升次数']
|
||||
},
|
||||
color: ['#07CCCA', '#FFBF00', '#77DA63'],
|
||||
xAxis: {
|
||||
name: '电压\n等级',
|
||||
data: res[1].data.map(item => item.name)
|
||||
},
|
||||
yAxis: {
|
||||
name: '次'
|
||||
},
|
||||
options: {
|
||||
series: [
|
||||
{
|
||||
name: '暂降次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
|
||||
barWidth: 20,
|
||||
|
||||
data: res[1].data.map(item => item.sagsCount)
|
||||
},
|
||||
{
|
||||
name: '中断次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
|
||||
barWidth: 20,
|
||||
|
||||
data: res[1].data.map(item => item.breakCount)
|
||||
},
|
||||
{
|
||||
name: '暂升次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
barWidth: 20,
|
||||
|
||||
data: res[1].data.map(item => item.upCount)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
const layout = mainHeight(150) as any
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.bars_w {
|
||||
width: 100%;
|
||||
height: calc(v-bind('layout.height') / 2);
|
||||
}
|
||||
.formFlex {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div>
|
||||
<el-form :inline="true" class="formFlex">
|
||||
<el-form-item label="统计时间">
|
||||
<DatePicker ref="datePickerRef"></DatePicker>
|
||||
</el-form-item>
|
||||
<el-form-item class="mr5">
|
||||
<el-button type="primary" @click="init" icon="el-icon-Search">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div v-loading="loading" :style="{ height: height }">
|
||||
<div style="display: flex">
|
||||
<my-echart class="bars_w" :options="options1" />
|
||||
<my-echart class="bars_w" :options="options2" />
|
||||
</div>
|
||||
<div style="display: flex">
|
||||
<my-echart class="bars_w" :options="options3" />
|
||||
<my-echart class="bars_w" :options="options4" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { getVoltage, getGeneralSituation } from '@/api/event-boot/report'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
const dictData = useDictData()
|
||||
const datePickerRef = ref()
|
||||
const loading = ref(true)
|
||||
const formData = reactive({
|
||||
deptIndex: dictData.state.area[0].id,
|
||||
monitorFlag: 2,
|
||||
powerFlag: 2,
|
||||
searchBeginTime: '',
|
||||
searchEndTime: '',
|
||||
serverName: 'event-boot'
|
||||
})
|
||||
const height = mainHeight(145).height
|
||||
const options1 = ref({})
|
||||
const options2 = ref({})
|
||||
const options3 = ref({})
|
||||
const options4 = ref({})
|
||||
|
||||
const init = () => {
|
||||
let label = {
|
||||
normal: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
//数值样式
|
||||
color: '#fff',
|
||||
fontSize: 14
|
||||
}
|
||||
}
|
||||
}
|
||||
loading.value = true
|
||||
formData.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
formData.searchEndTime = datePickerRef.value.timeValue[1]
|
||||
|
||||
Promise.all([
|
||||
getGeneralSituation({
|
||||
...formData,
|
||||
statisticalType: dictData.getBasicData('Statistical_Type', [
|
||||
'Report_Type',
|
||||
'Manufacturer',
|
||||
|
||||
'Voltage_Level',
|
||||
'Load_Type'
|
||||
])[0]
|
||||
}),
|
||||
getVoltage({
|
||||
...formData,
|
||||
statisticalType: dictData.getBasicData('Statistical_Type', [
|
||||
'Report_Type',
|
||||
'Power_Network',
|
||||
'Manufacturer',
|
||||
'Load_Type'
|
||||
])[0]
|
||||
})
|
||||
]).then(res => {
|
||||
// region.value = res[0].data
|
||||
// voltage.value = res[1].data
|
||||
|
||||
let area = []
|
||||
let onlineData = []
|
||||
let offlineData = []
|
||||
res[0].data.forEach(item => {
|
||||
area.push(item.name)
|
||||
onlineData.push(item.onLine)
|
||||
offlineData.push(item.offLine)
|
||||
})
|
||||
options1.value = {
|
||||
title: {
|
||||
text: '终端运行情况',
|
||||
subtext: '区域统计'
|
||||
},
|
||||
|
||||
legend: {
|
||||
data: ['在线', '离线']
|
||||
},
|
||||
|
||||
xAxis: {
|
||||
name: '(区域)',
|
||||
data: res[0].data.map(item => item.name)
|
||||
},
|
||||
yAxis: {
|
||||
name: '个' // 给X轴加单位
|
||||
},
|
||||
color: ['#07CCCA', '#FFBF00'],
|
||||
options: {
|
||||
series: [
|
||||
{
|
||||
name: '在线',
|
||||
type: 'bar',
|
||||
barMaxWidth: 20,
|
||||
stack: 'account',
|
||||
|
||||
// color: 'green',
|
||||
data: res[0].data.map(item => item.onLine)
|
||||
},
|
||||
{
|
||||
name: '离线',
|
||||
type: 'bar',
|
||||
barMaxWidth: 20,
|
||||
stack: 'account',
|
||||
|
||||
// color: 'orange',
|
||||
data: res[0].data.map(item => item.offLine)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
options2.value = {
|
||||
title: {
|
||||
text: '终端运行情况',
|
||||
subtext: '电压等级统计'
|
||||
},
|
||||
|
||||
legend: {
|
||||
data: ['在线', '离线']
|
||||
},
|
||||
|
||||
xAxis: {
|
||||
name: '电压\n等级',
|
||||
data: res[1].data.map(item => item.name)
|
||||
},
|
||||
yAxis: {
|
||||
name: '个' // 给X轴加单位
|
||||
},
|
||||
color: ['#07CCCA', '#FFBF00'],
|
||||
options: {
|
||||
series: [
|
||||
{
|
||||
name: '在线',
|
||||
type: 'bar',
|
||||
barMaxWidth: 20,
|
||||
stack: 'account',
|
||||
|
||||
// color: 'green',
|
||||
data: res[1].data.map(item => item.onLine)
|
||||
},
|
||||
{
|
||||
name: '离线',
|
||||
type: 'bar',
|
||||
barMaxWidth: 20,
|
||||
stack: 'account',
|
||||
|
||||
// color: 'orange',
|
||||
data: res[1].data.map(item => item.offLine)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
options3.value = {
|
||||
title: {
|
||||
text: '暂态事件次数',
|
||||
subtext: '区域统计'
|
||||
},
|
||||
|
||||
legend: {
|
||||
data: ['暂降次数', '中断次数', '暂升次数']
|
||||
},
|
||||
|
||||
xAxis: {
|
||||
name: '(区域)',
|
||||
data: res[0].data.map(item => item.name)
|
||||
},
|
||||
yAxis: {
|
||||
name: '次' // 给X轴加单位
|
||||
},
|
||||
color: ['#07CCCA', '#FFBF00', '#77DA63'],
|
||||
options: {
|
||||
series: [
|
||||
{
|
||||
name: '暂降次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
|
||||
barWidth: 20,
|
||||
|
||||
data: res[0].data.map(item => item.sagsCount)
|
||||
},
|
||||
{
|
||||
name: '中断次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
|
||||
barWidth: 20,
|
||||
|
||||
data: res[0].data.map(item => item.breakCount)
|
||||
},
|
||||
{
|
||||
name: '暂升次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
|
||||
barWidth: 20,
|
||||
|
||||
data: res[0].data.map(item => item.upCount)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
options4.value = {
|
||||
title: {
|
||||
text: '暂态事件次数',
|
||||
subtext: '电压等级统计'
|
||||
},
|
||||
|
||||
legend: {
|
||||
data: ['暂降次数', '中断次数', '暂升次数']
|
||||
},
|
||||
color: ['#07CCCA', '#FFBF00', '#77DA63'],
|
||||
xAxis: {
|
||||
name: '电压\n等级',
|
||||
data: res[1].data.map(item => item.name)
|
||||
},
|
||||
yAxis: {
|
||||
name: '次'
|
||||
},
|
||||
options: {
|
||||
series: [
|
||||
{
|
||||
name: '暂降次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
|
||||
barWidth: 20,
|
||||
|
||||
data: res[1].data.map(item => item.sagsCount)
|
||||
},
|
||||
{
|
||||
name: '中断次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
|
||||
barWidth: 20,
|
||||
|
||||
data: res[1].data.map(item => item.breakCount)
|
||||
},
|
||||
{
|
||||
name: '暂升次数',
|
||||
type: 'bar',
|
||||
stack: 'account',
|
||||
barWidth: 20,
|
||||
|
||||
data: res[1].data.map(item => item.upCount)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
const layout = mainHeight(150) as any
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.bars_w {
|
||||
width: 100%;
|
||||
height: calc(v-bind('layout.height') / 2);
|
||||
}
|
||||
.formFlex {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user