3 Commits

Author SHA1 Message Date
guanj
a7b5762946 告警事件添加设备选取功能 2026-07-14 09:18:32 +08:00
guanj
0e70182c89 修改列设置点击问题 2026-07-10 08:55:28 +08:00
guanj
e6313ca8c3 全局添加列配置功能 2026-07-09 15:42:58 +08:00
92 changed files with 8535 additions and 8563 deletions

5761
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,10 @@
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite --mode ypt" ,
"dev:zl": "vite --mode zl", "dev:zl": "vite --mode zl",
"dev:ypt": "vite --mode ypt", "dev:ypt": "vite --mode ypt",
"build": "vite build", "build": "vite build --mode ypt",
"build:zl": "vite build --mode zl", "build:zl": "vite build --mode zl",
"build:ypt": "vite build --mode ypt", "build:ypt": "vite build --mode ypt",
"preview": "vite preview" "preview": "vite preview"
@@ -51,7 +51,8 @@
"vue-i18n": "9.10.2", "vue-i18n": "9.10.2",
"vue-router": "4", "vue-router": "4",
"vue-types": "^5.1.1", "vue-types": "^5.1.1",
"vxe-table": "^4.5.17", "vxe-pc-ui": "~4.15.19",
"vxe-table": "^4.19.22",
"vxe-table-plugin-export-xlsx": "^4.0.7", "vxe-table-plugin-export-xlsx": "^4.0.7",
"web-storage-cache": "^1.1.1", "web-storage-cache": "^1.1.1",
"xe-utils": "^3.5.14" "xe-utils": "^3.5.14"
@@ -67,6 +68,7 @@
"typescript": "^5.2.2", "typescript": "^5.2.2",
"unplugin-auto-import": "^0.16.7", "unplugin-auto-import": "^0.16.7",
"vite": "^5.0.8", "vite": "^5.0.8",
"vite-plugin-lazy-import": "^1.0.7",
"vue-tsc": "^1.8.25" "vue-tsc": "^1.8.25"
} }
} }

6848
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--指标越限程度 --> <!--指标越限程度 -->
<TableHeader ref="TableHeaderRef" :showReset="false" @selectChange="selectChange" datePicker <TableHeader ref="TableHeaderRef" :showReset="false" showCustomColumn @selectChange="selectChange" datePicker
:timeKeyList="prop.timeKey" v-if="fullscreen"></TableHeader> :timeKeyList="prop.timeKey" v-if="fullscreen"></TableHeader>
<my-echart class="tall" :options="echartList" <my-echart class="tall" :options="echartList"
:style="{ width: prop.width, height: `calc(${prop.height} / 2 )` }" /> :style="{ width: prop.width, height: `calc(${prop.height} / 2 )` }" />

View File

@@ -2,7 +2,7 @@
<div> <div>
<!-- 指标越限详情 --> <!-- 指标越限详情 -->
<el-dialog draggable :title="title" v-model="dialogVisible" append-to-body width="70%"> <el-dialog draggable :title="title" v-model="dialogVisible" append-to-body width="70%">
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef"> <TableHeader datePicker showExport :showReset="false" showCustomColumn ref="tableHeaderRef">
<template v-slot:select> <template v-slot:select>
<!-- <el-form-item label="监测点"> <!-- <el-form-item label="监测点">
<el-select <el-select
@@ -76,18 +76,18 @@ const tableStore: any = new TableStore({
{ {
title: '日期', title: '日期',
field: 'time', field: 'time',
width: '120', minWidth: '120',
sortable: true sortable: true
}, },
{ {
title: '名称', title: '名称',
field: 'lineName', field: 'lineName',
width: '120' minWidth: '120'
}, },
{ {
title: '长时闪变越限(%)', title: '长时闪变越限(%)',
field: 'flickerOvertime', field: 'flickerOvertime',
width: '90', minWidth: '90',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
@@ -96,7 +96,7 @@ const tableStore: any = new TableStore({
{ {
title: '电压偏差越限(%)', title: '电压偏差越限(%)',
field: 'voltageDevOvertime', field: 'voltageDevOvertime',
width: '100', minWidth: '100',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
@@ -105,7 +105,7 @@ const tableStore: any = new TableStore({
{ {
title: '三相不平衡度越限(%)', title: '三相不平衡度越限(%)',
field: 'ubalanceOvertime', field: 'ubalanceOvertime',
width: '100', minWidth: '100',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--电网侧指标越限统计 --> <!--电网侧指标越限统计 -->
<TableHeader :showReset="false" ref="TableHeaderRef" @selectChange="selectChange" datePicker <TableHeader :showReset="false" ref="TableHeaderRef" showCustomColumn @selectChange="selectChange" datePicker
:timeKeyList="prop.timeKey" v-if="fullscreen"></TableHeader> :timeKeyList="prop.timeKey" v-if="fullscreen"></TableHeader>
<my-echart class="tall" :options="echartList" :style="{ <my-echart class="tall" :options="echartList" :style="{
width: prop.width, width: prop.width,

View File

@@ -2,7 +2,7 @@
<div> <div>
<!-- 指标越限详情 --> <!-- 指标越限详情 -->
<el-dialog draggable :title="title" v-model="dialogVisible" append-to-body width="70%"> <el-dialog draggable :title="title" v-model="dialogVisible" append-to-body width="70%">
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef"> <TableHeader datePicker showExport showCustomColumn :showReset="false" ref="tableHeaderRef">
<!-- <template v-slot:select> <!-- <template v-slot:select>
<el-form-item label="监测点"> <el-form-item label="监测点">
<el-select <el-select
@@ -77,18 +77,18 @@ const tableStore: any = new TableStore({
{ {
title: '日期', title: '日期',
field: 'time', field: 'time',
width: '120', minWidth: '120',
sortable: true sortable: true
}, },
{ {
title: '监测点名称', title: '监测点名称',
field: 'lineName', field: 'lineName',
width: '150' minWidth: '150'
}, },
{ {
title: '长时闪变越限(分钟)', title: '长时闪变越限(分钟)',
field: 'flickerOvertime', field: 'flickerOvertime',
width: '100', minWidth: '100',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
@@ -96,7 +96,7 @@ const tableStore: any = new TableStore({
}, { }, {
title: '电压偏差越限(分钟)', title: '电压偏差越限(分钟)',
field: 'uaberranceOvertime', field: 'uaberranceOvertime',
width: '100', minWidth: '100',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
@@ -105,7 +105,7 @@ const tableStore: any = new TableStore({
{ {
title: '三相不平衡度越限(分钟)', title: '三相不平衡度越限(分钟)',
field: 'ubalanceOvertime', field: 'ubalanceOvertime',
width: '100', minWidth: '100',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--主要监测点列表 --> <!--主要监测点列表 -->
<TableHeader :showReset="false" showExport :timeKeyList="prop.timeKey" @selectChange="selectChange" <TableHeader :showReset="false" showExport showCustomColumn :timeKeyList="prop.timeKey" @selectChange="selectChange"
v-if="fullscreen" ref="TableHeaderRef"> v-if="fullscreen" ref="TableHeaderRef">
<template v-slot:select> <template v-slot:select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">

View File

@@ -1,7 +1,7 @@
<template> <template>
<!-- 综合评估详情 --> <!-- 综合评估详情 -->
<el-dialog draggable title="指标合格率统计" v-model="dialogVisible" append-to-body width="70%"> <el-dialog draggable title="指标合格率统计" v-model="dialogVisible" append-to-body width="70%">
<TableHeader datePicker showExport :showReset="false"> <TableHeader datePicker showExport showCustomColumn :showReset="false">
<template v-slot:select> <template v-slot:select>
<el-form-item label="监测点名称"> <el-form-item label="监测点名称">
<el-select <el-select
@@ -38,7 +38,7 @@ const loop50 = (key: string) => {
title: i + '次', title: i + '次',
// field: key + i, // field: key + i,
field: 'flicker', field: 'flicker',
width: '80' minWidth: '80'
}) })
} }
return list return list
@@ -61,32 +61,32 @@ const tableStore: any = new TableStore({
{ {
title: '日期', title: '日期',
field: 'time', field: 'time',
width: '150' minWidth: '150'
}, },
{ {
title: '名称', title: '名称',
field: 'name', field: 'name',
width: '150' minWidth: '150'
}, },
{ {
title: '长时闪变越限(分钟)', title: '长时闪变越限(分钟)',
field: 'flicker', field: 'flicker',
width: '80' minWidth: '80'
}, },
{ {
title: '三相不平衡度越限(分钟)', title: '三相不平衡度越限(分钟)',
field: 'flicker', field: 'flicker',
width: '100' minWidth: '100'
}, },
{ {
title: '电压偏差越限(分钟)', title: '电压偏差越限(分钟)',
field: 'flicker', field: 'flicker',
width: '100' minWidth: '100'
}, },
{ {
title: '频率偏差越限(分钟)', title: '频率偏差越限(分钟)',
field: 'flicker', field: 'flicker',
width: '100' minWidth: '100'
}, },
{ {
title: '谐波电压越限(分钟)', title: '谐波电压越限(分钟)',

View File

@@ -2,7 +2,7 @@
<div> <div>
<!-- 综合评估详情 --> <!-- 综合评估详情 -->
<el-dialog draggable title="指标合格率统计" v-model="dialogVisible" append-to-body width="70%"> <el-dialog draggable title="指标合格率统计" v-model="dialogVisible" append-to-body width="70%">
<TableHeader datePicker showExport :showReset="false"> <TableHeader datePicker showExport showCustomColumn :showReset="false">
<template v-slot:select> <template v-slot:select>
<el-form-item label="监测点名称"> <el-form-item label="监测点名称">
<el-select <el-select
@@ -76,17 +76,17 @@ const tableStore: any = new TableStore({
{ {
title: '日期', title: '日期',
field: 'time', field: 'time',
width: '150' minWidth: '150'
}, },
{ {
title: '名称', title: '名称',
field: 'name', field: 'name',
width: '150' minWidth: '150'
}, },
{ {
title: '长时闪变越限(分钟)', title: '长时闪变越限(分钟)',
field: 'flicker', field: 'flicker',
width: '80', minWidth: '80',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flicker}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.flicker}</span>`
@@ -95,17 +95,17 @@ const tableStore: any = new TableStore({
{ {
title: '三相不平衡度越限(分钟)', title: '三相不平衡度越限(分钟)',
field: 'flicker', field: 'flicker',
width: '100' minWidth: '100'
}, },
{ {
title: '电压偏差越限(分钟)', title: '电压偏差越限(分钟)',
field: 'flicker', field: 'flicker',
width: '100' minWidth: '100'
}, },
{ {
title: '频率偏差越限(分钟)', title: '频率偏差越限(分钟)',
field: 'flicker', field: 'flicker',
width: '100' minWidth: '100'
}, },
{ {
title: '谐波电压越限(分钟)', title: '谐波电压越限(分钟)',

View File

@@ -2,7 +2,7 @@
<div> <div>
<!-- 指标越限详情 --> <!-- 指标越限详情 -->
<el-dialog draggable :title="title" v-model="dialogVisible" append-to-body width="70%"> <el-dialog draggable :title="title" v-model="dialogVisible" append-to-body width="70%">
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef"> <TableHeader datePicker showExport showCustomColumn :showReset="false" ref="tableHeaderRef">
<template v-slot:select> <template v-slot:select>
<!-- <el-form-item label="监测点"> <!-- <el-form-item label="监测点">
<el-select <el-select
@@ -49,7 +49,7 @@ const loop50 = (key: string) => {
list.push({ list.push({
title: i + '次', title: i + '次',
field: key + i + 'Overtime', field: key + i + 'Overtime',
width: '60', minWidth: '60',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
@@ -76,18 +76,18 @@ const tableStore: any = new TableStore({
{ {
title: '日期', title: '日期',
field: 'time', field: 'time',
width: '120', minWidth: '120',
sortable: true sortable: true
}, },
{ {
title: '名称', title: '名称',
field: 'lineName', field: 'lineName',
width: '120' minWidth: '120'
}, },
{ {
title: '长时闪变越限(%)', title: '长时闪变越限(%)',
field: 'flickerOvertime', field: 'flickerOvertime',
width: '90', minWidth: '90',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
@@ -96,7 +96,7 @@ const tableStore: any = new TableStore({
{ {
title: '电压偏差越限(%)', title: '电压偏差越限(%)',
field: 'voltageDevOvertime', field: 'voltageDevOvertime',
width: '100', minWidth: '100',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
@@ -105,7 +105,7 @@ const tableStore: any = new TableStore({
{ {
title: '三相不平衡度越限(%)', title: '三相不平衡度越限(%)',
field: 'ubalanceOvertime', field: 'ubalanceOvertime',
width: '100', minWidth: '100',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`

View File

@@ -1,26 +1,56 @@
<template> <template>
<div> <div>
<!-- 监测点列表 --> <!-- 监测点列表 -->
<TableHeader ref="TableHeaderRef" :showReset="false" showExport @selectChange="selectChange" v-if="fullscreen" <TableHeader
:timeKeyList="prop.timeKey"> ref="TableHeaderRef"
:showReset="false"
showExport
@selectChange="selectChange"
v-if="fullscreen"
:timeKeyList="prop.timeKey"
>
<template #select> <template #select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit style="width: 240px" <el-input
v-model.trim="tableStore.table.params.searchValue" clearable placeholder="请输入监测点名称" /> maxlength="32"
show-word-limit
style="width: 240px"
v-model.trim="tableStore.table.params.searchValue"
clearable
placeholder="请输入监测点名称"
/>
</el-form-item> </el-form-item>
</template> </template>
</TableHeader> </TableHeader>
<Table ref="tableRef" @cell-click="cellClickEvent" <Table
:height="`calc(${prop.height} - ${headerHeight}px + ${fullscreen ? -58 : 56}px )`"></Table> ref="tableRef"
@cell-click="cellClickEvent"
:height="`calc(${prop.height} - ${headerHeight}px + ${fullscreen ? -58 : 56}px )`"
></Table>
<!-- 指标越限详情 --> <!-- 指标越限详情 -->
<OverLimitDetails ref="OverLimitDetailsRef" /> <OverLimitDetails ref="OverLimitDetailsRef" />
<!-- 上传对话框 --> <!-- 上传对话框 -->
<el-dialog v-model="uploadDialogVisible" title="上传报告" append-to-body width="500px" @closed="handleDialogClosed"> <el-dialog
<el-upload ref="uploadRef" class="upload-demo" action="" accept=".doc,.docx,.PDF" :on-change="handleChange" v-model="uploadDialogVisible"
:before-upload="beforeUpload" :limit="1" :auto-upload="false" :on-exceed="handleExceed" title="上传报告"
:on-remove="handleRemove" :file-list="fileList"> append-to-body
width="500px"
@closed="handleDialogClosed"
>
<el-upload
ref="uploadRef"
class="upload-demo"
action=""
accept=".doc,.docx,.PDF"
:on-change="handleChange"
:before-upload="beforeUpload"
:limit="1"
:auto-upload="false"
:on-exceed="handleExceed"
:on-remove="handleRemove"
:file-list="fileList"
>
<el-button type="primary">点击上传</el-button> <el-button type="primary">点击上传</el-button>
<template #tip> <template #tip>
<div class="el-upload__tip">请上传Word或PDF文件</div> <div class="el-upload__tip">请上传Word或PDF文件</div>
@@ -110,7 +140,7 @@ const tableStore: any = new TableStore({
minWidth: 150, minWidth: 150,
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row?.cellValue || '/'}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row?.lineName || '/'}</span>`
} }
}, },
{ title: '设备名称', field: 'devName', minWidth: 150, align: 'center' }, { title: '设备名称', field: 'devName', minWidth: 150, align: 'center' },
@@ -166,7 +196,6 @@ const tableStore: any = new TableStore({
} }
}, },
{ {
title: '治理方案', title: '治理方案',
field: 'govern', field: 'govern',
@@ -395,7 +424,6 @@ const handleUpload = async () => {
uploadDialogVisible.value = false uploadDialogVisible.value = false
tableStore.index() tableStore.index()
return Promise.resolve(result) return Promise.resolve(result)
} catch (error: any) { } catch (error: any) {
ElMessage.error('上传失败: ' + (error.message || '未知错误')) ElMessage.error('上传失败: ' + (error.message || '未知错误'))
return Promise.reject(error) return Promise.reject(error)

View File

@@ -2,7 +2,7 @@
<div> <div>
<!-- 指标越限详情 --> <!-- 指标越限详情 -->
<el-dialog draggable :title="title" v-model="dialogVisible" append-to-body width="1200"> <el-dialog draggable :title="title" v-model="dialogVisible" append-to-body width="1200">
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef"> <TableHeader datePicker showExport showCustomColumn :showReset="false" ref="tableHeaderRef">
<template v-slot:select> <template v-slot:select>
<!-- <el-form-item label="监测点"> <!-- <el-form-item label="监测点">
<el-select <el-select
@@ -76,18 +76,18 @@ const tableStore: any = new TableStore({
{ {
title: '日期', title: '日期',
field: 'time', field: 'time',
width: '120', minWidth: '120',
sortable: true sortable: true
}, },
{ {
title: '名称', title: '名称',
field: 'lineName', field: 'lineName',
width: '120' minWidth: '120'
}, },
{ {
title: '长时闪变越限(%)', title: '长时闪变越限(%)',
field: 'flickerOvertime', field: 'flickerOvertime',
width: '90', minWidth: '90',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
@@ -96,7 +96,7 @@ const tableStore: any = new TableStore({
{ {
title: '电压偏差越限(%)', title: '电压偏差越限(%)',
field: 'voltageDevOvertime', field: 'voltageDevOvertime',
width: '100', minWidth: '100',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
@@ -105,7 +105,7 @@ const tableStore: any = new TableStore({
{ {
title: '三相不平衡度越限(%)', title: '三相不平衡度越限(%)',
field: 'ubalanceOvertime', field: 'ubalanceOvertime',
width: '100', minWidth: '100',
render: 'customTemplate', render: 'customTemplate',
customTemplate: (row: any) => { customTemplate: (row: any) => {
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>` return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--敏感负荷列表 --> <!--敏感负荷列表 -->
<TableHeader ref="TableHeaderRef" :showReset="false" @selectChange="selectChange" v-if="fullscreen" <TableHeader ref="TableHeaderRef" :showReset="false" showCustomColumn @selectChange="selectChange" v-if="fullscreen"
:timeKeyList="prop.timeKey"> :timeKeyList="prop.timeKey">
<template #select> <template #select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<el-dialog draggable title="暂态事件" v-model="dialogVisible" append-to-body width="70%"> <el-dialog draggable title="暂态事件" v-model="dialogVisible" append-to-body width="70%">
<TableHeader datePicker showExport ref="tableHeaderRef" @selectChange="selectChange" <TableHeader datePicker showExport showCustomColumn ref="tableHeaderRef" @selectChange="selectChange"
@onResetForm="onResetForm"> @onResetForm="onResetForm">
<template v-slot:operation> <template v-slot:operation>
<el-button type="primary" icon="el-icon-Operation" @click="openFilterDialog">事件筛选</el-button> <el-button type="primary" icon="el-icon-Operation" @click="openFilterDialog">事件筛选</el-button>

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<el-dialog draggable :title="title" v-model="dialogVisible" append-to-body width="70%"> <el-dialog draggable :title="title" v-model="dialogVisible" append-to-body width="70%">
<TableHeader datePicker showExport ref="tableHeaderRef" @selectChange="selectChange" <TableHeader datePicker showExport showCustomColumn ref="tableHeaderRef" @selectChange="selectChange"
@onResetForm="onResetForm"> @onResetForm="onResetForm">
<template v-slot:operation> <template v-slot:operation>
<el-button type="primary" icon="el-icon-Operation" @click="openFilterDialog">事件筛选</el-button> <el-button type="primary" icon="el-icon-Operation" @click="openFilterDialog">事件筛选</el-button>

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<!--暂态事件统计 --> <!--暂态事件统计 -->
<TableHeader ref="TableHeaderRef" :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen" <TableHeader ref="TableHeaderRef" :showReset="false" showCustomColumn @selectChange="selectChange" datePicker v-if="fullscreen"
:timeKeyList="prop.timeKey"></TableHeader> :timeKeyList="prop.timeKey"></TableHeader>
<my-echart class="tall" :options="echartList" :style="{ <my-echart class="tall" :options="echartList" :style="{
width: prop.width, width: prop.width,

View File

@@ -5,7 +5,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, defineExpose, watch, nextTick } from 'vue' import { onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue'
// import echarts from './echarts' // import echarts from './echarts'
import * as echarts from 'echarts' // 全引入 import * as echarts from 'echarts' // 全引入
import 'echarts-gl' import 'echarts-gl'

View File

@@ -14,10 +14,17 @@ import html2canvas from 'html2canvas'
import $ from 'jquery' import $ from 'jquery'
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { calcRmsYAxisRange, formatAxisLabel } from '@/utils/chartAxisHelper' import {
calcRmsYAxisRange,
createWaveLineSeries,
formatAxisLabel,
formatWaveAxisTooltip,
WAVE_AXIS_POINTER,
WAVE_DATA_ZOOM
} from '@/utils/chartAxisHelper'
import url from '@/assets/img/point.png' import url from '@/assets/img/point.png'
import url2 from '@/assets/img/dw.png' import url2 from '@/assets/img/dw.png'
import { buildWaveCacheKey, getWaveCache, setWaveCache } from '@/utils/waveCache' import { buildWaveCacheKey, getWaveCache, setWaveCache, removeWaveCacheByEvent } from '@/utils/waveCache'
import { getRmsWorker, buildWorkerPayload } from '@/utils/waveWorkerPool' import { getRmsWorker, buildWorkerPayload } from '@/utils/waveWorkerPool'
import { buildExportBaseName, formatExportDateTime } from '@/utils/echartMethod' import { buildExportBaseName, formatExportDateTime } from '@/utils/echartMethod'
let waveRequestId = 0 let waveRequestId = 0
@@ -186,6 +193,9 @@ onMounted(() => {
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {
waveRequestId++
pendingCacheKeys.clear()
removeWaveCacheByEvent(props.wp, props.boxoList)
backbxlb() backbxlb()
window.removeEventListener('resize', handleResize) window.removeEventListener('resize', handleResize)
}) })
@@ -660,21 +670,9 @@ const initWave = (
tooltip: { tooltip: {
top: '10px', top: '10px',
trigger: 'axis', trigger: 'axis',
axisPointer: WAVE_AXIS_POINTER,
borderColor: 'grey', borderColor: 'grey',
formatter: function (params: any) { formatter: (params: any) => formatWaveAxisTooltip(params),
let tips = '时刻:' + params[0].data[0] + '</br/>'
for (let i = 0; i < params.length; i++) {
if (params[i].seriesName != '暂降触发点') {
tips +=
params[i].marker +
params[i].seriesName +
':' +
(params[i].value[1] - 0).toFixed(2) +
'<br/>'
}
}
return tips
},
textStyle: { textStyle: {
color: '#fff', color: '#fff',
fontStyle: 'normal', fontStyle: 'normal',
@@ -814,52 +812,11 @@ const initWave = (
top: '60px' top: '60px'
// containLabel: true // containLabel: true
}, },
dataZoom: [ dataZoom: WAVE_DATA_ZOOM,
{
type: 'inside',
height: 13,
start: 0,
bottom: '10px',
end: 100,
filterMode: 'none'
},
{
start: 0,
height: 13,
bottom: '10px',
end: 100,
filterMode: 'none'
}
],
series: [ series: [
{ createWaveLineSeries(a, radata, '#DAA520'),
name: a, createWaveLineSeries(b, rbdata, '#2E8B57'),
type: 'line', createWaveLineSeries(c, rcdata, '#A52a2a'),
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#DAA520' },
data: radata
},
{
name: b,
type: 'line',
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#2E8B57' },
data: rbdata
},
{
name: c,
type: 'line',
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#A52a2a' },
data: rcdata
},
{ {
name: '暂降触发点', name: '暂降触发点',
type: 'scatter', type: 'scatter',
@@ -1024,21 +981,9 @@ const drawPics = (
tooltip: { tooltip: {
top: '10px', top: '10px',
trigger: 'axis', trigger: 'axis',
axisPointer: WAVE_AXIS_POINTER,
borderColor: 'grey', borderColor: 'grey',
formatter: function (params: any) { formatter: (params: any) => formatWaveAxisTooltip(params, { showMarker: false }),
let tips = '时刻:' + params[0].data[0] + '</br/>'
for (let i = 0; i < params.length; i++) {
if (params[i].seriesName != '暂降触发点') {
tips +=
params[i].marker +
params[i].seriesName +
':' +
(params[i].value[1] - 0).toFixed(2) +
'<br/>'
}
}
return tips
},
textStyle: { textStyle: {
color: '#fff', color: '#fff',
fontStyle: 'normal', fontStyle: 'normal',
@@ -1163,52 +1108,11 @@ const drawPics = (
top: '60px' top: '60px'
// containLabel: true // containLabel: true
}, },
dataZoom: [ dataZoom: WAVE_DATA_ZOOM,
{
type: 'inside',
height: 13,
start: 0,
bottom: '10px',
end: 100,
filterMode: 'none'
},
{
start: 0,
height: 13,
bottom: '10px',
end: 100,
filterMode: 'none'
}
],
series: [ series: [
{ createWaveLineSeries(a, radata, '#DAA520'),
name: a, createWaveLineSeries(b, rbdata, '#2E8B57'),
type: 'line', createWaveLineSeries(c, rcdata, '#A52a2a')
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#DAA520' },
data: radata
},
{
name: b,
type: 'line',
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#2E8B57' },
data: rbdata
},
{
name: c,
type: 'line',
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#A52a2a' },
data: rcdata
}
] ]
} }

View File

@@ -14,9 +14,17 @@ import html2canvas from 'html2canvas'
import $ from 'jquery' import $ from 'jquery'
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { calcShuYAxisRange, formatAxisLabel } from '@/utils/chartAxisHelper' import {
calcShuYAxisRange,
createWaveLineSeries,
formatAxisLabel,
formatWaveAxisTooltip,
WAVE_AXIS_POINTER,
WAVE_DATA_ZOOM
} from '@/utils/chartAxisHelper'
import url from '@/assets/img/point.png' import url from '@/assets/img/point.png'
import { buildWaveCacheKey, getWaveCache, setWaveCache } from '@/utils/waveCache'
import { buildWaveCacheKey, getWaveCache, setWaveCache, removeWaveCacheByEvent } from '@/utils/waveCache'
import { getShuWorker, buildWorkerPayload } from '@/utils/waveWorkerPool' import { getShuWorker, buildWorkerPayload } from '@/utils/waveWorkerPool'
import { buildExportBaseName, formatExportDateTime } from '@/utils/echartMethod' import { buildExportBaseName, formatExportDateTime } from '@/utils/echartMethod'
@@ -192,6 +200,9 @@ onMounted(() => {
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {
waveRequestId++
pendingCacheKeys.clear()
removeWaveCacheByEvent(props.wp, props.boxoList)
backbxlb() backbxlb()
window.removeEventListener('resize', handleResize) window.removeEventListener('resize', handleResize)
}) })
@@ -430,26 +441,14 @@ const initWave = (
tooltip: { tooltip: {
top: '10px', top: '10px',
trigger: 'axis', trigger: 'axis',
axisPointer: WAVE_AXIS_POINTER,
borderColor: 'grey', borderColor: 'grey',
style: { style: {
color: '#fff', color: '#fff',
fontSize: '15px', fontSize: '15px',
padding: 10 padding: 10
}, },
formatter: function (params: any) { formatter: (params: any) => formatWaveAxisTooltip(params),
let tips = '时刻:' + params[0].data[0] + '</br/>'
for (let i = 0; i < params.length; i++) {
if (params[i].seriesName != '暂降触发点') {
tips +=
params[i].marker +
params[i].seriesName +
':' +
(params[i].value[1] - 0).toFixed(2) +
'<br/>'
}
}
return tips
},
textStyle: { textStyle: {
color: '#fff', color: '#fff',
fontStyle: 'normal', fontStyle: 'normal',
@@ -577,55 +576,11 @@ const initWave = (
bottom: '45px', bottom: '45px',
top: '60px' top: '60px'
}, },
dataZoom: [ dataZoom: WAVE_DATA_ZOOM,
{
type: 'inside',
height: 13,
start: 0,
bottom: '10px',
end: 100,
filterMode: 'none'
},
{
start: 0,
height: 13,
bottom: '10px',
end: 100,
filterMode: 'none'
}
],
series: [ series: [
{ createWaveLineSeries(a, adata, '#DAA520'),
name: a, createWaveLineSeries(b, bdata, '#2E8B57'),
type: 'line', createWaveLineSeries(c, cdata, '#A52a2a'),
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#DAA520' },
data: adata
},
{
name: b,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#2E8B57' },
data: bdata
},
{
name: c,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#A52a2a' },
data: cdata
},
{ {
name: '暂降触发点', name: '暂降触发点',
type: 'scatter', type: 'scatter',
@@ -778,16 +733,9 @@ const drawPics = (
const option = { const option = {
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
axisPointer: WAVE_AXIS_POINTER,
borderColor: 'grey', borderColor: 'grey',
formatter: function (params: any) { formatter: (params: any) => formatWaveAxisTooltip(params, { showMarker: false }),
let tips = '时刻:' + params[0].data[0] + '</br/>'
for (let i = 0; i < params.length; i++) {
if (params[i].seriesName != '暂降触发点') {
tips += params[i].seriesName + ':' + (params[i].value[1] - 0).toFixed(2) + '<br/>'
}
}
return tips
},
textStyle: { textStyle: {
color: '#fff', color: '#fff',
fontStyle: 'normal', fontStyle: 'normal',
@@ -905,55 +853,11 @@ const drawPics = (
top: '60px' top: '60px'
// containLabel: true // containLabel: true
}, },
dataZoom: [ dataZoom: WAVE_DATA_ZOOM,
{
type: 'inside',
height: 13,
start: 0,
bottom: '10px',
end: 100,
filterMode: 'none'
},
{
start: 0,
height: 13,
bottom: '10px',
end: 100,
filterMode: 'none'
}
],
series: [ series: [
{ createWaveLineSeries(a, adata, '#DAA520'),
name: a, createWaveLineSeries(b, bdata, '#2E8B57'),
type: 'line', createWaveLineSeries(c, cdata, '#A52a2a')
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#DAA520' },
data: adata
},
{
name: b,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#2E8B57' },
data: bdata
},
{
name: c,
type: 'line',
large: true,
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: { color: '#A52a2a' },
data: cdata
}
] ]
} }

View File

@@ -16,7 +16,7 @@ export default defineComponent({
required: true required: true
}, },
size: { size: {
type: String, type: [String, Number],
default: '18px' default: '18px'
}, },
color: { color: {
@@ -27,7 +27,7 @@ export default defineComponent({
setup(props) { setup(props) {
const iconStyle = computed((): CSSProperties => { const iconStyle = computed((): CSSProperties => {
const { size, color } = props const { size, color } = props
let s = `${size.replace('px', '')}px` const s = typeof size === 'number' ? `${size}px` : `${String(size).replace('px', '')}px`
return { return {
fontSize: s, fontSize: s,
color: color color: color

View File

@@ -10,7 +10,7 @@ import { computed, type CSSProperties } from 'vue'
import { isExternal } from '@/utils/common' import { isExternal } from '@/utils/common'
interface Props { interface Props {
name: string name: string
size: string size: string | number
color: string color: string
} }
@@ -20,19 +20,21 @@ const props = withDefaults(defineProps<Props>(), {
color: '#000000', color: '#000000',
}) })
const s = `${props.size.replace('px', '')}px` const s = computed(() =>
typeof props.size === 'number' ? `${props.size}px` : `${String(props.size).replace('px', '')}px`
)
const iconName = computed(() => `#${props.name}`) const iconName = computed(() => `#${props.name}`)
const iconStyle = computed((): CSSProperties => { const iconStyle = computed((): CSSProperties => {
return { return {
color: props.color, color: props.color,
fontSize: s, fontSize: s.value,
} }
}) })
const isUrl = computed(() => isExternal(props.name)) const isUrl = computed(() => isExternal(props.name))
const urlIconStyle = computed(() => { const urlIconStyle = computed(() => {
return { return {
width: s, width: s.value,
height: s, height: s.value,
mask: `url(${props.name}) no-repeat 50% 50%`, mask: `url(${props.name}) no-repeat 50% 50%`,
'-webkit-mask': `url(${props.name}) no-repeat 50% 50%`, '-webkit-mask': `url(${props.name}) no-repeat 50% 50%`,
} }

View File

@@ -9,9 +9,8 @@ export const defaultAttribute: VxeTableProps = {
columnConfig: { resizable: true }, columnConfig: { resizable: true },
rowConfig: { isCurrent: true, isHover: true }, rowConfig: { isCurrent: true, isHover: true },
scrollX: { scrollToLeftOnChange: true }, scrollX: { scrollToLeftOnChange: true },
scrollY: { scrollToTopOnChange: true, enabled: true }, scrollY: { scrollToTopOnChange: true, enabled: true, gt: 100 },
treeConfig: { customConfig: { enabled: true, allowFixed: false, showFooter: false, immediate: true ,mode:'default'},
reserve: true showOverflow: 'tooltip',
}, showHeaderOverflow: false
showOverflow:true
} }

View File

@@ -2,7 +2,7 @@
<div ref="tableHeader" class="cn-table-header"> <div ref="tableHeader" class="cn-table-header">
<div class="table-header ba-scroll-style" :key="num"> <div class="table-header ba-scroll-style" :key="num">
<el-form <el-form
style="flex: 1; height: 34px; margin-right: 0px; display: flex; flex-wrap: wrap" style="flex: 1; min-height: 34px; margin-right: 0px; display: flex; flex-wrap: wrap; align-items: center"
ref="headerForm" ref="headerForm"
@submit.prevent="" @submit.prevent=""
@keyup.enter="onComSearch" @keyup.enter="onComSearch"
@@ -26,8 +26,8 @@
</el-form> </el-form>
<template v-if="$slots.select || datePicker || showSearch"> <template v-if="$slots.select || datePicker || showSearch">
<el-button type="primary" @click="showSelectChange" v-if="showUnfoldButton"> <el-button type="primary" @click="showSelectChange" v-if="showUnfoldButton">
<Icon size="14" name="el-icon-ArrowUp" style="color: #fff" v-if="showSelect" /> <Icon :size="14" name="el-icon-ArrowUp" style="color: #fff" v-if="showSelect" />
<Icon size="14" name="el-icon-ArrowDown" style="color: #fff" v-else /> <Icon :size="14" name="el-icon-ArrowDown" style="color: #fff" v-else />
</el-button> </el-button>
<el-button <el-button
@click="onComSearch" @click="onComSearch"
@@ -57,6 +57,14 @@
</el-button> </el-button>
</template> </template>
<slot name="operation"></slot> <slot name="operation"></slot>
<el-button
class="ml10 vxe-toolbar-custom-target"
v-if="showCustomColumn"
:icon="Setting"
@click="openCustomColumn"
>
列设置
</el-button>
</div> </div>
<el-form <el-form
:style="showSelect && showUnfoldButton ? headerFormSecondStyleOpen : headerFormSecondStyleClose" :style="showSelect && showUnfoldButton ? headerFormSecondStyleOpen : headerFormSecondStyleClose"
@@ -76,8 +84,7 @@ import DatePicker from '@/components/form/datePicker/index.vue'
import Area from '@/components/form/area/index.vue' import Area from '@/components/form/area/index.vue'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { useDictData } from '@/stores/dictData' import { useDictData } from '@/stores/dictData'
import { Search, RefreshLeft } from '@element-plus/icons-vue' import { Search, RefreshLeft, Setting } from '@element-plus/icons-vue'
import { defineProps } from 'vue'
import { useTimeCacheStore } from '@/stores/timeCache' import { useTimeCacheStore } from '@/stores/timeCache'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
@@ -105,6 +112,7 @@ interface Props {
showQuery?: boolean //是否显示查詢 showQuery?: boolean //是否显示查詢
showReset?: boolean //是否显示重置 showReset?: boolean //是否显示重置
showExport?: boolean //导出控制 showExport?: boolean //导出控制
showCustomColumn?: boolean // 列设置
timeCacheFlag?: boolean //是否取缓存时间 timeCacheFlag?: boolean //是否取缓存时间
timeKeyList?: string[] //日期下拉列表 timeKeyList?: string[] //日期下拉列表
} }
@@ -118,10 +126,21 @@ const props = withDefaults(defineProps<Props>(), {
showReset: true, showReset: true,
showQuery: true, showQuery: true,
showExport: false, showExport: false,
showCustomColumn: false,
timeCacheFlag: true, timeCacheFlag: true,
timeKeyList: () => ['1', '2', '3', '4', '5'] // 修改为箭头函数返回空数组 timeKeyList: () => ['1', '2', '3', '4', '5'] // 修改为箭头函数返回空数组
}) })
const openCustomColumn = () => {
const tableRef = tableStore?.table?.ref
if (!tableRef) return
if (tableRef.getCustomVisible?.()) {
tableRef.closeCustom?.()
} else {
tableRef.openCustom?.()
}
}
// 处理 DatePicker 值变化事件 // 处理 DatePicker 值变化事件
const handleDatePickerChange = (value: any) => { const handleDatePickerChange = (value: any) => {
// 将值缓存到 timeCache // 将值缓存到 timeCache
@@ -152,6 +171,9 @@ const headerFormSecondStyleClose = {
padding: '0' padding: '0'
} }
onMounted(() => { onMounted(() => {
if (props.showCustomColumn && tableStore?.table) {
tableStore.table.customColumnInHeader = true
}
// 设置初始值到 DatePicker // 设置初始值到 DatePicker
if (props.datePicker && datePickerRef.value) { if (props.datePicker && datePickerRef.value) {
// 从缓存中获取值并设置 // 从缓存中获取值并设置
@@ -183,6 +205,9 @@ onMounted(() => {
}) })
}) })
onUnmounted(() => { onUnmounted(() => {
if (tableStore?.table) {
tableStore.table.customColumnInHeader = false
}
resizeObserver.disconnect() resizeObserver.disconnect()
}) })
@@ -398,4 +423,5 @@ html.dark {
--el-input-width: 220px; --el-input-width: 220px;
} }
} }
</style> </style>

View File

@@ -1,21 +1,22 @@
<template> <template>
<div :style="{ height: typeof props.height === 'string' ? props.height : tableStore.table.height }"> <div :style="{ height: typeof props.height === 'string' ? props.height : tableStore.table.height }">
<div v-if="showCustomColumn && !tableStore?.table?.customColumnInHeader" class="table-custom-toolbar">
<el-button class="vxe-toolbar-custom-target" :icon="Setting" @click="openCustomColumn">列设置</el-button>
</div>
<vxe-table <vxe-table
ref="tableRef" ref="tableRef"
height="auto" height="auto"
:key="key" :key="key"
:data="tableStore.table.data" :data="tableStore.table.data"
v-loading="tableStore.table.loading" v-loading="tableStore.table.loading"
v-bind="Object.assign({}, defaultAttribute, $attrs)" v-bind="tableBindProps"
@checkbox-all="selectChangeEvent" @checkbox-all="selectChangeEvent"
@checkbox-change="selectChangeEvent" @checkbox-change="selectChangeEvent"
:showOverflow="showOverflow"
> >
<!-- :sort-config="{ remote: true }" --> <!-- :sort-config="{ remote: true }" -->
<!-- @sort-change="handleSortChange" --> <!-- @sort-change="handleSortChange" -->
<!-- Column 组件内部是 el-table-column --> <!-- Column 组件内部是 el-table-column -->
<template v-if="isGroup"> <template v-if="isGroup">
<GroupColumn :column="tableStore.table.column" /> <GroupColumn :column="tableStore.table.column" />
</template> </template>
@@ -64,9 +65,9 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, nextTick, inject, computed, onMounted, watch } from 'vue' import { ref, inject, computed, onMounted, watch, useAttrs } from 'vue'
import type { ElTable } from 'element-plus'
import { VxeTableEvents, VxeTableInstance } from 'vxe-table' import { VxeTableEvents, VxeTableInstance } from 'vxe-table'
import { Setting } from '@element-plus/icons-vue'
import FieldRender from '@/components/table/fieldRender/index.vue' import FieldRender from '@/components/table/fieldRender/index.vue'
import Column from '@/components/table/column/index.vue' import Column from '@/components/table/column/index.vue'
import GroupColumn from '@/components/table/column/groupColumn.vue' import GroupColumn from '@/components/table/column/groupColumn.vue'
@@ -74,28 +75,49 @@ import { useConfig } from '@/stores/config'
import type TableStoreClass from '@/utils/tableStore' import type TableStoreClass from '@/utils/tableStore'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { defaultAttribute } from '@/components/table/defaultAttribute' import { defaultAttribute } from '@/components/table/defaultAttribute'
import { buildExportBaseName,formatExportDateTime } from '@/utils/echartMethod' import { buildExportBaseName, formatExportDateTime } from '@/utils/echartMethod'
defineOptions({
inheritAttrs: false
})
const config = useConfig() const config = useConfig()
const tableRef = ref<VxeTableInstance>() const tableRef = ref<VxeTableInstance>()
const tableStore = inject('tableStore') as TableStoreClass const tableStore = inject('tableStore') as TableStoreClass
const router = useRouter() const router = useRouter()
const key = ref(0) const key = ref(0)
interface Props extends /* @vue-ignore */ Partial<InstanceType<typeof ElTable>> { interface Props extends /* @vue-ignore */ Partial<VxeTableInstance> {
isGroup?: boolean isGroup?: boolean
showOverflow?: boolean showOverflow?: boolean | 'ellipsis' | 'title' | 'tooltip'
showCustomColumn?: boolean
height?: string | number height?: string | number
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
isGroup: false, isGroup: false,
showOverflow: true, showOverflow: 'tooltip',
showCustomColumn: false,
height: undefined height: undefined
}) })
const attrs = useAttrs()
const tableBindProps = computed(() => {
const overflow = props.showOverflow ?? defaultAttribute.showOverflow
return Object.assign({}, defaultAttribute, attrs, {
showOverflow: overflow,
showHeaderOverflow: false
})
})
const openCustomColumn = () => {
if (!tableRef.value) return
if (tableRef.value.getCustomVisible?.()) {
tableRef.value.closeCustom?.()
} else {
tableRef.value.openCustom?.()
}
}
onMounted(() => { onMounted(() => {
if (!tableStore?.table) return
tableStore.table.ref = tableRef.value as VxeTableInstance tableStore.table.ref = tableRef.value as VxeTableInstance
}) })
// console.log(props) // console.log(props)
const onTableSizeChange = (val: number) => { const onTableSizeChange = (val: number) => {
@@ -119,7 +141,7 @@ const handleSortChange = ({ field, order }: any) => {
// console.log('🚀 ~ handleSortChange ~ prop, order :', field, order) // console.log('🚀 ~ handleSortChange ~ prop, order :', field, order)
if (field && order) { if (field && order) {
// 根据当前排序条件对所有数据进行排序 // 根据当前排序条件对所有数据进行排序
const list = tableStore.table.copyData.sort((a, b) => { const list = tableStore.table.copyData.sort((a: any, b: any) => {
if (order === 'asc') { if (order === 'asc') {
return a[field] > b[field] ? 1 : -1 return a[field] > b[field] ? 1 : -1
} else { } else {
@@ -151,13 +173,19 @@ const selectChangeEvent: VxeTableEvents.CheckboxChange<any> = ({ checked }) => {
const getRef = () => { const getRef = () => {
return tableRef.value return tableRef.value
} }
const exportColumnFilterMethod = ({ column }: { column: any }) => {
return !(column.title === undefined || column.title === '序号' || column.title === '操作')
}
const getTableExportFilename = () => { const getTableExportFilename = () => {
const exportName = tableStore.exportName const exportName = tableStore.exportName
if (exportName && typeof exportName === 'object') { if (exportName && typeof exportName === 'object') {
return buildExportBaseName(exportName) return buildExportBaseName(exportName)
} }
const feature = const feature =
exportName || (document.querySelectorAll('.ba-nav-tab.active')[0] as HTMLElement | undefined)?.textContent || '导出' exportName ||
(document.querySelectorAll('.ba-nav-tab.active')[0] as HTMLElement | undefined)?.textContent ||
'导出'
return buildExportBaseName({ feature }) return buildExportBaseName({ feature })
} }
@@ -172,14 +200,9 @@ watch(
sheetName: 'Sheet1', sheetName: 'Sheet1',
type: 'xlsx', //导出文件类型 xlsx 和 csv type: 'xlsx', //导出文件类型 xlsx 和 csv
useStyle: true, useStyle: true,
isTitle: true,
data: tableStore.table.allData, // 数据源 // 过滤那个字段导出 data: tableStore.table.allData, // 数据源 // 过滤那个字段导出
columnFilterMethod: function (column: any) { columnFilterMethod: exportColumnFilterMethod
return !(
column.column.title === undefined ||
column.column.title === '序号' ||
column.column.title === '操作'
)
}
}) })
tableStore.table.allFlag = false tableStore.table.allFlag = false
} }
@@ -204,9 +227,14 @@ defineExpose({
.ba-data-table :deep(.table-header-cell) .cell { .ba-data-table :deep(.table-header-cell) .cell {
color: var(--el-text-color-primary); color: var(--el-text-color-primary);
overflow: hidden; }
text-overflow: ellipsis;
white-space: nowrap; :deep(.vxe-header--column.table-header-cell) .vxe-cell,
:deep(.vxe-header--column.table-header-cell) .vxe-cell .vxe-cell--wrapper,
:deep(.vxe-header--column.table-header-cell) .vxe-cell .vxe-cell--title {
overflow: visible;
text-overflow: unset;
white-space: normal;
} }
.table-pagination { .table-pagination {
@@ -226,5 +254,14 @@ defineExpose({
min-width: 128px; min-width: 128px;
} }
} }
.table-custom-toolbar {
display: flex;
justify-content: flex-end;
padding: 8px 15px 0;
background-color: var(--ba-bg-color-overlay);
border-left: 1px solid #e4e7e9;
border-right: 1px solid #e4e7e9;
}
</style> </style>
<!-- @/components/table/column/GroupColumn.vue@/components/table/column/GroupColumn.vue --> <!-- @/components/table/column/GroupColumn.vue@/components/table/column/GroupColumn.vue -->

View File

@@ -4,8 +4,10 @@ import router from './router'
import pinia from '@/stores/index' import pinia from '@/stores/index'
import { registerIcons } from '@/utils/common' import { registerIcons } from '@/utils/common'
import mitt from 'mitt' import mitt from 'mitt'
import VxeUI from 'vxe-pc-ui'
import VXETable from 'vxe-table' import VXETable from 'vxe-table'
import XEUtils from 'xe-utils' import XEUtils from 'xe-utils'
import 'vxe-pc-ui/lib/style.css'
import 'vxe-table/lib/style.css' import 'vxe-table/lib/style.css'
import ElementPlus from 'element-plus' import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css' import 'element-plus/dist/index.css'
@@ -30,6 +32,7 @@ app.use(router)
app.use(pinia) app.use(pinia)
app.use(ElementPlus) app.use(ElementPlus)
app.component('ElDialog', CnDialog) app.component('ElDialog', CnDialog)
app.use(VxeUI)
app.use(VXETable) app.use(VXETable)
registerIcons(app) // icons registerIcons(app) // icons

View File

@@ -244,3 +244,7 @@
min-width: 100% !important; min-width: 100% !important;
// display: inline-block !important; // display: inline-block !important;
} }
.el-radio-button__inner {
border: 1px solid var(--el-border-color);
}

View File

@@ -31,6 +31,8 @@ $border-color: map.merge(
@include set-component-css-var('border-color', $border-color); @include set-component-css-var('border-color', $border-color);
--el-color-danger: #e26257; --el-color-danger: #e26257;
--el-color-success: #2ab914; --el-color-success: #2ab914;
--vxe-ui-font-primary-color: var(--el-color-primary);
--vxe-ui-font-primary-lighten-color: var(--el-color-primary);
// --vxe-table-row-current-background-color: var(--el-color-primary-light-7); // --vxe-table-row-current-background-color: var(--el-color-primary-light-7);
// --vxe-table-row-hover-background-color: var(--el-color-primary-light-9); // --vxe-table-row-hover-background-color: var(--el-color-primary-light-9);
// --vxe-table-row-hover-current-background-color: var(--el-color-primary-light-7); // --vxe-table-row-hover-current-background-color: var(--el-color-primary-light-7);

View File

@@ -20,8 +20,22 @@
// } // }
.vxe-header--row { .vxe-header--row {
background: var(--vxe-table-header-background-color); background: var(--vxe-ui-table-header-background-color, var(--vxe-table-header-background-color));
color: var(--vxe-table-header-font-color); color: var(--vxe-ui-table-header-font-color, var(--vxe-table-header-font-color));
}
.vxe-table--render-default .vxe-body--column.col--ellipsis > .vxe-cell,
.vxe-table--render-default .vxe-body--column.col--ellipsis > .vxe-cell > .vxe-cell--wrapper {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.vxe-table--render-default .vxe-body--column.col--ellipsis .cn-render-buttons,
.vxe-table--render-default .vxe-body--column.col--ellipsis .ba-render-image {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.is--checked.vxe-checkbox, .is--checked.vxe-checkbox,
@@ -61,6 +75,7 @@
color: var(--el-color-primary-light-5); color: var(--el-color-primary-light-5);
} }
.vxe-table--render-default .vxe-body--row.row--current, .vxe-table--render-default .vxe-body--row.row--current,
.vxe-table--render-default .vxe-body--row.row--current > .vxe-body--column,
.vxe-table--render-default .vxe-body--row.row--current:hover { .vxe-table--render-default .vxe-body--row.row--current:hover {
background-color: var(--el-color-primary-light-9); background-color: var(--el-color-primary-light-9);
} }
@@ -85,3 +100,8 @@
// .vxe-table--body .vxe-body--row:nth-child(odd) { // .vxe-table--body .vxe-body--row:nth-child(odd) {
// background-color: #ffffff; // background-color: #ffffff;
// } // }
.vxe-table-custom--panel-list > li {
max-width: 28em;
min-width: 15em;
padding: 0.3em 1em 0.2em 1em;
}

View File

@@ -89,6 +89,83 @@ export function calcShuYAxisRange(dataMin: number, dataMax: number): YAxisRange
return buildYAxisRange(axisMin, axisMax) return buildYAxisRange(axisMin, axisMax)
} }
/** 波形图 dataZoom默认 filterMode仅缩放 X 轴) */
export const WAVE_DATA_ZOOM = [
{
type: 'inside' as const,
xAxisIndex: 0,
start: 0,
end: 100,
},
{
type: 'slider' as const,
xAxisIndex: 0,
height: 13,
bottom: '10px',
start: 0,
end: 100
}
]
export const WAVE_AXIS_POINTER = {
type: 'line' as const,
snap: true
}
/** 波形折线 series不做 sampling/smooth保证 tooltip 与折线位置一致 */
export function createWaveLineSeries(name: string | null, data: number[][], color: string) {
return {
name,
type: 'line' as const,
large: data.length > 2000,
largeThreshold: 2000,
smooth: false,
symbol: 'none' as const,
itemStyle: { color },
data
}
}
const WAVE_TOOLTIP_SKIP_SERIES = new Set(['暂降触发点', '最小暂降幅值'])
/** 波形图 axis tooltip从 data/value 中安全取 [x, y] */
export function formatWaveAxisTooltip(
params: any[],
options?: { showMarker?: boolean }
): string {
if (!params?.length) return ''
const showMarker = options?.showMarker !== false
let time = ''
const axisValue = params[0]?.axisValue
if (axisValue != null && Number.isFinite(Number(axisValue))) {
time = String(Number(Number(axisValue).toFixed(2)))
} else {
for (const param of params) {
if (!param || WAVE_TOOLTIP_SKIP_SERIES.has(param.seriesName)) continue
const point = param.data ?? param.value
if (Array.isArray(point) && point.length >= 2) {
time = String(point[0])
break
}
}
}
let tips = `时刻:${time}<br/>`
for (const param of params) {
if (!param?.seriesName || WAVE_TOOLTIP_SKIP_SERIES.has(param.seriesName)) continue
const point = param.data ?? param.value
const y = Array.isArray(point) ? Number(point[1]) : Number(point)
if (!Number.isFinite(y)) continue
const prefix = showMarker ? param.marker || '' : ''
tips += `${prefix}${param.seriesName}:${y.toFixed(2)}<br/>`
}
return tips
}
/** RMS 波形 Y 轴范围 */ /** RMS 波形 Y 轴范围 */
export function calcRmsYAxisRange(dataMin: number, dataMax: number): YAxisRange { export function calcRmsYAxisRange(dataMin: number, dataMax: number): YAxisRange {
const min = Number(dataMin) const min = Number(dataMin)

View File

@@ -131,6 +131,9 @@ export const yMethod = (arr: any) => {
// } else if (max == 0 && minValue > -1 && minValue < 0) { // } else if (max == 0 && minValue > -1 && minValue < 0) {
// min = -1 // min = -1
// } // }
if (max > 1 && max < 10) {
max = Math.ceil(max)
}
return [min, max] return [min, max]
} }

View File

@@ -8,18 +8,23 @@ const useSetTheme = () => {
const elementPlusTheme = useElementPlusTheme(configStore.getColorVal('elementUiPrimary')) const elementPlusTheme = useElementPlusTheme(configStore.getColorVal('elementUiPrimary'))
const updateTheme = () => { const updateTheme = () => {
const root = document.documentElement const root = document.documentElement
root.style.setProperty('--vxe-table-header-background-color', configStore.getColorVal('tableHeaderBackground')) const tableHeaderBackground = configStore.getColorVal('tableHeaderBackground')
root.style.setProperty('--vxe-table-header-font-color', configStore.getColorVal('tableHeaderColor')) const tableHeaderColor = configStore.getColorVal('tableHeaderColor')
root.style.setProperty('--vxe-table-row-current-background-color', configStore.getColorVal('tableCurrent')) const tableCurrent = configStore.getColorVal('tableCurrent')
root.style.setProperty('--vxe-table-row-hover-background-color', configStore.getColorVal('tableCurrent'))
root.style.setProperty( root.style.setProperty('--vxe-table-header-background-color', tableHeaderBackground)
'--vxe-table-row-hover-current-background-color', root.style.setProperty('--vxe-table-header-font-color', tableHeaderColor)
configStore.getColorVal('tableCurrent') root.style.setProperty('--vxe-table-row-current-background-color', tableCurrent)
) root.style.setProperty('--vxe-table-row-hover-background-color', tableCurrent)
root.style.setProperty( root.style.setProperty('--vxe-table-row-hover-current-background-color', tableCurrent)
'--vxe-table-row-hover-striped-background-color', root.style.setProperty('--vxe-table-row-hover-striped-background-color', tableCurrent)
configStore.getColorVal('tableCurrent')
) root.style.setProperty('--vxe-ui-table-header-background-color', tableHeaderBackground)
root.style.setProperty('--vxe-ui-table-header-font-color', tableHeaderColor)
root.style.setProperty('--vxe-ui-table-row-current-background-color', tableCurrent)
root.style.setProperty('--vxe-ui-table-row-hover-background-color', tableCurrent)
root.style.setProperty('--vxe-ui-table-row-hover-current-background-color', tableCurrent)
root.style.setProperty('--vxe-ui-table-row-hover-striped-background-color', tableCurrent)
} }
onMounted(updateTheme) onMounted(updateTheme)
watch( watch(

View File

@@ -46,6 +46,7 @@ export default class TableStore {
}, },
loading: true, loading: true,
exportLoading: false, exportLoading: false,
customColumnInHeader: false,
column: [], column: [],
loadCallback: null, loadCallback: null,
resetCallback: null, resetCallback: null,

View File

@@ -40,3 +40,27 @@ export function setWaveCache(key: string, value: unknown): void {
if (oldest !== undefined) cache.delete(oldest) if (oldest !== undefined) cache.delete(oldest)
} }
} }
export function removeWaveCache(key: string): void {
if (key) cache.delete(key)
}
/** 关闭波形页时清空全部缓存 */
export function clearWaveCache(): void {
cache.clear()
}
/** 移除当前事件相关的 shu/rms 缓存(一次值、二次值、开环等组合) */
export function removeWaveCacheByEvent(
wp: Record<string, any> | undefined,
boxoList: Record<string, any>
): void {
if (!wp) return
for (const type of ['shu', 'rms'] as const) {
for (const value of [1, 2]) {
for (const isOpen of [true, false]) {
removeWaveCache(buildWaveCacheKey(type, wp, value, isOpen, boxoList))
}
}
}
}

View File

@@ -1,9 +1,14 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<div class="custom-table-header"> <!-- <div class="custom-table-header">
<div class="title">待审核用户</div> <div class="title">待审核用户</div>
<el-button :icon="Check" type="primary" @click="addRole" class="ml10">审核通过</el-button> <el-button :icon="Check" type="primary" @click="addRole" class="ml10">审核通过</el-button>
</div> </div> -->
<TableHeader :showReset="false" showCustomColumn ref="tableHeaderRef">
<template #operation>
<el-button :icon="Check" type="primary" @click="addRole" class="ml10">审核通过</el-button>
</template>
</TableHeader>
<Table ref="tableRef" /> <Table ref="tableRef" />
</div> </div>
</template> </template>
@@ -14,7 +19,7 @@ import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue' import Table from '@/components/table/index.vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { checkUser } from '@/api/user-boot/user' import { checkUser } from '@/api/user-boot/user'
import TableHeader from '@/components/table/header/index.vue'
defineOptions({ defineOptions({
name: 'auth/audit' name: 'auth/audit'
}) })
@@ -24,6 +29,14 @@ const tableStore = new TableStore({
url: '/user-boot/user/checkUserList', url: '/user-boot/user/checkUserList',
column: [ column: [
{ width: '60', type: 'checkbox' }, { width: '60', type: 'checkbox' },
{
field: 'index',
title: '序号',
width: '80',
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '名称', field: 'name' }, { title: '名称', field: 'name' },
{ title: '登录名', field: 'loginName' }, { title: '登录名', field: 'loginName' },
{ title: '角色', field: 'roleName' }, { title: '角色', field: 'roleName' },
@@ -33,7 +46,8 @@ const tableStore = new TableStore({
{ title: '类型', field: 'casualUserName' }, { title: '类型', field: 'casualUserName' },
{ title: '状态', field: 'stateName' }, { title: '状态', field: 'stateName' },
{ {
title: '操作', fixed: 'right', title: '操作',
fixed: 'right',
width: '180', width: '180',
render: 'buttons', render: 'buttons',
buttons: [ buttons: [

View File

@@ -1,22 +1,36 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader> <TableHeader showCustomColumn>
<template v-slot:select> <template v-slot:select>
<el-form-item label="用户状态"> <el-form-item label="用户状态">
<el-select v-model.trim="tableStore.table.params.searchState" placeholder="选择用户状态"> <el-select v-model.trim="tableStore.table.params.searchState" placeholder="选择用户状态">
<el-option v-for="(item, index) in userState" :label="item.label" :key="index" <el-option
:value="item.value"></el-option> v-for="(item, index) in userState"
:label="item.label"
:key="index"
:value="item.value"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="用户类型:"> <el-form-item label="用户类型:">
<el-select v-model.trim="tableStore.table.params.casualUser" placeholder="选择用户类型"> <el-select v-model.trim="tableStore.table.params.casualUser" placeholder="选择用户类型">
<el-option v-for="(item, index) in casualUser" :label="item.label" :key="index" <el-option
:value="item.value"></el-option> v-for="(item, index) in casualUser"
:label="item.label"
:key="index"
:value="item.value"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="关键字筛选:"> <el-form-item label="关键字筛选:">
<el-input maxlength="32" show-word-limit style="width: 240px" <el-input
v-model.trim="tableStore.table.params.searchValue" clearable placeholder="仅根据用户名/登录名" /> maxlength="32"
show-word-limit
style="width: 240px"
v-model.trim="tableStore.table.params.searchValue"
clearable
placeholder="仅根据用户名/登录名"
/>
</el-form-item> </el-form-item>
</template> </template>
<template v-slot:operation> <template v-slot:operation>
@@ -48,6 +62,14 @@ const tableStore = new TableStore({
url: '/user-boot/user/list', url: '/user-boot/user/list',
method: 'POST', method: 'POST',
column: [ column: [
{
field: 'index',
title: '序号',
width: '80',
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '用户名称', field: 'name', minWidth: '130' }, { title: '用户名称', field: 'name', minWidth: '130' },
{ title: '登录名', field: 'loginName', minWidth: '130' }, { title: '登录名', field: 'loginName', minWidth: '130' },
{ title: '角色', field: 'roleName', minWidth: '130' }, { title: '角色', field: 'roleName', minWidth: '130' },
@@ -79,7 +101,8 @@ const tableStore = new TableStore({
} }
}, },
{ {
title: '操作', fixed: 'right', title: '操作',
fixed: 'right',
width: '180', width: '180',
render: 'buttons', render: 'buttons',

View File

@@ -1,26 +1,40 @@
<template> <template>
<TableHeader datePicker ref="refheader" showExport> <TableHeader datePicker ref="refheader" showCustomColumn showExport>
<template v-slot:select> <template v-slot:select>
<!-- <el-form-item label="数据来源"> <el-form-item label="设备选取">
<el-cascader <el-tree-select
v-model.trim="tableStore.table.params.cascader" v-model="tableStore.table.params.cascader"
filterable :data="deviceTree"
placeholder="请选择数据来源"
@change="sourceChange"
:options="deviceTreeOptions"
:show-all-levels="false"
:props="{ checkStrictly: true, value: 'id', label: 'name' }"
clearable clearable
></el-cascader> :props="treeProps"
</el-form-item> --> filterable
:filter-node-method="filterNode"
check-strictly
default-expand-all
placeholder="请选择需要筛选的数据"
@node-click="sourceChange"
@clear="onTreeClear"
style="width: 100%"
></el-tree-select>
</el-form-item>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit style="width: 240px" <el-input
v-model.trim="tableStore.table.params.searchValue" clearable placeholder="请输入设备名称/告警代码" /> maxlength="32"
show-word-limit
style="width: 240px"
v-model.trim="tableStore.table.params.searchValue"
clearable
placeholder="请输入告警代码"
/>
</el-form-item> </el-form-item>
<el-form-item label="级别"> <el-form-item label="级别">
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable> <el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
<el-option v-for="item in rankOptions" :key="item.value" :label="item.label" <el-option
:value="item.value"></el-option> v-for="item in rankOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</template> </template>
@@ -35,25 +49,13 @@ import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue' import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue' import TableHeader from '@/components/table/header/index.vue'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { createTreeFilterNode } from '@/components/tree/govern/treeFilterUtils'
const props = defineProps(['deviceTree']) const props = defineProps(['deviceTree'])
const treeProps = {
const refheader = ref() value: 'id',
const deviceTree = ref([]) label: 'name',
const tabsList = ref([ children: 'children'
{ }
label: '设备告警',
name: 3
},
{
label: '稳态越限告警',
name: 1
},
{
label: '暂态事件',
name: 0
}
])
const rankOptions = ref([ const rankOptions = ref([
{ {
value: '1', value: '1',
@@ -66,7 +68,7 @@ const rankOptions = ref([
{ {
value: '3', value: '3',
label: '3级' label: '3级'
}, }
// { // {
// value: '4', // value: '4',
// label: 'DEBUG' // label: 'DEBUG'
@@ -100,7 +102,11 @@ const tableStore = new TableStore({
}, },
{ title: '发生时刻', field: 'startTime', align: 'center', minWidth: 180, sortable: true }, { title: '发生时刻', field: 'startTime', align: 'center', minWidth: 180, sortable: true },
{ {
title: '监测点名称', field: 'lineName', minWidth: 150, align: 'center', formatter: (row: any) => { title: '监测点名称',
field: 'lineName',
minWidth: 150,
align: 'center',
formatter: (row: any) => {
return row.cellValue ? row.cellValue : '/' return row.cellValue ? row.cellValue : '/'
} }
}, },
@@ -109,7 +115,6 @@ const tableStore = new TableStore({
{ title: '工程名称', field: 'engineeringName', align: 'center', minWidth: 150 }, { title: '工程名称', field: 'engineeringName', align: 'center', minWidth: 150 },
// { title: '监测点名称', field: 'lineName', align: 'center', minWidth: 120 }, // { title: '监测点名称', field: 'lineName', align: 'center', minWidth: 120 },
{ {
title: '事件描述', title: '事件描述',
minWidth: 300, minWidth: 300,
@@ -169,7 +174,7 @@ const tableStore = new TableStore({
// } // }
// } // }
], ],
beforeSearchFun: () => { }, beforeSearchFun: () => {},
exportProcessingData: () => { exportProcessingData: () => {
tableStore.table.allData = tableStore.table.allData.filter(item => { tableStore.table.allData = tableStore.table.allData.filter(item => {
item.level = item.level =
@@ -196,52 +201,41 @@ provide('tableStore', tableStore)
// "type": "", // "type": "",
// "userId": "" // "userId": ""
tableStore.table.params.searchValue = '' tableStore.table.params.searchValue = ''
// tableStore.table.params.cascader = '' tableStore.table.params.engineeringid = ''
// tableStore.table.params.level = '' tableStore.table.params.projectId = ''
// tableStore.table.params.engineeringid = '' tableStore.table.params.deviceId = ''
// tableStore.table.params.projectId = '' tableStore.table.params.lineId = ''
// tableStore.table.params.deviceId = '' tableStore.table.params.cascader = ''
tableStore.table.params.type = 3 tableStore.table.params.type = 3
// tableStore.table.params.eventIds = [] tableStore.table.params.level = ''
// tableStore.table.params.status = ''
// tableStore.table.params.target = [] const filterNode = createTreeFilterNode()
// tableStore.table.params.userId = ''
// tableStore.table.params.deviceTypeId = '' const onTreeClear = () => {
// tableStore.table.params.deviceTypeName = ''
const deviceTreeOptions = ref<any>(props.deviceTree)
deviceTreeOptions.value.map((item: any, index: any) => {
if (item?.children.length == 0) {
deviceTreeOptions.value.splice(index, 1)
}
})
const sourceChange = (e: any) => {
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.engineeringid = '' tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = '' tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = '' tableStore.table.params.deviceId = ''
if (e) { tableStore.table.params.lineId = ''
let name = deviceTreeOptions.value.filter((item: any) => {
return item.id == e[0]
})[0].name
tableStore.table.params.deviceTypeName = name
if (name == '便携式设备') {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.deviceId = e[1] || ''
} else {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.engineeringid = e[1] || ''
tableStore.table.params.projectId = e[2] || ''
tableStore.table.params.deviceId = e[3] || ''
}
}
} }
const sourceChange = (e: any) => {
onTreeClear()
if (e.level == 0) {
tableStore.table.params.engineeringid = e.id
} else if (e.level == 1) {
tableStore.table.params.projectId = e.id
} else if (e.level == 2) {
tableStore.table.params.deviceId = e.id
} else if (e.level == 3) {
tableStore.table.params.lineId = e.id
}
}
onMounted(() => { onMounted(() => {
tableStore.index() tableStore.index()
}) })
setTimeout(() => { setTimeout(() => {
// tableStore.table.height = mainHeight(200).height as any // tableStore.table.height = mainHeight(200).height as any
}, 0) }, 0)
const addMenu = () => { } const addMenu = () => {}
</script> </script>
<style></style> <style></style>

View File

@@ -1,5 +1,5 @@
<template> <template>
<TableHeader datePicker ref="refheader" showExport> <TableHeader datePicker ref="refheader" showCustomColumn showExport>
<template v-slot:select> <template v-slot:select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit <el-input maxlength="32" show-word-limit
@@ -76,10 +76,10 @@ const tableStore = new TableStore({
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1 return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
} }
}, },
{ title: '发生时刻', field: 'startTime', align: 'center', width: 180, sortable: true }, { title: '发生时刻', field: 'startTime', align: 'center', minWidth: 180, sortable: true },
{ title: '服务器名称', field: 'lineId', align: 'center', width: 150 }, { title: '服务器名称', field: 'lineId', align: 'center', minWidth: 150 },
{ title: 'IP', field: 'wavePath', align: 'center', width: 150 }, { title: 'IP', field: 'wavePath', align: 'center', minWidth: 150 },
{ title: '进程号', field: 'clDid', align: 'center', width: 70 }, { title: '进程号', field: 'clDid', align: 'center', minWidth: 70 },
{ {
title: '事件描述', title: '事件描述',

View File

@@ -1,15 +1,32 @@
<template> <template>
<TableHeader datePicker ref="refheader" showExport> <TableHeader datePicker ref="refheader" showCustomColumn showExport>
<template v-slot:select> <template v-slot:select>
<!-- <el-form-item label="数据来源"> <el-form-item label="设备选取">
<el-cascader v-model.trim="tableStore.table.params.cascader" filterable placeholder="请选择数据来源" <el-tree-select
@change="sourceChange" :options="deviceTreeOptions" :show-all-levels="false" v-model="tableStore.table.params.cascader"
:props="{ checkStrictly: true, value: 'id', label: 'name' }" clearable></el-cascader> :data="deviceTree"
</el-form-item> --> clearable
<el-form-item label="关键字筛选"> :props="treeProps"
<el-input maxlength="32" show-word-limit style="width: 240px" filterable
v-model.trim="tableStore.table.params.searchValue" clearable placeholder="请输入监测点名称" /> :filter-node-method="filterNode"
check-strictly
default-expand-all
placeholder="请选择需要筛选的数据"
@node-click="sourceChange"
@clear="onTreeClear"
style="width: 100%"
></el-tree-select>
</el-form-item> </el-form-item>
<!-- <el-form-item label="关键字筛选">
<el-input
maxlength="32"
show-word-limit
style="width: 240px"
v-model.trim="tableStore.table.params.searchValue"
clearable
placeholder="请输入监测点名称"
/>
</el-form-item> -->
<!-- <el-form-item label="级别"> <!-- <el-form-item label="级别">
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable> <el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
<el-option <el-option
@@ -32,39 +49,14 @@ import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue' import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue' import TableHeader from '@/components/table/header/index.vue'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { createTreeFilterNode } from '@/components/tree/govern/treeFilterUtils'
const props = defineProps(['deviceTree']) const props = defineProps(['deviceTree'])
const refheader = ref() const treeProps = {
const deviceTree = ref([]) value: 'id',
const tabsList = ref([ label: 'name',
{ children: 'children'
label: '设备告警', }
name: 3
},
{
label: '稳态越限告警',
name: 1
},
{
label: '暂态事件',
name: 0
}
])
const rankOptions = ref([
{
value: '1',
label: '1级'
},
{
value: '2',
label: '2级'
},
{
value: '3',
label: '3级'
}
])
const tableStore = new TableStore({ const tableStore = new TableStore({
url: '/cs-harmonic-boot/eventUser/queryEventpageWeb', url: '/cs-harmonic-boot/eventUser/queryEventpageWeb',
@@ -79,18 +71,23 @@ const tableStore = new TableStore({
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1 return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
} }
}, },
{ title: '发生时刻', field: 'startTime', align: 'center', sortable: true, minWidth: 180, }, { title: '发生时刻', field: 'startTime', align: 'center', sortable: true, minWidth: 180 },
{ title: '监测点名称', field: 'lineName', align: 'center', minWidth: 150,formatter: (row: any) => { {
title: '监测点名称',
field: 'lineName',
align: 'center',
minWidth: 150,
formatter: (row: any) => {
return row.cellValue ? row.cellValue : '/' return row.cellValue ? row.cellValue : '/'
} }, }
{ title: '设备名称', field: 'equipmentName', align: 'center', minWidth: 150, }, },
{ title: '项目名称', field: 'projectName', align: 'center', minWidth: 150, }, { title: '设备名称', field: 'equipmentName', align: 'center', minWidth: 150 },
{ title: '工程名称', field: 'engineeringName', align: 'center', minWidth: 150, }, { title: '项目名称', field: 'projectName', align: 'center', minWidth: 150 },
{ title: '工程名称', field: 'engineeringName', align: 'center', minWidth: 150 },
{ title: '事件描述', field: 'showName', align: 'center', minWidth: 250 }
{ title: '事件描述', field: 'showName', align: 'center', minWidth: 250, }
], ],
beforeSearchFun: () => { } beforeSearchFun: () => {}
}) })
provide('tableStore', tableStore) provide('tableStore', tableStore)
@@ -98,44 +95,32 @@ provide('tableStore', tableStore)
// "type": "", // "type": "",
// "userId": "" // "userId": ""
tableStore.table.params.searchValue = '' tableStore.table.params.searchValue = ''
// tableStore.table.params.engineeringid = '' tableStore.table.params.engineeringid = ''
// tableStore.table.params.deviceTypeId = '' tableStore.table.params.projectId = ''
// tableStore.table.params.projectId = '' tableStore.table.params.deviceId = ''
// tableStore.table.params.deviceId = '' tableStore.table.params.lineId = ''
tableStore.table.params.cascader = ''
tableStore.table.params.type = 1 tableStore.table.params.type = 1
// tableStore.table.params.eventIds = []
// tableStore.table.params.status = ''
// tableStore.table.params.target = []
// tableStore.table.params.userId = ''
// tableStore.table.params.cascader = ''
// tableStore.table.params.deviceTypeName = ''
// tableStore.table.params.level=''
const deviceTreeOptions = ref<any>(props.deviceTree) const filterNode = createTreeFilterNode()
deviceTreeOptions.value.map((item: any, index: any) => {
if (item?.children.length == 0) { const onTreeClear = () => {
deviceTreeOptions.value.splice(index, 1)
}
})
const sourceChange = (e: any) => {
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.engineeringid = '' tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = '' tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = '' tableStore.table.params.deviceId = ''
if (e) { tableStore.table.params.lineId = ''
let name = deviceTreeOptions.value.filter((item: any) => { }
return item.id == e[0]
})[0].name const sourceChange = (e: any) => {
tableStore.table.params.deviceTypeName = name onTreeClear()
if (name == '便携式设备') { if (e.level == 0) {
tableStore.table.params.deviceTypeId = e[0] || '' tableStore.table.params.engineeringid = e.id
tableStore.table.params.deviceId = e[1] || '' } else if (e.level == 1) {
} else { tableStore.table.params.projectId = e.id
tableStore.table.params.deviceTypeId = e[0] || '' } else if (e.level == 2) {
tableStore.table.params.engineeringid = e[1] || '' tableStore.table.params.deviceId = e.id
tableStore.table.params.projectId = e[2] || '' } else if (e.level == 3) {
tableStore.table.params.deviceId = e[3] || '' tableStore.table.params.lineId = e.id
}
} }
} }
onMounted(() => { onMounted(() => {
@@ -144,6 +129,6 @@ onMounted(() => {
setTimeout(() => { setTimeout(() => {
tableStore.table.height = mainHeight(200).height as any tableStore.table.height = mainHeight(200).height as any
}, 0) }, 0)
const addMenu = () => { } const addMenu = () => {}
</script> </script>
<style></style> <style></style>

View File

@@ -1,17 +1,33 @@
<template> <template>
<div ref="refheader" v-show="!isWaveCharts" style="width: 100%"> <div ref="refheader" v-show="!isWaveCharts" style="width: 100%">
<TableHeader datePicker showExport @onResetForm="onResetForm"> <TableHeader datePicker showExport showCustomColumn @onResetForm="onResetForm">
<template v-slot:select> <template v-slot:select>
<!-- <el-form-item label="数据来源"> <el-form-item label="设备选取">
<el-cascader placeholder="请选择数据来源" @change="sourceChange" filterable <el-tree-select
v-model.trim="tableStore.table.params.cascader" :options="deviceTreeOptions" v-model="tableStore.table.params.cascader"
:show-all-levels="false" :props="{ checkStrictly: true, value: 'id', label: 'name' }" :data="deviceTree"
clearable></el-cascader> clearable
</el-form-item> --> :props="treeProps"
<el-form-item label="关键字筛选"> filterable
<el-input maxlength="32" show-word-limit style="width: 240px" :filter-node-method="filterNode"
v-model.trim="tableStore.table.params.searchValue" clearable placeholder="请输入监测点名称" /> check-strictly
default-expand-all
placeholder="请选择需要筛选的数据"
@node-click="sourceChange"
@clear="onTreeClear"
style="width: 100%"
></el-tree-select>
</el-form-item> </el-form-item>
<!-- <el-form-item label="关键字筛选">
<el-input
maxlength="32"
show-word-limit
style="width: 240px"
v-model.trim="tableStore.table.params.searchValue"
clearable
placeholder="请输入监测点名称"
/>
</el-form-item> -->
<!-- <el-form-item> <!-- <el-form-item>
<el-button type="primary" plain @click="openFilterDialog">事件筛选</el-button> <el-button type="primary" plain @click="openFilterDialog">事件筛选</el-button>
</el-form-item> --> </el-form-item> -->
@@ -22,16 +38,24 @@
</template> </template>
</TableHeader> </TableHeader>
<MultiCondition v-model:visible="filterVisible" :params="tableStore.table.params" ref="multiConditionRef" <MultiCondition
@confirm="onFilterConfirm" /> v-model:visible="filterVisible"
:params="tableStore.table.params"
ref="multiConditionRef"
@confirm="onFilterConfirm"
/>
<Table></Table> <Table></Table>
<!-- 补召日志 --> <!-- 补召日志 -->
<analysisList ref="analysisListRef"></analysisList> <analysisList ref="analysisListRef"></analysisList>
</div> </div>
<waveFormAnalysis v-loading="loading" v-if="isWaveCharts" ref="waveFormAnalysisRef" <waveFormAnalysis
@handleHideCharts="isWaveCharts = false" :wp="wp" /> v-loading="loading"
v-if="isWaveCharts"
ref="waveFormAnalysisRef"
@handleHideCharts="isWaveCharts = false"
:wp="wp"
/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, provide, nextTick } from 'vue' import { ref, onMounted, provide, nextTick } from 'vue'
@@ -48,6 +72,7 @@ import { buildWaveExportFileName, getExportSubjectFromRow } from '@/utils/echart
import { useDictData } from '@/stores/dictData' import { useDictData } from '@/stores/dictData'
import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree' import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree'
import analysisList from '@/views/govern/device/control/analysisList/index.vue' import analysisList from '@/views/govern/device/control/analysisList/index.vue'
import { createTreeFilterNode } from '@/components/tree/govern/treeFilterUtils'
const props = defineProps(['deviceTree']) const props = defineProps(['deviceTree'])
const emit = defineEmits(['statistics']) const emit = defineEmits(['statistics'])
@@ -65,7 +90,11 @@ const EventTypeList: any = dictData.getBasicData('Event_Type')
const filterVisible = ref(false) const filterVisible = ref(false)
const multiConditionRef = ref<InstanceType<typeof MultiCondition>>() const multiConditionRef = ref<InstanceType<typeof MultiCondition>>()
const treeProps = {
value: 'id',
label: 'name',
children: 'children'
}
const tableStore = new TableStore({ const tableStore = new TableStore({
url: '/cs-harmonic-boot/eventUser/queryEventpageWeb', url: '/cs-harmonic-boot/eventUser/queryEventpageWeb',
method: 'POST', method: 'POST',
@@ -81,34 +110,50 @@ const tableStore = new TableStore({
}, },
{ title: '发生时刻', field: 'startTime', align: 'center', minWidth: 180, sortable: true }, { title: '发生时刻', field: 'startTime', align: 'center', minWidth: 180, sortable: true },
{ title: '暂降幅值(%)', minWidth: 120, field: 'evtParamVVaDepth', align: 'center', sortable: true },
{ title: '暂降幅值(%)', minWidth: 120, field: 'evtParamVVaDepth', align: 'center', sortable: true, },
{ title: '持续时间(s)', field: 'evtParamTm', minWidth: 110, align: 'center', sortable: true }, { title: '持续时间(s)', field: 'evtParamTm', minWidth: 110, align: 'center', sortable: true },
{ {
title: '严重度', field: 'severity', minWidth: 80, align: 'center', sortable: true, formatter: (row: any) => { title: '严重度',
field: 'severity',
minWidth: 80,
align: 'center',
sortable: true,
formatter: (row: any) => {
return row.cellValue ? row.cellValue : '/' return row.cellValue ? row.cellValue : '/'
} }
}, },
{ title: '相别', field: 'evtParamPhase', minWidth: 80, align: 'center' }, { title: '相别', field: 'evtParamPhase', minWidth: 80, align: 'center' },
{ title: '触发类型', field: 'showName', minWidth: 100, align: 'center' }, { title: '触发类型', field: 'showName', minWidth: 100, align: 'center' },
{ {
title: '暂降原因', field: 'advanceReason', minWidth: 100, align: 'center', formatter: (row: any) => { title: '暂降原因',
field: 'advanceReason',
minWidth: 100,
align: 'center',
formatter: (row: any) => {
return ReasonList.find((item: any) => item.id == row.cellValue)?.name || '其他' return ReasonList.find((item: any) => item.id == row.cellValue)?.name || '其他'
} }
}, },
{ {
title: '暂降类型', field: 'advanceType', minWidth: 100, align: 'center', formatter: (row: any) => { title: '暂降类型',
field: 'advanceType',
minWidth: 100,
align: 'center',
formatter: (row: any) => {
return EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '其他' return EventTypeList.find((item: any) => item.id == row.cellValue)?.name || '其他'
} }
}, },
{ title: '监测点名称', field: 'lineName', minWidth: 150, align: 'center' }, { title: '监测点名称', field: 'lineName', minWidth: 150, align: 'center' },
{ title: '电压等级(kV)', field: 'lineVoltage', minWidth: 120, align: 'center', sortable: true, }, { title: '电压等级(kV)', field: 'lineVoltage', minWidth: 120, align: 'center', sortable: true },
{ title: '设备名称', field: 'equipmentName', minWidth: 150, align: 'center' }, { title: '设备名称', field: 'equipmentName', minWidth: 150, align: 'center' },
{ title: '项目名称', field: 'projectName', minWidth: 150, align: 'center' }, { title: '项目名称', field: 'projectName', minWidth: 150, align: 'center' },
{ title: '工程名称', field: 'engineeringName', minWidth: 150, align: 'center' }, { title: '工程名称', field: 'engineeringName', minWidth: 150, align: 'center' },
{ {
title: '发生位置', field: 'sagSource', minWidth: 120, align: 'center', formatter: (row: any) => { title: '发生位置',
field: 'sagSource',
minWidth: 120,
align: 'center',
formatter: (row: any) => {
return row.cellValue == 1 ? '上游' : row.cellValue == 2 ? '下游' : '暂无' return row.cellValue == 1 ? '上游' : row.cellValue == 2 ? '下游' : '暂无'
} }
}, },
@@ -145,7 +190,7 @@ const tableStore = new TableStore({
persistTime: row.evtParamTm, persistTime: row.evtParamTm,
featureAmplitude: featureAmplitude:
row.evtParamVVaDepth != '-' ? (row.evtParamVVaDepth - 0) / 100 : null, row.evtParamVVaDepth != '-' ? (row.evtParamVVaDepth - 0) / 100 : null,
systemType: 'YPT', systemType: 'YPT'
} }
wp.value = res.data wp.value = res.data
} }
@@ -161,7 +206,6 @@ const tableStore = new TableStore({
waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true) waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
// waveFormAnalysisRef.value && waveFormAnalysisRef.value.setHeight(200, 190) // waveFormAnalysisRef.value && waveFormAnalysisRef.value.setHeight(200, 190)
}) })
} }
}, },
{ {
@@ -177,7 +221,8 @@ const tableStore = new TableStore({
click: row => { click: row => {
row.loading2 = true row.loading2 = true
ElMessage.info('下载中......') ElMessage.info('下载中......')
getFileZip({ eventId: row.id }).then(res => { getFileZip({ eventId: row.id })
.then(res => {
let blob = new Blob([res], { type: 'application/zip' }) // console.log(blob) // var href = window.URL.createObjectURL(blob); //创建下载的链接 let blob = new Blob([res], { type: 'application/zip' }) // console.log(blob) // var href = window.URL.createObjectURL(blob); //创建下载的链接
const url = window.URL.createObjectURL(blob) const url = window.URL.createObjectURL(blob)
const link = document.createElement('a') // 创建a标签 const link = document.createElement('a') // 创建a标签
@@ -188,7 +233,8 @@ const tableStore = new TableStore({
document.body.removeChild(link) //释放标签 document.body.removeChild(link) //释放标签
ElMessage.success('波形下载成功') ElMessage.success('波形下载成功')
row.loading2 = false row.loading2 = false
}).catch(() => { })
.catch(() => {
row.loading2 = false row.loading2 = false
}) })
} }
@@ -202,8 +248,7 @@ const tableStore = new TableStore({
disabled: row => { disabled: row => {
let code = DeviceType.value.filter((item: any) => item.id == row.devType)[0]?.code let code = DeviceType.value.filter((item: any) => item.id == row.devType)[0]?.code
return !((code == 'Direct_Connected_Device' || code == 'Gateway') && row.wavePath == null) return !((code == 'Direct_Connected_Device' || code == 'Gateway') && row.wavePath == null)
}, }
}, },
{ {
name: 'edit', name: 'edit',
@@ -227,22 +272,21 @@ const tableStore = new TableStore({
deviceData: row, deviceData: row,
deviceId: row.deviceId deviceId: row.deviceId
}) })
} else if (code == 'DEV_CLD') { } else if (code == 'DEV_CLD') {
row.loading2 = true row.loading2 = true
// 监测设备 // 监测设备
getFileByEventId(row.id).then(res => { getFileByEventId(row.id)
.then(res => {
ElMessage.success(res.message) ElMessage.success(res.message)
tableStore.index() tableStore.index()
row.loading2 = false row.loading2 = false
}).catch(() => { })
.catch(() => {
row.loading2 = false row.loading2 = false
}) })
} }
} }
}, }
] ]
} }
], ],
@@ -267,17 +311,14 @@ provide('tableStore', tableStore)
// "type": "", // "type": "",
// "userId": "" // "userId": ""
tableStore.table.params.searchValue = '' tableStore.table.params.searchValue = ''
// tableStore.table.params.engineeringid = '' tableStore.table.params.engineeringid = ''
// tableStore.table.params.projectId = '' tableStore.table.params.projectId = ''
// tableStore.table.params.deviceTypeId = '' tableStore.table.params.deviceId = ''
// tableStore.table.params.deviceId = '' tableStore.table.params.lineId = ''
tableStore.table.params.cascader = ''
tableStore.table.params.type = 0 tableStore.table.params.type = 0
// tableStore.table.params.eventIds = []
// tableStore.table.params.status = ''
// tableStore.table.params.target = []
// tableStore.table.params.userId = ''
// tableStore.table.params.cascader = ''
// tableStore.table.params.deviceTypeName = ''
Object.assign(tableStore.table.params, { Object.assign(tableStore.table.params, {
featureAmplitudeMin: undefined, featureAmplitudeMin: undefined,
featureAmplitudeMax: undefined, featureAmplitudeMax: undefined,
@@ -292,55 +333,27 @@ Object.assign(tableStore.table.params, {
const openFilterDialog = () => { const openFilterDialog = () => {
filterVisible.value = true filterVisible.value = true
} }
const onTreeClear = () => {
const deviceTreeOptions: any = ref<any>(props.deviceTree)
deviceTreeOptions.value.map((item: any, index: any) => {
if (item?.children.length == 0) {
deviceTreeOptions.value.splice(index, 1)
}
})
const sourceChange = (e: any) => {
tableStore.table.params.deviceTypeId = ''
tableStore.table.params.engineeringid = '' tableStore.table.params.engineeringid = ''
tableStore.table.params.projectId = '' tableStore.table.params.projectId = ''
tableStore.table.params.deviceId = '' tableStore.table.params.deviceId = ''
if (e) { tableStore.table.params.lineId = ''
let name = deviceTreeOptions.value.filter((item: any) => {
return item.id == e[0]
})[0].name
tableStore.table.params.deviceTypeName = name
if (name == '便携式设备') {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.deviceId = e[1] || ''
} else {
tableStore.table.params.deviceTypeId = e[0] || ''
tableStore.table.params.engineeringid = e[1] || ''
tableStore.table.params.projectId = e[2] || ''
tableStore.table.params.deviceId = e[3] || ''
}
}
// tableStore.table.params.engineeringid = e[1] || ''
// tableStore.table.params.projectId = e[2] || ''
// const zlIndex = deviceTreeOptions.value.findIndex((item: any) => {
// return item.name == '治理设备'
// })
// const bxsIndex = deviceTreeOptions.value.findIndex((item: any) => {
// return item.name == '便携式设备'
// })
// console.log("🚀 ~ zlIndex ~ zlIndex:", zlIndex,bxsIndex)
// //便携式设备特殊处理
// if (bxsIndex != -1 && deviceTreeOptions.value[bxsIndex].id == e[0] && e.length == 2) {
// tableStore.table.params.deviceId = e[1]
// }
// //治理设备
// if (zlIndex != -1 && deviceTreeOptions.value[zlIndex].id == e[0]) {
// tableStore.table.params.deviceId = e[2] || ''
// }
} }
const sourceChange = (e: any) => {
onTreeClear()
if (e.level == 0) {
tableStore.table.params.engineeringid = e.id
} else if (e.level == 1) {
tableStore.table.params.projectId = e.id
} else if (e.level == 2) {
tableStore.table.params.deviceId = e.id
} else if (e.level == 3) {
tableStore.table.params.lineId = e.id
}
}
const filterNode = createTreeFilterNode()
const onFilterConfirm = () => { const onFilterConfirm = () => {
tableStore.onTableAction('search', {}) tableStore.onTableAction('search', {})
} }
@@ -374,6 +387,6 @@ setTimeout(() => {
tableStore.table.height = mainHeight(200).height as any tableStore.table.height = mainHeight(200).height as any
}, 0) }, 0)
const addMenu = () => { } const addMenu = () => {}
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader select :showReset="false" ref="TableHeaderRef"> <TableHeader select :showReset="false" showCustomColumn ref="TableHeaderRef">
<template #operation> <template #operation>
<el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button> <el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button>
</template> </template>

View File

@@ -38,6 +38,7 @@ import TableHeader from '@/components/table/header/index.vue'
import { defaultAttribute } from '@/components/table/defaultAttribute' import { defaultAttribute } from '@/components/table/defaultAttribute'
import { getTime } from '@/utils/formatTime' import { getTime } from '@/utils/formatTime'
import { useDictData } from '@/stores/dictData' import { useDictData } from '@/stores/dictData'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { color1 } from '@/components/echarts/color' import { color1 } from '@/components/echarts/color'
const dictData = useDictData() const dictData = useDictData()

View File

@@ -5,7 +5,6 @@
<Transient <Transient
v-if="!showEventStatistics" v-if="!showEventStatistics"
:deviceTree="deviceTree" :deviceTree="deviceTree"
:key="key"
@statistics="showEventStatistics = true" @statistics="showEventStatistics = true"
/> />
<eventStatistics v-else @back="showEventStatistics = false" /> <eventStatistics v-else @back="showEventStatistics = false" />
@@ -14,17 +13,14 @@
</el-tab-pane> --> </el-tab-pane> -->
<el-tab-pane label="稳态越限告警" name="3"> <el-tab-pane label="稳态越限告警" name="3">
<Steady v-if="activeName == '3'" :deviceTree="deviceTree" :key="key" /> <Steady :deviceTree="deviceTree" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="设备告警" name="1"> <el-tab-pane label="设备告警" name="1">
<Device v-if="activeName == '1'" :deviceTree="deviceTree" :key="key" /> <Device :deviceTree="deviceTree" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="前置告警" name="2"> <el-tab-pane label="前置告警" name="2">
<Front v-if="activeName == '2'" :deviceTree="deviceTree" :key="key" /> <Front />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
@@ -35,7 +31,7 @@ import Transient from './Transient.vue'
import Device from './Device.vue' import Device from './Device.vue'
import Front from './Front.vue' import Front from './Front.vue'
import eventStatistics from './eventStatistics.vue' import eventStatistics from './eventStatistics.vue'
import { getDeviceTree } from '@/api/cs-device-boot/csLedger' import { getLineTree } from '@/api/cs-device-boot/csLedger'
defineOptions({ defineOptions({
name: 'govern/alarm/index' name: 'govern/alarm/index'
}) })
@@ -50,26 +46,13 @@ watch(activeName, val => {
showEventStatistics.value = false showEventStatistics.value = false
} }
}) })
// getDeviceTree().then(res => { getLineTree({ type: 'engineering' }).then(res => {
// res.data.forEach((item: any) => { deviceTree.value = res.data
// item.value = item.id
// item.label = item.name
// item.children.forEach((child: any) => {
// child.value = child.id
// child.label = child.name
// child.children.forEach((grand: any) => {
// grand.value = grand.id
// grand.label = grand.name
// delete grand.children
// })
// })
// })
// deviceTree.value = res.data
// key.value += 1
// activeName.value = '4'
// })
onMounted(() => { })
const addMenu = () => { } activeName.value = '4'
})
onMounted(() => {})
const addMenu = () => {}
</script> </script>
<style></style> <style></style>

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader ref="TableHeaderRef"> <TableHeader showCustomColumn ref="TableHeaderRef">
<template #select> <template #select>
<el-form-item label="数据来源"> <el-form-item label="数据来源">
<el-select v-model="tableStore.table.params.dataSource" clearable placeholder="请选择数据来源"> <el-select v-model="tableStore.table.params.dataSource" clearable placeholder="请选择数据来源">
@@ -69,41 +69,41 @@ const tableStore: any = new TableStore({
{ field: 'influxdbTableName', title: '表名', minWidth: 150 }, { field: 'influxdbTableName', title: '表名', minWidth: 150 },
{ field: 'influxdbColumnName', title: '列属性', minWidth: 150 }, { field: 'influxdbColumnName', title: '列属性', minWidth: 150 },
{ {
field: 'harmStart', title: '谐波次数', width: 90, field: 'harmStart', title: '谐波次数', minWidth: 90,
formatter: (row: any) => { formatter: (row: any) => {
return row.cellValue == null ? '/' : row.cellValue + '-' + row.row.harmEnd return row.cellValue == null ? '/' : row.cellValue + '-' + row.row.harmEnd
} }
}, },
{ {
field: 'phaseType', title: '相别', width: 100, formatter: (row: any) => { field: 'phaseType', title: '相别', minWidth: 100, formatter: (row: any) => {
return row.cellValue == 'T' ? '/' : row.cellValue return row.cellValue == 'T' ? '/' : row.cellValue
} }
}, },
{ {
field: 'unit', title: '单位', width: 80, field: 'unit', title: '单位', minWidth: 80,
formatter: (row: any) => { formatter: (row: any) => {
return row.cellValue || '/' return row.cellValue || '/'
} }
}, },
{ field: 'minValue', title: '指标下限', width: 100 }, { field: 'minValue', title: '指标下限', minWidth: 100 },
{ field: 'maxValue', title: '指标上限', width: 100 }, { field: 'maxValue', title: '指标上限', minWidth: 100 },
{ {
field: 'isVoltage', field: 'isVoltage',
title: '电压等级参与', title: '电压等级参与',
width: 110, minWidth: 110,
formatter: (row: any) => yesNo(row.cellValue) formatter: (row: any) => yesNo(row.cellValue)
}, },
{ {
field: 'ctAttendFlag', field: 'ctAttendFlag',
title: 'CT变比参与', title: 'CT变比参与',
width: 100, minWidth: 100,
formatter: (row: any) => yesNo(row.cellValue) formatter: (row: any) => yesNo(row.cellValue)
}, },
{ field: 'dataSource', title: '数据来源', width: 100 }, { field: 'dataSource', title: '数据来源', minWidth: 100 },
{ field: 'belongingSystem', title: '所属系统', width: 100 }, { field: 'belongingSystem', title: '所属系统', minWidth: 100 },
@@ -119,7 +119,7 @@ const tableStore: any = new TableStore({
formatter: (row: any) => { formatter: (row: any) => {
return row.cellValue || '/' return row.cellValue || '/'
} }
}, { field: 'sort', title: '排序', width: 70 }, }, { field: 'sort', title: '排序', minWidth: 70 },
{ {
title: '操作', title: '操作',

View File

@@ -5,7 +5,7 @@
<APFTree @node-click="nodeClick" :height="60" :type="'dvr'" @init="nodeClick" <APFTree @node-click="nodeClick" :height="60" :type="'dvr'" @init="nodeClick"
@deviceTypeChange="deviceTypeChange"></APFTree> @deviceTypeChange="deviceTypeChange"></APFTree>
<div class="analyze-dvr-right" v-if="tableStore.table.params.deviceId"> <div class="analyze-dvr-right" v-if="tableStore.table.params.deviceId">
<TableHeader datePicker showExport @onResetForm="onResetForm"> <TableHeader datePicker showExport showCustomColumn @onResetForm="onResetForm">
<template v-slot:select> <template v-slot:select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit style="width: 240px" <el-input maxlength="32" show-word-limit style="width: 240px"

View File

@@ -2,7 +2,7 @@
<template> <template>
<el-dialog modal-class="analysisList" v-model.trim="dialogVisible" title="补召日志" width="70%" draggable <el-dialog modal-class="analysisList" v-model.trim="dialogVisible" title="补召日志" width="70%" draggable
@closed="close"> @closed="close">
<TableHeader date-picker :showReset="false"> <TableHeader date-picker showCustomColumn :showReset="false">
<template #operation> <template #operation>
<el-button type="primary" icon="el-icon-Connection" @click="handleImport"> <el-button type="primary" icon="el-icon-Connection" @click="handleImport">
离线补召 离线补召
@@ -63,7 +63,7 @@ const tableStore: any = new TableStore({
{ {
title: '解析状态', title: '解析状态',
field: 'status', field: 'status',
width: 100, minWidth: 100,
render: 'tag', render: 'tag',
custom: { custom: {
0: 'warning', 0: 'warning',

View File

@@ -99,7 +99,6 @@ const echartList: any = ref({})
const dataType = ref([0]) const dataType = ref([0])
const key = ref(0) const key = ref(0)
import * as echarts from 'echarts' // 全引入 import * as echarts from 'echarts' // 全引入
import { max } from 'lodash'
const echartsData: any = ref({ const echartsData: any = ref({
title: { title: {
show: false show: false
@@ -161,7 +160,7 @@ const echartsData: any = ref({
}, },
grid: { grid: {
top: '80px', top: '80px',
right: '50px', right: '50px'
}, },
yAxis: [{}], yAxis: [{}],
@@ -190,7 +189,7 @@ const setData = (data: any) => {
fontSize: 16 fontSize: 16
} }
}, },
formatter: function (params) { formatter: function (params: any) {
// console.log("🚀 ~ data.forEach ~ params:", params) // console.log("🚀 ~ data.forEach ~ params:", params)
let tip = '' let tip = ''
for (let i = 0; i < params.length; i++) { for (let i = 0; i < params.length; i++) {
@@ -372,15 +371,19 @@ const changeDataType = () => {
echartsData.value.yAxis = [{}] echartsData.value.yAxis = [{}]
echartsData.value.options.series = [] echartsData.value.options.series = []
const currentTab = list.value[activeTab.value] || {}
const loadList = currentTab.loadList || []
const modOutList = currentTab.modOutList || []
const temperatureList = currentTab.temperatureList || []
let flag = dataType.value.includes(0) || dataType.value.includes(1) let flag = dataType.value.includes(0) || dataType.value.includes(1)
if (flag) { if (flag) {
let data1 = dataType.value.includes(0) let data1 = dataType.value.includes(0)
? list.value[activeTab.value]?.loadList.map(k => (k.data == 3.14159 ? 0 : k.data)) ? loadList.map((k: any) => (k.data == 3.14159 ? null : k.data))
: [0] : []
let data2 = dataType.value.includes(1) let data2 = dataType.value.includes(1)
? list.value[activeTab.value]?.modOutList.map(k => (k.data == 3.14159 ? 0 : k.data)) ? modOutList.map((k: any) => (k.data == 3.14159 ? null : k.data))
: [0] : []
let [modOuMin, modOuMax] = yMethod([...data1||[0], ...data2||[0]]) let [modOuMin, modOuMax] = yMethod([...data1, ...data2])
echartsData.value.yAxis[0] = { echartsData.value.yAxis[0] = {
name: 'A', name: 'A',
@@ -395,7 +398,7 @@ const changeDataType = () => {
{ {
name: 'A相负载电流', name: 'A相负载电流',
type: 'line', type: 'line',
data: list.value[activeTab.value]?.loadList data: loadList
.filter((k: any) => k.phasicType == 'A') .filter((k: any) => k.phasicType == 'A')
.map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[0].type]), .map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[0].type]),
smooth: true, //让线变得平滑 smooth: true, //让线变得平滑
@@ -407,7 +410,7 @@ const changeDataType = () => {
{ {
name: 'B相负载电流', name: 'B相负载电流',
type: 'line', type: 'line',
data: list.value[activeTab.value]?.loadList data: loadList
.filter((k: any) => k.phasicType == 'B') .filter((k: any) => k.phasicType == 'B')
.map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[0].type]), .map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[0].type]),
smooth: true, //让线变得平滑 smooth: true, //让线变得平滑
@@ -419,7 +422,7 @@ const changeDataType = () => {
{ {
name: 'C相负载电流', name: 'C相负载电流',
type: 'line', type: 'line',
data: list.value[activeTab.value]?.loadList data: loadList
.filter((k: any) => k.phasicType == 'C') .filter((k: any) => k.phasicType == 'C')
.map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[0].type]), .map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[0].type]),
smooth: true, //让线变得平滑 smooth: true, //让线变得平滑
@@ -435,7 +438,7 @@ const changeDataType = () => {
{ {
name: 'A相输入电流', name: 'A相输入电流',
type: 'line', type: 'line',
data: list.value[activeTab.value].modOutList data: modOutList
.filter((k: any) => k.phasicType == 'A') .filter((k: any) => k.phasicType == 'A')
.map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[1].type]), .map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[1].type]),
smooth: true, //让线变得平滑 smooth: true, //让线变得平滑
@@ -447,7 +450,7 @@ const changeDataType = () => {
{ {
name: 'B相输入电流', name: 'B相输入电流',
type: 'line', type: 'line',
data: list.value[activeTab.value].modOutList data: modOutList
.filter((k: any) => k.phasicType == 'B') .filter((k: any) => k.phasicType == 'B')
.map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[1].type]), .map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[1].type]),
smooth: true, //让线变得平滑 smooth: true, //让线变得平滑
@@ -459,7 +462,7 @@ const changeDataType = () => {
{ {
name: 'C相输入电流', name: 'C相输入电流',
type: 'line', type: 'line',
data: list.value[activeTab.value].modOutList data: modOutList
.filter((k: any) => k.phasicType == 'C') .filter((k: any) => k.phasicType == 'C')
.map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[1].type]), .map((k: any) => [k.time, k.data == 3.14159 ? null : k.data, 'A', lineStyle[1].type]),
smooth: true, //让线变得平滑 smooth: true, //让线变得平滑
@@ -473,7 +476,7 @@ const changeDataType = () => {
} }
if (dataType.value.includes(2)) { if (dataType.value.includes(2)) {
let [temperatureMin, temperatureMax] = yMethod( let [temperatureMin, temperatureMax] = yMethod(
list.value[activeTab.value].temperatureList.map(k => (k.data == 3.14159 ? 0 : k.data)) temperatureList.map((k: any) => (k.data == 3.14159 ? 0 : k.data))
) )
echartsData.value.yAxis[flag ? 1 : 0] = { echartsData.value.yAxis[flag ? 1 : 0] = {
name: '℃', name: '℃',
@@ -481,12 +484,16 @@ const changeDataType = () => {
splitNumber: 5, splitNumber: 5,
max: temperatureMax, max: temperatureMax,
min: temperatureMin, min: temperatureMin,
minInterval: 1 minInterval: 1,
splitLine: {
show: false
} }
}
echartsData.value.options.series.push({ echartsData.value.options.series.push({
name: '温度', name: '温度',
type: 'line', type: 'line',
data: list.value[activeTab.value].temperatureList.map((k: any) => [ data: temperatureList.map((k: any) => [
k.time, k.time,
k.data == 3.14159 ? null : k.data, k.data == 3.14159 ? null : k.data,
'℃', '℃',
@@ -501,7 +508,7 @@ const changeDataType = () => {
} }
key.value += 1 key.value += 1
} }
function renderItem(params, api) { function renderItem(params: any, api: any) {
var categoryIndex = api.value(0) var categoryIndex = api.value(0)
var start = api.coord([api.value(1), categoryIndex]) var start = api.coord([api.value(1), categoryIndex])
var end = api.coord([api.value(2), categoryIndex]) var end = api.coord([api.value(2), categoryIndex])
@@ -531,7 +538,7 @@ function renderItem(params, api) {
) )
} }
// 三角形标记渲染函数 // 三角形标记渲染函数
function renderMarker(params, api) { function renderMarker(params: any, api: any) {
var point = api.coord([api.value(0), 0]) var point = api.coord([api.value(0), 0])
var symbolSize = 8 var symbolSize = 8
var offsetY = 40 var offsetY = 40

View File

@@ -1,32 +1,78 @@
<template> <template>
<div class="near-realtime-data"> <div class="near-realtime-data">
<div class="view_bot"> <div class="view_bot">
<template v-for="(section, sectionIndex) in tableSections" :key="sectionIndex"> <template v-for="(section, sectionIndex) in tableSections" :key="sectionIndex">
<vxe-table class="near-realtime-table" border height="" width="100%" :data="[section.row]" <vxe-table
:column-config="tableColumnConfig" :tooltip-config="tableTooltipConfig"> class="near-realtime-table"
border
height=""
width="100%"
:data="[section.row]"
v-bind="defaultAttribute"
:column-config="tableColumnConfig"
:tooltip-config="tableTooltipConfig"
>
<template v-for="(item, colIndex) in section.columns" :key="colIndex"> <template v-for="(item, colIndex) in section.columns" :key="colIndex">
<vxe-colgroup v-if="item.type === 'abc'" align="center" :title="getPrimaryTitle(item.data)" <vxe-colgroup
:width="getMetricWidth(section)"> v-if="item.type === 'abc'"
<vxe-column align="center" :field="`v${colIndex}A`" :title="item.data.phaseLabels![0]" align="center"
:width="getPhaseWidth(section)" :formatter="cellFormatter"></vxe-column> :title="getPrimaryTitle(item.data)"
<vxe-column align="center" :field="`v${colIndex}B`" :title="item.data.phaseLabels![1]" :width="getMetricWidth(section)"
:width="getPhaseWidth(section)" :formatter="cellFormatter"></vxe-column> >
<vxe-column align="center" :field="`v${colIndex}C`" :title="item.data.phaseLabels![2]" <vxe-column
:width="getPhaseWidth(section)" :formatter="cellFormatter"></vxe-column> align="center"
:field="`v${colIndex}A`"
:title="item.data.phaseLabels![0]"
:width="getPhaseWidth(section)"
:formatter="cellFormatter"
></vxe-column>
<vxe-column
align="center"
:field="`v${colIndex}B`"
:title="item.data.phaseLabels![1]"
:width="getPhaseWidth(section)"
:formatter="cellFormatter"
></vxe-column>
<vxe-column
align="center"
:field="`v${colIndex}C`"
:title="item.data.phaseLabels![2]"
:width="getPhaseWidth(section)"
:formatter="cellFormatter"
></vxe-column>
</vxe-colgroup> </vxe-colgroup>
<vxe-colgroup v-else-if="item.type === 't-multi'" align="center" <vxe-colgroup
:title="getPrimaryTitle(item.data)" :width="getMetricWidth(section)"> v-else-if="item.type === 't-multi'"
<vxe-column v-for="(sub, subIndex) in item.data.subItems" :key="subIndex" align="center" align="center"
:field="`t${colIndex}_${subIndex}`" :title="sub.subTitle" :title="getPrimaryTitle(item.data)"
:width="getMetricWidth(section)"
>
<vxe-column
v-for="(sub, subIndex) in item.data.subItems"
:key="subIndex"
align="center"
:field="`t${colIndex}_${subIndex}`"
:title="sub.subTitle"
:width="getSubColWidth(section, item.data.subItems!.length)" :width="getSubColWidth(section, item.data.subItems!.length)"
:formatter="cellFormatter"></vxe-column> :formatter="cellFormatter"
></vxe-column>
</vxe-colgroup> </vxe-colgroup>
<vxe-column v-else align="center" :field="`s${colIndex}`" :title="getScalarTitle(item.data)" <vxe-column
:width="getMetricWidth(section)" show-overflow :formatter="cellFormatter"></vxe-column> v-else
align="center"
:field="`s${colIndex}`"
:title="getScalarTitle(item.data)"
:width="getMetricWidth(section)"
show-overflow
:formatter="cellFormatter"
></vxe-column>
</template> </template>
<vxe-column v-for="emptyIndex in section.emptySlotCount" :key="`empty-${emptyIndex}`" align="center" <vxe-column
:width="getMetricWidth(section)"></vxe-column> v-for="emptyIndex in section.emptySlotCount"
:key="`empty-${emptyIndex}`"
align="center"
:width="getMetricWidth(section)"
></vxe-column>
</vxe-table> </vxe-table>
<div v-if="sectionIndex < tableSections.length - 1" class="table-gap"></div> <div v-if="sectionIndex < tableSections.length - 1" class="table-gap"></div>
</template> </template>
@@ -38,6 +84,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { defaultAttribute } from '@/components/table/defaultAttribute'
import { ref } from 'vue' import { ref } from 'vue'
const ROW_WITH_GROUP = 4 const ROW_WITH_GROUP = 4
@@ -97,7 +144,7 @@ interface NameGroup {
const PHASE_GROUPS = [ const PHASE_GROUPS = [
{ keys: ['A', 'B', 'C'], labels: ['A相', 'B相', 'C相'] as [string, string, string] }, { keys: ['A', 'B', 'C'], labels: ['A相', 'B相', 'C相'] as [string, string, string] },
{ keys: ['AB', 'BC', 'CA'], labels: ['AB相', 'BC相', 'CA相'] as [string, string, string] }, { keys: ['AB', 'BC', 'CA'], labels: ['AB相', 'BC相', 'CA相'] as [string, string, string] }
] ]
const height = mainHeight(345) const height = mainHeight(345)
@@ -110,8 +157,7 @@ const getMetricWidth = (section: TableSection) => `${100 / section.slotsPerRow}%
const getPhaseWidth = (section: TableSection) => `${100 / section.slotsPerRow / 3}%` const getPhaseWidth = (section: TableSection) => `${100 / section.slotsPerRow / 3}%`
const getSubColWidth = (section: TableSection, subCount: number) => const getSubColWidth = (section: TableSection, subCount: number) => `${100 / section.slotsPerRow / subCount}%`
`${100 / section.slotsPerRow / subCount}%`
const formatCellValue = (value: unknown): string | number => { const formatCellValue = (value: unknown): string | number => {
if (value == null || value === 3.14159) return '/' if (value == null || value === 3.14159) return '/'
@@ -174,7 +220,7 @@ const buildAbcMetric = (name: string, items: RawMetricItem[]): DisplayMetric =>
valueA: phaseMap[keys[0]], valueA: phaseMap[keys[0]],
valueB: phaseMap[keys[1]], valueB: phaseMap[keys[1]],
valueC: phaseMap[keys[2]], valueC: phaseMap[keys[2]],
phaseLabels: labels, phaseLabels: labels
} }
} }
} }
@@ -187,7 +233,7 @@ const buildAbcMetric = (name: string, items: RawMetricItem[]): DisplayMetric =>
valueA: phaseMap.A ?? phaseMap.AB, valueA: phaseMap.A ?? phaseMap.AB,
valueB: phaseMap.B ?? phaseMap.BC, valueB: phaseMap.B ?? phaseMap.BC,
valueC: phaseMap.C ?? phaseMap.CA, valueC: phaseMap.C ?? phaseMap.CA,
phaseLabels: phaseMap.AB != null ? ['AB相', 'BC相', 'CA相'] : ['A相', 'B相', 'C相'], phaseLabels: phaseMap.AB != null ? ['AB相', 'BC相', 'CA相'] : ['A相', 'B相', 'C相']
} }
} }
@@ -200,7 +246,7 @@ const buildTMetric = (name: string, items: RawMetricItem[]): DisplayMetric => {
otherName: items[0].otherName || name, otherName: items[0].otherName || name,
unit: items[0].unit ?? null, unit: items[0].unit ?? null,
type: 'scalar', type: 'scalar',
valueM: items[0].data, valueM: items[0].data
} }
} }
@@ -212,12 +258,9 @@ const buildTMetric = (name: string, items: RawMetricItem[]): DisplayMetric => {
unit: sharedUnit, unit: sharedUnit,
type: 't-multi', type: 't-multi',
subItems: items.map(item => ({ subItems: items.map(item => ({
subTitle: buildTitle( subTitle: buildTitle(extractSubTitle(item.otherName || item.name || ''), item.unit),
extractSubTitle(item.otherName || item.name || ''), value: item.data
item.unit }))
),
value: item.data,
})),
} }
} }
@@ -245,7 +288,7 @@ const normalizeOldItem = (item: RawMetricItem): DisplayMetric => {
valueA: item.valueA, valueA: item.valueA,
valueB: item.valueB, valueB: item.valueB,
valueC: item.valueC, valueC: item.valueC,
phaseLabels: ['A相', 'B相', 'C相'], phaseLabels: ['A相', 'B相', 'C相']
} }
} }
@@ -254,7 +297,7 @@ const normalizeOldItem = (item: RawMetricItem): DisplayMetric => {
otherName, otherName,
unit: item.unit ?? null, unit: item.unit ?? null,
type: 'scalar', type: 'scalar',
valueM: item.valueM, valueM: item.valueM
} }
} }
@@ -268,7 +311,7 @@ const normalizeMetrics = (data: RawMetricItem[]): DisplayMetric[] => {
const toMetricItem = (data: DisplayMetric): MetricItem => ({ const toMetricItem = (data: DisplayMetric): MetricItem => ({
type: data.type, type: data.type,
data, data
}) })
const buildRow = (columns: MetricItem[]) => { const buildRow = (columns: MetricItem[]) => {
@@ -312,7 +355,7 @@ const buildTableSections = (metrics: DisplayMetric[]) => {
columns, columns,
row: buildRow(columns), row: buildRow(columns),
slotsPerRow, slotsPerRow,
emptySlotCount: Math.max(0, slotsPerRow - columns.length), emptySlotCount: Math.max(0, slotsPerRow - columns.length)
}) })
} }
@@ -346,52 +389,5 @@ defineExpose({ setData })
height: 20px; height: 20px;
} }
:deep(.view_bot) {
.near-realtime-table {
width: 100%;
}
.near-realtime-table .vxe-table--render-wrapper,
.near-realtime-table .vxe-table--main-wrapper,
.near-realtime-table .vxe-table--header-wrapper,
.near-realtime-table .vxe-table--body-wrapper,
.near-realtime-table .vxe-table--layout-wrapper {
width: 100% !important;
}
.near-realtime-table table {
width: 100% !important;
table-layout: fixed;
}
.near-realtime-table .vxe-header--column .vxe-cell,
.near-realtime-table .vxe-body--column .vxe-cell {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 22px !important;
}
.vxe-table--render-default .vxe-body--column:not(.col--ellipsis),
.vxe-table--render-default .vxe-footer--column:not(.col--ellipsis),
.vxe-table--render-default .vxe-header--column:not(.col--ellipsis) {
padding: 5px !important;
}
.vxe-table--body-wrapper {
min-height: 32px !important;
}
.vxe-body--row {
height: 32px !important;
}
.vxe-table--render-default {
font-size: 13px !important;
}
}
:deep(.vxe-table--render-default .vxe-body--column.col--ellipsis, .vxe-table--render-default .vxe-footer--column.col--ellipsis, .vxe-table--render-default .vxe-header--column.col--ellipsis, .vxe-table--render-default.vxe-editable .vxe-body--column) {
height: 32px !important;
}
</style> </style>

View File

@@ -1,7 +1,7 @@
<!-- 历史数据补召 --> <!-- 历史数据补召 -->
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader> <TableHeader showCustomColumn>
<template v-slot:select> <template v-slot:select>
<el-form-item label="设备类型"> <el-form-item label="设备类型">
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备类型" /> --> <!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备类型" /> -->

View File

@@ -42,6 +42,7 @@ import rmsboxi from '@/components/echarts/rmsboxi.vue'
import MyEchart from '@/components/echarts/MyEchart.vue' import MyEchart from '@/components/echarts/MyEchart.vue'
import { Platform, TrendCharts, DataLine, Back } from '@element-plus/icons-vue' import { Platform, TrendCharts, DataLine, Back } from '@element-plus/icons-vue'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { clearWaveCache } from '@/utils/waveCache'
const props = defineProps(['wp']) const props = defineProps(['wp'])
const searchForm = ref({ const searchForm = ref({
type: 0 type: 0
@@ -126,6 +127,7 @@ const handleClick = (tab: any, event: any) => {
}, 1000) }, 1000)
} }
const handleBack = () => { const handleBack = () => {
clearWaveCache()
emit('handleHideCharts') emit('handleHideCharts')
} }
const setHeight = (h: any, vh: any, num = 1) => { const setHeight = (h: any, vh: any, num = 1) => {

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="view"> <div class="view">
<div v-show="!isWaveCharts"> <div v-show="!isWaveCharts">
<TableHeader datePicker showExport ref="headerRef" @onResetForm="onResetForm"> <TableHeader datePicker showExport showCustomColumn ref="headerRef" @onResetForm="onResetForm">
<template v-slot:operation> <template v-slot:operation>
<el-button type="primary" icon="el-icon-Operation" @click="openFilterDialog">事件筛选</el-button> <el-button type="primary" icon="el-icon-Operation" @click="openFilterDialog">事件筛选</el-button>
</template> </template>

View File

@@ -1,12 +1,13 @@
<template> <template>
<div class="view" v-loading="loading"> <div class="view" v-loading="loading">
<div class="charts-panel"> <div class="charts-panel">
<el-collapse v-model="activeNames" class="charts-collapse"> <el-collapse v-model="activeNames" class="charts-collapse">
<el-collapse-item name="1"> <el-collapse-item name="1">
<template #title> <template #title>
<div class="charts-collapse-header"> <div class="charts-collapse-header">
<div style="font-weight: 700; font-size: 13px; text-align: center">数据时间{{ dataTime || '-' }}</div> <div style="font-weight: 700; font-size: 13px; text-align: center">
数据时间{{ dataTime || '-' }}
</div>
</div> </div>
</template> </template>
<template #icon> <template #icon>
@@ -54,36 +55,144 @@
</div> </div>
<div class="view_bot"> <div class="view_bot">
<vxe-table border height="" :data="realList" :column-config="{ resizable: true, tooltip: true }" <vxe-table
:tooltip-config="{ enterable: true }"> border
<vxe-colgroup align="center" :title="`电压有效值(${voltageUnit})`" > height=""
<vxe-column align="center" how-overflow-tooltip min-width="80" field="vRmsA" title="A相"></vxe-column> :data="realList"
<vxe-column align="center" how-overflow-tooltip min-width="80" field="vRmsB" title="B相"></vxe-column> v-bind="defaultAttribute"
<vxe-column align="center" how-overflow-tooltip min-width="80" field="vRmsC" title="C相"></vxe-column> :column-config="{ resizable: true, tooltip: true }"
:tooltip-config="{ enterable: true }"
>
<vxe-colgroup align="center" :title="`电压有效值(${voltageUnit})`">
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="vRmsA"
title="A相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="vRmsB"
title="B相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="vRmsC"
title="C相"
></vxe-column>
</vxe-colgroup> </vxe-colgroup>
<vxe-colgroup align="center" title="电流有效值(A)"> <vxe-colgroup align="center" title="电流有效值(A)">
<vxe-column align="center" how-overflow-tooltip min-width="80" field="iRmsA" title="A相"></vxe-column> <vxe-column
<vxe-column align="center" how-overflow-tooltip min-width="80" field="iRmsB" title="B相"></vxe-column> align="center"
<vxe-column align="center" how-overflow-tooltip min-width="80" field="iRmsC" title="C相"></vxe-column> how-overflow-tooltip
min-width="80"
field="iRmsA"
title="A相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="iRmsB"
title="B相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="iRmsC"
title="C相"
></vxe-column>
</vxe-colgroup> </vxe-colgroup>
<vxe-colgroup align="center" title="基波电压相位(°)"> <vxe-colgroup align="center" title="基波电压相位(°)">
<vxe-column align="center" how-overflow-tooltip min-width="80" field="v1AngA" title="A相"></vxe-column> <vxe-column
<vxe-column align="center" how-overflow-tooltip min-width="80" field="v1AngB" title="B相"></vxe-column> align="center"
<vxe-column align="center" how-overflow-tooltip min-width="80" field="v1AngC" title="C相"></vxe-column> how-overflow-tooltip
min-width="80"
field="v1AngA"
title="A相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="v1AngB"
title="B相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="v1AngC"
title="C相"
></vxe-column>
</vxe-colgroup> </vxe-colgroup>
<vxe-colgroup align="center" title="基波电流相位(°)"> <vxe-colgroup align="center" title="基波电流相位(°)">
<vxe-column align="center" how-overflow-tooltip min-width="80" field="i1AngA" title="A相"></vxe-column> <vxe-column
<vxe-column align="center" how-overflow-tooltip min-width="80" field="i1AngB" title="B相"></vxe-column> align="center"
<vxe-column align="center" how-overflow-tooltip min-width="80" field="i1AngC" title="C相"></vxe-column> how-overflow-tooltip
min-width="80"
field="i1AngA"
title="A相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="i1AngB"
title="B相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="i1AngC"
title="C相"
></vxe-column>
</vxe-colgroup> </vxe-colgroup>
</vxe-table> </vxe-table>
<br /> <br />
<vxe-table border height="" :data="realList" :column-config="{ resizable: true, tooltip: true }" <vxe-table
:tooltip-config="{ enterable: true }"> border
<vxe-column align="center" field="freq"how-overflow-tooltip min-width="160" title="频率(Hz)"></vxe-column> height=""
<vxe-column align="center" field="freqDev"how-overflow-tooltip min-width="160" title="频率偏差(Hz)"></vxe-column> :data="realList"
<vxe-column align="center"how-overflow-tooltip min-width="160" field="vUnbalance" title="电压不平衡度(%)"></vxe-column> v-bind="defaultAttribute"
<vxe-column align="center"how-overflow-tooltip min-width="160" field="iUnbalance" title="电流不平衡度(%)"></vxe-column> :column-config="{ resizable: true, tooltip: true }"
:tooltip-config="{ enterable: true }"
>
<vxe-column
align="center"
field="freq"
how-overflow-tooltip
min-width="160"
title="频率(Hz)"
></vxe-column>
<vxe-column
align="center"
field="freqDev"
how-overflow-tooltip
min-width="160"
title="频率偏差(Hz)"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="160"
field="vUnbalance"
title="电压不平衡度(%)"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="160"
field="iUnbalance"
title="电流不平衡度(%)"
></vxe-column>
<vxe-colgroup align="center" :title="`基波电压幅值(${voltageUnit})`"> <vxe-colgroup align="center" :title="`基波电压幅值(${voltageUnit})`">
<vxe-column align="center" how-overflow-tooltip min-width="80" field="v1A" title="A相"></vxe-column> <vxe-column align="center" how-overflow-tooltip min-width="80" field="v1A" title="A相"></vxe-column>
<vxe-column align="center" how-overflow-tooltip min-width="80" field="v1B" title="B相"></vxe-column> <vxe-column align="center" how-overflow-tooltip min-width="80" field="v1B" title="B相"></vxe-column>
@@ -96,22 +205,82 @@
</vxe-colgroup> </vxe-colgroup>
</vxe-table> </vxe-table>
<br /> <br />
<vxe-table border height="" :data="realList" :column-config="{ resizable: true, tooltip: true }" <vxe-table
:tooltip-config="{ enterable: true }"> border
height=""
:data="realList"
v-bind="defaultAttribute"
:column-config="{ resizable: true, tooltip: true }"
:tooltip-config="{ enterable: true }"
>
<vxe-colgroup align="center" title="电压偏差(%)"> <vxe-colgroup align="center" title="电压偏差(%)">
<vxe-column align="center" how-overflow-tooltip min-width="80" field="vDevA" title="A相"></vxe-column> <vxe-column
<vxe-column align="center" how-overflow-tooltip min-width="80" field="vDevB" title="B相"></vxe-column> align="center"
<vxe-column align="center" how-overflow-tooltip min-width="80" field="vDevC" title="C相"></vxe-column> how-overflow-tooltip
min-width="80"
field="vDevA"
title="A相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="vDevB"
title="B相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="vDevC"
title="C相"
></vxe-column>
</vxe-colgroup> </vxe-colgroup>
<vxe-colgroup align="center" title="电压总谐波畸变率(%)"> <vxe-colgroup align="center" title="电压总谐波畸变率(%)">
<vxe-column align="center" how-overflow-tooltip min-width="80" field="vThdA" title="A相"></vxe-column> <vxe-column
<vxe-column align="center" how-overflow-tooltip min-width="80" field="vThdB" title="B相"></vxe-column> align="center"
<vxe-column align="center" how-overflow-tooltip min-width="80" field="vThdC" title="C相"></vxe-column> how-overflow-tooltip
min-width="80"
field="vThdA"
title="A相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="vThdB"
title="B相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="vThdC"
title="C相"
></vxe-column>
</vxe-colgroup> </vxe-colgroup>
<vxe-colgroup align="center" title="电流总谐波畸变率(%)"> <vxe-colgroup align="center" title="电流总谐波畸变率(%)">
<vxe-column align="center" how-overflow-tooltip min-width="80" field="iThdA" title="A相"></vxe-column> <vxe-column
<vxe-column align="center" how-overflow-tooltip min-width="80" field="iThdB" title="B相"></vxe-column> align="center"
<vxe-column align="center" how-overflow-tooltip min-width="80" field="iThdC" title="C相"></vxe-column> how-overflow-tooltip
min-width="80"
field="iThdA"
title="A相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="iThdB"
title="B相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="iThdC"
title="C相"
></vxe-column>
</vxe-colgroup> </vxe-colgroup>
<vxe-colgroup align="center" :title="`有功功率(${powerUnit})`"> <vxe-colgroup align="center" :title="`有功功率(${powerUnit})`">
<vxe-column align="center" how-overflow-tooltip min-width="80" field="pA" title="A相"></vxe-column> <vxe-column align="center" how-overflow-tooltip min-width="80" field="pA" title="A相"></vxe-column>
@@ -121,8 +290,14 @@
</vxe-colgroup> </vxe-colgroup>
</vxe-table> </vxe-table>
<br /> <br />
<vxe-table border height="" :data="realList" :column-config="{ resizable: true, tooltip: true }" <vxe-table
:tooltip-config="{ enterable: true }"> border
height=""
:data="realList"
v-bind="defaultAttribute"
:column-config="{ resizable: true, tooltip: true }"
:tooltip-config="{ enterable: true }"
>
<vxe-colgroup align="center" :title="`无功功率(${reactivePowerUnit})`"> <vxe-colgroup align="center" :title="`无功功率(${reactivePowerUnit})`">
<vxe-column align="center" how-overflow-tooltip min-width="80" field="qA" title="A相"></vxe-column> <vxe-column align="center" how-overflow-tooltip min-width="80" field="qA" title="A相"></vxe-column>
<vxe-column align="center" how-overflow-tooltip min-width="80" field="qB" title="B相"></vxe-column> <vxe-column align="center" how-overflow-tooltip min-width="80" field="qB" title="B相"></vxe-column>
@@ -143,13 +318,43 @@
<vxe-column align="center" how-overflow-tooltip min-width="80" field="pfA" title="A相"></vxe-column> <vxe-column align="center" how-overflow-tooltip min-width="80" field="pfA" title="A相"></vxe-column>
<vxe-column align="center" how-overflow-tooltip min-width="80" field="pfB" title="B相"></vxe-column> <vxe-column align="center" how-overflow-tooltip min-width="80" field="pfB" title="B相"></vxe-column>
<vxe-column align="center" how-overflow-tooltip min-width="80" field="pfC" title="C相"></vxe-column> <vxe-column align="center" how-overflow-tooltip min-width="80" field="pfC" title="C相"></vxe-column>
<vxe-column align="center" how-overflow-tooltip min-width="80" field="pfTot" title="总"></vxe-column> <vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="pfTot"
title="总"
></vxe-column>
</vxe-colgroup> </vxe-colgroup>
<vxe-colgroup align="center" title="位移功率因数(P/S1)"> <vxe-colgroup align="center" title="位移功率因数(P/S1)">
<vxe-column align="center" how-overflow-tooltip min-width="80" field="dpfA" title="A相"></vxe-column> <vxe-column
<vxe-column align="center" how-overflow-tooltip min-width="80" field="dpfB" title="B相"></vxe-column> align="center"
<vxe-column align="center" how-overflow-tooltip min-width="80" field="dpfC" title="C相"></vxe-column> how-overflow-tooltip
<vxe-column align="center" how-overflow-tooltip min-width="80" field="dpfTot" title="总"></vxe-column> min-width="80"
field="dpfA"
title="A相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="dpfB"
title="B相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="dpfC"
title="C相"
></vxe-column>
<vxe-column
align="center"
how-overflow-tooltip
min-width="80"
field="dpfTot"
title="总"
></vxe-column>
</vxe-colgroup> </vxe-colgroup>
</vxe-table> </vxe-table>
</div> </div>
@@ -160,7 +365,7 @@ import { ref, onMounted, computed } from 'vue'
import { ArrowDown } from '@element-plus/icons-vue' import { ArrowDown } from '@element-plus/icons-vue'
import MyEchart from '@/components/echarts/MyEchart.vue' import MyEchart from '@/components/echarts/MyEchart.vue'
import { getRealTimeTableList } from '@/api/cs-device-boot/EquipmentDelivery' import { getRealTimeTableList } from '@/api/cs-device-boot/EquipmentDelivery'
import { defaultAttribute } from '@/components/table/defaultAttribute'
const props = defineProps({ const props = defineProps({
dataTime: String dataTime: String
@@ -189,7 +394,7 @@ const previousDataLevel = ref('')
const PHASE_COLORS = { const PHASE_COLORS = {
A: '#DAA520', A: '#DAA520',
B: '#2E8B57', B: '#2E8B57',
C: '#A52a2a', C: '#A52a2a'
} }
const PHASE_RING_COLOR = '#9D322D' const PHASE_RING_COLOR = '#9D322D'
@@ -199,7 +404,7 @@ type GaugeAlign = 'left' | 'right'
const createPhaseGaugeData = (name: string, value: number, color: string) => ({ const createPhaseGaugeData = (name: string, value: number, color: string) => ({
name, name,
value, value,
itemStyle: { color, shadowBlur: 0, shadowColor: 'transparent' }, itemStyle: { color, shadowBlur: 0, shadowColor: 'transparent' }
}) })
const createRmsGaugeOptions = (name: string, color: string, align: GaugeAlign) => { const createRmsGaugeOptions = (name: string, color: string, align: GaugeAlign) => {
@@ -223,8 +428,8 @@ const createRmsGaugeOptions = (name: string, color: string, align: GaugeAlign) =
lineStyle: { lineStyle: {
width: 5, width: 5,
shadowBlur: 0, shadowBlur: 0,
color: [[1, color]], color: [[1, color]]
}, }
}, },
axisTick: { axisTick: {
show: true, show: true,
@@ -233,14 +438,14 @@ const createRmsGaugeOptions = (name: string, color: string, align: GaugeAlign) =
lineStyle: { lineStyle: {
color, color,
width: 2, width: 2,
type: 'solid', type: 'solid'
}, }
}, },
axisLabel: { axisLabel: {
show: true, show: true,
distance: 12, distance: 12,
color, color,
fontSize: 12, fontSize: 12
}, },
splitLine: { splitLine: {
show: true, show: true,
@@ -249,22 +454,22 @@ const createRmsGaugeOptions = (name: string, color: string, align: GaugeAlign) =
lineStyle: { lineStyle: {
color, color,
width: 3, width: 3,
type: 'solid', type: 'solid'
}, }
}, },
title: { title: {
show: true, show: true,
fontWeight: 'bolder', fontWeight: 'bolder',
fontSize: 12, fontSize: 12,
color, color,
offsetCenter: isLeft ? ['-130%', '-20%'] : ['130%', '-20%'], offsetCenter: isLeft ? ['-130%', '-20%'] : ['130%', '-20%']
}, },
detail: { detail: {
fontSize: 14, fontSize: 14,
color, color,
valueAnimation: true, valueAnimation: true,
formatter: '{value}', formatter: '{value}',
offsetCenter: isLeft ? ['50%', '-35%'] : ['-45%', '-35%'], offsetCenter: isLeft ? ['50%', '-35%'] : ['-45%', '-35%']
}, },
pointer: { pointer: {
length: '80%', length: '80%',
@@ -274,18 +479,18 @@ const createRmsGaugeOptions = (name: string, color: string, align: GaugeAlign) =
itemStyle: { itemStyle: {
color, color,
shadowBlur: 0, shadowBlur: 0,
shadowColor: 'transparent', shadowColor: 'transparent'
}, }
}, },
itemStyle: { itemStyle: {
color, color,
shadowBlur: 0, shadowBlur: 0,
shadowColor: 'transparent', shadowColor: 'transparent'
},
data: [createPhaseGaugeData(name, 0, color)],
},
],
}, },
data: [createPhaseGaugeData(name, 0, color)]
}
]
}
} }
} }
@@ -297,7 +502,7 @@ const applyGaugePhaseColor = (options: any, color: string) => {
...series.pointer, ...series.pointer,
itemStyle: { color, shadowBlur: 0, shadowColor: 'transparent' }, itemStyle: { color, shadowBlur: 0, shadowColor: 'transparent' },
shadowBlur: 0, shadowBlur: 0,
shadowColor: 'transparent', shadowColor: 'transparent'
} }
series.axisTick.lineStyle.color = color series.axisTick.lineStyle.color = color
series.splitLine.lineStyle.color = color series.splitLine.lineStyle.color = color
@@ -313,38 +518,22 @@ const buildPhaseLegendGraphic = () => {
const phases = [ const phases = [
{ key: 'A', label: 'A相', color: PHASE_COLORS.A }, { key: 'A', label: 'A相', color: PHASE_COLORS.A },
{ key: 'B', label: 'B相', color: PHASE_COLORS.B }, { key: 'B', label: 'B相', color: PHASE_COLORS.B },
{ key: 'C', label: 'C相', color: PHASE_COLORS.C }, { key: 'C', label: 'C相', color: PHASE_COLORS.C }
] ]
const voltageValues = [ const voltageValues = [realData.value.v1AngA ?? 0, realData.value.v1AngB ?? 0, realData.value.v1AngC ?? 0]
realData.value.v1AngA ?? 0, const currentValues = [realData.value.i1AngA ?? 0, realData.value.i1AngB ?? 0, realData.value.i1AngC ?? 0]
realData.value.v1AngB ?? 0,
realData.value.v1AngC ?? 0,
]
const currentValues = [
realData.value.i1AngA ?? 0,
realData.value.i1AngB ?? 0,
realData.value.i1AngC ?? 0,
]
return [ return [
{ {
type: 'group', type: 'group',
right: 20, right: 20,
bottom: 20, bottom: 20
// children, // children,
}, }
] ]
} }
const updateRmsGaugeChart = ( const updateRmsGaugeChart = (chartRef: any, chartData: any, name: string, value: number, color: string) => {
chartRef: any,
chartData: any,
name: string,
value: number,
color: string
) => {
chartData.value.options.series[0].max = value == 0 ? 1 : Math.ceil(value * 1.2) chartData.value.options.series[0].max = value == 0 ? 1 : Math.ceil(value * 1.2)
chartData.value.options.series[0].data = [createPhaseGaugeData(name, value || 0, color)] chartData.value.options.series[0].data = [createPhaseGaugeData(name, value || 0, color)]
applyGaugePhaseColor(chartData.value.options, color) applyGaugePhaseColor(chartData.value.options, color)
@@ -399,10 +588,10 @@ const initRadioCharts = () => {
[0.25, PHASE_RING_COLOR], [0.25, PHASE_RING_COLOR],
[0.5, PHASE_RING_COLOR], [0.5, PHASE_RING_COLOR],
[0.75, PHASE_RING_COLOR], [0.75, PHASE_RING_COLOR],
[1, PHASE_RING_COLOR], [1, PHASE_RING_COLOR]
], ],
width: 2, width: 2
}, }
}, },
axisTick: { axisTick: {
show: true, show: true,
@@ -412,8 +601,8 @@ const initRadioCharts = () => {
lineStyle: { lineStyle: {
color: PHASE_RING_COLOR, color: PHASE_RING_COLOR,
width: 1, width: 1,
type: 'solid', type: 'solid'
}, }
}, },
splitLine: { splitLine: {
show: true, show: true,
@@ -422,8 +611,8 @@ const initRadioCharts = () => {
lineStyle: { lineStyle: {
color: PHASE_RING_COLOR, color: PHASE_RING_COLOR,
width: 2, width: 2,
type: 'solid', type: 'solid'
}, }
}, },
// 分割线标识 // 分割线标识
axisLabel: { axisLabel: {
@@ -451,7 +640,7 @@ const initRadioCharts = () => {
width: 15, width: 15,
opacity: 1, opacity: 1,
shadowBlur: 0, shadowBlur: 0,
shadowColor: 'transparent', shadowColor: 'transparent'
}, },
detail: { detail: {
show: false show: false
@@ -508,10 +697,10 @@ const initRadioCharts = () => {
[0.25, PHASE_RING_COLOR], [0.25, PHASE_RING_COLOR],
[0.5, PHASE_RING_COLOR], [0.5, PHASE_RING_COLOR],
[0.75, PHASE_RING_COLOR], [0.75, PHASE_RING_COLOR],
[1, PHASE_RING_COLOR], [1, PHASE_RING_COLOR]
], ],
width: 1.5, width: 1.5
}, }
}, },
axisTick: { axisTick: {
show: true, show: true,
@@ -521,8 +710,8 @@ const initRadioCharts = () => {
lineStyle: { lineStyle: {
color: PHASE_RING_COLOR, color: PHASE_RING_COLOR,
width: 1, width: 1,
type: 'solid', type: 'solid'
}, }
}, },
splitLine: { splitLine: {
show: true, show: true,
@@ -531,8 +720,8 @@ const initRadioCharts = () => {
lineStyle: { lineStyle: {
color: PHASE_RING_COLOR, color: PHASE_RING_COLOR,
width: 2, width: 2,
type: 'solid', type: 'solid'
}, }
}, },
// 分割线标识 // 分割线标识
axisLabel: { axisLabel: {
@@ -560,7 +749,7 @@ const initRadioCharts = () => {
width: 15, width: 15,
opacity: 1, opacity: 1,
shadowBlur: 0, shadowBlur: 0,
shadowColor: 'transparent', shadowColor: 'transparent'
}, },
detail: { detail: {
show: false show: false
@@ -761,8 +950,6 @@ onMounted(() => {
border: none; border: none;
} }
:deep(.el-collapse-item__arrow) { :deep(.el-collapse-item__arrow) {
display: none; display: none;
} }
@@ -777,8 +964,6 @@ onMounted(() => {
pointer-events: none; pointer-events: none;
} }
.charts-collapse-action { .charts-collapse-action {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
@@ -895,102 +1080,5 @@ onMounted(() => {
display: none; display: none;
} }
.table_container {
width: 100%;
height: auto;
display: flex;
align-items: center;
justify-content: center;
.table {
flex: 1;
.table_info {
width: 100%;
height: 120px;
// border: 1px solid #eee;
border-bottom: 2px solid #eee;
margin-bottom: 20px;
display: flex;
flex-direction: column;
}
.thead {
width: 100%;
height: auto;
background: #f4f6f9;
text-align: center;
display: flex;
flex-direction: column;
.thead_top {
width: 100%;
height: 40px;
line-height: 40px;
border: 1px solid #eee;
color: #111;
font-size: 14px;
font-weight: 800;
}
.thead_bot {
width: 100%;
height: 40px;
line-height: 40px;
display: flex;
color: #111;
font-size: 14px;
font-weight: 800;
.thead_bot_cell {
flex: 1;
border: 1px solid #eee;
}
}
}
.tbody {
flex: 1;
display: flex;
text-align: center;
.tbody_cell {
flex: 1;
text-align: center;
line-height: 40px;
border: 1px solid #eee;
border-bottom: 0;
}
}
.tbody:hover {
background: #f4f6f9;
}
}
}
.table_container:hover {
.table {
.tbody {
background: #f4f6f9;
}
}
}
:deep(.view_bot) {
.vxe-table--render-default .vxe-body--column:not(.col--ellipsis),
.vxe-table--render-default .vxe-footer--column:not(.col--ellipsis),
.vxe-table--render-default .vxe-header--column:not(.col--ellipsis) {
padding: 5px !important;
}
.vxe-table--body-wrapper {
min-height: 32px !important;
}
}
:deep(.vxe-table--render-default) {
font-size: 13px !important;
}
</style> </style>

View File

@@ -31,7 +31,7 @@
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="接入方式"> <el-descriptions-item label="接入方式">
{{ deviceData.devAccessMethod =='CLD'?'1056协议':deviceData.devAccessMethod || '/' }} {{ deviceData.devAccessMethod == 'CLD' ? '1056协议' : deviceData.devAccessMethod || '/' }}
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="网络设备ID"> <el-descriptions-item label="网络设备ID">
{{ deviceData.ndid || '/' }} {{ deviceData.ndid || '/' }}
@@ -309,7 +309,7 @@ const exportData = () => {
} }
</script> </script>
<style lang="scss"> <style lang="scss" scoped>
.device-manage { .device-manage {
display: flex; display: flex;
@@ -343,4 +343,7 @@ const exportData = () => {
right: 10px; right: 10px;
z-index: 10; z-index: 10;
} }
:deep(.el-tabs__header) {
width: calc(100% - 100px);
}
</style> </style>

View File

@@ -1,7 +1,7 @@
<template> <template>
<div> <div>
<div v-show="!isWaveCharts"> <div v-show="!isWaveCharts">
<TableHeader showExport ref="headerRef" :showQuery="false" @onResetForm="onResetForm"> <TableHeader showExport showCustomColumn ref="headerRef" :showQuery="false" @onResetForm="onResetForm">
<template v-slot:operation> <template v-slot:operation>
<el-button type="primary" icon="el-icon-Operation" @click="openFilterDialog">事件筛选</el-button> <el-button type="primary" icon="el-icon-Operation" @click="openFilterDialog">事件筛选</el-button>
</template> </template>

View File

@@ -1,6 +1,6 @@
<template> <template>
<div> <div>
<TableHeader datePicker showExport> <TableHeader datePicker showExport showCustomColumn>
<template v-slot:select> <template v-slot:select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue"
@@ -76,10 +76,10 @@ const tableStore = new TableStore({
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1 return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
} }
}, },
{ title: '调试时间', field: 'startTime', align: 'center', sortable: true, width: 180 }, { title: '调试时间', field: 'startTime', align: 'center', sortable: true, minWidth: 180 },
{ title: '设备名称', field: 'deviceName', align: 'center', width: 180 }, { title: '设备名称', field: 'deviceName', align: 'center', minWidth: 180 },
{ {
title: '监测点名称', field: 'lineName', align: 'center', width: 180, formatter: (row: any) => { title: '监测点名称', field: 'lineName', align: 'center', minWidth: 180, formatter: (row: any) => {
return row.cellValue ? row.cellValue : '/' return row.cellValue ? row.cellValue : '/'
} }
}, },

View File

@@ -1,6 +1,6 @@
<template> <template>
<!-- 异常事件 --> <!-- 异常事件 -->
<TableHeader datePicker ref="refheader" showExport> <TableHeader datePicker ref="refheader" showExport >
<!-- <template v-slot:select> <!-- <template v-slot:select>
<el-form-item label="数据来源"> <el-form-item label="数据来源">
<el-cascader <el-cascader

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader datePicker showExport></TableHeader> <TableHeader datePicker showExport showCustomColumn></TableHeader>
<Table ref="tableRef" :isGroup="true" /> <Table ref="tableRef" :isGroup="true" />
</div> </div>
</template> </template>
@@ -26,15 +26,15 @@ const tableStore = new TableStore({
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1 return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
} }
}, },
{ title: '操作日期', field: 'createTime', align: 'center', sortable: true, width: '180' }, { title: '操作日期', field: 'createTime', align: 'center', sortable: true, minWidth: '180' },
{ title: '用户名称', field: 'userName', align: 'center', width: '180' }, { title: '用户名称', field: 'userName', align: 'center', minWidth: '180' },
{ title: '操作描述', field: 'operate', align: 'center', minWidth: '300' }, { title: '操作描述', field: 'operate', align: 'center', minWidth: '300' },
{ {
title: '状态', title: '状态',
field: 'result', field: 'result',
align: 'center', align: 'center',
width: '100', minWidth: '100',
render: 'tag', render: 'tag',
custom: { custom: {
0: 'danger', 0: 'danger',

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader datePicker> </TableHeader> <TableHeader datePicker > </TableHeader>
<Table ref="tableRef" /> <Table ref="tableRef" />
</div> </div>
</template> </template>

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader> <TableHeader showCustomColumn>
<template #select> <template #select>
<el-form-item label="数据分类"> <el-form-item label="数据分类">
<el-select v-model.trim="tableStore.table.params.dataType" multiple filterable collapse-tags <el-select v-model.trim="tableStore.table.params.dataType" multiple filterable collapse-tags

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main" v-loading="loading"> <div class="default-main" v-loading="loading">
<TableHeader ref="tableHeaderRef"> <TableHeader ref="tableHeaderRef" showCustomColumn>
<template #select> <template #select>
<el-form-item label="模版名称"> <el-form-item label="模版名称">
<el-input maxlength="32" show-word-limit <el-input maxlength="32" show-word-limit

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader ref="tableHeaderRef" :showReset="false" showExport> <TableHeader ref="tableHeaderRef" :showReset="false" showExport showCustomColumn>
<template #select> <template #select>
<el-form-item label="设备型号:"> <el-form-item label="设备型号:">
<el-select v-model.trim="tableStore.table.params.devType" filterable placeholder="请选择设备型号" <el-select v-model.trim="tableStore.table.params.devType" filterable placeholder="请选择设备型号"

View File

@@ -1,6 +1,6 @@
<template> <template>
<div v-loading="loading"> <div v-loading="loading">
<TableHeader> <TableHeader showCustomColumn>
<template v-slot:select> <template v-slot:select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue"

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader datePicker> <TableHeader datePicker >
<template v-slot:select> <template v-slot:select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue"

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader> <TableHeader >
<template v-slot:operation> <template v-slot:operation>
<el-upload <el-upload
action="" action=""

View File

@@ -1,168 +1,270 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader datePicker ref="refheader"> <TableHeader datePicker showCustomColumn ref="refheader">
<template v-slot:select> <template v-slot:select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit <el-input
maxlength="32"
show-word-limit
v-model.trim="tableStore.table.params.name" v-model.trim="tableStore.table.params.name"
placeholder="请输入关键字" placeholder="请输入关键字"
clearable clearable
></el-input> ></el-input>
</el-form-item> </el-form-item>
<!-- <el-form-item label="流程阶段"> <!-- <el-form-item label="流程阶段">
<el-select v-model.trim="tableStore.table.params.process" clearable placeholder="请选择"> <el-select v-model.trim="tableStore.table.params.process" clearable placeholder="请选择">
<el-option label="功能调试" :value="2"></el-option> <el-option label="功能调试" :value="2"></el-option>
<el-option label="出厂调试" :value="3"></el-option> <el-option label="出厂调试" :value="3"></el-option>
<el-option label="正式投运" :value="4"></el-option> <el-option label="正式投运" :value="4"></el-option>
</el-select> </el-select>
</el-form-item> --> </el-form-item> -->
</template> </template>
<template v-slot:operation> <template v-slot:operation>
<el-button type="primary" icon="el-icon-Download" @click="exportTab">导出</el-button> <el-button type="primary" icon="el-icon-Download" @click="exportTab">导出</el-button>
</template> </template>
</TableHeader> </TableHeader>
<Table ref="tableRef" />
<Table ref="tableRef" id="monthly-report-table" />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, provide } from 'vue' import { ref, provide } from 'vue'
import TableStore from '@/utils/tableStore' import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue' import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue' import TableHeader from '@/components/table/header/index.vue'
import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree' import { queryByCode, queryByid, queryCsDictTree } from '@/api/system-boot/dictTree'
import { buildExportBaseName } from '@/utils/echartMethod' import { buildExportBaseName } from '@/utils/echartMethod'
defineOptions({ defineOptions({
name: 'manage/monthly' name: 'manage/monthly'
}) })
const refheader = ref() const refheader = ref()
const devModelOptions: any = ref([]) const devModelOptions: any = ref([])
queryByCode('Device_Type').then(res => { queryByCode('Device_Type').then(res => {
queryByid(res.data.id).then(res => { queryByid(res.data.id).then(res => {
devModelOptions.value = res.data.map((item: any) => { devModelOptions.value = res.data.map((item: any) => {
return { return {
value: item.id, value: item.id,
label: item.name, label: item.name,
...item ...item
} }
}) })
}) })
tableStore.index() tableStore.index()
}) })
const tableStore = new TableStore({ const tableStore = new TableStore({
url: '/cs-harmonic-boot/statisticsData/halfMonthReport', url: '/cs-harmonic-boot/statisticsData/halfMonthReport',
method: 'POST', method: 'POST',
isWebPaging: true, isWebPaging: true,
exportName: '半月报功能', exportName: '半月报功能',
column: [ column: [
{ {
title: '序号', title: '序号',
width: 80, width: 80,
formatter: (row: any) => { formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1 return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
} }
}, },
{ title: '工程名称', field: 'engineeringName', minWidth: 150 }, { title: '工程名称', field: 'engineeringName', minWidth: 150 },
{ title: '项目名称', field: 'projectName', minWidth: 150 }, { title: '项目名称', field: 'projectName', minWidth: 150 },
{ title: '设备名称', field: 'devName', minWidth: 150 }, { title: '设备名称', field: 'devName', minWidth: 150 },
{ title: '监测点名称', field: 'lineName', minWidth: 150 }, { title: '监测点名称', field: 'lineName', minWidth: 150 },
{ {
title: '投运时间', title: '投运时间',
field: 'operationalTime', field: 'operationalTime',
width: 180,
minWidth: 180,
sortable: true sortable: true
}, },
{ {
title: '数据更新时间', title: '数据更新时间',
field: 'latestTime', field: 'latestTime',
width: 180,
minWidth: 180,
sortable: true sortable: true
// formatter: (row: any) => { // formatter: (row: any) => {
// return row.cellValue || '/' // return row.cellValue || '/'
// } // }
}, },
// { // {
// title: '设备型号', // title: '设备型号',
// field: 'devType', // field: 'devType',
// width: 130, // width: 130,
// formatter: row => { // formatter: row => {
// return devModelOptions.value.filter((item: any) => item.value == row.cellValue)[0]?.label // return devModelOptions.value.filter((item: any) => item.value == row.cellValue)[0]?.label
// } // }
// }, // },
// { title: 'Mac地址', field: 'mac', width: 140 }, // { title: 'Mac地址', field: 'mac', width: 140 },
// { // {
// title: '流程阶段', // title: '流程阶段',
// field: 'process', // field: 'process',
// width: 100, // width: 100,
// fixed: 'right', // fixed: 'right',
// render: 'tag', // render: 'tag',
// custom: { // custom: {
// 2: 'warning', // 2: 'warning',
// 3: 'warning', // 3: 'warning',
// 4: 'success' // 4: 'success'
// }, // },
// replaceValue: { // replaceValue: {
// 2: '功能调试', // 2: '功能调试',
// 3: '出厂调试', // 3: '出厂调试',
// 4: '正式投运' // 4: '正式投运'
// }, // },
// minWidth: 80 // minWidth: 80
// }, // },
{ {
title: '运行状态', title: '运行状态',
field: 'operationalStatus', field: 'operationalStatus',
render: 'tag', render: 'tag',
fixed: 'right', fixed: 'right',
width: 100, width: 100,
custom: { custom: {
停运: 'danger', 停运: 'danger',
在运: 'success' 在运: 'success'
}, },
replaceValue: { replaceValue: {
在运: '在运', 在运: '在运',
停运: '停运' 停运: '停运'
} }
}, },
{ {
title: '通讯状态', title: '通讯状态',
field: 'communicationStatus', field: 'communicationStatus',
width: 100, width: 100,
fixed: 'right', fixed: 'right',
render: 'tag', render: 'tag',
custom: { custom: {
离线: 'danger', 离线: 'danger',
在线: 'success' 在线: 'success'
}, },
replaceValue: { replaceValue: {
离线: '离线', 离线: '离线',
在线: '在线' 在线: '在线'
} }
}, },
{ title: '在线率(%)', fixed: 'right', width: 100, field: 'onlineRate', sortable: true }, { title: '在线率(%)', fixed: 'right', width: 100, field: 'onlineRate', sortable: true },
{ title: '完整性(%)', fixed: 'right', width: 100, field: 'integrity', sortable: true } { title: '完整性(%)', fixed: 'right', width: 100, field: 'integrity', sortable: true }
], ],
beforeSearchFun: () => {}, beforeSearchFun: () => {},
exportProcessingData: () => { exportProcessingData: () => {
tableStore.table.allData = tableStore.table.allData.filter(item => { tableStore.table.allData = tableStore.table.allData.filter(item => {
item.process = item.process == 2 ? '功能调试' : item.process == 3 ? '出厂调试' : '正式投运' item.process = item.process == 2 ? '功能调试' : item.process == 3 ? '出厂调试' : '正式投运'
return item return item
}) })
}, },
loadCallback: () => { loadCallback: () => {
let name = tableStore.table.params.name let name = tableStore.table.params.name
let data = tableStore.table.copyData.filter(item => { let data = tableStore.table.copyData.filter(item => {
// 处理latestTime默认值 // 处理latestTime默认值
item.latestTime = item.latestTime || '/' item.latestTime = item.latestTime || '/'
// 需要检查的字段列表 // 需要检查的字段列表
const fieldsToCheck = ['projectName', 'engineeringName', 'mac', 'devName', 'lineName'] const fieldsToCheck = ['projectName', 'engineeringName', 'mac', 'devName', 'lineName']
// 检查任何一个字段包含搜索名称 // 检查任何一个字段包含搜索名称
return fieldsToCheck.some(field => item[field]?.includes(name)) return fieldsToCheck.some(field => item[field]?.includes(name))
}) })
tableStore.table.copyData = JSON.parse(JSON.stringify(data)) tableStore.table.copyData = JSON.parse(JSON.stringify(data))
tableStore.table.total = tableStore.table.copyData.length tableStore.table.total = tableStore.table.copyData.length
if (data.length == 0) { if (data.length == 0) {
tableStore.table.data = [] tableStore.table.data = []
} else { } else {
@@ -176,33 +278,44 @@ const tableStore = new TableStore({
}) })
provide('tableStore', tableStore) provide('tableStore', tableStore)
// tableStore.table.params.process = 4 // tableStore.table.params.process = 4
tableStore.table.params.name = '' tableStore.table.params.name = ''
const tableRef = ref() const tableRef = ref()
const exportColumnFilterMethod = ({ column }: { column: any }) => {
return !(column.title === undefined || column.title === '序号' || column.title === '操作')
}
const exportTab = () => { const exportTab = () => {
tableRef.value.getRef()?.exportData({ tableRef.value.getRef()?.exportData({
filename: buildExportBaseName({ feature: '半月报功能' }), // 文件名字 filename: buildExportBaseName({ feature: '半月报功能' }), // 文件名字
sheetName: 'Sheet1', sheetName: 'Sheet1',
type: 'xlsx', //导出文件类型 xlsx 和 csv type: 'xlsx', //导出文件类型 xlsx 和 csv
useStyle: true, useStyle: true,
isTitle: true,
data: tableStore.table.copyData.filter(item => { data: tableStore.table.copyData.filter(item => {
item.process = item.process == 2 ? '功能调试' : item.process == 3 ? '出厂调试' : '正式投运' item.process = item.process == 2 ? '功能调试' : item.process == 3 ? '出厂调试' : '正式投运'
return item return item
}), // 数据源 // 过滤那个字段导出 }), // 数据源 // 过滤那个字段导出
columnFilterMethod: function (column: any) {
return !( columnFilterMethod: exportColumnFilterMethod
column.column.title === undefined ||
column.column.title === '序号' ||
column.column.title === '操作'
)
}
}) })
} }
onMounted(() => {})
setTimeout(() => { setTimeout(() => {
// tableStore.table.height = mainHeight(200).height as any // tableStore.table.height = mainHeight(200).height as any
}, 0) }, 0)
const addMenu = () => {} const addMenu = () => {}
</script> </script>
<style></style> <style></style>

View File

@@ -4,7 +4,6 @@
<div class="manage-process-right"> <div class="manage-process-right">
<div class="process-flow-section"> <div class="process-flow-section">
<el-descriptions title="数据链路"> <el-descriptions title="数据链路">
</el-descriptions> </el-descriptions>
<div class="process-flow-wrap"> <div class="process-flow-wrap">
<div class="process-flow"> <div class="process-flow">
@@ -44,18 +43,18 @@
<div class="process-list-section"> <div class="process-list-section">
<el-descriptions title="数据列表" /> <el-descriptions title="数据列表" />
<div class="process-list-body"> <div class="process-list-body">
<el-table :data="processTableData" border stripe height="100%"> <vxe-table :data="processTableData" v-bind="defaultAttribute" height="100%" auto-resize>
<el-table-column type="index" label="序号" width="60" align="center" /> <vxe-column type="seq" title="序号" width="60" />
<el-table-column prop="name" label="节点" min-width="100" align="center" /> <vxe-column field="name" title="节点" min-width="100" />
<el-table-column prop="link" label="上游链路" min-width="140" align="center" /> <vxe-column field="link" title="上游链路" min-width="140" />
<el-table-column prop="status" label="连接状态" min-width="100" align="center"> <vxe-column field="status" title="连接状态" min-width="100">
<template #default="{ row }"> <template #default="{ row }">
<span :class="`process-table-status process-table-status--${row.state}`"> <span :class="`process-table-status process-table-status--${row.state}`">
{{ row.status }} {{ row.status }}
</span> </span>
</template> </template>
</el-table-column> </vxe-column>
</el-table> </vxe-table>
</div> </div>
</div> </div>
</div> </div>
@@ -66,6 +65,7 @@ import { h, watch, onUnmounted, ref, computed, defineComponent } from 'vue'
import { Monitor, Coin } from '@element-plus/icons-vue' import { Monitor, Coin } from '@element-plus/icons-vue'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import DeviceTree from '@/components/tree/govern/deviceTree.vue' import DeviceTree from '@/components/tree/govern/deviceTree.vue'
import { defaultAttribute } from '@/components/table/defaultAttribute'
defineOptions({ defineOptions({
name: 'process' name: 'process'
@@ -74,7 +74,7 @@ defineOptions({
const pageHeight = mainHeight(20) const pageHeight = mainHeight(20)
/** 连接状态null-初始0-终端绿/终端↔前置1-前置绿/前置↔MQTT2-MQTT绿/MQTT↔数据库3-数据库绿/数据库↔Web4-全部完成 */ /** 连接状态null-初始0-终端绿/终端↔前置1-前置绿/前置↔MQTT2-MQTT绿/MQTT↔数据库3-数据库绿/数据库↔Web4-全部完成 */
const linkStatus = ref<number | null>(2) const linkStatus = ref<number | null>(0)
const COLOR = { const COLOR = {
pending: '#94a3b8', pending: '#94a3b8',

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader ref="tableHeaderRef" showExport> <TableHeader ref="tableHeaderRef" showExport showCustomColumn>
<template #select> <template #select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit v-model="tableStore.table.params.searchValue" clearable placeholder="请输入设备名称" <el-input maxlength="32" show-word-limit v-model="tableStore.table.params.searchValue" clearable placeholder="请输入设备名称"
@@ -84,7 +84,7 @@ const tableStore: any = new TableStore({
{ title: '协议版本', field: 'protocolVersion', minWidth: '100', formatter: (row: any) => { return row.cellValue || '/' } }, { title: '协议版本', field: 'protocolVersion', minWidth: '100', formatter: (row: any) => { return row.cellValue || '/' } },
{ title: '版本日期', field: 'versionDate', minWidth: '150', formatter: (row: any) => { return row.cellValue || '/' } }, { title: '版本日期', field: 'versionDate', minWidth: '150', formatter: (row: any) => { return row.cellValue || '/' } },
{ title: '设备型号', field: 'devModelName', minWidth: '120', formatter: (row: any) => { return row.cellValue || '/' } }, { title: '设备型号', field: 'devModelName', minWidth: '120', formatter: (row: any) => { return row.cellValue || '/' } },
{ title: 'icd模型', field: 'icd', minWidth: '120', formatter: (row: any) => { return icdList.value.filter((item: any) => item.id == row.cellValue)[0]?.name || '/' } }, { title: 'icd模型', field: 'icd', minWidth: '120', formatter: (row: any) => { return icdList.value?.filter((item: any) => item.id == row.cellValue)[0]?.name || '/' } },
{ title: '所属工程', field: 'associatedEngineering', minWidth: '120', formatter: (row: any) => { return row.cellValue || '/' } }, { title: '所属工程', field: 'associatedEngineering', minWidth: '120', formatter: (row: any) => { return row.cellValue || '/' } },
{ title: '所属项目', field: 'associatedProject', minWidth: '120', formatter: (row: any) => { return row.cellValue || '/' } }, { title: '所属项目', field: 'associatedProject', minWidth: '120', formatter: (row: any) => { return row.cellValue || '/' } },
{ {

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="view"> <div class="view">
<TableHeader datePicker ref="TableHeaderRef" :showReset="false" showExport> <TableHeader datePicker ref="TableHeaderRef" :showReset="false" showExport >
<template #operation> <template #operation>
<el-button type="primary" :icon="Setting" @click="recall1">事件补召</el-button> <el-button type="primary" :icon="Setting" @click="recall1">事件补召</el-button>
<el-button type="primary" :icon="Setting" @click="recall2">波形补召</el-button> <el-button type="primary" :icon="Setting" @click="recall2">波形补召</el-button>

View File

@@ -1,7 +1,7 @@
<!-- 补召日志 --> <!-- 补召日志 -->
<template> <template>
<TableHeader date-picker :showReset="false"> <TableHeader date-picker :showReset="false" showCustomColumn>
<template #operation> <template #operation>
<el-button type="primary" icon="el-icon-Connection" @click="handleImport"> <el-button type="primary" icon="el-icon-Connection" @click="handleImport">
离线补召 离线补召
@@ -160,7 +160,7 @@ const handleaddDevice = () => {
query: { query: {
activeName: '0', activeName: '0',
id: lineId.value, id: lineId.value,
ndid: deviceData.value?.ndid, ndid: (deviceData.value as any)?.ndid || '',
} }
}) })

View File

@@ -1,14 +1,24 @@
<template> <template>
<div class="default-main report-zl-page" :style="height"> <div class="default-main report-zl-page" :style="height">
<div class="report-zl-sidebar"> <div class="report-zl-sidebar">
<pointTree ref="terminalRef" template @Policy="stencil" @node-click="handleNodeClick" <pointTree
@init="handleNodeClick" @pointTypeChange="pointTypeChange" /> ref="terminalRef"
template
@Policy="stencil"
@node-click="handleNodeClick"
@init="handleNodeClick"
@pointTypeChange="pointTypeChange"
/>
</div> </div>
<el-tabs v-model="activeTab" type="border-card" class="report-zl-tabs"> <el-tabs v-model="activeTab" type="border-card" class="report-zl-tabs">
<el-tab-pane label="报表" name="sheet"> <el-tab-pane label="报表" name="sheet">
<Sheet :dot-list="dotList" :line-flag="lineFlag" :template-policy="templatePolicy" <Sheet
:active="activeTab === 'sheet'" /> :dot-list="dotList"
:line-flag="lineFlag"
:template-policy="templatePolicy"
:active="activeTab === 'sheet'"
/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="报告" name="report"> <el-tab-pane label="报告" name="report">
<Report :dot-list="dotList" :line-flag="lineFlag" /> <Report :dot-list="dotList" :line-flag="lineFlag" />
@@ -26,7 +36,7 @@ import Sheet from './components/sheet.vue'
import Report from './components/report.vue' import Report from './components/report.vue'
defineOptions({ defineOptions({
name: 'govern/reportCore/statisticsWx/index', name: 'govern/reportCore/statisticsWx/index'
}) })
const props = withDefaults( const props = withDefaults(
@@ -34,7 +44,7 @@ const props = withDefaults(
defaultTab?: 'sheet' | 'report' defaultTab?: 'sheet' | 'report'
}>(), }>(),
{ {
defaultTab: 'sheet', defaultTab: 'sheet'
} }
) )
@@ -54,7 +64,7 @@ const pointTypeChange = (_val: any, obj: any) => {
} }
const handleNodeClick = (data: any) => { const handleNodeClick = (data: any) => {
if (data.name.includes('治理监测点')) { if (data.name.includes('治理监测点') ) {
lineFlag.value = false lineFlag.value = false
return return
} }
@@ -78,16 +88,10 @@ const handleNodeClick = (data: any) => {
overflow: hidden; overflow: hidden;
} }
.report-zl-tabs { .report-zl-tabs {
flex: 1; flex: 1;
min-height: 0; min-height: 0;
.el-tab-pane { .el-tab-pane {
height: 100%; height: 100%;
display: flex; display: flex;

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="dictiontary-list-detail child-router"> <div class="dictiontary-list-detail child-router">
<TableHeader> <TableHeader showCustomColumn>
<template #select> <template #select>
<el-form-item label=""> <el-form-item label="">
<span class="text-large font-600 mr-3" style="font-weight: 600;">{{ props.bingRow.name <span class="text-large font-600 mr-3" style="font-weight: 600;">{{ props.bingRow.name
@@ -37,16 +37,23 @@ const tableStore = new TableStore({
url: '/cs-harmonic-boot/pqGovernPlan/getListByPid', url: '/cs-harmonic-boot/pqGovernPlan/getListByPid',
method: 'GET', method: 'GET',
column: [ column: [
{ title: '治理点名称', field: 'governName', width: 200 }, {
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '治理点名称', field: 'governName', minWidth: 200 },
{ {
title: '治理类型', title: '治理类型',
field: 'governType', field: 'governType',
width: 120, minWidth: 120,
formatter: row => { formatter: row => {
return row.cellValue == 'harmonic' ? '稳态治理' : '暂态治理' return row.cellValue == 'harmonic' ? '稳态治理' : '暂态治理'
} }
}, },
{ title: '治理方法', field: 'governMethod', width: 120 }, { title: '治理方法', field: 'governMethod', minWidth: 120 },
{ title: '治理前-监测点', field: 'ledgerBefore', minWidth: 200, formatter: row => row.cellValue || row.row?.governBefore || '/' }, { title: '治理前-监测点', field: 'ledgerBefore', minWidth: 200, formatter: row => row.cellValue || row.row?.governBefore || '/' },
{ title: '治理后-监测点', field: 'ledgerAfter', minWidth: 200, formatter: row => row.cellValue || row.row?.governAfter || '/' }, { title: '治理后-监测点', field: 'ledgerAfter', minWidth: 200, formatter: row => row.cellValue || row.row?.governAfter || '/' },

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main" style="position: relative"> <div class="default-main" style="position: relative">
<TableHeader :showReset="false" showExport> <TableHeader :showReset="false" showExport showCustomColumn>
<template #select> <template #select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit style="width: 240px" <el-input maxlength="32" show-word-limit style="width: 240px"

View File

@@ -2,7 +2,7 @@
<div class="default-main"> <div class="default-main">
<div class="default"> <div class="default">
<div style="width: calc(100% - 300px);"> <div style="width: calc(100% - 300px);">
<TableHeader> <TableHeader showCustomColumn>
<template v-slot:select> <template v-slot:select>
<el-form-item label="前置等级"> <el-form-item label="前置等级">
<el-select v-model="tableStore.table.params.nodeGrade" clearable placeholder="请选择前置等级"> <el-select v-model="tableStore.table.params.nodeGrade" clearable placeholder="请选择前置等级">

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader> <TableHeader showCustomColumn>
<template #select> <template #select>
<el-form-item label="设备类型"> <el-form-item label="设备类型">
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备类型" /> --> <!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备类型" /> -->
@@ -181,6 +181,13 @@ const tableStore = new TableStore({
url: '/cs-device-boot/EquipmentDelivery/list', url: '/cs-device-boot/EquipmentDelivery/list',
method: 'POST', method: 'POST',
column: [ column: [
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '设备名称', field: 'name' }, { title: '设备名称', field: 'name' },
{ {
title: '设备类型', title: '设备类型',

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader> <TableHeader showCustomColumn>
<template #select> <template #select>
<el-form-item label="设备类型"> <el-form-item label="设备类型">
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备类型" /> --> <!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备类型" /> -->
@@ -183,6 +183,13 @@ const tableStore = new TableStore({
url: '/cs-device-boot/EquipmentDelivery/list', url: '/cs-device-boot/EquipmentDelivery/list',
method: 'POST', method: 'POST',
column: [ column: [
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '设备名称', field: 'name' }, { title: '设备名称', field: 'name' },
{ {
title: '设备类型', title: '设备类型',

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader date-picker> <TableHeader date-picker showCustomColumn>
<template v-slot:select> <template v-slot:select>
<!-- <el-form-item label="用户名"> <!-- <el-form-item label="用户名">
<el-select v-model.trim="value" class="m-2" placeholder="Select" size="large"> <el-select v-model.trim="value" class="m-2" placeholder="Select" size="large">
@@ -29,18 +29,25 @@ import { saveLogParam } from '@/api/common'
defineOptions({ defineOptions({
name: 'comptroller/list' name: 'comptroller/list'
}) })
const tableStore = new TableStore({ const tableStore: any = new TableStore({
url: '/system-boot/audit/getAuditLog', url: '/system-boot/audit/getAuditLog',
method: 'POST', method: 'POST',
column: [ column: [
{ title: '操作时间', field: 'time', align: 'center', width: 200 , sortable: true}, {
{ title: '操作人员', field: 'userName', align: 'center', width: 120 }, title: '序号',
{ title: '操作类型', field: 'operate', align: 'center', width: 220 }, width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ title: '操作时间', field: 'time', align: 'center', minWidth: 200 , sortable: true},
{ title: '操作人员', field: 'userName', align: 'center', minWidth: 120 },
{ title: '操作类型', field: 'operate', align: 'center', minWidth: 220 },
{ title: '事件描述', field: 'describe', align: 'center', showOverflow: true, minWidth: 200 }, { title: '事件描述', field: 'describe', align: 'center', showOverflow: true, minWidth: 200 },
{ title: '事件类型', field: 'type', align: 'center', width: 160 }, { title: '事件类型', field: 'type', align: 'center', minWidth: 160 },
{ title: '操作结果', field: 'type', align: 'center', width: 100 }, { title: '操作结果', field: 'type', align: 'center', minWidth: 100 },
{ title: '操作IP', field: 'ip', align: 'center', width: 160 }, { title: '操作IP', field: 'ip', align: 'center', minWidth: 160 },
{ title: '事件等级', field: 'level', align: 'center', width: 100 } { title: '事件等级', field: 'level', align: 'center', minWidth: 100 }
] ]
}) })
tableStore.table.params.loginName = '' tableStore.table.params.loginName = ''

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader date-picker area> <TableHeader date-picker area showCustomColumn>
<template v-slot:select> <template v-slot:select>
<el-form-item label="终端状态"> <el-form-item label="终端状态">
@@ -47,7 +47,7 @@ defineOptions({
const dictData = useDictData() const dictData = useDictData()
const manufacturer = dictData.getBasicData('Dev_Manufacturers') const manufacturer = dictData.getBasicData('Dev_Manufacturers')
const manufacturerForm = ref<string[]>([]) const manufacturerForm = ref<string[]>([])
const tableStore = new TableStore({ const tableStore: any = new TableStore({
isWebPaging: true, isWebPaging: true,
url: '/device-boot/runManage/getRuntimeData', url: '/device-boot/runManage/getRuntimeData',
method: 'POST', method: 'POST',
@@ -57,23 +57,23 @@ const tableStore = new TableStore({
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1 return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
} }
}, },
{ title: '区域', field: 'areaName', align: 'center', width: 120 }, { title: '区域', field: 'areaName', align: 'center', minWidth: 120 },
{ title: '供电公司', field: 'gdName', align: 'center', width: 120 }, { title: '供电公司', field: 'gdName', align: 'center', minWidth: 120 },
{ title: '变电站', field: 'bdName', align: 'center', showOverflow: true, minWidth: 100 }, { title: '变电站', field: 'bdName', align: 'center', showOverflow: true, minWidth: 100 },
{ title: '终端编号', field: 'devName', align: 'center', width: 160 }, { title: '终端编号', field: 'devName', align: 'center', minWidth: 160 },
{ title: '投运时间', field: 'loginTime', align: 'center', width: 200 , sortable: true}, { title: '投运时间', field: 'loginTime', align: 'center', minWidth: 200 , sortable: true},
{ title: '厂家', field: 'manufacturer', align: 'center', width: 160 }, { title: '厂家', field: 'manufacturer', align: 'center', minWidth: 160 },
{ title: '型号', field: 'devType', align: 'center', width: 200 }, { title: '型号', field: 'devType', align: 'center', minWidth: 200 },
{ title: '网络参数', field: 'ip', align: 'center', width: 200 }, { title: '网络参数', field: 'ip', align: 'center', minWidth: 200 },
{ title: '端口', field: 'port', align: 'center', width: 100 }, { title: '端口', field: 'port', align: 'center', minWidth: 100 },
{ title: '终端状态', field: 'runFlag', align: 'center', width: 100 }, { title: '终端状态', field: 'runFlag', align: 'center', minWidth: 100 },
{ title: '通讯状态', field: 'comFlag', align: 'center', width: 100 }, { title: '通讯状态', field: 'comFlag', align: 'center', minWidth: 100 },
{ title: '最新数据', field: 'updateTime', align: 'center', width: 200, sortable: true }, { title: '最新数据', field: 'updateTime', align: 'center', minWidth: 200, sortable: true },
{ {
title: '评价', title: '评价',
field: 'onlineEvaluate', field: 'onlineEvaluate',
align: 'center', align: 'center',
width: 100, minWidth: 100,
render: 'customRender', render: 'customRender',
customRender: props => { customRender: props => {
if (props.renderValue == null) { if (props.renderValue == null) {

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader date-picker area> <TableHeader date-picker area showCustomColumn>
<template v-slot:select> <template v-slot:select>
<el-form-item label="干扰源类型"> <el-form-item label="干扰源类型">
<el-select multiple clearable collapse-tags v-model.trim="interferenceSourceForm" placeholder="请选择" <el-select multiple clearable collapse-tags v-model.trim="interferenceSourceForm" placeholder="请选择"
@@ -47,70 +47,77 @@ const interferenceSource = dictData.getBasicData('Interference_Source')
const level = dictData.getBasicData('Dev_Voltage_Stand') const level = dictData.getBasicData('Dev_Voltage_Stand')
const interferenceSourceForm = ref<string[]>([]) const interferenceSourceForm = ref<string[]>([])
const scaleForm = ref<string[]>([]) const scaleForm = ref<string[]>([])
const tableStore = new TableStore({ const tableStore: any = new TableStore({
isWebPaging: true, isWebPaging: true,
url: '/device-boot/runManage/getLineLedger', url: '/device-boot/runManage/getLineLedger',
method: 'POST', method: 'POST',
column: [ column: [
{ field: 'areaName', title: '省公司', width: 150 }, {
{ field: 'gdName', title: '市公司', width: 150 }, title: '序号',
{ field: 'scale', title: '监测点电压等级', width: 150 }, width: 80,
{ field: 'lineName', title: '监测点名称', width: 150 }, formatter: (row: any) => {
{ field: 'bdName', title: '所属变电站', width: 150 }, return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
{ field: 'loadType', title: '干扰源类型', width: 120 }, }
{ field: 'objName', title: '监测对象名称', width: 180 }, },
{ field: 'shortCapacity', title: '最小短路容量(MVA)', width: 190 }, { field: 'areaName', title: '省公司', minWidth: 150 },
{ field: 'devCapacity', title: '供电设备容量(MVA )', width: 190 }, { field: 'gdName', title: '市公司', minWidth: 150 },
{ field: 'dealCapacity', title: '用户协议容量(MVA)', width: 190 }, { field: 'scale', title: '监测点电压等级', minWidth: 150 },
{ field: 'comFlag', title: '通讯状态 ', width: 120 }, { field: 'lineName', title: '监测点名称', minWidth: 150 },
{ field: 'id', title: '监测点序号', width: 120 }, { field: 'bdName', title: '所属变电站', minWidth: 150 },
{ field: 'devName', title: '监测终端编号 ', width: 140 }, { field: 'loadType', title: '干扰源类型', minWidth: 120 },
{ field: 'ptType', title: '监测终端接线方式', width: 160 }, { field: 'objName', title: '监测对象名称', minWidth: 180 },
{ field: 'voltageDev', title: '电压偏差上限(%)', width: 160 }, { field: 'shortCapacity', title: '最小短路容量(MVA)', minWidth: 190 },
{ field: 'uvoltageDev', title: '电压偏差下限(%)', width: 160 }, { field: 'devCapacity', title: '供电设备容量(MVA )', minWidth: 190 },
{ field: 'dealCapacity', title: '用户协议容量(MVA)', minWidth: 190 },
{ field: 'comFlag', title: '通讯状态 ', minWidth: 120 },
{ field: 'id', title: '监测点序号', minWidth: 120 },
{ field: 'devName', title: '监测终端编号 ', minWidth: 140 },
{ field: 'ptType', title: '监测终端接线方式', minWidth: 160 },
{ field: 'voltageDev', title: '电压偏差上限(%)', minWidth: 160 },
{ field: 'uvoltageDev', title: '电压偏差下限(%)', minWidth: 160 },
{ {
field: 'limitValue', field: 'limitValue',
title: '限值', title: '限值',
children: [ children: [
{ field: 'freqDev', title: '频率(Hz)', width: 120 }, { field: 'freqDev', title: '频率(Hz)', minWidth: 120 },
{ field: 'ubalance', title: '三相电压不平衡度(%)', width: 190 }, { field: 'ubalance', title: '三相电压不平衡度(%)', minWidth: 190 },
{ field: 'ineg', title: '负序电流(A)', width: 120 }, { field: 'ineg', title: '负序电流(A)', minWidth: 120 },
{ field: 'flicker', title: '长时闪变', width: 120 }, { field: 'flicker', title: '长时闪变', minWidth: 120 },
{ field: 'uaberrance', title: '电压总谐波畸变率(%)', width: 190 }, { field: 'uaberrance', title: '电压总谐波畸变率(%)', minWidth: 190 },
{ field: 'oddHarm', title: '奇数次谐波电压(%)', width: 180 }, { field: 'oddHarm', title: '奇数次谐波电压(%)', minWidth: 180 },
{ field: 'evenHarm', title: '偶数次谐波电压(%)', width: 180 } { field: 'evenHarm', title: '偶数次谐波电压(%)', minWidth: 180 }
] ]
}, },
{ {
field: 'evaluate', field: 'evaluate',
title: '电流限值', title: '电流限值',
children: [ children: [
{ field: 'iharm2', title: '2次谐波(A)', width: 120 }, { field: 'iharm2', title: '2次谐波(A)', minWidth: 120 },
{ field: 'iharm3', title: '3次谐波(A)', width: 120 }, { field: 'iharm3', title: '3次谐波(A)', minWidth: 120 },
{ field: 'iharm4', title: '4次谐波(A)', width: 120 }, { field: 'iharm4', title: '4次谐波(A)', minWidth: 120 },
{ field: 'iharm5', title: '5次谐波(A)', width: 120 }, { field: 'iharm5', title: '5次谐波(A)', minWidth: 120 },
{ field: 'iharm6', title: '6次谐波(A)', width: 120 }, { field: 'iharm6', title: '6次谐波(A)', minWidth: 120 },
{ field: 'iharm7', title: '7次谐波(A)', width: 120 }, { field: 'iharm7', title: '7次谐波(A)', minWidth: 120 },
{ field: 'iharm8', title: '8次谐波(A)', width: 120 }, { field: 'iharm8', title: '8次谐波(A)', minWidth: 120 },
{ field: 'iharm9', title: '9次谐波(A)', width: 120 }, { field: 'iharm9', title: '9次谐波(A)', minWidth: 120 },
{ field: 'iharm10', title: '10次谐波(A)', width: 140 }, { field: 'iharm10', title: '10次谐波(A)', minWidth: 140 },
{ field: 'iharm11', title: '11次谐波(A)', width: 140 }, { field: 'iharm11', title: '11次谐波(A)', minWidth: 140 },
{ field: 'iharm12', title: '12次谐波(A)', width: 140 }, { field: 'iharm12', title: '12次谐波(A)', minWidth: 140 },
{ field: 'iharm13', title: '13次谐波(A)', width: 140 }, { field: 'iharm13', title: '13次谐波(A)', minWidth: 140 },
{ field: 'iharm14', title: '14次谐波(A)', width: 140 }, { field: 'iharm14', title: '14次谐波(A)', minWidth: 140 },
{ field: 'iharm15', title: '15次谐波(A)', width: 140 }, { field: 'iharm15', title: '15次谐波(A)', minWidth: 140 },
{ field: 'iharm16', title: '16次谐波(A)', width: 140 }, { field: 'iharm16', title: '16次谐波(A)', minWidth: 140 },
{ field: 'iharm17', title: '17次谐波(A)', width: 140 }, { field: 'iharm17', title: '17次谐波(A)', minWidth: 140 },
{ field: 'iharm18', title: '18次谐波(A)', width: 140 }, { field: 'iharm18', title: '18次谐波(A)', minWidth: 140 },
{ field: 'iharm19', title: '19次谐波(A)', width: 140 }, { field: 'iharm19', title: '19次谐波(A)', minWidth: 140 },
{ field: 'iharm10', title: '20次谐波(A)', width: 140 }, { field: 'iharm10', title: '20次谐波(A)', minWidth: 140 },
{ field: 'iharm21', title: '21次谐波(A)', width: 140 }, { field: 'iharm21', title: '21次谐波(A)', minWidth: 140 },
{ field: 'iharm22', title: '22次谐波(A)', width: 140 }, { field: 'iharm22', title: '22次谐波(A)', minWidth: 140 },
{ field: 'iharm23', title: '23次谐波(A)', width: 140 }, { field: 'iharm23', title: '23次谐波(A)', minWidth: 140 },
{ field: 'iharm24', title: '24次谐波(A)', width: 140 }, { field: 'iharm24', title: '24次谐波(A)', minWidth: 140 },
{ field: 'iharm25', title: '25次谐波(A)', width: 140 }, { field: 'iharm25', title: '25次谐波(A)', minWidth: 140 },
{ field: 'inUharm', title: '0.5-1.5次间谐波(A)', width: 180 }, { field: 'inUharm', title: '0.5-1.5次间谐波(A)', minWidth: 180 },
{ field: 'inUharm16', title: '2.5-15.5次间谐波(A)', width: 190 } { field: 'inUharm16', title: '2.5-15.5次间谐波(A)', minWidth: 190 }
] ]
} }
], ],

View File

@@ -4,23 +4,40 @@
<!-- 实时数据 走驾驶舱--> <!-- 实时数据 走驾驶舱-->
<!-- 添加加载事件监听 --> <!-- 添加加载事件监听 -->
<div class="dataBox" :style="{ height: prop.height ? prop.height : pageHeight.height }"> <div class="dataBox" :style="{ height: prop.height ? prop.height : pageHeight.height }">
<div class="iframe-container" :style="{ <div
class="iframe-container"
:style="{
boxShadow: `var(--el-box-shadow-light)` boxShadow: `var(--el-box-shadow-light)`
}" style="position: relative"> }"
<iframe v-if="bindId" :key="bindId" :src="iframeSrc" width="100%" height="100%" frameborder="0" style="position: relative"
scrolling="no" id="iframeLeft" @load="onIframeLoad"></iframe> >
<iframe
v-if="bindId"
:key="bindId"
:src="iframeSrc"
width="100%"
height="100%"
frameborder="0"
scrolling="no"
id="iframeLeft"
@load="onIframeLoad"
></iframe>
<el-empty v-else description="暂无绑定页面" style="height: 100%" /> <el-empty v-else description="暂无绑定页面" style="height: 100%" />
</div> </div>
</div> </div>
<div class="bottom-container"> <div class="bottom-container">
<el-button type="primary" :icon="show ? 'el-icon-ArrowDownBold' : 'el-icon-ArrowUpBold'" <el-button
@click="show = !show" style="width: 100%" > type="primary"
:icon="show ? 'el-icon-ArrowDownBold' : 'el-icon-ArrowUpBold'"
@click="show = !show"
style="width: 100%"
>
事件列表 事件列表
</el-button> </el-button>
<!-- <el-button class="bindBut" type="primary" icon="el-icon-Sort" @click="bindClick">绑定</el-button> --> <!-- <el-button class="bindBut" type="primary" icon="el-icon-Sort" @click="bindClick">绑定</el-button> -->
<el-icon class="bindBut"> <el-icon class="bindBut">
<Sort style="width: 30px;height: 30px;" color="#fff" @click="bindClick" /> <Sort style="width: 30px; height: 30px" color="#fff" @click="bindClick" />
</el-icon> </el-icon>
<!-- <div class="buttonBox"> <!-- <div class="buttonBox">
<el-button type="primary" icon="el-icon-Aim" @click="reset">复位</el-button> <el-button type="primary" icon="el-icon-Aim" @click="reset">复位</el-button>
@@ -28,7 +45,14 @@
<transition name="table-fade"> <transition name="table-fade">
<div class="tableBox" v-if="show"> <div class="tableBox" v-if="show">
<vxe-table border auto-resize height="230px" :data="tableData" ref="tableRef"> <vxe-table
border
auto-resize
height="230px"
:data="tableData"
ref="tableRef"
v-bind="defaultAttribute"
>
<vxe-column type="seq" title="序号" align="center" width="80px"></vxe-column> <vxe-column type="seq" title="序号" align="center" width="80px"></vxe-column>
<vxe-column field="date" align="center" sortable title="发生时间" width="200px"></vxe-column> <vxe-column field="date" align="center" sortable title="发生时间" width="200px"></vxe-column>
<vxe-column field="name" align="center" title="监测点名称" width="200px"></vxe-column> <vxe-column field="name" align="center" title="监测点名称" width="200px"></vxe-column>
@@ -46,6 +70,7 @@ import { ref, watch, onMounted, onUnmounted, provide } from 'vue'
import Table from '@/components/table/index.vue' import Table from '@/components/table/index.vue'
import TableStore from '@/utils/tableStore' import TableStore from '@/utils/tableStore'
import { mainHeight } from '@/utils/layout' import { mainHeight } from '@/utils/layout'
import { defaultAttribute } from '@/components/table/defaultAttribute'
import { Sort } from '@element-plus/icons-vue' import { Sort } from '@element-plus/icons-vue'
import { useAdminInfo } from '@/stores/adminInfo' import { useAdminInfo } from '@/stores/adminInfo'
import { audit, add, coFqueryPage, getByUserId } from '@/api/cs-harmonic-boot/mxgraph' import { audit, add, coFqueryPage, getByUserId } from '@/api/cs-harmonic-boot/mxgraph'
@@ -159,7 +184,6 @@ const info = async () => {
pageSize: 1000 pageSize: 1000
}).then(res => { }).then(res => {
bindId.value = res.data.records.filter(item => item.scope == 1)[0]?.id || null bindId.value = res.data.records.filter(item => item.scope == 1)[0]?.id || null
}) })
}) })
await setTimeout(() => { await setTimeout(() => {

View File

@@ -15,7 +15,7 @@
<el-button type="primary" @click="onSubmitadd" icon="el-icon-Plus">新增</el-button> <el-button type="primary" @click="onSubmitadd" icon="el-icon-Plus">新增</el-button>
</template> </template>
</TableHeader> </TableHeader>
<!-- <Table ref="tableRef" /> -->
<div <div
style="overflow-x: hidden; overflow-y: scroll; padding: 0 10px" style="overflow-x: hidden; overflow-y: scroll; padding: 0 10px"
v-loading="tableStore.table.loading" v-loading="tableStore.table.loading"

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="dictiontary-list-detail child-router"> <div class="dictiontary-list-detail child-router">
<TableHeader> <TableHeader showCustomColumn>
<template #select> <template #select>
<el-form-item label=""> <el-form-item label="">
<!-- <el-page-header @back="$emit('close')"> <!-- <el-page-header @back="$emit('close')">

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main" style="position: relative"> <div class="default-main" style="position: relative">
<TableHeader> <TableHeader showCustomColumn>
<template #select> <template #select>
<el-form-item label="关键字筛选"> <el-form-item label="关键字筛选">
<el-input maxlength="32" show-word-limit style="width: 240px" <el-input maxlength="32" show-word-limit style="width: 240px"
@@ -32,7 +32,7 @@ defineOptions({
}) })
const popupEditRef = ref() const popupEditRef = ref()
const detail = ref<anyObj | null>(null) const detail = ref<anyObj | null>(null)
const tableStore = new TableStore({ const tableStore: any = new TableStore({
url: '/system-boot/dictType/list', url: '/system-boot/dictType/list',
method: 'POST', method: 'POST',
column: [ column: [

View File

@@ -1,10 +1,11 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader :showReset="false"> <TableHeader :showReset="false" showCustomColumn>
<template #select> <template #select>
<el-radio-group v-model.trim="tableStore.table.params.versionType" @change="tableStore.index()"> <el-radio-group v-model.trim="tableStore.table.params.versionType" @change="tableStore.index()">
<el-radio-button label="web" value="WEB" /> <el-radio-button label="web" value="WEB" />
<el-radio-button label="app" value="APP" /> <el-radio-button label="app" value="APP" />
</el-radio-group> </el-radio-group>
</template> </template>
<template #operation> <template #operation>
@@ -13,20 +14,38 @@
</TableHeader> </TableHeader>
<Table ref="tableRef"> <Table ref="tableRef">
<template v-slot:columns> <template v-slot:columns>
<vxe-column field="androidPath" title="Android路径" minWidth="250px" <vxe-column
v-if="tableStore.table.params.versionType == 'APP'"></vxe-column> field="androidPath"
<vxe-column field="iosPath" title="IOS路径" minWidth="250px" title="Android路径"
v-if="tableStore.table.params.versionType == 'APP'"></vxe-column> minWidth="250px"
v-if="tableStore.table.params.versionType == 'APP'"
></vxe-column>
<vxe-column
field="iosPath"
title="IOS路径"
minWidth="250px"
v-if="tableStore.table.params.versionType == 'APP'"
></vxe-column>
</template> </template>
</Table> </Table>
<el-dialog width="500px" v-model.trim="dialogVisible" :title="dialogTitle"> <el-dialog width="500px" v-model.trim="dialogVisible" :title="dialogTitle">
<el-form :inline="false" :model="form" ref="formRef" label-width="auto" class="form-one" :rules="rules"> <el-form :inline="false" :model="form" ref="formRef" label-width="auto" class="form-one" :rules="rules">
<el-form-item label="版本号" prop="appVersion"> <el-form-item label="版本号" prop="appVersion">
<el-input maxlength="32" show-word-limit v-model.trim="form.appVersion" placeholder="请输入版本号" /> <el-input
maxlength="32"
show-word-limit
v-model.trim="form.appVersion"
placeholder="请输入版本号"
/>
</el-form-item> </el-form-item>
<el-form-item label="整改内容"> <el-form-item label="整改内容">
<el-input show-word-limit maxlength="300" type="textarea" v-model.trim="form.content" <el-input
placeholder="请输入整改内容" /> show-word-limit
maxlength="300"
type="textarea"
v-model.trim="form.content"
placeholder="请输入整改内容"
/>
</el-form-item> </el-form-item>
<el-form-item label="发布类型"> <el-form-item label="发布类型">
<el-select v-model.trim="form.sev" placeholder="请选择发布类型"> <el-select v-model.trim="form.sev" placeholder="请选择发布类型">
@@ -83,7 +102,7 @@ const rules = {
iosPath: [{ required: true, message: '请输入IOS路径', trigger: 'blur' }] iosPath: [{ required: true, message: '请输入IOS路径', trigger: 'blur' }]
} }
const formRef = ref() const formRef = ref()
const tableStore = new TableStore({ const tableStore: any = new TableStore({
url: '/cs-system-boot/appVersion/getAllData', url: '/cs-system-boot/appVersion/getAllData',
method: 'POST', method: 'POST',
showPage: false, showPage: false,
@@ -123,7 +142,7 @@ const tableStore = new TableStore({
click: row => { click: row => {
editMenu(row) editMenu(row)
} }
}, }
// { // {
// name: 'del', // name: 'del',
// title: '删除', // title: '删除',
@@ -201,3 +220,7 @@ const editMenu = (row: any) => {
form.value.iosPath = row.iosPath || '' form.value.iosPath = row.iosPath || ''
} }
</script> </script>
<style scoped lang="scss">
</style>

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<div v-show="show && lookShow"> <div v-show="show && lookShow">
<TableHeader ref="TableHeaderRef"> <TableHeader ref="TableHeaderRef" showCustomColumn>
<template #operation> <template #operation>
<el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button> <el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button>
</template> </template>
@@ -39,6 +39,13 @@ const tableStore: any = new TableStore({
method: 'POST', method: 'POST',
isWebPaging: true, isWebPaging: true,
column: [ column: [
{
title: '序号',
width: 80,
formatter: (row: any) => {
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
}
},
{ field: 'name', title: '模板名称' }, { field: 'name', title: '模板名称' },
{ field: 'createBy', title: '创建用户' }, { field: 'createBy', title: '创建用户' },
{ field: 'updateBy', title: '更新用户' }, { field: 'updateBy', title: '更新用户' },

View File

@@ -105,12 +105,12 @@ const tableStore: any = new TableStore({
onChangeField: (row: any, value: any) => { onChangeField: (row: any, value: any) => {
if (row.jobStatus == 1) { if (row.jobStatus == 1) {
stop({ id: row.id }).then(res => { stop({ id: row.id }).then(res => {
ElMessage.success(res.message) ElMessage.success((res as any).message)
tableStore.index() tableStore.index()
}) })
} else { } else {
start({ id: row.id }).then(res => { start({ id: row.id }).then(res => {
ElMessage.success(res.message) ElMessage.success((res as any).message)
tableStore.index() tableStore.index()
}) })
} }

View File

@@ -1,6 +1,6 @@
<template> <template>
<div class="default-main"> <div class="default-main">
<TableHeader select ref="TableHeaderRef"> <TableHeader select ref="TableHeaderRef" showCustomColumn>
<template #operation> <template #operation>
<el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button> <el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button>
</template> </template>

View File

@@ -2,7 +2,7 @@
"compilerOptions": { "compilerOptions": {
"target": "esnext", "target": "esnext",
"useDefineForClassFields": true, "useDefineForClassFields": true,
"suppressImplicitAnyIndexErrors": true, // "suppressImplicitAnyIndexErrors": true,
"module": "esnext", "module": "esnext",
"moduleResolution": "node", "moduleResolution": "node",
"removeComments": false, "removeComments": false,

1
types/table.d.ts vendored
View File

@@ -7,6 +7,7 @@ import { Mutable } from 'element-plus/es/utils'
declare global { declare global {
interface CnTable { interface CnTable {
ref: VxeTableInstance | null ref: VxeTableInstance | null
customColumnInHeader: boolean
data: TableRow[] | any data: TableRow[] | any
allData: TableRow[] | any allData: TableRow[] | any
copyData: TableRow[] | any copyData: TableRow[] | any

View File

@@ -26,8 +26,8 @@ export default defineConfig({
// target: 'http://192.168.1.24:10215', // // target: 'http://192.168.1.24:10215', //
// target: 'http://192.168.1.122:10215', //gfh // target: 'http://192.168.1.122:10215', //gfh
// target: 'http://192.168.1.127:10215', //cdf // target: 'http://192.168.1.127:10215', //cdf
// target: 'http://192.168.1.125:10215',
target: 'http://192.168.1.103:10215', target: 'http://192.168.1.103:10215',
// target: 'http://pqmcn.com:27707/api',
// target: 'https://pqmcn.com:8092/api', //治理 // target: 'https://pqmcn.com:8092/api', //治理
// target:'http://www.zhilitest.com:8089/api', // target:'http://www.zhilitest.com:8089/api',
changeOrigin: true, changeOrigin: true,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long