Compare commits
50 Commits
2026-01
...
cd2be0f4aa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd2be0f4aa | ||
|
|
855c569535 | ||
| 6a84d28101 | |||
|
|
1a69be62a0 | ||
|
|
02caca969e | ||
|
|
3f1af5e4cc | ||
|
|
88e9812d5f | ||
|
|
83a827ba5b | ||
| 40b1092718 | |||
|
|
83a1128884 | ||
| 1a44a2f9e0 | |||
|
|
5044c88946 | ||
|
|
51a862ed00 | ||
|
|
1ca8e536dd | ||
|
|
2445cfbff3 | ||
|
|
21ac0611cd | ||
|
|
ff841cfa93 | ||
|
|
01cc29c8b2 | ||
|
|
a324f7afcf | ||
|
|
4272f7756e | ||
|
|
070e404bbb | ||
| ed60e2b7f3 | |||
| 7785d4f708 | |||
| 0c64711dd8 | |||
|
|
d85dba8bf8 | ||
|
|
56b8158f4a | ||
| 765507398e | |||
| 9224ea17b8 | |||
| dc08f7d1ac | |||
| 1652b5faf8 | |||
|
|
fae2a7d735 | ||
|
|
bf3a99cbf3 | ||
|
|
2e7c0b7f44 | ||
|
|
98e0f9de02 | ||
|
|
21756e05d4 | ||
|
|
abfdf29a38 | ||
|
|
120892808b | ||
|
|
0f5cb1d3c5 | ||
| dbaa42ff7e | |||
|
|
48472bdb85 | ||
|
|
fafc5f82c4 | ||
| 93ee7e4034 | |||
|
|
7d2ce51510 | ||
|
|
9202da17f1 | ||
|
|
30eddd0572 | ||
|
|
15bd1ac6d2 | ||
|
|
f5c76c1b7a | ||
|
|
b25515b5db | ||
|
|
bfa061fb03 | ||
|
|
15e3d4aec8 |
6
.env.LN
Normal file
6
.env.LN
Normal file
@@ -0,0 +1,6 @@
|
||||
# 辽宁嵌入
|
||||
NODE_ENV = LN
|
||||
VITE_NAME="LN"
|
||||
# 电网一张图 地图图层
|
||||
VITE_NARIMAP=null
|
||||
VITE_NRGISCOMMON=null
|
||||
6
.env.LNqr
Normal file
6
.env.LNqr
Normal file
@@ -0,0 +1,6 @@
|
||||
# 辽宁嵌入
|
||||
NODE_ENV = LNqr
|
||||
VITE_NAME="LNqr"
|
||||
# 电网一张图 地图图层
|
||||
VITE_NARIMAP=null
|
||||
VITE_NRGISCOMMON=null
|
||||
156
README.md
156
README.md
@@ -1,78 +1,78 @@
|
||||
#### 介绍
|
||||
|
||||
```
|
||||
Vue 3 + TypeScript + Vite这个模板可以帮助您开始使用Vue 3和TypeScript在Vite中进行开发。该模板使用了Vue 3的<script setup>单文件组件,请查看script setup文档了解更多信息。
|
||||
```
|
||||
|
||||
#### 安装依赖&运行项目
|
||||
|
||||
> node version:^18.17.0 || >=20.5.0"
|
||||
|
||||
```shell
|
||||
#项目使用pnpm包管理器
|
||||
npm i pnpm -g
|
||||
|
||||
#安装依赖
|
||||
pnpm i
|
||||
|
||||
#运行项目
|
||||
npm run dev
|
||||
|
||||
#冀北现场启动命令 区分是否加载现场电网一张图内网api
|
||||
npm run dev:jibei
|
||||
|
||||
#去除后台所有模块名 如除/xxxx-boot
|
||||
npm run dev:removeMode
|
||||
|
||||
|
||||
|
||||
#因海南和冀北技术监督不同 通过修改文件的方式来区分
|
||||
#海南打包 需要吧pqs目录下supervise_hn 文件夹改成supervise 原文件改成supervise_jb
|
||||
#冀北打包 需要吧pqs目录下supervise_jb 文件夹改成supervise 原文件改成supervise_hn
|
||||
```
|
||||
|
||||
#### 页面编写-示例
|
||||
|
||||
```
|
||||
基础页面写法请查看`src/template`下的readme.md
|
||||
```
|
||||
|
||||
#### 开发规范
|
||||
|
||||
> 初衷:养成合理的习惯,精力留在技术调研、业务开发中。
|
||||
>
|
||||
> 常见点如下描述,更多的规范待前端开发人员有时间后,慢慢丰富。
|
||||
|
||||
- 命名风格:所有的包(文件夹)、文件名以小驼峰的风格命名,比如 xxxAaa,禁止 XxxAaa 或者 xxx-aaa。
|
||||
- 命名语义:禁止中文命名或拼音,英文命名借用下工具,稍微准确一点,不要与实际业务相差太远。
|
||||
- 功能组件创建风格:以**功能名称**命名文件夹,每个功能下以**index.vue**作为该功能的组件入口。正确示例参考:/src/views/auth/menu/index.vue。
|
||||
|
||||

|
||||
|
||||
- todo...:待后续补充。
|
||||
|
||||
#### 开发助手
|
||||
|
||||
##### 1、表格系列
|
||||
|
||||
- 页面表格以及表格页面按钮的弹出等功能参考:/views/pqs/voltageSags/sagGovern/index.vue
|
||||
- 表格中需要替换数据:
|
||||
|
||||
```js
|
||||
// 通过formatter函数返回实际需要返回的值
|
||||
{
|
||||
title: '数据来源', field: 'dataSource', minWidth: '130',
|
||||
formatter: (row: any) => {
|
||||
return row.dataSource == 0 ? '离线导入' : '监测点同步'
|
||||
}
|
||||
}****
|
||||
```
|
||||
|
||||
##### 2、样式系列
|
||||
|
||||
- 获取当前主体的高度:import { mainHeight } from '@/utils/layout'
|
||||
- 弹框内输入框长度设置 1 行 1 个 class="form-one" 1 行 2 个 class="form-two"
|
||||
|
||||
#### 依赖变更记录
|
||||
|
||||
- 2024-04-25 新增 vform3,by 洪圣文,用于页面表单设计保存为 json,命令:pnpm i vform3-builds
|
||||
#### 介绍
|
||||
|
||||
```
|
||||
Vue 3 + TypeScript + Vite这个模板可以帮助您开始使用Vue 3和TypeScript在Vite中进行开发。该模板使用了Vue 3的<script setup>单文件组件,请查看script setup文档了解更多信息。
|
||||
```
|
||||
|
||||
#### 安装依赖&运行项目
|
||||
|
||||
> node version:^18.17.0 || >=20.5.0"
|
||||
|
||||
```shell
|
||||
#项目使用pnpm包管理器
|
||||
npm i pnpm -g
|
||||
|
||||
#安装依赖
|
||||
pnpm i
|
||||
|
||||
#运行项目
|
||||
npm run dev
|
||||
|
||||
#jb现场启动命令 区分是否加载现场电网一张图内网api
|
||||
npm run dev:jibei
|
||||
|
||||
#去除后台所有模块名 如除/xxxx-boot
|
||||
npm run dev:removeMode
|
||||
|
||||
|
||||
|
||||
#因海南和jb技术监督不同 通过修改文件的方式来区分
|
||||
#海南打包 需要吧pqs目录下supervise_hn 文件夹改成supervise 原文件改成supervise_jb
|
||||
#jb打包 需要吧pqs目录下supervise_jb 文件夹改成supervise 原文件改成supervise_hn
|
||||
```
|
||||
|
||||
#### 页面编写-示例
|
||||
|
||||
```
|
||||
基础页面写法请查看`src/template`下的readme.md
|
||||
```
|
||||
|
||||
#### 开发规范
|
||||
|
||||
> 初衷:养成合理的习惯,精力留在技术调研、业务开发中。
|
||||
>
|
||||
> 常见点如下描述,更多的规范待前端开发人员有时间后,慢慢丰富。
|
||||
|
||||
- 命名风格:所有的包(文件夹)、文件名以小驼峰的风格命名,比如 xxxAaa,禁止 XxxAaa 或者 xxx-aaa。
|
||||
- 命名语义:禁止中文命名或拼音,英文命名借用下工具,稍微准确一点,不要与实际业务相差太远。
|
||||
- 功能组件创建风格:以**功能名称**命名文件夹,每个功能下以**index.vue**作为该功能的组件入口。正确示例参考:/src/views/auth/menu/index.vue。
|
||||
|
||||

|
||||
|
||||
- todo...:待后续补充。
|
||||
|
||||
#### 开发助手
|
||||
|
||||
##### 1、表格系列
|
||||
|
||||
- 页面表格以及表格页面按钮的弹出等功能参考:/views/pqs/voltageSags/sagGovern/index.vue
|
||||
- 表格中需要替换数据:
|
||||
|
||||
```js
|
||||
// 通过formatter函数返回实际需要返回的值
|
||||
{
|
||||
title: '数据来源', field: 'dataSource', minWidth: '130',
|
||||
formatter: (row: any) => {
|
||||
return row.dataSource == 0 ? '离线导入' : '监测点同步'
|
||||
}
|
||||
}****
|
||||
```
|
||||
|
||||
##### 2、样式系列
|
||||
|
||||
- 获取当前主体的高度:import { mainHeight } from '@/utils/layout'
|
||||
- 弹框内输入框长度设置 1 行 1 个 class="form-one" 1 行 2 个 class="form-two"
|
||||
|
||||
#### 依赖变更记录
|
||||
|
||||
- 2024-04-25 新增 vform3,by 洪圣文,用于页面表单设计保存为 json,命令:pnpm i vform3-builds
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<script src="/static/luckysheet/plugin.js"></script>
|
||||
<script src="/static/luckysheet/luckysheet.umd.js"></script>
|
||||
|
||||
<!-- 冀北地图 -->
|
||||
<!-- jb地图 -->
|
||||
<!--引入样式文件-->
|
||||
<script src="%VITE_NARIMAP%"></script>
|
||||
<!-- <script src="%VITE_NRGISCOMMON%"></script> -->
|
||||
|
||||
8813
package-lock.json
generated
8813
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
207
package.json
207
package.json
@@ -1,103 +1,108 @@
|
||||
{
|
||||
"name": "canneng-admin",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --mode dev",
|
||||
"dev:jibei": "vite --mode jibei",
|
||||
"dev:hainan": "vite --mode hainan",
|
||||
"dev:qujing": "vite --mode qujing",
|
||||
"dev:removeMode": "vite --mode removeMode",
|
||||
"build": "vite build --mode dev",
|
||||
"build:jibei": "vite build --mode jibei",
|
||||
"build:hainan": "vite build --mode hainan",
|
||||
"build:qujing": "vite build --mode qujing",
|
||||
"build:removeMode": "vite build --mode removeMode",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "^7.0.2",
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@form-create/designer": "^3.1.3",
|
||||
"@form-create/element-ui": "^3.1.24",
|
||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
||||
"@kjgl77/datav-vue3": "^1.7.4",
|
||||
"@vue-office/docx": "^1.6.3",
|
||||
"@vue-office/excel": "^1.7.8",
|
||||
"@vue-office/pdf": "^2.0.2",
|
||||
"@vueuse/core": "^10.7.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"@wangeditor/plugin-formula": "^1.0.11",
|
||||
"axios": "^1.6.2",
|
||||
"bpmn-js": "8.9.0",
|
||||
"bpmn-js-properties-panel": "0.46.0",
|
||||
"bpmn-js-token-simulation": "^0.10.0",
|
||||
"bpmn-moddle": "^6.0.0",
|
||||
"camunda-bpmn-moddle": "^7.0.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"diagram-js": "^11.4.1",
|
||||
"diagram-js-minimap": "^2.0.4",
|
||||
"echarts": "^5.4.3",
|
||||
"echarts-gl": "^2.0.9",
|
||||
"echarts-liquidfill": "^3.1.0",
|
||||
"echarts4": "npm:echarts@^4.9.0",
|
||||
"element-plus": "^2.9.11",
|
||||
"exceljs": "^4.4.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"grid-layout-plus": "^1.1.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"jquery": "^3.7.1",
|
||||
"js-pinyin": "^0.2.5",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"katex": "^0.16.11",
|
||||
"less": "^4.2.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"luckyexcel": "^1.0.1",
|
||||
"luckysheet": "^2.1.13",
|
||||
"mathjax": "^3.2.2",
|
||||
"min-dash": "^4.2.1",
|
||||
"mitt": "^3.0.1",
|
||||
"mqtt": "^5.13.3",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"qs": "^6.12.0",
|
||||
"screenfull": "^6.0.2",
|
||||
"splitpanes": "^3.1.5",
|
||||
"steady-xml": "0.1.0",
|
||||
"svg-pan-zoom": "^3.6.2",
|
||||
"use-element-plus-theme": "^0.0.5",
|
||||
"vexip-ui": "^2.3.28",
|
||||
"vue": "^3.3.11",
|
||||
"vue-baidu-map-3x": "^1.0.35",
|
||||
"vue-baidu-map-offline": "^1.0.7",
|
||||
"vue-demi": "^0.14.8",
|
||||
"vue-draggable-resizable": "3.0.0-beta.2",
|
||||
"vue-i18n": "9.10.2",
|
||||
"vue-katex": "^0.5.0",
|
||||
"vue-router": "4",
|
||||
"vue-types": "^5.1.1",
|
||||
"vxe-table": "^4.5.17",
|
||||
"vxe-table-plugin-export-xlsx": "^4.0.1",
|
||||
"web-storage-cache": "^1.1.1",
|
||||
"xe-utils": "^3.5.14",
|
||||
"yarn": "^1.22.22"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@purge-icons/generated": "^0.9.0",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^20.10.5",
|
||||
"@types/splitpanes": "^2.2.6",
|
||||
"@vitejs/plugin-vue": "^4.5.2",
|
||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||
"sass": "^1.69.5",
|
||||
"typescript": "^5.2.2",
|
||||
"unplugin-auto-import": "^0.16.7",
|
||||
"vite": "^5.0.8",
|
||||
"vite-plugin-mkcert": "^1.17.3",
|
||||
"vue-tsc": "^1.8.25"
|
||||
}
|
||||
"name": "canneng-admin",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --mode dev",
|
||||
"dev:jibei": "vite --mode jibei",
|
||||
"dev:hainan": "vite --mode hainan",
|
||||
"dev:qujing": "vite --mode qujing",
|
||||
"dev:LN": "vite --mode LN",
|
||||
"dev:LNqr": "vite --mode LNqr",
|
||||
"dev:removeMode": "vite --mode removeMode",
|
||||
"build": "vite build --mode dev",
|
||||
"build:jibei": "vite build --mode jibei",
|
||||
"build:hainan": "vite build --mode hainan",
|
||||
"build:qujing": "vite build --mode qujing",
|
||||
"build:LN": "vite build --mode LN",
|
||||
"build:LNqr": "vite build --mode LNqr",
|
||||
"build:removeMode": "vite build --mode removeMode",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "^7.0.2",
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@form-create/designer": "^3.1.3",
|
||||
"@form-create/element-ui": "^3.1.24",
|
||||
"@fortawesome/fontawesome-free": "^6.5.1",
|
||||
"@kjgl77/datav-vue3": "^1.7.4",
|
||||
"@vue-office/docx": "^1.6.3",
|
||||
"@vue-office/excel": "^1.7.8",
|
||||
"@vue-office/pdf": "^2.0.2",
|
||||
"@vueuse/core": "^10.7.0",
|
||||
"@wangeditor/editor": "^5.1.23",
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"@wangeditor/plugin-formula": "^1.0.11",
|
||||
"axios": "^1.6.2",
|
||||
"bpmn-js": "8.9.0",
|
||||
"bpmn-js-properties-panel": "0.46.0",
|
||||
"bpmn-js-token-simulation": "^0.10.0",
|
||||
"bpmn-moddle": "^6.0.0",
|
||||
"camunda-bpmn-moddle": "^7.0.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.10",
|
||||
"diagram-js": "^11.4.1",
|
||||
"diagram-js-minimap": "^2.0.4",
|
||||
"echarts": "^5.4.3",
|
||||
"echarts-gl": "^2.0.9",
|
||||
"echarts-liquidfill": "^3.1.0",
|
||||
"echarts4": "npm:echarts@^4.9.0",
|
||||
"element-plus": "^2.9.11",
|
||||
"exceljs": "^4.4.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"grid-layout-plus": "^1.1.0",
|
||||
"html2canvas": "^1.4.1",
|
||||
"jquery": "^3.7.1",
|
||||
"js-pinyin": "^0.2.5",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"katex": "^0.16.11",
|
||||
"less": "^4.2.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"luckyexcel": "^1.0.1",
|
||||
"luckysheet": "^2.1.13",
|
||||
"mathjax": "^3.2.2",
|
||||
"min-dash": "^4.2.1",
|
||||
"mitt": "^3.0.1",
|
||||
"mqtt": "^5.13.3",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.1.7",
|
||||
"pinia-plugin-persistedstate": "^3.2.1",
|
||||
"qs": "^6.12.0",
|
||||
"screenfull": "^6.0.2",
|
||||
"splitpanes": "^3.1.5",
|
||||
"steady-xml": "0.1.0",
|
||||
"svg-pan-zoom": "^3.6.2",
|
||||
"use-element-plus-theme": "^0.0.5",
|
||||
"vexip-ui": "^2.3.28",
|
||||
"vue": "^3.3.11",
|
||||
"vue-baidu-map-3x": "^1.0.35",
|
||||
"vue-baidu-map-offline": "^1.0.7",
|
||||
"vue-demi": "^0.14.8",
|
||||
"vue-draggable-resizable": "3.0.0-beta.2",
|
||||
"vue-i18n": "9.10.2",
|
||||
"vue-katex": "^0.5.0",
|
||||
"vue-router": "4",
|
||||
"vue-types": "^5.1.1",
|
||||
"vxe-pc-ui": "~4.15.19",
|
||||
"vxe-table": "^4.19.22",
|
||||
"vxe-table-plugin-export-xlsx": "^4.0.7",
|
||||
"web-storage-cache": "^1.1.1",
|
||||
"xe-utils": "^3.5.14",
|
||||
"yarn": "^1.22.22"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@purge-icons/generated": "^0.9.0",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^20.10.5",
|
||||
"@types/splitpanes": "^2.2.6",
|
||||
"@vitejs/plugin-vue": "^4.5.2",
|
||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||
"sass": "^1.69.5",
|
||||
"typescript": "^5.2.2",
|
||||
"unplugin-auto-import": "^0.16.7",
|
||||
"vite": "^5.0.8",
|
||||
"vite-plugin-mkcert": "^1.17.3",
|
||||
"vue-tsc": "^1.8.25"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
16
src/App.vue
16
src/App.vue
@@ -9,14 +9,20 @@ import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||
import useSetTheme from '@/utils/setTheme'
|
||||
import { onMounted } from 'vue'
|
||||
useSetTheme()
|
||||
onMounted(async () => {
|
||||
const fetchMqttUrl = async () => {
|
||||
const response = await fetch('/')
|
||||
const WebSocketUrl:any = response.headers.get('X-WebSocket-Url')
|
||||
const WebSocketUrl2:any = response.headers.get('X-WebSocket-Url2')
|
||||
const MqttUrl:any = response.headers.get('X-MqttUrl-Url')
|
||||
localStorage.setItem('WebSocketUrl2', WebSocketUrl2)
|
||||
const WebSocketUrl: any = response.headers.get('X-WebSocket-Url')
|
||||
const WebSocketUrl2: any = response.headers.get('X-WebSocket-Url2')
|
||||
const WebSocketUrl3: any = response.headers.get('X-WebSocket-Url3')
|
||||
const MqttUrl: any = response.headers.get('X-MqttUrl-Url')
|
||||
localStorage.setItem('WebSocketUrl', WebSocketUrl)
|
||||
localStorage.setItem('WebSocketUrl2', WebSocketUrl2)
|
||||
localStorage.setItem('WebSocketUrl3', WebSocketUrl3)
|
||||
localStorage.setItem('MqttUrl', MqttUrl)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchMqttUrl()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import createAxios from '@/utils/request'
|
||||
|
||||
|
||||
// 密码规则修改
|
||||
export function ruleUpdate(data) {
|
||||
return createAxios({
|
||||
@@ -24,3 +25,77 @@ export function unlockRoot(data) {
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//根据客户端名查询信息
|
||||
export function getClientInfoByPath() {
|
||||
|
||||
return createAxios({
|
||||
url: '/user-boot/authClient/getAuthClientByName/njcn',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
//客户端会话配置更新
|
||||
export function updateClientSessionConfig(data) {
|
||||
return createAxios({
|
||||
url: '/user-boot/authClient/sessionConfigUpdate',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//获取用户配置
|
||||
export function getUserConfig() {
|
||||
return createAxios({
|
||||
url: '/user-boot/password/getUserStrategyList',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
//查询系统列表
|
||||
export function getSystemList() {
|
||||
return createAxios({
|
||||
url: '/system-boot/config/getSysConfigData',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
//激活系统配置
|
||||
export function activeSystemConfig(data) {
|
||||
return createAxios({
|
||||
url: '/system-boot/config/updateSysConfig',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//删除系统配置
|
||||
export function deleteSystemConfig( data) {
|
||||
return createAxios({
|
||||
url: '/system-boot/config/removeSysConfigById',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
//新增系统配置
|
||||
export function addSystemConfig(data) {
|
||||
return createAxios({
|
||||
url: '/system-boot/config/addSysConfig',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//修改系统配置
|
||||
export function updateSystemConfig(data) {
|
||||
return createAxios({
|
||||
url: '/system-boot/config/updateSysConfig',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
@@ -129,7 +129,7 @@ export function queryAllByType(params: any) {
|
||||
//获取用户
|
||||
export function selectUserList(data: any) {
|
||||
return createAxios({
|
||||
url: '/supervision-boot/userReport/selectUserList',
|
||||
url: '/device-boot/userReport/selectUserList',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获取区域中断终端
|
||||
export function getAreaOffDev(data) {
|
||||
export function getAreaOffDev(data:any) {
|
||||
return request({
|
||||
url: '/device-boot/device/getAreaOffDev',
|
||||
method: 'post',
|
||||
@@ -9,10 +9,28 @@ export function getAreaOffDev(data) {
|
||||
})
|
||||
}
|
||||
// 获取区域中断终端
|
||||
export function getYwZtSubstation(data) {
|
||||
export function getYwZtSubstation(data:any) {
|
||||
return request({
|
||||
url: '/device-boot/ywZt/getYwZtSubstation',
|
||||
method: 'GET',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
//终端周期检测
|
||||
export function terminalCheckPage(data:any) {
|
||||
return request({
|
||||
url: '/device-boot/alarm/terminalCheckPage',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function userCheckUpload(data:any) {
|
||||
return request({
|
||||
url: '/device-boot/userReport/userCheckUpload',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
@@ -45,3 +45,13 @@ export const getLineOverLimitData = (id: string) => {
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
//导出数据总览
|
||||
export function dataVerifyExcel(params: any) {
|
||||
return request({
|
||||
url: '/device-boot/dataVerify/dataVerifyExcel',
|
||||
method: 'get',
|
||||
params,
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
@@ -31,4 +31,13 @@ export function getDevTypeList() {
|
||||
method: 'post',
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export const getDeviceTypeList = (params: any) => {
|
||||
return createAxios({
|
||||
url: '/device-boot/devType/pageDevTypeList',
|
||||
method: 'POST',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
@@ -4,6 +4,10 @@ import request from '@/utils/request'
|
||||
export function getSubLineGiveAnAlarm(data: any) {
|
||||
return request({ url: '/harmonic-boot/gridDiagram/getSubLineGiveAnAlarm', method: 'post', data })
|
||||
}
|
||||
|
||||
export function getAreaObjAlarm(data: any) {
|
||||
return request({ url: '/harmonic-boot/gridDiagram/getAreaObjAlarm', method: 'post', data })
|
||||
}
|
||||
// 变电站详细列表
|
||||
export function getPollutionAlarmPageData(data: any) {
|
||||
return request({ url: '/harmonic-boot/gridDiagram/getPollutionAlarmPageData', method: 'post', data })
|
||||
|
||||
103
src/api/device-boot/sensitiveLoadMange.ts
Normal file
103
src/api/device-boot/sensitiveLoadMange.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 新增敏感用户
|
||||
export function saveUser(data: any) {
|
||||
return request({
|
||||
url: '/device-boot/pqSensitiveUser/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改敏感用户
|
||||
export function updateUser(data: any) {
|
||||
return request({
|
||||
url: '/device-boot/pqSensitiveUser/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除敏感用户
|
||||
export function deleteUser(data: any) {
|
||||
return request({
|
||||
url: '/device-boot/pqSensitiveUser/delete',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 干扰源接入功能删除流程
|
||||
*/
|
||||
export const deleteUserReport = (data: any) => {
|
||||
return request({
|
||||
url: '/device-boot/userReport/deleteUserReport',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 提交表单数据
|
||||
*/
|
||||
export const submitFormData = (data: any) => {
|
||||
return request({
|
||||
url: '/device-boot/userReport/add',
|
||||
method: 'POST',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 根据id获取用户档案录入的详细数据
|
||||
export const getById = (data: any) => {
|
||||
return request({
|
||||
url: '/device-boot/userReport/getById',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交表单数据
|
||||
*/
|
||||
export const addEditor = (data: any) => {
|
||||
return request({
|
||||
url: '/device-boot/userReportRenewal/addEditor',
|
||||
method: 'POST',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 根据id获取用户档案录入的详细数据
|
||||
export const getByDeptDevLine = (params: any) => {
|
||||
return request({
|
||||
url: '/device-boot/line/getByDeptDevLine',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 根据id获取用户档案录入的详细数据
|
||||
*/
|
||||
export const getUserReportUpdateById = (id: any) => {
|
||||
return request({
|
||||
url: '/device-boot/userReportRenewal/getUserReportUpdateById?businessId='+id,
|
||||
method: 'POST',
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// 根据id获取用户档案录入的详细数据
|
||||
export const getUserReportById = (id: any) => {
|
||||
return request({
|
||||
url: '/device-boot/userReport/getUserReportById?id='+id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 根据id查询文件信息集合
|
||||
export const getFileById = (params: any) => {
|
||||
return request({
|
||||
url: '/device-boot/fileUrl/getFileById',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
@@ -2,13 +2,35 @@ import createAxios from '@/utils/request'
|
||||
import { genFileId, ElMessage, ElNotification } from 'element-plus'
|
||||
|
||||
//事件报告
|
||||
// export function getEventReport(data) {
|
||||
// return createAxios({
|
||||
// url: '/event-boot/report/getEventReport',
|
||||
// method: 'post',
|
||||
// data
|
||||
// })
|
||||
// }
|
||||
|
||||
export function getEventReport(data) {
|
||||
return createAxios({
|
||||
url: '/event-boot/report/getEventReport',
|
||||
url: '/event-boot/report/createEventReport',
|
||||
method: 'post',
|
||||
data
|
||||
data,
|
||||
responseType: 'blob'
|
||||
}).then(async res => {
|
||||
let load: any = await readJsonBlob(res)
|
||||
if (load.code) {
|
||||
if (load.data.code == 'A0011') {
|
||||
ElMessage.warning('下载失败!')
|
||||
} else {
|
||||
ElMessage.warning(load.data.message)
|
||||
}
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 生成报告
|
||||
export function getAreaReport(data) {
|
||||
return createAxios({
|
||||
|
||||
@@ -1,106 +1,114 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getTypeIdData(data: any) {
|
||||
return request({
|
||||
url: '/system-boot/dictData/getTypeIdData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getOnlineRateData2(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/onlineRateData/getOnlineRateData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getAreaDept() {
|
||||
return request({
|
||||
url: '/user-boot/dept/loginDeptTree',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
export function getOnlineRateDataCensus(data:any) {
|
||||
return request({
|
||||
url: '/device-boot/terminalOnlineRateData/getOnlineRateDataCensus',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function IntegrityIcon(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/integrity/getIntegrityIcon',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getDeptIdAreaTree() {
|
||||
return request({
|
||||
url: '/system-boot/area/getDeptIdAreaTree',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
export function getOnlineRateData(data:any) {
|
||||
return request({
|
||||
url: '/device-boot/terminalOnlineRateData/getOnlineRateData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getSubstationInfoById(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/PollutionSubstation/getSubstationInfoById',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getLineInfoById(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/PollutionSubstation/getLineInfoById',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getLineRank(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/PollutionSubstation/getLineRank',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function deptInfo(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/detailAnalysis/deptInfo',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getXbLineInfoById(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/detailAnalysis/getXbLineInfoById',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getSubInfoById(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/detailAnalysis/getSubInfoById',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getXbLineRank(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/detailAnalysis/getXbLineRank',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 数据补招
|
||||
export function FullRecall(data:any) {
|
||||
return request({
|
||||
url: '/data-processing-boot/data/FullRecall',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getTypeIdData(data: any) {
|
||||
return request({
|
||||
url: '/system-boot/dictData/getTypeIdData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getOnlineRateData2(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/onlineRateData/getOnlineRateData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getAreaDept() {
|
||||
return request({
|
||||
url: '/user-boot/dept/loginDeptTree',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
// 承载能力评估去除前缀
|
||||
export function getAreaDeptRemoveMode(params) {
|
||||
return request({
|
||||
url: '/user-boot/dept/loginDeptTree',
|
||||
method: 'GET',
|
||||
params: params
|
||||
})
|
||||
}
|
||||
export function getOnlineRateDataCensus(data:any) {
|
||||
return request({
|
||||
url: '/device-boot/terminalOnlineRateData/getOnlineRateDataCensus',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function IntegrityIcon(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/integrity/getIntegrityIcon',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getDeptIdAreaTree() {
|
||||
return request({
|
||||
url: '/system-boot/area/getDeptIdAreaTree',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
export function getOnlineRateData(data:any) {
|
||||
return request({
|
||||
url: '/device-boot/terminalOnlineRateData/getOnlineRateData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getSubstationInfoById(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/PollutionSubstation/getSubstationInfoById',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getLineInfoById(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/PollutionSubstation/getLineInfoById',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getLineRank(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/PollutionSubstation/getLineRank',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function deptInfo(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/detailAnalysis/deptInfo',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getXbLineInfoById(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/detailAnalysis/getXbLineInfoById',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getSubInfoById(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/detailAnalysis/getSubInfoById',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function getXbLineRank(data:any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/detailAnalysis/getXbLineRank',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 数据补招
|
||||
export function FullRecall(data:any) {
|
||||
return request({
|
||||
url: '/data-processing-boot/data/FullRecall',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
42
src/api/system-boot/MonitoringPoint.ts
Normal file
42
src/api/system-boot/MonitoringPoint.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
//查询所有模板
|
||||
export function getList(data: any) {
|
||||
return request({
|
||||
url: "/system-boot/EventTemplate/getList",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
//字典树
|
||||
export function getDictTree(data: any) {
|
||||
return request({
|
||||
url: "/system-boot/reportDict/DictTree",
|
||||
method: "post",
|
||||
params:data
|
||||
});
|
||||
}
|
||||
//新增模板
|
||||
export function addData(data: any) {
|
||||
return request({
|
||||
url: "/system-boot/EventTemplate/add",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
//修改模板
|
||||
export function updateData(data: any) {
|
||||
return request({
|
||||
url: "/system-boot/EventTemplate/update",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
//删除模板
|
||||
export function deleteData(data: any) {
|
||||
return request({
|
||||
url: "/system-boot/EventTemplate/delete",
|
||||
method: "post",
|
||||
data,
|
||||
});
|
||||
}
|
||||
43
src/api/system-boot/ReportTemplate.ts
Normal file
43
src/api/system-boot/ReportTemplate.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
//获取字典树数据
|
||||
export function getDictTree(data) {
|
||||
return request({
|
||||
url: "/system-boot/reportDict/DictTree",
|
||||
method: "post",
|
||||
params:data
|
||||
});
|
||||
}
|
||||
|
||||
//查询字典列表
|
||||
export function getReportDictList(data: any) {
|
||||
return request({
|
||||
url: "/system-boot/reportDict/getReportDictList",
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
}
|
||||
//新增字典表
|
||||
export function addDict(data: any) {
|
||||
return request({
|
||||
url: "/system-boot/reportDict/addDict",
|
||||
method: "post",
|
||||
data
|
||||
});
|
||||
}
|
||||
//更新字典表
|
||||
export function updateDict(data: any) {
|
||||
return request({
|
||||
url: "/system-boot/reportDict/updateDict",
|
||||
method: "put",
|
||||
data
|
||||
});
|
||||
}
|
||||
//删除字典表
|
||||
export function deleteDict(data: any) {
|
||||
return request({
|
||||
url: "/system-boot/reportDict/deleteDict",
|
||||
method: "delete",
|
||||
params:data
|
||||
});
|
||||
}
|
||||
37
src/api/system-boot/area.ts
Normal file
37
src/api/system-boot/area.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import request from '@/utils/request'
|
||||
//区域树形表格接口
|
||||
export function areaTree(data: any) {
|
||||
return request({
|
||||
url: '/system-boot/area/areaTree',
|
||||
method: 'post',
|
||||
params: data,
|
||||
})
|
||||
}
|
||||
export function areaAdd(data: any) {
|
||||
return request({
|
||||
url: '/system-boot/area/add',
|
||||
method: 'post',
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
export function areaDelete(data: any) {
|
||||
return request({
|
||||
url: '/system-boot/area/delete',
|
||||
method: 'post',
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
export function update(data: any) {
|
||||
return request({
|
||||
url: '/system-boot/area/update',
|
||||
method: 'post',
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
export function selectPid(data: any) {
|
||||
return request({
|
||||
url: '/system-boot/area/selectPid',
|
||||
method: 'post',
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
@@ -1,215 +1,250 @@
|
||||
import request from '@/utils/request'
|
||||
import { LoginData } from '@/api/types'
|
||||
import { useAdminInfo } from '@/stores/adminInfo'
|
||||
import { sm3Digest } from '@/assets/commjs/sm3.js'
|
||||
import { sm2, encrypt } from '@/assets/commjs/sm2.js'
|
||||
|
||||
// 获取公钥
|
||||
export function gongkey(params?: any) {
|
||||
if (!params) {
|
||||
const adminInfo = useAdminInfo()
|
||||
params = {
|
||||
loginName: encrypt(adminInfo.$state.loginName)
|
||||
}
|
||||
}
|
||||
return request({
|
||||
url: '/user-boot/user/generateSm2Key',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export async function pwdSm3(pwd: any, loginName?: string) {
|
||||
let publicKey = await gongkey(
|
||||
loginName
|
||||
? {
|
||||
loginName: encrypt(loginName)
|
||||
}
|
||||
: false
|
||||
)
|
||||
let sm3Pwd = sm3Digest(pwd) //SM3加密
|
||||
return sm2(sm3Pwd + '|' + pwd, publicKey.data, 0)
|
||||
}
|
||||
|
||||
//登录获取token
|
||||
export async function login(params: any) {
|
||||
if (params.refresh_token == undefined) {
|
||||
params.password = await pwdSm3(params.password, params.username)
|
||||
}
|
||||
params.username = encrypt(params.username)
|
||||
return request({
|
||||
url: '/pqs-auth/oauth/token',
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
//获取用户信息
|
||||
export function getUserById() {
|
||||
const adminInfo = useAdminInfo()
|
||||
return request({
|
||||
url: '/user-boot/user/getUserById?id=' + adminInfo.userIndex,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 刷新token
|
||||
// 导出一个名为refreshToken的函数,该函数返回一个Promise对象
|
||||
export function refreshToken(): Promise<any> {
|
||||
// 调用useAdminInfo函数获取管理员信息,并将其赋值给adminInfo变量
|
||||
const adminInfo = useAdminInfo()
|
||||
// 调用login函数,传入一个对象作为参数,该对象包含grant_type、refresh_token和username三个属性
|
||||
// grant_type设置为'refresh_token',表示使用刷新令牌的方式获取新的访问令牌
|
||||
// refresh_token使用adminInfo中的refresh_token属性
|
||||
// username使用adminInfo中的loginName属性
|
||||
// 返回login函数的调用结果,即一个Promise对象
|
||||
return login({
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: adminInfo.refresh_token,
|
||||
username: adminInfo.loginName
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取营销用户列表
|
||||
* @returns {AxiosPromise}
|
||||
*/
|
||||
export const getMarketList = () => {
|
||||
return request({
|
||||
url: '/user-boot/user/getMarketList',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function add(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function edit(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export async function passwordConfirm(pwd: string) {
|
||||
return request({
|
||||
url: '/user-boot/user/passwordConfirm?password=' + (await pwdSm3(pwd)),
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function deluser(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/delete',
|
||||
method: 'delete',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
export function activateUser(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/activateUser',
|
||||
method: 'put',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
export async function updatePassword(params: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/updatePassword',
|
||||
method: 'put',
|
||||
params: {
|
||||
id: params.id,
|
||||
newPassword: await pwdSm3(params.newPassword)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function updateFirstPassword(params: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/updateFirstPassword',
|
||||
method: 'put',
|
||||
data: {
|
||||
name: encrypt(params.name),
|
||||
password: await pwdSm3(params.password, params.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function checkUser(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/check',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function existMonitorDeptTree() {
|
||||
return request({
|
||||
url: '/user-boot/dept/existMonitorDeptTree',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
// 获取用户
|
||||
export function getUserByRoleType(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/getUserByRoleType?roleType=' + data,
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取部门下所有用户
|
||||
export function listAllUserByDeptId(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/listAllUserByDeptId?deptId=' + data,
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
// 根据id获取所有用户信息
|
||||
export function getUserListByIds(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/getUserListByIds',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有用户不包括管理员
|
||||
*/
|
||||
export const getUserSimpleList = () => {
|
||||
return request({
|
||||
url: '/user-boot/user/simpleList',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有用户包括管理员
|
||||
*/
|
||||
export const getAllUserSimpleList = () => {
|
||||
return request({
|
||||
url: '/user-boot/user/getAllUserSimpleList',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
export const getSysConfig = () => {
|
||||
return request({
|
||||
url: '/system-boot/config/getSysConfig',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 驾驶舱组件配置
|
||||
export const componentTree = () => {
|
||||
return request({
|
||||
url: '/user-boot/component/componentTree',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
import request from '@/utils/request'
|
||||
import { LoginData } from '@/api/types'
|
||||
import { useAdminInfo } from '@/stores/adminInfo'
|
||||
import { sm3Digest } from '@/assets/commjs/sm3.js'
|
||||
import { sm2, encrypt } from '@/assets/commjs/sm2.js'
|
||||
|
||||
// 获取公钥
|
||||
export function gongkey(params?: any) {
|
||||
if (!params) {
|
||||
const adminInfo = useAdminInfo()
|
||||
params = {
|
||||
loginName: encrypt(adminInfo.$state.loginName)
|
||||
}
|
||||
}
|
||||
return request({
|
||||
url: '/user-boot/user/generateSm2Key',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export async function pwdSm3(pwd: any, loginName?: string) {
|
||||
let publicKey = await gongkey(
|
||||
loginName
|
||||
? {
|
||||
loginName: encrypt(loginName)
|
||||
}
|
||||
: false
|
||||
)
|
||||
let sm3Pwd = sm3Digest(pwd) //SM3加密
|
||||
return sm2(sm3Pwd + '|' + pwd, publicKey.data, 0)
|
||||
}
|
||||
|
||||
//登录获取token
|
||||
export async function login(params: any) {
|
||||
if (params.refresh_token == undefined) {
|
||||
params.password = await pwdSm3(params.password, params.username)
|
||||
}
|
||||
params.username = encrypt(params.username)
|
||||
return request({
|
||||
url: '/pqs-auth/oauth/token',
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
//辽宁嵌入登录获取token
|
||||
export async function loginLNqr(data: any) {
|
||||
return request({
|
||||
url: '/pqs-auth/oauth/lnLogin',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
export async function lnRefreshToken(data: any) {
|
||||
return request({
|
||||
url: '/pqs-auth/oauth/lnRefreshToken',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
export async function logout() {
|
||||
return request({
|
||||
url: '/pqs-auth/oauth/logout',
|
||||
method: 'DELETE',
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//获取用户信息
|
||||
export function getUserById() {
|
||||
const adminInfo = useAdminInfo()
|
||||
return request({
|
||||
url: '/user-boot/user/getUserById?id=' + adminInfo.userIndex,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 刷新token
|
||||
// 导出一个名为refreshToken的函数,该函数返回一个Promise对象
|
||||
export function refreshToken(): Promise<any> {
|
||||
// 调用useAdminInfo函数获取管理员信息,并将其赋值给adminInfo变量
|
||||
const adminInfo = useAdminInfo()
|
||||
// 调用login函数,传入一个对象作为参数,该对象包含grant_type、refresh_token和username三个属性
|
||||
// grant_type设置为'refresh_token',表示使用刷新令牌的方式获取新的访问令牌
|
||||
// refresh_token使用adminInfo中的refresh_token属性
|
||||
// username使用adminInfo中的loginName属性
|
||||
// 返回login函数的调用结果,即一个Promise对象
|
||||
return login({
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: adminInfo.refresh_token,
|
||||
username: adminInfo.loginName
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function lnRefreshTokenTo(): Promise<any> {
|
||||
// 调用useAdminInfo函数获取管理员信息,并将其赋值给adminInfo变量
|
||||
const adminInfo = useAdminInfo()
|
||||
return lnRefreshToken({
|
||||
refreshToken: adminInfo.refresh_token,
|
||||
clientId: "njcn",
|
||||
clientSecret:"njcnpqs"
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取营销用户列表
|
||||
* @returns {AxiosPromise}
|
||||
*/
|
||||
export const getMarketList = () => {
|
||||
return request({
|
||||
url: '/user-boot/user/getMarketList',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function add(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function edit(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/update',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export async function passwordConfirm(pwd: string) {
|
||||
return request({
|
||||
url: '/user-boot/user/passwordConfirm?password=' + (await pwdSm3(pwd)),
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function deluser(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/delete',
|
||||
method: 'delete',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
export function activateUser(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/activateUser',
|
||||
method: 'put',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
export async function updatePassword(params: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/updatePassword',
|
||||
method: 'put',
|
||||
params: {
|
||||
id: params.id,
|
||||
newPassword: await pwdSm3(params.newPassword)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function updateFirstPassword(params: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/updateFirstPassword',
|
||||
method: 'put',
|
||||
data: {
|
||||
name: encrypt(params.name),
|
||||
password: await pwdSm3(params.password, params.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function checkUser(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/check',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
export function existMonitorDeptTree() {
|
||||
return request({
|
||||
url: '/user-boot/dept/existMonitorDeptTree',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
// 获取用户
|
||||
export function getUserByRoleType(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/getUserByRoleType?roleType=' + data,
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取部门下所有用户
|
||||
export function listAllUserByDeptId(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/listAllUserByDeptId?deptId=' + data,
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
// 根据id获取所有用户信息
|
||||
export function getUserListByIds(data: any) {
|
||||
return request({
|
||||
url: '/user-boot/user/getUserListByIds',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有用户不包括管理员
|
||||
*/
|
||||
export const getUserSimpleList = () => {
|
||||
return request({
|
||||
url: '/user-boot/user/simpleList',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有用户包括管理员
|
||||
*/
|
||||
export const getAllUserSimpleList = () => {
|
||||
return request({
|
||||
url: '/user-boot/user/getAllUserSimpleList',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
export const getSysConfig = () => {
|
||||
return request({
|
||||
url: '/system-boot/config/getSysConfig',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
// 驾驶舱组件配置
|
||||
export const componentTree = () => {
|
||||
return request({
|
||||
url: '/user-boot/component/componentTree',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
BIN
src/assets/imgs/m0.png
Normal file
BIN
src/assets/imgs/m0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
BIN
src/assets/imgs/m1.png
Normal file
BIN
src/assets/imgs/m1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/assets/imgs/m2.png
Normal file
BIN
src/assets/imgs/m2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
BIN
src/assets/imgs/m3.png
Normal file
BIN
src/assets/imgs/m3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
BIN
src/assets/imgs/m4.png
Normal file
BIN
src/assets/imgs/m4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
File diff suppressed because one or more lines are too long
@@ -30,7 +30,7 @@ import { downloadFile } from '@/api/system-boot/file'
|
||||
import { previewFile } from '@/utils/fileDownLoad'
|
||||
|
||||
const { push, options, currentRoute } = useRouter()
|
||||
const VITE_FLAG = import.meta.env.VITE_NAME == 'jibei'
|
||||
const VITE_FLAG = false//import.meta.env.VITE_NAME == 'jibei'
|
||||
// const url = 'http://192.168.1.22:9009/excelreport' + currentRoute.value.href?.split('?')[1]
|
||||
const url = ref('')
|
||||
const excelOptions = ref({})
|
||||
|
||||
@@ -126,7 +126,8 @@ const prop = defineProps({
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeValue: { type: Object },
|
||||
searchKey: { type: [String, Number] }
|
||||
})
|
||||
|
||||
const headerHeight = ref(57)
|
||||
@@ -347,22 +348,22 @@ onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
() => prop.searchKey,
|
||||
val => {
|
||||
tableStore.index()
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
// watch(
|
||||
// () => prop.timeValue,
|
||||
|
||||
val => {
|
||||
tableStore.index()
|
||||
},
|
||||
// val => {
|
||||
// tableStore.index()
|
||||
// },
|
||||
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
// {
|
||||
// deep: true
|
||||
// }
|
||||
// )
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
|
||||
@@ -122,7 +122,8 @@ const prop = defineProps({
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeValue: { type: Object },
|
||||
searchKey: { type: [String, Number] }
|
||||
})
|
||||
|
||||
const headerHeight = ref(57)
|
||||
@@ -183,7 +184,7 @@ const tableStore: any = new TableStore({
|
||||
if (tableStore.table.params.statisticalType.name == '终端厂家') {
|
||||
return k.citTotalNum != 0
|
||||
} else {
|
||||
return k.citName != '上送国网' && k.citName != '非上送国网'
|
||||
return !k.citName.includes('上送')
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -329,22 +330,22 @@ onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
() => prop.searchKey,
|
||||
val => {
|
||||
tableStore.index()
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
// watch(
|
||||
// () => prop.timeValue,
|
||||
|
||||
val => {
|
||||
tableStore.index()
|
||||
},
|
||||
// val => {
|
||||
// tableStore.index()
|
||||
// },
|
||||
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
// {
|
||||
// deep: true
|
||||
// }
|
||||
// )
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
v-if="fullscreen"
|
||||
></TableHeader>
|
||||
>
|
||||
</TableHeader>
|
||||
<div
|
||||
class="monitoringPoints"
|
||||
:style="{
|
||||
@@ -120,7 +121,8 @@ const prop = defineProps({
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeValue: { type: Object },
|
||||
searchKey: { type: [String, Number] }
|
||||
})
|
||||
|
||||
const headerHeight = ref(57)
|
||||
@@ -181,7 +183,7 @@ const tableStore: any = new TableStore({
|
||||
if (tableStore.table.params.statisticalType.name == '终端厂家') {
|
||||
return k.citTotalNum != 0
|
||||
} else {
|
||||
return k.citName != '上送国网' && k.citName != '非上送国网'
|
||||
return !k.citName.includes('上送')
|
||||
}
|
||||
})
|
||||
|
||||
@@ -328,22 +330,22 @@ onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
() => prop.searchKey,
|
||||
val => {
|
||||
tableStore.index()
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
// watch(
|
||||
// () => prop.timeValue,
|
||||
|
||||
val => {
|
||||
tableStore.index()
|
||||
},
|
||||
// val => {
|
||||
// tableStore.index()
|
||||
// },
|
||||
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
// {
|
||||
// deep: true
|
||||
// }
|
||||
// )
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
|
||||
@@ -150,7 +150,8 @@ const prop = defineProps({
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeValue: { type: Object },
|
||||
searchKey: { type: [String, Number] }
|
||||
})
|
||||
|
||||
const headerHeight = ref(57)
|
||||
@@ -233,7 +234,7 @@ const tableStore: any = new TableStore({
|
||||
if (tableStore.table.params.statisticalType.name == '终端厂家') {
|
||||
return k.count != 0
|
||||
} else {
|
||||
return k.name != '上送国网' && k.name != '非上送国网'
|
||||
return !k.name.includes('上送')
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -246,22 +247,28 @@ onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
() => prop.searchKey,
|
||||
val => {
|
||||
tableStore.index()
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
// watch(
|
||||
// () => prop.timeKey,
|
||||
// val => {
|
||||
// tableStore.index()
|
||||
// }
|
||||
// )
|
||||
// watch(
|
||||
// () => prop.timeValue,
|
||||
|
||||
val => {
|
||||
tableStore.index()
|
||||
},
|
||||
// val => {
|
||||
// tableStore.index()
|
||||
// },
|
||||
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
// {
|
||||
// deep: true
|
||||
// }
|
||||
// )
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/font/iconfont.css';
|
||||
|
||||
@@ -6,29 +6,40 @@
|
||||
</div>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="暂态波形上送" :style="'height:' + vhh">
|
||||
<el-table stripe :data="Data" :height="height" border style="width: 100%"
|
||||
header-cell-class-name="table_header">
|
||||
<el-table-column align="center" prop="number" label="事件段"></el-table-column>
|
||||
<el-table-column align="center" prop="number" label="波形起始点相位(°)">
|
||||
<el-table-column align="center" prop="number" label="A相"></el-table-column>
|
||||
<el-table-column align="center" prop="number" label="B相"></el-table-column>
|
||||
<el-table-column align="center" prop="number" label="C相"></el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="number" label="跳变段电压变化率(V/ms)">
|
||||
<el-table-column align="center" prop="number" label="A相"></el-table-column>
|
||||
<el-table-column align="center" prop="number" label="B相"></el-table-column>
|
||||
<el-table-column align="center" prop="number" label="C相"></el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="number" label="相位跳变(°)">
|
||||
<el-table-column align="center" prop="number" label="A相"></el-table-column>
|
||||
<el-table-column align="center" prop="number" label="B相"></el-table-column>
|
||||
<el-table-column align="center" prop="number" label="C相"></el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" prop="number" label="总分段数目"></el-table-column>
|
||||
<el-table-column align="center" prop="number" label="三相电压不平衡度(%)" width="180"></el-table-column>
|
||||
<el-table-column align="center" prop="number" label="触发类型"></el-table-column>
|
||||
<el-table-column align="center" prop="number" label="暂降原因"></el-table-column>
|
||||
</el-table>
|
||||
<vxe-table
|
||||
stripe
|
||||
:data="Data"
|
||||
:height="height"
|
||||
border
|
||||
style="width: 100%"
|
||||
header-cell-class-name="table_header"
|
||||
>
|
||||
<vxe-column align="center" field="number" title="事件段"></vxe-column>
|
||||
<vxe-colgroup align="center" field="number1" title="波形起始点相位(°)">
|
||||
<vxe-column align="center" field="number2" title="A相"></vxe-column>
|
||||
<vxe-column align="center" field="number3" title="B相"></vxe-column>
|
||||
<vxe-column align="center" field="number4" title="C相"></vxe-column>
|
||||
</vxe-colgroup>
|
||||
<vxe-colgroup align="center" field="number" title="跳变段电压变化率(V/ms)">
|
||||
<vxe-column align="center" field="number5" title="A相"></vxe-column>
|
||||
<vxe-column align="center" field="number6" title="B相"></vxe-column>
|
||||
<vxe-column align="center" field="number7" title="C相"></vxe-column>
|
||||
</vxe-colgroup>
|
||||
<vxe-colgroup align="center" field="number" title="相位跳变(°)">
|
||||
<vxe-column align="center" field="number8" title="A相"></vxe-column>
|
||||
<vxe-column align="center" field="number9" title="B相"></vxe-column>
|
||||
<vxe-column align="center" field="number10" title="C相"></vxe-column>
|
||||
</vxe-colgroup>
|
||||
<vxe-column align="center" field="number11" title="总分段数目"></vxe-column>
|
||||
<vxe-column
|
||||
align="center"
|
||||
field="number12"
|
||||
title="三相电压不平衡度(%)"
|
||||
width="180"
|
||||
></vxe-column>
|
||||
<vxe-column align="center" field="number13" title="触发类型"></vxe-column>
|
||||
<vxe-column align="center" field="number14" title="暂降原因"></vxe-column>
|
||||
</vxe-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
@@ -73,7 +84,25 @@ export default {
|
||||
subName: '',
|
||||
waveDatas: [],
|
||||
|
||||
Data: [],
|
||||
Data: [
|
||||
{
|
||||
number: 1,
|
||||
number1: 0,
|
||||
number2: 0,
|
||||
number3: 0,
|
||||
number4: 0,
|
||||
number5: 0,
|
||||
number6: 0,
|
||||
number7: 0,
|
||||
number8: 0,
|
||||
number9: 0,
|
||||
number10: 0,
|
||||
number11: 1,
|
||||
number12: 0,
|
||||
number13: '其他',
|
||||
number14: '其他'
|
||||
}
|
||||
],
|
||||
height: null,
|
||||
vhh: null,
|
||||
ptpass: '',
|
||||
@@ -88,7 +117,7 @@ export default {
|
||||
zoom: ''
|
||||
}
|
||||
},
|
||||
created() { },
|
||||
created() {},
|
||||
watch: {
|
||||
value: function (a, b) {
|
||||
if (a == 2) {
|
||||
@@ -116,10 +145,10 @@ export default {
|
||||
this.zoom = 1 / document.body.style.zoom
|
||||
if (this.flag) {
|
||||
// console.log(123);
|
||||
this.vh = mainHeight(250).height
|
||||
this.vh = mainHeight(280).height
|
||||
} else {
|
||||
// console.log(3333);
|
||||
this.vh = mainHeight(270).height
|
||||
this.vh = mainHeight(305).height
|
||||
}
|
||||
},
|
||||
query() {
|
||||
@@ -197,6 +226,8 @@ export default {
|
||||
'#FF9999'
|
||||
]
|
||||
}
|
||||
console.log('🚀 ~ this.boxoList:', this.boxoList)
|
||||
|
||||
var option = {
|
||||
tooltip: {
|
||||
top: '10px',
|
||||
@@ -239,7 +270,7 @@ export default {
|
||||
|
||||
title: {
|
||||
left: 'center',
|
||||
text: '发生时刻:' + this.boxoList.startTime + ' PT变化:' + this.boxoList.measurementPointName,
|
||||
text: '发生时刻:' + this.boxoList.startTime + ' PT变化:' + this.boxoList.pt,
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
color: _this.DColor ? '#fff' : echartsColor.WordColor
|
||||
@@ -378,6 +409,33 @@ export default {
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '跳变期',
|
||||
type: 'line',
|
||||
data: [],
|
||||
showSymbol: true, // 强制显示标记
|
||||
symbol: 'rect', // 标记形状为方块
|
||||
symbolSize: 10, // 方块大小
|
||||
itemStyle: {
|
||||
color: '#888888', // 方块颜色为灰色
|
||||
borderWidth: 0
|
||||
},
|
||||
|
||||
markArea: {
|
||||
silent: true, // 不响应交互
|
||||
itemStyle: { color: '#ccc' },
|
||||
data: [
|
||||
[
|
||||
{ xAxis: '0' }, // 第一个跳变期起始
|
||||
{ xAxis: '5' } // 第一个跳变期结束
|
||||
],
|
||||
[
|
||||
{ xAxis: '210' }, // 第二个跳变期起始
|
||||
{ xAxis: '220' } // 第二个跳变期结束
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'A相',
|
||||
type: 'line',
|
||||
|
||||
1498
src/components/echarts/gaoji.js
Normal file
1498
src/components/echarts/gaoji.js
Normal file
File diff suppressed because it is too large
Load Diff
322
src/components/echarts/rmsWorker.js
Normal file
322
src/components/echarts/rmsWorker.js
Normal file
@@ -0,0 +1,322 @@
|
||||
// 辅助函数
|
||||
const getMax = (temp, tempA, tempB, tempC) => {
|
||||
temp = temp > tempA ? temp : tempA
|
||||
temp = temp > tempB ? temp : tempB
|
||||
if (tempC !== undefined) {
|
||||
temp = temp > tempC ? temp : tempC
|
||||
}
|
||||
return temp
|
||||
}
|
||||
|
||||
const getMaxTwo = (temp, tempA, tempB) => {
|
||||
temp = temp > tempA ? temp : tempA
|
||||
temp = temp > tempB ? temp : tempB
|
||||
return temp
|
||||
}
|
||||
|
||||
const getMin = (temp, tempA, tempB, tempC) => {
|
||||
temp = temp < tempA ? temp : tempA
|
||||
temp = temp < tempB ? temp : tempB
|
||||
if (tempC !== undefined) {
|
||||
temp = temp < tempC ? temp : tempC
|
||||
}
|
||||
return temp
|
||||
}
|
||||
|
||||
const getMinOpen = (temp, tempA, tempB) => {
|
||||
temp = temp < tempA ? temp : tempA
|
||||
temp = temp < tempB ? temp : tempB
|
||||
return temp
|
||||
}
|
||||
|
||||
// 数据处理函数
|
||||
const fliteWaveData = (wp, step, iphasicValue, isOpen) => {
|
||||
const rmsData = wp.listRmsData
|
||||
const pt = Number(wp.pt) / 1000
|
||||
const ct = Number(wp.ct)
|
||||
const titleList = wp.waveTitle
|
||||
let xishu = pt
|
||||
let aTitle = '',
|
||||
bTitle = '',
|
||||
cTitle = '',
|
||||
unit = '电压'
|
||||
let rmsvFirstX = 0,
|
||||
rmsvFirstY = 0,
|
||||
rmsvSecondX = 0,
|
||||
rmsvSecondY = 0,
|
||||
firstZhou = 'a',
|
||||
secondeZhou = 'a'
|
||||
let ifmax = 0,
|
||||
ifmin = 0,
|
||||
ismax = 0,
|
||||
ismin = 0,
|
||||
rfmax = 0,
|
||||
rfmin = 0,
|
||||
rsmax = 0,
|
||||
rsmin = 0
|
||||
|
||||
const shunshiFA = []
|
||||
const shunshiFB = []
|
||||
const shunshiFC = []
|
||||
const shunshiSA = []
|
||||
const shunshiSB = []
|
||||
const shunshiSC = []
|
||||
const rmsFA = []
|
||||
const rmsFB = []
|
||||
const rmsFC = []
|
||||
const rmsSA = []
|
||||
const rmsSB = []
|
||||
const rmsSC = []
|
||||
|
||||
if (titleList[iphasicValue * step + 1]?.substring(0, 1) !== 'U') {
|
||||
xishu = ct
|
||||
unit = '电流'
|
||||
}
|
||||
|
||||
for (let i = 1; i <= iphasicValue; i++) {
|
||||
switch (i) {
|
||||
case 1:
|
||||
aTitle = titleList[iphasicValue * step + i]?.substring(1) || ''
|
||||
break
|
||||
case 2:
|
||||
bTitle = titleList[iphasicValue * step + i]?.substring(1) || ''
|
||||
break
|
||||
case 3:
|
||||
cTitle = titleList[iphasicValue * step + i]?.substring(1) || ''
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (rmsData[0] && rmsData[0][iphasicValue * step + 1] !== undefined) {
|
||||
rfmax = rmsData[0][iphasicValue * step + 1] * xishu
|
||||
rfmin = rmsData[0][iphasicValue * step + 1] * xishu
|
||||
rmsvFirstY = rmsData[0][iphasicValue * step + 1] * xishu
|
||||
rmsvFirstX = rmsData[0][0]
|
||||
rsmax = rmsData[0][iphasicValue * step + 1]
|
||||
rsmin = rmsData[0][iphasicValue * step + 1]
|
||||
rmsvSecondY = rmsData[0][iphasicValue * step + 1]
|
||||
rmsvSecondX = rmsData[0][0]
|
||||
}
|
||||
|
||||
for (let rms = 0; rms < rmsData.length; rms++) {
|
||||
if (!rmsData[rms] || rmsData[rms][iphasicValue * step + 1] === undefined) {
|
||||
break
|
||||
}
|
||||
|
||||
switch (iphasicValue) {
|
||||
case 1:
|
||||
const rmsFirstA = rmsData[rms][iphasicValue * step + 1] * xishu
|
||||
rmsFA.push([rmsData[rms][0], rmsFirstA])
|
||||
rfmax = rfmax > rmsFirstA ? rfmax : rmsFirstA
|
||||
rfmin = rfmin < rmsFirstA ? rfmin : rmsFirstA
|
||||
if (rfmin < rmsvFirstY) {
|
||||
rmsvFirstY = rfmin
|
||||
firstZhou = 'a'
|
||||
rmsvFirstX = rmsData[rms][0]
|
||||
}
|
||||
|
||||
const rmsSecondA = rmsData[rms][iphasicValue * step + 1]
|
||||
rmsSA.push([rmsData[rms][0], rmsSecondA])
|
||||
rsmax = rsmax > rmsSecondA ? rsmax : rmsSecondA
|
||||
rsmin = rsmin < rmsSecondA ? rsmin : rmsSecondA
|
||||
if (rsmin < rmsvSecondY) {
|
||||
rmsvSecondY = rsmin
|
||||
secondeZhou = 'a'
|
||||
rmsvSecondX = rmsData[rms][0]
|
||||
}
|
||||
break
|
||||
case 2:
|
||||
const rmsFirstA2 = rmsData[rms][iphasicValue * step + 1] * xishu
|
||||
const rmsFirstB2 = rmsData[rms][iphasicValue * step + 2] * xishu
|
||||
rmsFA.push([rmsData[rms][0], rmsFirstA2])
|
||||
rmsFB.push([rmsData[rms][0], rmsFirstB2])
|
||||
rfmax = getMaxTwo(rfmax, rmsFirstA2, rmsFirstB2)
|
||||
rfmin = getMinOpen(rfmin, rmsFirstA2, rmsFirstB2)
|
||||
if (rfmin < rmsvFirstY) {
|
||||
rmsvFirstY = rfmin
|
||||
if (rfmin === rmsFirstA2) {
|
||||
firstZhou = 'a'
|
||||
} else if (rfmin === rmsFirstB2) {
|
||||
firstZhou = 'b'
|
||||
}
|
||||
rmsvFirstX = rmsData[rms][0]
|
||||
}
|
||||
|
||||
const rmsSecondA2 = rmsData[rms][iphasicValue * step + 1]
|
||||
const rmsSecondB2 = rmsData[rms][iphasicValue * step + 2]
|
||||
rmsSA.push([rmsData[rms][0], rmsSecondA2])
|
||||
rmsSB.push([rmsData[rms][0], rmsSecondB2])
|
||||
rsmax = getMaxTwo(rsmax, rmsSecondA2, rmsSecondB2)
|
||||
rsmin = getMinOpen(rsmin, rmsSecondA2, rmsSecondB2)
|
||||
if (rsmin < rmsvSecondY) {
|
||||
rmsvSecondY = rsmin
|
||||
if (rsmin === rmsSecondA2) {
|
||||
secondeZhou = 'a'
|
||||
} else if (rsmin === rmsSecondB2) {
|
||||
secondeZhou = 'b'
|
||||
}
|
||||
rmsvSecondX = rmsData[rms][0]
|
||||
}
|
||||
break
|
||||
case 3:
|
||||
const rmsFirstA3 = rmsData[rms][iphasicValue * step + 1] * xishu
|
||||
const rmsFirstB3 = rmsData[rms][iphasicValue * step + 2] * xishu
|
||||
const rmsFirstC3 = rmsData[rms][iphasicValue * step + 3] * xishu
|
||||
rmsFA.push([rmsData[rms][0], rmsFirstA3])
|
||||
rmsFB.push([rmsData[rms][0], rmsFirstB3])
|
||||
rmsFC.push([rmsData[rms][0], rmsFirstC3])
|
||||
rfmax = getMax(rfmax, rmsFirstA3, rmsFirstB3, rmsFirstC3)
|
||||
rfmin = isOpen
|
||||
? getMinOpen(rfmin, rmsFirstA3, rmsFirstC3)
|
||||
: getMin(rfmin, rmsFirstA3, rmsFirstB3, rmsFirstC3)
|
||||
if (rfmin < rmsvFirstY) {
|
||||
rmsvFirstY = rfmin
|
||||
if (rfmin === rmsFirstA3) {
|
||||
firstZhou = 'a'
|
||||
} else if (rfmin === rmsFirstB3) {
|
||||
firstZhou = 'b'
|
||||
} else {
|
||||
firstZhou = 'c'
|
||||
}
|
||||
rmsvFirstX = rmsData[rms][0]
|
||||
}
|
||||
|
||||
const rmsSecondA3 = rmsData[rms][iphasicValue * step + 1]
|
||||
const rmsSecondB3 = rmsData[rms][iphasicValue * step + 2]
|
||||
const rmsSecondC3 = rmsData[rms][iphasicValue * step + 3]
|
||||
rmsSA.push([rmsData[rms][0], rmsSecondA3])
|
||||
rmsSB.push([rmsData[rms][0], rmsSecondB3])
|
||||
rmsSC.push([rmsData[rms][0], rmsSecondC3])
|
||||
rsmax = getMax(rsmax, rmsSecondA3, rmsSecondB3, rmsSecondC3)
|
||||
rsmin = isOpen
|
||||
? getMinOpen(rsmin, rmsSecondA3, rmsSecondC3)
|
||||
: getMin(rsmin, rmsSecondA3, rmsSecondB3, rmsSecondC3)
|
||||
if (rsmin < rmsvSecondY) {
|
||||
rmsvSecondY = rsmin
|
||||
if (rsmin === rmsSecondA3) {
|
||||
secondeZhou = 'a'
|
||||
} else if (rsmin === rmsSecondB3) {
|
||||
secondeZhou = 'b'
|
||||
} else {
|
||||
secondeZhou = 'c'
|
||||
}
|
||||
rmsvSecondX = rmsData[rms][0]
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const instantF = { max: ifmax, min: ifmin }
|
||||
const instantS = { max: ismax, min: ismin }
|
||||
const RMSF = { max: rfmax, min: rfmin }
|
||||
const RMSS = { max: rsmax, min: rsmin }
|
||||
const RMSFMinDetail = { rmsvFirstX, rmsvFirstY, firstZhou }
|
||||
const RMSSMinDetail = { rmsvSecondX, rmsvSecondY, secondeZhou }
|
||||
const shunshiF = { shunshiFA, shunshiFB, shunshiFC }
|
||||
const shunshiS = { shunshiSA, shunshiSB, shunshiSC }
|
||||
const RMSFWave = { rmsFA, rmsFB, rmsFC }
|
||||
const RMSSWave = { rmsSA, rmsSB, rmsSC }
|
||||
const title = { aTitle, bTitle, cTitle, unit }
|
||||
|
||||
return {
|
||||
instantF,
|
||||
instantS,
|
||||
RMSF,
|
||||
RMSS,
|
||||
RMSFMinDetail,
|
||||
RMSSMinDetail,
|
||||
shunshiF,
|
||||
shunshiS,
|
||||
RMSFWave,
|
||||
RMSSWave,
|
||||
title,
|
||||
unit
|
||||
}
|
||||
}
|
||||
|
||||
// 监听消息
|
||||
self.onmessage = function (e) {
|
||||
const { wp, isOpen, value, boxoList, requestId } = e.data
|
||||
|
||||
try {
|
||||
const iphasicValue = wp.iphasic || 1
|
||||
|
||||
const picCounts = (wp.waveTitle.length - 1) / iphasicValue
|
||||
const waveDatas = []
|
||||
|
||||
for (let i = 0; i < picCounts; i++) {
|
||||
const data = fliteWaveData(wp, i, iphasicValue, isOpen, boxoList)
|
||||
waveDatas.push(data)
|
||||
}
|
||||
// 处理标题
|
||||
let titles = ''
|
||||
if (boxoList.systemType == 'pms') {
|
||||
titles =
|
||||
'变电站名称:' +
|
||||
boxoList.powerStationName +
|
||||
' 监测点名称:' +
|
||||
boxoList.measurementPointName +
|
||||
' 发生时刻:' +
|
||||
boxoList.startTime +
|
||||
' 暂降(骤升)幅值:' +
|
||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||
'% 持续时间:' +
|
||||
boxoList.duration +
|
||||
's'
|
||||
} else if (boxoList.systemType == 'ZL') {
|
||||
titles =
|
||||
(boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) +
|
||||
' 监测点名称:' +
|
||||
boxoList.equipmentName +
|
||||
' 发生时刻:' +
|
||||
boxoList.startTime +
|
||||
' 暂降(骤升)幅值:' +
|
||||
boxoList.evtParamVVaDepth +
|
||||
'% 持续时间:' +
|
||||
boxoList.evtParamTm +
|
||||
's'
|
||||
} else if (boxoList.systemType == 'YPT') {
|
||||
titles =
|
||||
(boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) +
|
||||
' 监测点名称:' +
|
||||
boxoList.lineName +
|
||||
' 发生时刻:' +
|
||||
boxoList.startTime +
|
||||
' 暂降(骤升)幅值:' +
|
||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||
'% 持续时间:' +
|
||||
boxoList.persistTime +
|
||||
's'
|
||||
} else {
|
||||
titles =
|
||||
' 变电站名称:' +
|
||||
boxoList.subName +
|
||||
' 监测点名称:' +
|
||||
boxoList.lineName +
|
||||
' 发生时刻:' +
|
||||
boxoList.startTime +
|
||||
' 暂降(骤升)幅值:' +
|
||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||
'% 持续时间:' +
|
||||
boxoList.duration +
|
||||
's'
|
||||
}
|
||||
// 发送处理结果回主线程
|
||||
self.postMessage({
|
||||
requestId,
|
||||
titles: titles,
|
||||
success: true,
|
||||
waveDatas,
|
||||
time: wp.time,
|
||||
type: wp.waveType,
|
||||
severity: wp.yzd,
|
||||
iphasic: iphasicValue
|
||||
})
|
||||
} catch (error) {
|
||||
self.postMessage({
|
||||
requestId,
|
||||
success: false,
|
||||
error: error.message
|
||||
})
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
207
src/components/echarts/shuWorker.js
Normal file
207
src/components/echarts/shuWorker.js
Normal file
@@ -0,0 +1,207 @@
|
||||
// waveData.worker.js
|
||||
self.addEventListener('message', function (e) {
|
||||
const { wp, value, iphasic, isOpen, boxoList, requestId } = e.data
|
||||
|
||||
// 处理波形数据的函数
|
||||
const fliteWaveData = (wp, step) => {
|
||||
// 将原有的fliteWaveData函数实现复制到这里
|
||||
const shunData = wp.listWaveData
|
||||
const pt = Number(wp.pt) / 1000
|
||||
const ct = Number(wp.ct)
|
||||
const titleList = wp.waveTitle
|
||||
let xishu = pt
|
||||
let aTitle = '',
|
||||
bTitle = '',
|
||||
cTitle = '',
|
||||
unit = '电压'
|
||||
let ifmax = 0,
|
||||
ifmin = 0,
|
||||
ismax = 0,
|
||||
ismin = 0
|
||||
|
||||
const shunshiFA = []
|
||||
const shunshiFB = []
|
||||
const shunshiFC = []
|
||||
const shunshiSA = []
|
||||
const shunshiSB = []
|
||||
const shunshiSC = []
|
||||
|
||||
if (shunData.length > 0) {
|
||||
if (titleList[iphasic * step + 1]?.substring(0, 1) !== 'U') {
|
||||
xishu = ct
|
||||
unit = '电流'
|
||||
}
|
||||
|
||||
for (let i = 1; i <= iphasic; i++) {
|
||||
switch (i) {
|
||||
case 1:
|
||||
aTitle = titleList[iphasic * step + i]?.substring(1) || ''
|
||||
break
|
||||
case 2:
|
||||
bTitle = titleList[iphasic * step + i]?.substring(1) || ''
|
||||
break
|
||||
case 3:
|
||||
cTitle = titleList[iphasic * step + i]?.substring(1) || ''
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (shunData[0][iphasic * step + 1] !== undefined) {
|
||||
ifmax = shunData[0][iphasic * step + 1] * xishu
|
||||
ifmin = shunData[0][iphasic * step + 1] * xishu
|
||||
ismax = shunData[0][iphasic * step + 1]
|
||||
ismin = shunData[0][iphasic * step + 1]
|
||||
}
|
||||
|
||||
for (let shun = 0; shun < shunData.length; shun++) {
|
||||
if (shunData[shun][iphasic * step + 1] === undefined) {
|
||||
break
|
||||
}
|
||||
|
||||
switch (iphasic) {
|
||||
case 1:
|
||||
const shunFirstA = shunData[shun][iphasic * step + 1] * xishu
|
||||
shunshiFA.push([shunData[shun][0], shunFirstA])
|
||||
ifmax = Math.max(ifmax, shunFirstA)
|
||||
ifmin = Math.min(ifmin, shunFirstA)
|
||||
|
||||
const shunSecondA = shunData[shun][iphasic * step + 1]
|
||||
shunshiSA.push([shunData[shun][0], shunSecondA])
|
||||
ismax = Math.max(ismax, shunSecondA)
|
||||
ismin = Math.min(ismin, shunSecondA)
|
||||
break
|
||||
case 2:
|
||||
const shunFirstA2 = shunData[shun][iphasic * step + 1] * xishu
|
||||
const shunFirstB2 = shunData[shun][iphasic * step + 2] * xishu
|
||||
shunshiFA.push([shunData[shun][0], shunFirstA2])
|
||||
shunshiFB.push([shunData[shun][0], shunFirstB2])
|
||||
ifmax = Math.max(ifmax, shunFirstA2, shunFirstB2)
|
||||
ifmin = Math.min(ifmin, shunFirstA2, shunFirstB2)
|
||||
|
||||
const shunSecondA2 = shunData[shun][iphasic * step + 1]
|
||||
const shunSecondB2 = shunData[shun][iphasic * step + 2]
|
||||
shunshiSA.push([shunData[shun][0], shunSecondA2])
|
||||
shunshiSB.push([shunData[shun][0], shunSecondB2])
|
||||
ismax = Math.max(ismax, shunSecondA2, shunSecondB2)
|
||||
ismin = Math.min(ismin, shunSecondA2, shunSecondB2)
|
||||
break
|
||||
case 3:
|
||||
const shunFirstA3 = shunData[shun][iphasic * step + 1] * xishu
|
||||
const shunFirstB3 = shunData[shun][iphasic * step + 2] * xishu
|
||||
const shunFirstC3 = shunData[shun][iphasic * step + 3] * xishu
|
||||
shunshiFA.push([shunData[shun][0], shunFirstA3])
|
||||
shunshiFB.push([shunData[shun][0], shunFirstB3])
|
||||
shunshiFC.push([shunData[shun][0], shunFirstC3])
|
||||
ifmax = Math.max(ifmax, shunFirstA3, shunFirstB3, shunFirstC3)
|
||||
ifmin = isOpen
|
||||
? Math.min(ifmin, shunFirstA3, shunFirstC3)
|
||||
: Math.min(ifmin, shunFirstA3, shunFirstB3, shunFirstC3)
|
||||
|
||||
const shunSecondA3 = shunData[shun][iphasic * step + 1]
|
||||
const shunSecondB3 = shunData[shun][iphasic * step + 2]
|
||||
const shunSecondC3 = shunData[shun][iphasic * step + 3]
|
||||
shunshiSA.push([shunData[shun][0], shunSecondA3])
|
||||
shunshiSB.push([shunData[shun][0], shunSecondB3])
|
||||
shunshiSC.push([shunData[shun][0], shunSecondC3])
|
||||
ismax = Math.max(ismax, shunSecondA3, shunSecondB3, shunSecondC3)
|
||||
ismin = isOpen
|
||||
? Math.min(ismin, shunSecondA3, shunSecondC3)
|
||||
: Math.min(ismin, shunSecondA3, shunSecondB3, shunSecondC3)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const instantF = { max: ifmax, min: ifmin }
|
||||
const instantS = { max: ismax, min: ismin }
|
||||
const shunshiF = { shunshiFA, shunshiFB, shunshiFC }
|
||||
const shunshiS = { shunshiSA, shunshiSB, shunshiSC }
|
||||
const title = { aTitle, bTitle, cTitle, unit }
|
||||
|
||||
return { instantF, instantS, shunshiF, shunshiS, title, unit }
|
||||
}
|
||||
|
||||
// 处理标题
|
||||
let titles = ''
|
||||
if (boxoList.systemType == 'pms') {
|
||||
titles =
|
||||
'变电站名称:' +
|
||||
boxoList.powerStationName +
|
||||
' 监测点名称:' +
|
||||
boxoList.measurementPointName +
|
||||
' 发生时刻:' +
|
||||
boxoList.startTime +
|
||||
' 暂降(骤升)幅值:' +
|
||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||
'% 持续时间:' +
|
||||
boxoList.duration +
|
||||
's'
|
||||
} else if (boxoList.systemType == 'ZL') {
|
||||
titles =
|
||||
(boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) +
|
||||
' 监测点名称:' +
|
||||
boxoList.equipmentName +
|
||||
' 发生时刻:' +
|
||||
boxoList.startTime +
|
||||
' 暂降(骤升)幅值:' +
|
||||
boxoList.evtParamVVaDepth +
|
||||
'% 持续时间:' +
|
||||
boxoList.evtParamTm +
|
||||
's'
|
||||
} else if (boxoList.systemType == 'YPT') {
|
||||
titles =
|
||||
(boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) +
|
||||
' 监测点名称:' +
|
||||
boxoList.lineName +
|
||||
' 发生时刻:' +
|
||||
boxoList.startTime +
|
||||
' 暂降(骤升)幅值:' +
|
||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||
'% 持续时间:' +
|
||||
boxoList.persistTime +
|
||||
's'
|
||||
} else {
|
||||
titles =
|
||||
'变电站名称:' +
|
||||
boxoList.subName +
|
||||
' 监测点名称:' +
|
||||
boxoList.lineName +
|
||||
' 发生时刻:' +
|
||||
boxoList.startTime +
|
||||
' 暂降(骤升)幅值:' +
|
||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||
'% 持续时间:' +
|
||||
boxoList.duration +
|
||||
's'
|
||||
}
|
||||
|
||||
const iphasicValue = wp.iphasic || 1
|
||||
const picCounts = (wp.waveTitle.length - 1) / iphasicValue
|
||||
const waveDatas = []
|
||||
|
||||
for (let i = 0; i < picCounts; i++) {
|
||||
const data = fliteWaveData(wp, i)
|
||||
waveDatas.push(data)
|
||||
}
|
||||
|
||||
const time = wp.time
|
||||
const type = wp.waveType
|
||||
let severity = wp.yzd
|
||||
|
||||
if (severity < 0) {
|
||||
severity = '/'
|
||||
type = '/'
|
||||
}
|
||||
|
||||
// 将处理结果发送回主线程
|
||||
self.postMessage({
|
||||
requestId,
|
||||
success: true,
|
||||
waveDatas,
|
||||
time,
|
||||
type,
|
||||
severity,
|
||||
titles,
|
||||
iphasic: iphasicValue
|
||||
})
|
||||
})
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
<div v-if="view2">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<span style="font-size: 14px; line-height: 30px">值类型选择:</span>
|
||||
<!-- <span style="font-size: 14px; line-height: 30px">值类型选择:</span>
|
||||
<el-select
|
||||
style="min-width: 200px; width: 200px"
|
||||
@change="changeView"
|
||||
@@ -15,52 +15,31 @@
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
<!-- <el-button v-if="view2 && senior" class="ml10" type="primary"
|
||||
@click="AdvancedAnalytics">高级分析</el-button> -->
|
||||
</el-select> -->
|
||||
<el-radio-group v-model.trim="value" @change="changeView">
|
||||
<el-radio-button label="一次值" :value="1" />
|
||||
<el-radio-button label="二次值" :value="2" />
|
||||
</el-radio-group>
|
||||
<!-- <el-button v-if="view2 && senior" class="ml10" type="primary" @click="AdvancedAnalytics">
|
||||
高级分析
|
||||
</el-button> -->
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-button
|
||||
@click="backbxlb"
|
||||
class="el-icon-refresh-right"
|
||||
icon="el-icon-Back"
|
||||
style="float: right"
|
||||
>
|
||||
返回
|
||||
</el-button>
|
||||
<el-button @click="backbxlb" icon="el-icon-Back" style="float: right">返回</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div v-loading="loading" style="height: calc(100vh - 190px)">
|
||||
<el-tabs v-if="view4" class="default-main" v-model="bxactiveName" @tab-click="bxhandleClick">
|
||||
<el-tab-pane
|
||||
label="瞬时波形"
|
||||
name="ssbx"
|
||||
class="boxbx pt10 pb10"
|
||||
:style="'height:' + bxecharts + ';overflow-y: scroll;'"
|
||||
>
|
||||
<shushiboxi
|
||||
ref="shushiboxiRef"
|
||||
v-if="bxactiveName == 'ssbx' && showBoxi"
|
||||
:value="value"
|
||||
:parentHeight="parentHeight"
|
||||
:boxoList="boxoList"
|
||||
:wp="wp"
|
||||
></shushiboxi>
|
||||
<div v-loading="loading" style="height: calc(100vh - 190px)" class="mt10">
|
||||
<el-tabs v-if="view4" type="border-card" v-model="bxactiveName"
|
||||
@tab-click="bxhandleClick">
|
||||
<el-tab-pane label="瞬时波形" name="ssbx" class="boxbx pt10 pb10"
|
||||
:style="'height:' + bxecharts + ';overflow-y: scroll;'">
|
||||
<shushiboxi ref="shushiboxiRef" v-if="bxactiveName == 'ssbx' && showBoxi" :value="value"
|
||||
:parentHeight="parentHeight" :boxoList="boxoList" :wp="wp"></shushiboxi>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane
|
||||
label="RMS波形"
|
||||
class="boxbx pt10 pb10"
|
||||
name="rmsbx"
|
||||
:style="'height:' + bxecharts + ';overflow-y: scroll;'"
|
||||
>
|
||||
<rmsboxi
|
||||
ref="rmsboxiRef"
|
||||
v-if="bxactiveName == 'rmsbx' && showBoxi"
|
||||
:value="value"
|
||||
:parentHeight="parentHeight"
|
||||
:boxoList="boxoList"
|
||||
:wp="wp"
|
||||
></rmsboxi>
|
||||
<el-tab-pane label="RMS波形" class="boxbx pt10 pb10" name="rmsbx"
|
||||
:style="'height:' + bxecharts + ';overflow-y: scroll;'">
|
||||
<rmsboxi ref="rmsboxiRef" v-if="bxactiveName == 'rmsbx' && showBoxi" :value="value"
|
||||
:parentHeight="parentHeight" :boxoList="boxoList" :wp="wp"></rmsboxi>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-empty v-else description="暂无数据" style="height: calc(100vh - 190px)" />
|
||||
@@ -76,10 +55,12 @@
|
||||
import shushiboxi from '@/components/echarts/shushiboxi.vue'
|
||||
import rmsboxi from '@/components/echarts/rmsboxi.vue'
|
||||
import analytics from '@/components/echarts/analytics.vue'
|
||||
import { ref, reactive } from 'vue'
|
||||
import { ref, shallowRef } from 'vue'
|
||||
import { analysis } from '@/api/advance-boot/analyse'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { getMonitorEventAnalyseWave, downloadWaveFile } from '@/api/event-boot/transient'
|
||||
import { buildWaveStoreKey, registerWaveRaw, buildSlimWp, releaseWaveRaw } from '@/utils/waveRawStore'
|
||||
import { clearWaveCache } from '@/utils/waveCache'
|
||||
const emit = defineEmits(['backbxlb'])
|
||||
interface Props {
|
||||
// boxoList: any
|
||||
@@ -106,14 +87,14 @@ const options = ref([
|
||||
}
|
||||
])
|
||||
const shushiboxiRef = ref()
|
||||
const bxecharts = ref(mainHeight(95).height as any)
|
||||
const bxecharts = ref(mainHeight(145).height as any)
|
||||
const view2 = ref(true)
|
||||
const boxoList = ref(null)
|
||||
const wp = ref(null)
|
||||
const boxoList: any = ref(null)
|
||||
const wp = shallowRef<any>(null)
|
||||
const showBoxi = ref(true)
|
||||
const view3 = ref(false)
|
||||
const view4 = ref(false)
|
||||
const GJList = ref([])
|
||||
const GJList = ref({})
|
||||
|
||||
const open = async (row: any) => {
|
||||
loading.value = true
|
||||
@@ -122,19 +103,20 @@ const open = async (row: any) => {
|
||||
row.loading = false
|
||||
if (res != undefined) {
|
||||
boxoList.value = row
|
||||
wp.value = res.data
|
||||
boxoList.value.pt = res.data.pt
|
||||
const storeKey = buildWaveStoreKey(row)
|
||||
registerWaveRaw(storeKey, res.data)
|
||||
wp.value = buildSlimWp(res.data, storeKey)
|
||||
loading.value = false
|
||||
view4.value = true
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
backbxlb()
|
||||
})
|
||||
}
|
||||
const bxhandleClick = (tab: any) => {
|
||||
if (shushiboxiRef.value) shushiboxiRef.value.backbxlb()
|
||||
if (rmsboxiRef.value) rmsboxiRef.value.backbxlb()
|
||||
|
||||
loading.value = true
|
||||
if (tab.name == 'ssbx') {
|
||||
bxactiveName.value = 'ssbx'
|
||||
@@ -147,10 +129,12 @@ const bxhandleClick = (tab: any) => {
|
||||
// console.log(tab, event);
|
||||
}
|
||||
const backbxlb = () => {
|
||||
const storeKey = wp.value?.waveStoreKey
|
||||
releaseWaveRaw(storeKey, 'all')
|
||||
clearWaveCache()
|
||||
boxoList.value = null
|
||||
wp.value = null
|
||||
if (shushiboxiRef.value) shushiboxiRef.value.backbxlb()
|
||||
if (rmsboxiRef.value) rmsboxiRef.value.backbxlb()
|
||||
|
||||
|
||||
emit('backbxlb')
|
||||
}
|
||||
@@ -168,14 +152,17 @@ const AdvancedAnalytics = () => {
|
||||
analysis({
|
||||
eventIndex: boxoList.value.eventId
|
||||
}).then(res => {
|
||||
GJList.value = res.data
|
||||
view3.value = true
|
||||
view2.value = false
|
||||
// GJList.value = res.data
|
||||
// view3.value = true
|
||||
// view2.value = false
|
||||
})
|
||||
GJList.value = {}
|
||||
view3.value = true
|
||||
view2.value = false
|
||||
}
|
||||
const changeView = () => {
|
||||
if (shushiboxiRef.value) shushiboxiRef.value.backbxlb()
|
||||
if (rmsboxiRef.value) rmsboxiRef.value.backbxlb()
|
||||
shushiboxiRef.value?.backbxlb?.()
|
||||
rmsboxiRef.value?.backbxlb?.()
|
||||
showBoxi.value = false
|
||||
setTimeout(() => {
|
||||
showBoxi.value = true
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<template>
|
||||
<div style="width: 540px">
|
||||
<div :style="{ width: isMinuteData ? '750px' : '610px' }">
|
||||
<el-select v-model="interval" style="min-width: 90px; width: 90px; margin-right: 10px" @change="timeChange">
|
||||
<el-option v-for="item in timeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
|
||||
<el-date-picker
|
||||
v-model="timeValue"
|
||||
type="daterange"
|
||||
:type="pickerType"
|
||||
:disabled="disabledPicker"
|
||||
:disabled-date="isFutureDate"
|
||||
style="width: 220px; margin-right: 10px"
|
||||
:style="{ width: isMinuteData ? '360px' : '220px', marginRight: '10px' }"
|
||||
unlink-panels
|
||||
:clearable="false"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
:shortcuts="shortcuts"
|
||||
:start-placeholder="isMinuteData ? '开始时间' : '开始日期'"
|
||||
:end-placeholder="isMinuteData ? '结束时间' : '结束日期'"
|
||||
:value-format="pickerValueFormat"
|
||||
:shortcuts="isMinuteData ? undefined : shortcuts"
|
||||
/>
|
||||
<el-button :disabled="backDisabled" type="primary" :icon="DArrowLeft" @click="preClick"></el-button>
|
||||
<el-button type="primary" :icon="VideoPause" @click="nowTime">当前</el-button>
|
||||
@@ -26,18 +26,41 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { DArrowLeft, VideoPause, DArrowRight } from '@element-plus/icons-vue'
|
||||
import { ref, onMounted, nextTick, watch } from 'vue'
|
||||
import { ref, onMounted, computed, watch } from 'vue'
|
||||
|
||||
interface Props {
|
||||
nextFlag?: boolean
|
||||
theCurrentTime?: boolean
|
||||
isStatisticData?: number | string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
nextFlag: false,
|
||||
theCurrentTime: false
|
||||
theCurrentTime: false,
|
||||
isStatisticData: 0
|
||||
})
|
||||
|
||||
const isMinuteData = computed(() => Number(props.isStatisticData) === 1)
|
||||
const pickerType = computed(() => (isMinuteData.value ? 'datetimerange' : 'daterange'))
|
||||
const pickerValueFormat = computed(() => (isMinuteData.value ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD'))
|
||||
|
||||
const toDatePart = (value: string) => (value?.includes(' ') ? value.split(' ')[0] : value)
|
||||
|
||||
const toMinuteStart = (date: string) => `${toDatePart(date)} 00:00:00`
|
||||
|
||||
const toMinuteEnd = (date: string) => `${toDatePart(date)} 23:59:59`
|
||||
|
||||
const normalizeRange = (start: string, end: string) => {
|
||||
if (!isMinuteData.value) {
|
||||
return [toDatePart(start), toDatePart(end)]
|
||||
}
|
||||
return [toMinuteStart(start), toMinuteEnd(end)]
|
||||
}
|
||||
|
||||
const setRangeValue = (start: string, end: string) => {
|
||||
timeValue.value = normalizeRange(start, end)
|
||||
}
|
||||
|
||||
const interval = ref(3)
|
||||
const timeFlag = ref(1)
|
||||
const count = ref(0)
|
||||
@@ -95,13 +118,13 @@ const timeChange = (e: number) => {
|
||||
if (e == 1) {
|
||||
disabledPicker.value = true
|
||||
|
||||
timeValue.value = [setTime(1), setTime()]
|
||||
setRangeValue(setTime(1), setTime())
|
||||
} else if (e == 2) {
|
||||
disabledPicker.value = true
|
||||
timeValue.value = [setTime(2), setTime()]
|
||||
setRangeValue(setTime(2), setTime())
|
||||
} else if (e == 3) {
|
||||
disabledPicker.value = true
|
||||
timeValue.value = [setTime(3), setTime()]
|
||||
setRangeValue(setTime(3), setTime())
|
||||
} else if (e == 4) {
|
||||
let year = parseInt(setTime().substring(0, 4))
|
||||
let month = parseInt(setTime().substring(5, 7))
|
||||
@@ -111,12 +134,12 @@ const timeChange = (e: number) => {
|
||||
var dayOfWeek = start.getDay() == 0 ? 7 : start.getDay() - 1 // 如果为周日,则置为7天
|
||||
|
||||
disabledPicker.value = true
|
||||
timeValue.value = [setTime(0, dayOfWeek), setTime(0, -6 + dayOfWeek)]
|
||||
setRangeValue(setTime(0, dayOfWeek), setTime(0, -6 + dayOfWeek))
|
||||
} else if (e == 5) {
|
||||
disabledPicker.value = false
|
||||
backDisabled.value = true
|
||||
preDisabled.value = props.nextFlag ? false : true
|
||||
timeValue.value = [setTime(), setTime()]
|
||||
setRangeValue(setTime(), setTime())
|
||||
}
|
||||
if (e == 1 || e == 2) {
|
||||
timeFlag.value = 0
|
||||
@@ -186,7 +209,7 @@ const preClick = () => {
|
||||
startTime = year + '-01-01'
|
||||
endTime = year + '-12-31'
|
||||
}
|
||||
timeValue.value = [startTime, endTime]
|
||||
setRangeValue(startTime, endTime)
|
||||
|
||||
// 判断向后键的状态
|
||||
// var temp = NowgetEndTime()
|
||||
@@ -415,16 +438,27 @@ const next = () => {
|
||||
}
|
||||
if (!props.nextFlag) {
|
||||
if (
|
||||
new Date(endTime + ' 00:00:00').getTime() >=
|
||||
new Date(toDatePart(endTime) + ' 00:00:00').getTime() >=
|
||||
new Date(window.XEUtils.toDateString(new Date(), 'yyyy-MM-dd ') + ' 00:00:00').getTime()
|
||||
) {
|
||||
preDisabled.value = props.nextFlag ? false : true
|
||||
}
|
||||
}
|
||||
|
||||
timeValue.value = [startTime, endTime]
|
||||
setRangeValue(startTime, endTime)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.isStatisticData,
|
||||
() => {
|
||||
if (timeValue.value?.length === 2) {
|
||||
setRangeValue(timeValue.value[0], timeValue.value[1])
|
||||
} else {
|
||||
timeChange(interval.value)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const setTime = (flag = 0, e = 0) => {
|
||||
let dd = window.XEUtils.toDateString(new Date().getTime() - e * 3600 * 1000 * 24, 'dd')
|
||||
|
||||
|
||||
@@ -9,11 +9,8 @@ export const defaultAttribute: VxeTableProps = {
|
||||
columnConfig: { resizable: true },
|
||||
rowConfig: { isCurrent: true, isHover: true },
|
||||
scrollX: { scrollToLeftOnChange: true },
|
||||
scrollY: { scrollToTopOnChange: true, enabled: true },
|
||||
treeConfig: {
|
||||
reserve: true
|
||||
},
|
||||
showOverflow: true,
|
||||
showFooter:true
|
||||
scrollY: { scrollToTopOnChange: true, enabled: true, gt: 100 },
|
||||
customConfig: { enabled: true, allowFixed: false, showFooter: false, immediate: true ,mode:'default'},
|
||||
showOverflow: 'tooltip',
|
||||
showHeaderOverflow: false
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
label-position="left"
|
||||
:inline="true"
|
||||
>
|
||||
<el-form-item v-if="datePicker" style="grid-column: span 2; max-width: 630px">
|
||||
<el-form-item
|
||||
v-if="datePicker"
|
||||
style="grid-column: span 2"
|
||||
:style="{ maxWidth: isStatisticData == 1 ? '750px' : '610px' }"
|
||||
>
|
||||
<template #label>
|
||||
<el-checkbox v-if="showTimeAll" v-model="timeAll" label="统计时间" />
|
||||
<span v-else>{{ dateLabel }}</span>
|
||||
@@ -19,11 +23,17 @@
|
||||
v-if="timeAll"
|
||||
:nextFlag="nextFlag"
|
||||
:theCurrentTime="theCurrentTime"
|
||||
:isStatisticData="isStatisticData"
|
||||
></DatePicker>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="区域" v-if="area">
|
||||
<Area ref="areaRef" v-model="tableStore.table.params.deptIndex" @change-value="onAreaChange" />
|
||||
<Area
|
||||
ref="areaRef"
|
||||
v-model="tableStore.table.params.deptIndex"
|
||||
@change-value="onAreaChange"
|
||||
style="width: 200px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<slot name="select"></slot>
|
||||
</el-form>
|
||||
@@ -60,6 +70,7 @@
|
||||
</el-button>
|
||||
</template>
|
||||
<slot name="operation"></slot>
|
||||
<el-button class="ml10" v-if="showCustomColumn" :icon="Setting" @click="openCustomColumn">列设置</el-button>
|
||||
</div>
|
||||
<el-form
|
||||
:style="showSelect && showUnfoldButton ? headerFormSecondStyleOpen : headerFormSecondStyleClose"
|
||||
@@ -79,9 +90,8 @@ import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import Area from '@/components/form/area/index.vue'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { Search, RefreshLeft } from '@element-plus/icons-vue'
|
||||
import { defineProps } from 'vue'
|
||||
const emit = defineEmits(['selectChange','areaChange'])
|
||||
import { Search, RefreshLeft, Setting } from '@element-plus/icons-vue'
|
||||
const emit = defineEmits(['selectChange', 'areaChange'])
|
||||
const tableStore = inject('tableStore') as TableStore
|
||||
const tableHeader = ref()
|
||||
const datePickerRef = ref()
|
||||
@@ -100,6 +110,8 @@ interface Props {
|
||||
showExport?: boolean //导出控制
|
||||
showTimeAll?: boolean //控制时间是否显示
|
||||
dateLabel?: string //设置时间名称
|
||||
isStatisticData?: number | string // 0统计数据 1分钟数据
|
||||
showCustomColumn?: boolean // 列设置
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@@ -111,7 +123,9 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
showReset: true,
|
||||
showExport: false,
|
||||
showTimeAll: false,
|
||||
dateLabel: '统计日期'
|
||||
dateLabel: '统计日期',
|
||||
isStatisticData: 0,
|
||||
showCustomColumn: false
|
||||
})
|
||||
// 动态计算table高度
|
||||
const resizeObserver = new ResizeObserver(entries => {
|
||||
@@ -132,9 +146,8 @@ const headerFormSecondStyleClose = {
|
||||
padding: '0'
|
||||
}
|
||||
|
||||
const onAreaChange = (data) => {
|
||||
|
||||
emit('areaChange', {label: data.label})
|
||||
const onAreaChange = data => {
|
||||
emit('areaChange', { label: data.label })
|
||||
}
|
||||
|
||||
watch(
|
||||
@@ -142,7 +155,6 @@ watch(
|
||||
newVal => {
|
||||
setTimeout(() => {
|
||||
areaRef.value && areaRef.value.change()
|
||||
|
||||
}, 0)
|
||||
}
|
||||
)
|
||||
@@ -155,7 +167,13 @@ watch(
|
||||
}, 500)
|
||||
}
|
||||
)
|
||||
const openCustomColumn = () => {
|
||||
tableStore?.table?.ref?.openCustom?.()
|
||||
}
|
||||
onMounted(() => {
|
||||
if (props.showCustomColumn && tableStore?.table) {
|
||||
tableStore.table.customColumnInHeader = true
|
||||
}
|
||||
timeAll.value = props.showTimeAll ? false : true
|
||||
if (props.datePicker && timeAll.value) {
|
||||
tableStore.table.params.searchBeginTime = datePickerRef.value.timeValue[0]
|
||||
@@ -238,14 +256,14 @@ const onResetForm = () => {
|
||||
//时间重置成默认值
|
||||
datePickerRef.value?.setTheDate(3)
|
||||
|
||||
if(props.showTimeAll){
|
||||
timeAll.value = false
|
||||
delete tableStore.table.params.searchBeginTime
|
||||
delete tableStore.table.params.searchEndTime
|
||||
delete tableStore.table.params.startTime
|
||||
delete tableStore.table.params.endTime
|
||||
delete tableStore.table.params.timeFlag
|
||||
delete tableStore.table.params.interval
|
||||
if (props.showTimeAll) {
|
||||
timeAll.value = false
|
||||
delete tableStore.table.params.searchBeginTime
|
||||
delete tableStore.table.params.searchEndTime
|
||||
delete tableStore.table.params.startTime
|
||||
delete tableStore.table.params.endTime
|
||||
delete tableStore.table.params.timeFlag
|
||||
delete tableStore.table.params.interval
|
||||
}
|
||||
|
||||
if (props.datePicker && timeAll.value) {
|
||||
@@ -264,7 +282,6 @@ const setTheDate = (val: any) => {
|
||||
}
|
||||
// 导出
|
||||
const onExport = () => {
|
||||
|
||||
tableStore.onTableAction('export', { showAllFlag: true })
|
||||
}
|
||||
|
||||
@@ -300,6 +317,7 @@ defineExpose({
|
||||
padding: 13px 15px;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
|
||||
.table-header-operate-text {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
@@ -1,24 +1,46 @@
|
||||
<template>
|
||||
<div :style="{ height: typeof props.height === 'string' ? props.height : tableStore.table.height }">
|
||||
<vxe-table ref="tableRef" height="auto" :key="key" :data="tableStore.table.data"
|
||||
v-loading="tableStore.table.loading" v-bind="Object.assign({}, defaultAttribute, $attrs)"
|
||||
@checkbox-all="selectChangeEvent" @checkbox-change="selectChangeEvent" :showOverflow="showOverflow"
|
||||
@sort-change="handleSortChange">
|
||||
<div v-if="showCustomColumn && !tableStore?.table?.customColumnInHeader" class="table-custom-toolbar">
|
||||
<el-button icon="el-icon-Setting" @click="openCustomColumn">列设置</el-button>
|
||||
</div>
|
||||
<vxe-table
|
||||
ref="tableRef"
|
||||
height="auto"
|
||||
:key="key"
|
||||
:data="tableStore.table.data"
|
||||
v-loading="tableStore.table.loading"
|
||||
v-bind="tableBindProps"
|
||||
@checkbox-all="selectChangeEvent"
|
||||
@checkbox-change="selectChangeEvent"
|
||||
@cell-click="onCellClick"
|
||||
>
|
||||
<!-- @sort-change="handleSortChange" -->
|
||||
<!-- Column 组件内部是 el-table-column -->
|
||||
<template v-if="isGroup">
|
||||
<GroupColumn :column="tableStore.table.column" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<Column :attr="item" :key="key + '-column'" v-for="(item, key) in tableStore.table.column"
|
||||
:tree-node="item.treeNode">
|
||||
<Column
|
||||
:attr="item"
|
||||
:key="key + '-column'"
|
||||
v-for="(item, key) in tableStore.table.column"
|
||||
:tree-node="item.treeNode"
|
||||
>
|
||||
<!-- tableStore 预设的列 render 方案 -->
|
||||
<template v-if="item.render" #default="scope">
|
||||
<FieldRender :field="item" :row="scope.row" :column="scope.column" :index="scope.rowIndex" :key="key +
|
||||
'-' +
|
||||
item.render +
|
||||
'-' +
|
||||
(item.field ? '-' + item.field + '-' + scope.row[item.field] : '')
|
||||
" />
|
||||
<FieldRender
|
||||
:field="item"
|
||||
:row="scope.row"
|
||||
:column="scope.column"
|
||||
:index="scope.rowIndex"
|
||||
:key="
|
||||
key +
|
||||
'-' +
|
||||
item.render +
|
||||
'-' +
|
||||
(item.field ? '-' + item.field + '-' + scope.row[item.field] : '')
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
</Column>
|
||||
</template>
|
||||
@@ -27,17 +49,22 @@
|
||||
</div>
|
||||
|
||||
<div v-if="tableStore.showPage" class="table-pagination">
|
||||
<el-pagination :currentPage="tableStore.table.params!.pageNum" :page-size="tableStore.table.params!.pageSize"
|
||||
:page-sizes="pageSizes" background
|
||||
<el-pagination
|
||||
:currentPage="tableStore.table.params!.pageNum"
|
||||
:page-size="tableStore.table.params!.pageSize"
|
||||
:page-sizes="pageSizes"
|
||||
background
|
||||
:layout="config.layout.shrink ? 'prev, next, jumper' : 'sizes,total, ->, prev, pager, next, jumper'"
|
||||
:total="tableStore.table.total" @size-change="onTableSizeChange"
|
||||
@current-change="onTableCurrentChange"></el-pagination>
|
||||
:total="tableStore.table.total"
|
||||
@size-change="onTableSizeChange"
|
||||
@current-change="onTableCurrentChange"
|
||||
></el-pagination>
|
||||
</div>
|
||||
<slot name="footer"></slot>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, inject, computed, onMounted, watch } from 'vue'
|
||||
import { ref, nextTick, inject, computed, onMounted, watch, useAttrs } from 'vue'
|
||||
import type { ElTable } from 'element-plus'
|
||||
import { VxeTableEvents, VxeTableInstance } from 'vxe-table'
|
||||
import FieldRender from '@/components/table/fieldRender/index.vue'
|
||||
@@ -53,17 +80,32 @@ const tableRef = ref<VxeTableInstance>()
|
||||
const tableStore = inject('tableStore') as TableStoreClass
|
||||
const router = useRouter()
|
||||
const key = ref(0)
|
||||
const emit = defineEmits<{
|
||||
(e: 'cell-click', params: any): void
|
||||
}>()
|
||||
interface Props extends /* @vue-ignore */ Partial<InstanceType<typeof ElTable>> {
|
||||
isGroup?: boolean
|
||||
showOverflow?: boolean
|
||||
showOverflow?: boolean | 'ellipsis' | 'title' | 'tooltip'
|
||||
height?: string | number
|
||||
showCustomColumn?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
isGroup: false,
|
||||
showOverflow: true,
|
||||
height: undefined
|
||||
showOverflow: 'tooltip',
|
||||
height: undefined,
|
||||
showCustomColumn: false
|
||||
})
|
||||
const attrs = useAttrs()
|
||||
const tableBindProps = computed(() => {
|
||||
return Object.assign({}, defaultAttribute, attrs, {
|
||||
showOverflow: props.showOverflow,
|
||||
showHeaderOverflow: false
|
||||
})
|
||||
})
|
||||
const onCellClick: VxeTableEvents.CellClick<any> = params => {
|
||||
emit('cell-click', params)
|
||||
}
|
||||
onMounted(() => {
|
||||
tableStore.table.ref = tableRef.value as VxeTableInstance
|
||||
})
|
||||
@@ -93,7 +135,9 @@ const selectChangeEvent: VxeTableEvents.CheckboxChange<any> = ({ checked }) => {
|
||||
const records = (tableRef.value as VxeTableInstance).getCheckboxRecords()
|
||||
tableStore.onTableAction('selection-change', records)
|
||||
}
|
||||
|
||||
const openCustomColumn = () => {
|
||||
tableRef.value?.openCustom?.()
|
||||
}
|
||||
const getRef = () => {
|
||||
return tableRef.value
|
||||
}
|
||||
|
||||
@@ -3,167 +3,177 @@
|
||||
<el-tabs type="border-card" v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane label="监测点详情" name="tab1">
|
||||
<el-descriptions :column="3" border label-width="150px">
|
||||
<el-descriptions-item label="项目工程">
|
||||
<el-descriptions-item label="项目工程">
|
||||
{{ details.areaName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="项目单位">
|
||||
<el-descriptions-item label="项目单位">
|
||||
{{ details.gdName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="所属变电站">
|
||||
<el-descriptions-item label="所属变电站">
|
||||
{{ details.bdName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="电压等级">
|
||||
{{ details.scale }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="终端厂家">
|
||||
{{ details.manufacturer }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="终端名称">
|
||||
{{ details.devName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="网络参数">
|
||||
{{ details.ip }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="监测点名称">
|
||||
<el-descriptions-item label="监测点名称">
|
||||
{{ details.lineName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="监测点序号">
|
||||
{{ details.id }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="通讯状态">
|
||||
{{ details.comFlag }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="干扰源类型">
|
||||
{{ details.loadType }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="监测点对象名称">
|
||||
<el-descriptions-item label="监测点对象名称">
|
||||
{{ details.objName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="接线方式">
|
||||
<el-descriptions-item label="监测点序号">
|
||||
{{ details.id }}
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="终端厂家">
|
||||
{{ details.manufacturer }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="终端名称">
|
||||
{{ details.devName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="终端型号">
|
||||
{{ typeArr.find(item => item.id == details.devType)?.name }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="电压等级">
|
||||
{{ details.scale }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="网络参数">
|
||||
{{ details.ip }}
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="通讯状态">
|
||||
{{ details.comFlag }}
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="干扰源类型">
|
||||
{{ details.loadType }}
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="接线方式">
|
||||
{{ details.ptType }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="PT变比">
|
||||
<el-descriptions-item label="统计间隔(分钟)">
|
||||
{{ details.timeInterval }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="PT变比">
|
||||
{{ details.pt }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="CT变比">
|
||||
<el-descriptions-item label="CT变比">
|
||||
{{ details.ct }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="基准容量(MVA)">
|
||||
<el-descriptions-item label="基准容量(MVA)">
|
||||
{{ details.standardCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="最小短路容量(MVA)">
|
||||
{{ details.shortCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="供电设备容量(MVA)">
|
||||
<el-descriptions-item label="供电设备容量(MVA)">
|
||||
{{ details.devCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户协议容量(MVA)">
|
||||
<el-descriptions-item label="最小短路容量(MW)">
|
||||
{{ details.shortCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户协议容量(MW)">
|
||||
{{ details.dealCapacity }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="监测点限值" name="tab2">
|
||||
<el-descriptions :column="3" border label-width="250px">
|
||||
<el-descriptions-item label="电压偏差上限值(%)">
|
||||
<el-descriptions :column="3" border label-width="250px">
|
||||
<el-descriptions-item label="电压偏差上限值(%)">
|
||||
{{ limitValue.voltageDev }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="电压偏差下限值(%)">
|
||||
<el-descriptions-item label="电压偏差下限值(%)">
|
||||
{{ limitValue.uvoltageDev }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="频率偏差限值(Hz)">
|
||||
<el-descriptions-item label="频率偏差限值(Hz)">
|
||||
{{ limitValue.freqDev }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="三相电压不平衡度限值(%)">
|
||||
<el-descriptions-item label="三相电压不平衡度限值(%)">
|
||||
{{ limitValue.ubalance }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="负序电流限值(A)">
|
||||
<el-descriptions-item label="负序电流限值(A)">
|
||||
{{ limitValue.ineg }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="长时闪变限值(%)">
|
||||
<el-descriptions-item label="长时闪变限值(%)">
|
||||
{{ limitValue.flicker }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="电压总畸变率限值(%)">
|
||||
<el-descriptions-item label="电压总畸变率限值(%)">
|
||||
{{ limitValue.uaberrance }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="奇次谐波电压含有率限值(%)">
|
||||
<el-descriptions-item label="奇次谐波电压含有率限值(%)">
|
||||
{{ limitValue.oddHarm }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="偶次谐波电压含有率限值(%)">
|
||||
<el-descriptions-item label="偶次谐波电压含有率限值(%)">
|
||||
{{ limitValue.evenHarm }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="3次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="3次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm3 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="4次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="4次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm4 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="5次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="5次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm5 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="6次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="6次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm6 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="7次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="7次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm7 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="8次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="8次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm8 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="9次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="9次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm9 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="10次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="10次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm10 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="11次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="11次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm11 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="12次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="12次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm12 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="13次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="13次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm13 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="14次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="14次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm14 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="15次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="15次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm15 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="16次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="16次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm16 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="17次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="17次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm17 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="18次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="18次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm18 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="19次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="19次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm19 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="20次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="20次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm20 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="21次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="21次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm21 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="22次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="22次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm22 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="23次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="23次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm23 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="24次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="24次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm24 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="25次谐波电流幅值限值(A)">
|
||||
<el-descriptions-item label="25次谐波电流幅值限值(A)">
|
||||
{{ limitValue.iharm25 }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="0.5-1.5次间谐波电压含有率限值(%)">
|
||||
<el-descriptions-item label="0.5-1.5次间谐波电压含有率限值(%)">
|
||||
{{ limitValue.inUharm }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="2.5-15.5次谐波电压含有率限值(%)">
|
||||
<el-descriptions-item label="2.5-15.5次谐波电压含有率限值(%)">
|
||||
{{ limitValue.inUharm16 }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
@@ -174,11 +184,14 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, inject } from 'vue'
|
||||
import { getLineOverLimitData, getLineDetailData } from '@/api/device-boot/line'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('')
|
||||
const activeName = ref('tab1')
|
||||
const details: any = ref([])
|
||||
const dictData = useDictData()
|
||||
const limitValue: any = ref([])
|
||||
const typeArr = dictData.getBasicData('Dev_Type')
|
||||
const open = (data: any) => {
|
||||
details.value = []
|
||||
limitValue.value = []
|
||||
@@ -187,7 +200,7 @@ const open = (data: any) => {
|
||||
|
||||
getLineDetailData(data.id).then(res => {
|
||||
details.value = res.data
|
||||
|
||||
res.data.objName ? (title.value = res.data.objName + '_' + title.value) : ''
|
||||
})
|
||||
getLineOverLimitData(data.id).then(res => {
|
||||
limitValue.value = res.data
|
||||
|
||||
@@ -28,66 +28,66 @@ const info = (id: any) => {
|
||||
expanded.value = [id]
|
||||
getTerminalTree().then(res => {
|
||||
// let arr: any[] = []
|
||||
if (VITE_FLAG) {
|
||||
res.data.forEach((item: any) => {
|
||||
item.icon = 'el-icon-Menu'
|
||||
item.plevel = item.level
|
||||
item.level = 0
|
||||
item.children.forEach((item2: any) => {
|
||||
item2.icon = 'el-icon-HomeFilled'
|
||||
// if (VITE_FLAG) {
|
||||
// res.data.forEach((item: any) => {
|
||||
// item.icon = 'el-icon-Menu'
|
||||
// item.plevel = item.level
|
||||
// item.level = 0
|
||||
// item.children.forEach((item2: any) => {
|
||||
// item2.icon = 'el-icon-HomeFilled'
|
||||
|
||||
item2.plevel = item2.level
|
||||
item2.level = 100
|
||||
expanded.value.push(item2.id)
|
||||
item2.children.forEach((item3: any) => {
|
||||
item3.icon = 'el-icon-CollectionTag'
|
||||
item3.plevel = item3.level
|
||||
item3.level = 200
|
||||
item3.children.forEach((item4: any) => {
|
||||
item4.icon = 'el-icon-Flag'
|
||||
item4.plevel = item4.level
|
||||
item4.level = 300
|
||||
// arr.push(item4)
|
||||
item4.children.forEach((item5: any) => {
|
||||
item5.icon = 'el-icon-OfficeBuilding'
|
||||
item5.plevel = item5.level
|
||||
item5.level = 300
|
||||
// item5.id = item4.id
|
||||
item5.children.forEach((item6: any) => {
|
||||
item6.icon = 'el-icon-HelpFilled'
|
||||
item6.plevel = 4
|
||||
if (item6.name == '电网侧' && item6.children.length == 0) {
|
||||
item6.level = 400
|
||||
} else {
|
||||
item6.level = 400
|
||||
}
|
||||
item6.children.forEach((item7: any) => {
|
||||
item7.icon = 'el-icon-Film'
|
||||
item7.plevel = item7.level
|
||||
item7.level = 400
|
||||
item7.children.forEach((item8: any) => {
|
||||
item8.icon = 'el-icon-Collection'
|
||||
item8.plevel = item8.level
|
||||
item8.level = 500
|
||||
item8.children.forEach((item9: any) => {
|
||||
item9.icon = 'el-icon-Share'
|
||||
item9.plevel = item9.level
|
||||
item9.level = 600
|
||||
item9.children.forEach((item10: any) => {
|
||||
item10.icon = 'el-icon-Location'
|
||||
item10.plevel = item10.level
|
||||
item10.level = 700
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// item2.plevel = item2.level
|
||||
// item2.level = 100
|
||||
// expanded.value.push(item2.id)
|
||||
// item2.children.forEach((item3: any) => {
|
||||
// item3.icon = 'el-icon-CollectionTag'
|
||||
// item3.plevel = item3.level
|
||||
// item3.level = 200
|
||||
// item3.children.forEach((item4: any) => {
|
||||
// item4.icon = 'el-icon-Flag'
|
||||
// item4.plevel = item4.level
|
||||
// item4.level = 300
|
||||
// // arr.push(item4)
|
||||
// item4.children.forEach((item5: any) => {
|
||||
// item5.icon = 'el-icon-OfficeBuilding'
|
||||
// item5.plevel = item5.level
|
||||
// item5.level = 300
|
||||
// // item5.id = item4.id
|
||||
// item5.children.forEach((item6: any) => {
|
||||
// item6.icon = 'el-icon-HelpFilled'
|
||||
// item6.plevel = 4
|
||||
// if (item6.name == '电网侧' && item6.children.length == 0) {
|
||||
// item6.level = 400
|
||||
// } else {
|
||||
// item6.level = 400
|
||||
// }
|
||||
// item6.children.forEach((item7: any) => {
|
||||
// item7.icon = 'el-icon-Film'
|
||||
// item7.plevel = item7.level
|
||||
// item7.level = 400
|
||||
// item7.children.forEach((item8: any) => {
|
||||
// item8.icon = 'el-icon-Collection'
|
||||
// item8.plevel = item8.level
|
||||
// item8.level = 500
|
||||
// item8.children.forEach((item9: any) => {
|
||||
// item9.icon = 'el-icon-Share'
|
||||
// item9.plevel = item9.level
|
||||
// item9.level = 600
|
||||
// item9.children.forEach((item10: any) => {
|
||||
// item10.icon = 'el-icon-Location'
|
||||
// item10.plevel = item10.level
|
||||
// item10.level = 700
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// } else {
|
||||
res.data.forEach((item: any) => {
|
||||
item.icon = 'el-icon-Menu'
|
||||
item.plevel = item.level
|
||||
@@ -129,7 +129,7 @@ const info = (id: any) => {
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
// }
|
||||
|
||||
tree.value = res.data
|
||||
|
||||
|
||||
@@ -11,25 +11,25 @@
|
||||
:data="eventList.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
|
||||
>
|
||||
<!-- <vxe-column type="seq" width="70px" title="序号"></vxe-column> -->
|
||||
<vxe-column field="time" width="180px" sortable title="发生时刻"></vxe-column>
|
||||
<vxe-column field="lineName" title="监测点"></vxe-column>
|
||||
<vxe-column field="powerCompany" title="变电站" width="100px"></vxe-column>
|
||||
<vxe-column field="powerCompany" title="供电公司" width="100px"></vxe-column>
|
||||
<vxe-column field="persistTime" width="120px" sortable title="持续时间(s)">
|
||||
<template #default="{ row }">
|
||||
{{ Math.floor(row.persistTime * 1000) / 1000 }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="time" width="180px" sortable title="暂降发生时刻"></vxe-column>
|
||||
<vxe-column field="eventValue" width="160px" sortable title="暂降(骤升)幅值(%)">
|
||||
<template #default="{ row }">
|
||||
{{ Math.floor(row.eventValue * 10000) / 100 }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="persistTime" width="120px" sortable title="持续时间(s)">
|
||||
<template #default="{ row }">
|
||||
{{ Math.floor(row.persistTime * 1000) / 1000 }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="eventType" width="100px" title="触发类型">
|
||||
<template #default="{ row }">
|
||||
{{ event.filter(item => item.id == row.eventType)[0]?.name || '/' }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="powerCompany" title="变电站" width="100px"></vxe-column>
|
||||
<vxe-column field="powerCompany" title="供电公司" width="100px"></vxe-column>
|
||||
<vxe-column field="lineName" title="监测点"></vxe-column>
|
||||
</vxe-table>
|
||||
<div class="table-pagination mt10">
|
||||
<el-pagination
|
||||
@@ -50,7 +50,8 @@ import { ref, reactive, onMounted } from 'vue'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import MQTT from '@/utils/mqtt'
|
||||
// import MQTT from '@/utils/mqtt'
|
||||
import socketClient from '@/utils/webSocketClient'
|
||||
const dictData = useDictData()
|
||||
const event = dictData.getBasicData('Event_Statis')
|
||||
import { useAdminInfo } from '@/stores/adminInfo'
|
||||
@@ -68,37 +69,71 @@ const handleClose = (done: any) => {
|
||||
drawer.value = false
|
||||
done()
|
||||
}
|
||||
const init = async () => {
|
||||
const mqttClient = new MQTT('/sendEvent')
|
||||
// 设置消息接收回调
|
||||
try {
|
||||
await mqttClient.init()
|
||||
const dataSocket = reactive({
|
||||
socketServe: socketClient.Instance
|
||||
})
|
||||
// const init = async () => {
|
||||
// const mqttClient = new MQTT('/sendEvent')
|
||||
// // 设置消息接收回调
|
||||
// try {
|
||||
// await mqttClient.init()
|
||||
|
||||
// 订阅主题
|
||||
await mqttClient.subscribe()
|
||||
// 设置消息接收回调
|
||||
mqttClient.onMessage((topic, message) => {
|
||||
const msg = JSON.parse(message.toString())
|
||||
// console.log('🚀 ~ init ~ msg:', msg)
|
||||
if (msg.deptList.includes(adminInfo.$state.deptId)) {
|
||||
drawer.value = true
|
||||
isLoading.value = true
|
||||
eventList.value.unshift(msg)
|
||||
setTimeout(() => {
|
||||
isLoading.value = false
|
||||
}, 500)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('MQTT 初始化失败:', error)
|
||||
}
|
||||
// // 订阅主题
|
||||
// await mqttClient.subscribe()
|
||||
// // 设置消息接收回调
|
||||
// mqttClient.onMessage((topic, message) => {
|
||||
// const msg = JSON.parse(message.toString())
|
||||
// // console.log('🚀 ~ init ~ msg:', msg)
|
||||
// if (msg.deptList.includes(adminInfo.$state.deptId)) {
|
||||
// drawer.value = true
|
||||
// isLoading.value = true
|
||||
// eventList.value.unshift(msg)
|
||||
// setTimeout(() => {
|
||||
// isLoading.value = false
|
||||
// }, 500)
|
||||
// }
|
||||
// })
|
||||
// } catch (error) {
|
||||
// // console.error('MQTT 初始化失败:', error)
|
||||
// }
|
||||
// }
|
||||
const socket = async () => {
|
||||
const url = localStorage.getItem('WebSocketUrl3') || 'null' //'ws://192.168.2.130:10203/event/'
|
||||
|
||||
// const url = 'ws://192.168.1.68:10203/event/'
|
||||
|
||||
await dataSocket.socketServe.connect(`${url}${adminInfo.id}`)
|
||||
|
||||
await dataSocket.socketServe.registerCallBack('message', (res: any) => {
|
||||
if (res.deptList.includes(adminInfo.$state.deptId)) {
|
||||
drawer.value = true
|
||||
isLoading.value = true
|
||||
eventList.value.unshift(res)
|
||||
setTimeout(() => {
|
||||
isLoading.value = false
|
||||
}, 500)
|
||||
}
|
||||
// logList.value.push({
|
||||
// type: res.code == 500 ? 'error' : '',
|
||||
// time: formatDate(new Date(), 'YYYY-MM-DD hh:mm:ss'),
|
||||
// name: res.message
|
||||
// })
|
||||
})
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
dataSocket.socketServe?.closeWs()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
// startMqtt('/sendEvent', (topic, message) => {
|
||||
// const msg = JSON.parse(message.toString())
|
||||
// console.log(msg)
|
||||
// })
|
||||
init()
|
||||
|
||||
setTimeout(() => {
|
||||
socket()
|
||||
}, 3000)
|
||||
})
|
||||
defineExpose({
|
||||
open,
|
||||
|
||||
@@ -8,41 +8,14 @@
|
||||
name="el-icon-BellFilled"
|
||||
size="18"
|
||||
/>
|
||||
<span class="nav-menu-text" v-if="globalPopUpRef?.eventList.length != 0">
|
||||
{{ (globalPopUpRef?.eventList.length>99? '99+':globalPopUpRef?.eventList.length) || 0 }}
|
||||
<span class="nav-menu-text" v-if="globalPopUpRef?.eventList?.length > 0">
|
||||
{{ globalPopUpRef.eventList.length > 99 ? '99+' : globalPopUpRef.eventList.length }}
|
||||
</span>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
<!-- <el-tooltip effect="dark" content="截图" placement="bottom">
|
||||
<div @click="savePng" class="nav-menu-item">
|
||||
<Icon
|
||||
:color="configStore.getColorVal('headerBarTabColor')"
|
||||
class="nav-menu-icon"
|
||||
name="el-icon-Camera"
|
||||
size="18"
|
||||
/>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="dark" :content="state.isFullScreen ? '缩小' : '放大'" placement="bottom">
|
||||
<div @click="onFullScreen" class="nav-menu-item" :class="state.isFullScreen ? 'hover' : ''">
|
||||
<Icon
|
||||
:color="configStore.getColorVal('headerBarTabColor')"
|
||||
class="nav-menu-icon"
|
||||
v-if="state.isFullScreen"
|
||||
name="fa-solid fa-compress"
|
||||
size="18"
|
||||
/>
|
||||
<Icon
|
||||
:color="configStore.getColorVal('headerBarTabColor')"
|
||||
class="nav-menu-icon"
|
||||
v-else
|
||||
name="fa-solid fa-expand"
|
||||
size="18"
|
||||
/>
|
||||
</div>
|
||||
</el-tooltip> -->
|
||||
|
||||
<el-dropdown style="height: 100%" @command="handleCommand">
|
||||
<div class="admin-info" :class="state.currentNavMenu == 'adminInfo' ? 'hover' : ''">
|
||||
<div class="admin-info" :class="state.currentNavMenu === 'adminInfo' ? 'hover' : ''">
|
||||
<el-avatar :size="25" fit="fill">
|
||||
<img src="@/assets/avatar.png" alt="" />
|
||||
</el-avatar>
|
||||
@@ -51,98 +24,115 @@
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="adminInfo">个人资料</el-dropdown-item>
|
||||
<el-dropdown-item command="changePwd">修改密码</el-dropdown-item>
|
||||
<el-dropdown-item command="layout">退出登录</el-dropdown-item>
|
||||
<el-dropdown-item command="changePwd" v-if="!IS_LNQR">修改密码</el-dropdown-item>
|
||||
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
<!-- <div @click="configStore.setLayout('showDrawer', true)" class="nav-menu-item">
|
||||
<Icon
|
||||
:color="configStore.getColorVal('headerBarTabColor')"
|
||||
class="nav-menu-icon"
|
||||
name="fa fa-cogs"
|
||||
size="18"
|
||||
/>
|
||||
</div> -->
|
||||
|
||||
<Config />
|
||||
<PopupPwd ref="popupPwd" />
|
||||
<AdminInfo ref="popupAdminInfo" />
|
||||
<!-- <TerminalVue /> -->
|
||||
<!-- 全局暂降事件 -->
|
||||
<globalPopUp ref="globalPopUpRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import screenfull from 'screenfull'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import Config from './config.vue'
|
||||
import { useAdminInfo } from '@/stores/adminInfo'
|
||||
import router from '@/router'
|
||||
import globalPopUp from './globalPopUp.vue'
|
||||
import { routePush } from '@/utils/router'
|
||||
import html2canvas from 'html2canvas'
|
||||
import { useNavTabs } from '@/stores/navTabs'
|
||||
import { logout } from '@/api/user-boot/user'
|
||||
import Config from './config.vue'
|
||||
import PopupPwd from './popup/password.vue'
|
||||
import AdminInfo from './popup/adminInfo.vue'
|
||||
import { useNavTabs } from '@/stores/navTabs'
|
||||
import globalPopUp from './globalPopUp.vue'
|
||||
const { replace } = useRouter()
|
||||
// 环境标识
|
||||
const IS_LNQR = import.meta.env.VITE_NAME === 'LNqr'
|
||||
|
||||
const adminInfo = useAdminInfo()
|
||||
const navTabs = useNavTabs()
|
||||
const configStore = useConfig()
|
||||
|
||||
// 引用
|
||||
const popupPwd = ref()
|
||||
const popupAdminInfo = ref()
|
||||
const state = reactive({
|
||||
isFullScreen: false,
|
||||
currentNavMenu: '',
|
||||
showLayoutDrawer: false,
|
||||
showAdminInfoPopover: false
|
||||
})
|
||||
const globalPopUpRef = ref()
|
||||
const savePng = () => {
|
||||
html2canvas(document.body, {
|
||||
scale: 1,
|
||||
useCORS: true
|
||||
}).then(function (canvas) {
|
||||
var link = document.createElement('a')
|
||||
link.href = canvas.toDataURL('image/png')
|
||||
link.download = 'screenshot.png'
|
||||
link.click()
|
||||
})
|
||||
}
|
||||
const onFullScreen = () => {
|
||||
if (!screenfull.isEnabled) {
|
||||
ElMessage.warning('layouts.Full screen is not supported')
|
||||
return false
|
||||
|
||||
// 状态
|
||||
const state = reactive({
|
||||
currentNavMenu: ''
|
||||
})
|
||||
|
||||
// 打开暂降事件
|
||||
const temporaryLandingEvent = () => {
|
||||
if (globalPopUpRef.value) {
|
||||
globalPopUpRef.value.open()
|
||||
}
|
||||
screenfull.toggle()
|
||||
screenfull.onchange(() => {
|
||||
state.isFullScreen = screenfull.isFullscreen
|
||||
})
|
||||
}
|
||||
|
||||
const handleCommand = (key: string) => {
|
||||
console.log(key)
|
||||
// 下拉菜单命令
|
||||
const handleCommand = async (key: string) => {
|
||||
switch (key) {
|
||||
case 'adminInfo':
|
||||
popupAdminInfo.value.open()
|
||||
popupAdminInfo.value?.open()
|
||||
break
|
||||
case 'changePwd':
|
||||
popupPwd.value.open()
|
||||
popupPwd.value?.open()
|
||||
break
|
||||
case 'layout':
|
||||
navTabs.closeTabs()
|
||||
window.localStorage.clear()
|
||||
adminInfo.reset()
|
||||
router.push({ name: 'login' })
|
||||
break
|
||||
default:
|
||||
case 'logout':
|
||||
await handleLogout()
|
||||
break
|
||||
}
|
||||
}
|
||||
const temporaryLandingEvent = () => {
|
||||
globalPopUpRef.value.open()
|
||||
|
||||
// 统一登出逻辑
|
||||
const handleLogout = async () => {
|
||||
try {
|
||||
// 1. 调用后端登出接口
|
||||
await logout()
|
||||
// console.log('✅ 后端登出成功')
|
||||
} catch (err) {
|
||||
// console.error('❌ 登出接口异常', err)
|
||||
} finally {
|
||||
// 2. 清理本地所有数据
|
||||
clearLocalData()
|
||||
|
||||
// 3. LNqr 环境跳 CAS 登出
|
||||
if (IS_LNQR) {
|
||||
redirectToCasLogout()
|
||||
} else {
|
||||
// 普通环境直接跳登录页
|
||||
replace('/login')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 清理本地数据
|
||||
const clearLocalData = () => {
|
||||
// 清空 localStorage
|
||||
window.localStorage.clear()
|
||||
|
||||
// 清空用户状态
|
||||
adminInfo.reset()
|
||||
|
||||
// 清空标签页
|
||||
navTabs.closeTabs()
|
||||
|
||||
console.log('✅ 本地数据已全部清空')
|
||||
}
|
||||
|
||||
// CAS 登出跳转
|
||||
const redirectToCasLogout = () => {
|
||||
const casLogoutUrl =
|
||||
'http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas/logout?service=http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas/login?service=http://PQMonitoring.dcloud.ln.dc.sgcc.com.cn'
|
||||
window.location.href = casLogoutUrl
|
||||
// 清 Cookie
|
||||
document.cookie.split(';').forEach(cookie => {
|
||||
const name = cookie.split('=')[0].trim()
|
||||
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -156,7 +146,6 @@ const temporaryLandingEvent = () => {
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// height: 100%;
|
||||
margin-left: auto;
|
||||
background-color: v-bind('configStore.getColorVal("headerBarBackground")');
|
||||
|
||||
@@ -212,37 +201,15 @@ const temporaryLandingEvent = () => {
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu-box :deep(.el-dropdown-menu__item) {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.admin-info-base {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 10px;
|
||||
|
||||
.admin-info-other {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
|
||||
.admin-info-name {
|
||||
font-size: var(--el-font-size-large);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.admin-info-footer {
|
||||
padding: 10px 0;
|
||||
margin: 0 -12px -12px -12px;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.pt2 {
|
||||
padding-top: 2px;
|
||||
.nav-menu-text {
|
||||
position: absolute;
|
||||
top: 13px;
|
||||
left: 20px;
|
||||
font-size: 12px;
|
||||
background: #ff0000;
|
||||
color: #fff;
|
||||
border-radius: 5px;
|
||||
padding: 0 3px;
|
||||
}
|
||||
|
||||
@keyframes twinkle {
|
||||
@@ -256,15 +223,4 @@ const temporaryLandingEvent = () => {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
.nav-menu-text {
|
||||
position: absolute;
|
||||
top: 13px;
|
||||
left: 20px;
|
||||
font-size: 12px;
|
||||
display: inline-block;
|
||||
background-color: #ff0000;
|
||||
color: #fff;
|
||||
border-radius: 5px;
|
||||
padding: 0 3px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -4,8 +4,10 @@ import router from './router'
|
||||
import pinia from '@/stores/index'
|
||||
import { registerIcons } from '@/utils/common'
|
||||
import mitt from 'mitt'
|
||||
import VxeUI from 'vxe-pc-ui'
|
||||
import VXETable from 'vxe-table'
|
||||
import XEUtils from 'xe-utils'
|
||||
import 'vxe-pc-ui/lib/style.css'
|
||||
import 'vxe-table/lib/style.css'
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
@@ -61,6 +63,7 @@ const setupAll = async () => {
|
||||
await setupI18n(app)
|
||||
app.use(router)
|
||||
app.use(pinia)
|
||||
app.use(VxeUI)
|
||||
app.use(ElementPlus)
|
||||
app.use(VXETable)
|
||||
|
||||
|
||||
@@ -1,55 +1,22 @@
|
||||
import type { App } from 'vue'
|
||||
// 👇使用 form-create 需额外全局引入 element plus 组件
|
||||
import {
|
||||
ElAlert,
|
||||
ElAside,
|
||||
ElContainer,
|
||||
ElDivider,
|
||||
ElHeader,
|
||||
ElMain,
|
||||
ElPopconfirm,
|
||||
ElTable,
|
||||
ElTableColumn,
|
||||
ElTabPane,
|
||||
ElTabs,
|
||||
ElTransfer
|
||||
} from 'element-plus'
|
||||
import FcDesigner from '@form-create/designer'
|
||||
import formCreate from '@form-create/element-ui'
|
||||
import install from '@form-create/element-ui/auto-import'
|
||||
//======================= 自定义组件 =======================
|
||||
import { UploadFile, UploadImg, UploadImgs } from '@/components/UploadFile'
|
||||
import { DictSelect } from '@/components/DictSelect'
|
||||
import UserSelect from '@/views/system/auth/userList/UserSelect.vue'
|
||||
import { Editor } from '@/components/Editor'
|
||||
|
||||
const components = [
|
||||
ElAside,
|
||||
ElPopconfirm,
|
||||
ElHeader,
|
||||
ElMain,
|
||||
ElContainer,
|
||||
ElDivider,
|
||||
ElTransfer,
|
||||
ElAlert,
|
||||
ElTabs,
|
||||
ElTable,
|
||||
ElTableColumn,
|
||||
ElTabPane,
|
||||
UploadImg,
|
||||
UploadImgs,
|
||||
UploadFile,
|
||||
DictSelect,
|
||||
UserSelect,
|
||||
Editor
|
||||
]
|
||||
|
||||
// 参考 http://www.form-create.com/v3/element-ui/auto-import.html 文档
|
||||
export const setupFormCreate = (app: App<Element>) => {
|
||||
components.forEach((component) => {
|
||||
app.component(component.name, component)
|
||||
})
|
||||
formCreate.use(install)
|
||||
app.use(formCreate)
|
||||
app.use(FcDesigner)
|
||||
}
|
||||
import type { App } from 'vue'
|
||||
import FcDesigner from '@form-create/designer'
|
||||
import formCreate from '@form-create/element-ui'
|
||||
import install from '@form-create/element-ui/auto-import'
|
||||
//======================= 自定义组件 =======================
|
||||
import { UploadFile, UploadImg, UploadImgs } from '@/components/UploadFile'
|
||||
import { DictSelect } from '@/components/DictSelect'
|
||||
import UserSelect from '@/views/system/auth/userList/UserSelect.vue'
|
||||
import { Editor } from '@/components/Editor'
|
||||
|
||||
// Element Plus 已在 main.ts 通过 app.use(ElementPlus) 全局注册,此处仅注册 form-create 自定义组件
|
||||
const components = [UploadImg, UploadImgs, UploadFile, DictSelect, UserSelect, Editor]
|
||||
|
||||
// 参考 http://www.form-create.com/v3/element-ui/auto-import.html 文档
|
||||
export const setupFormCreate = (app: App<Element>) => {
|
||||
components.forEach((component) => {
|
||||
app.component(component.name!, component)
|
||||
})
|
||||
formCreate.use(install)
|
||||
app.use(formCreate)
|
||||
app.use(FcDesigner)
|
||||
}
|
||||
|
||||
@@ -404,6 +404,11 @@ body,
|
||||
.el-select__wrapper {
|
||||
height: 32px !important;
|
||||
}
|
||||
.BMap_center,
|
||||
.BMap_top,
|
||||
.BMap_bottom {
|
||||
background-color: #fff;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'AlimamaFangYuanTiVF';
|
||||
src: url('../assets/font/ali/AlimamaFangYuanTiVF-Thin.woff') format('woff'),
|
||||
|
||||
@@ -31,6 +31,8 @@ $border-color: map.merge(
|
||||
@include set-component-css-var('border-color', $border-color);
|
||||
--vxe-ui-table-row-current-background-color: var(--el-color-primary-light-8);
|
||||
--vxe-ui-table-row-hover-current-background-color: var(--el-color-primary-light-8);
|
||||
--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-hover-background-color: var(--el-color-primary-light-9);
|
||||
// --vxe-table-row-hover-current-background-color: var(--el-color-primary-light-7);
|
||||
|
||||
@@ -70,7 +70,8 @@
|
||||
// .vxe-table--render-default .is--disabled.vxe-cell--checkbox .vxe-checkbox--icon{
|
||||
// color: #fff0;
|
||||
// }
|
||||
.vxe-table--tooltip-wrapper {
|
||||
.vxe-table--tooltip-wrapper,
|
||||
.vxe-tooltip--wrapper {
|
||||
z-index: 10000 !important;
|
||||
}
|
||||
.is--disabled {
|
||||
@@ -98,3 +99,8 @@
|
||||
background-color: #000 !important;
|
||||
}
|
||||
}
|
||||
.vxe-table-custom--panel-list > li {
|
||||
max-width: 28em;
|
||||
min-width: 15em;
|
||||
padding: 0.3em 1em 0.2em 1em;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class='default-main'>
|
||||
<!-- 表头 -->
|
||||
<!-- date-picker 时间组件 area区域组件-->
|
||||
<TableHeader date-picker area>
|
||||
<TableHeader date-picker area showCustomColumn>
|
||||
<template v-slot:select>
|
||||
<el-form-item label='关键词:'>
|
||||
<el-input
|
||||
|
||||
59
src/utils/chartAxisHelper.ts
Normal file
59
src/utils/chartAxisHelper.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
const AXIS_DECIMALS = 2
|
||||
|
||||
export function roundAxisValue(val: number, decimals = AXIS_DECIMALS): number {
|
||||
if (!Number.isFinite(val)) return 0
|
||||
const factor = 10 ** decimals
|
||||
return Math.round(val * factor) / factor
|
||||
}
|
||||
|
||||
/** Y 轴刻度:最多 2 位小数,末尾 0 去掉(如 1.00 → 1,0.10 → 0.1) */
|
||||
export function formatAxisLabel(value: number): string {
|
||||
if (!Number.isFinite(value)) return '0'
|
||||
return String(Number(roundAxisValue(value).toFixed(AXIS_DECIMALS)))
|
||||
}
|
||||
|
||||
/** 瞬间波形 Y 轴范围 */
|
||||
export function calcShuYAxisRange(dataMin: number, dataMax: number): { min: number; max: number } {
|
||||
const min = Number(dataMin)
|
||||
const max = Number(dataMax)
|
||||
if (!Number.isFinite(min) || !Number.isFinite(max)) {
|
||||
return { min: 0, max: 1 }
|
||||
}
|
||||
|
||||
let axisMax = max * 1.1
|
||||
let axisMin = min > 0 ? min - min * 0.1 : min * 1.1
|
||||
|
||||
if (axisMax <= axisMin) {
|
||||
const pad = Math.abs(max) * 0.1 || 0.01
|
||||
axisMax = max + pad
|
||||
axisMin = min - pad
|
||||
}
|
||||
|
||||
return {
|
||||
min: roundAxisValue(axisMin),
|
||||
max: roundAxisValue(axisMax)
|
||||
}
|
||||
}
|
||||
|
||||
/** RMS 波形 Y 轴范围 */
|
||||
export function calcRmsYAxisRange(dataMin: number, dataMax: number): { min: number; max: number } {
|
||||
const min = Number(dataMin)
|
||||
const max = Number(dataMax)
|
||||
if (!Number.isFinite(min) || !Number.isFinite(max)) {
|
||||
return { min: 0, max: 1 }
|
||||
}
|
||||
|
||||
let axisMax = max * 1.06 * 1.1
|
||||
let axisMin = min - min * 0.2
|
||||
|
||||
if (axisMax <= axisMin) {
|
||||
const pad = Math.abs(max - min) * 0.1 || Math.abs(max) * 0.1 || 0.01
|
||||
axisMax = max + pad
|
||||
axisMin = min - pad
|
||||
}
|
||||
|
||||
return {
|
||||
min: roundAxisValue(axisMin),
|
||||
max: roundAxisValue(axisMax)
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
// 高级算法
|
||||
export const ADVANCE_BOOT = '/advance-boot'
|
||||
|
||||
//技术监督
|
||||
export const PROCESS_BOOT = '/process-boot'
|
||||
|
||||
//工作流模块
|
||||
export const BPM_BOOT = '/bpm-boot'
|
||||
|
||||
//冀北技术监督
|
||||
export const SUPERVISION_BOOT = '/supervision-boot'
|
||||
|
||||
//终端模块
|
||||
// 高级算法
|
||||
export const ADVANCE_BOOT = '/advance-boot'
|
||||
|
||||
//技术监督
|
||||
export const PROCESS_BOOT = '/process-boot'
|
||||
|
||||
//工作流模块
|
||||
export const BPM_BOOT = '/bpm-boot'
|
||||
|
||||
//网公司技术监督
|
||||
export const SUPERVISION_BOOT = '/supervision-boot'
|
||||
|
||||
//终端模块
|
||||
export const DEVICE_BOOT = '/device-boot'
|
||||
@@ -1,286 +1,337 @@
|
||||
//指标类型
|
||||
export const indexOptions = [
|
||||
{
|
||||
label: '电压趋势',
|
||||
options: [
|
||||
{
|
||||
value: '10',
|
||||
label: '相电压有效值'
|
||||
},
|
||||
{
|
||||
value: '11',
|
||||
label: '线电压有效值'
|
||||
},
|
||||
{
|
||||
value: '12',
|
||||
label: '电压偏差'
|
||||
},
|
||||
{
|
||||
value: '13',
|
||||
label: '三相电压不平衡'
|
||||
},
|
||||
{
|
||||
value: '14',
|
||||
label: '电压不平衡'
|
||||
},
|
||||
{
|
||||
value: '15',
|
||||
label: '电压总谐波畸变率'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '电流趋势',
|
||||
options: [
|
||||
{
|
||||
value: '20',
|
||||
label: '电流有效值'
|
||||
},
|
||||
{
|
||||
value: '21',
|
||||
label: '电流总谐波畸变率'
|
||||
},
|
||||
{
|
||||
value: '22',
|
||||
label: '负序电流'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '频率趋势',
|
||||
options: [
|
||||
{
|
||||
value: '30',
|
||||
label: '频率'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '谐波趋势',
|
||||
options: [
|
||||
{
|
||||
value: '40',
|
||||
label: '谐波电压含有率'
|
||||
},
|
||||
{
|
||||
value: '43',
|
||||
label: '谐波电流幅值'
|
||||
},
|
||||
{
|
||||
value: '44',
|
||||
label: '谐波电压相角'
|
||||
},
|
||||
{
|
||||
value: '45',
|
||||
label: '谐波电流相角'
|
||||
},
|
||||
{
|
||||
value: '46',
|
||||
label: '间谐波电压含有率'
|
||||
},
|
||||
// {
|
||||
// value: '47',
|
||||
// label: '间谐波电流含有率'
|
||||
// },
|
||||
// {
|
||||
// value: '48',
|
||||
// label: '间谐波电压幅值'
|
||||
// },
|
||||
{
|
||||
value: '49',
|
||||
label: '间谐波电流幅值'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '功率趋势',
|
||||
options: [
|
||||
{
|
||||
value: '50',
|
||||
label: '谐波有功功率'
|
||||
},
|
||||
{
|
||||
value: '51',
|
||||
label: '谐波无功功率'
|
||||
},
|
||||
{
|
||||
value: '52',
|
||||
label: '谐波视在功率'
|
||||
},
|
||||
{
|
||||
value: '53',
|
||||
label: '三相有功功率'
|
||||
},
|
||||
{
|
||||
value: '54',
|
||||
label: '三相无功功率'
|
||||
},
|
||||
{
|
||||
value: '55',
|
||||
label: '三相视在功率'
|
||||
},
|
||||
{
|
||||
value: '56',
|
||||
label: '三相总有功功率'
|
||||
},
|
||||
{
|
||||
value: '57',
|
||||
label: '三相总无功功率'
|
||||
},
|
||||
{
|
||||
value: '58',
|
||||
label: '三相总视在功率'
|
||||
},
|
||||
{
|
||||
value: '59',
|
||||
label: '视在功率因数'
|
||||
},
|
||||
{
|
||||
value: '591',
|
||||
label: '位移功率因数'
|
||||
},
|
||||
{
|
||||
value: '592',
|
||||
label: '总视在功率因数'
|
||||
},
|
||||
{
|
||||
value: '593',
|
||||
label: '总位移功率因数'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '闪变趋势',
|
||||
options: [
|
||||
{
|
||||
value: '60',
|
||||
label: '短时电压闪变'
|
||||
},
|
||||
{
|
||||
value: '61',
|
||||
label: '长时电压闪变'
|
||||
},
|
||||
{
|
||||
value: '62',
|
||||
label: '电压波动'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
//谐波次数
|
||||
export const harmonicOptions = [
|
||||
{ label: '基波', value: 1 },
|
||||
{ label: '2次', value: 2 },
|
||||
{ label: '3次', value: 3 },
|
||||
{ label: '4次', value: 4 },
|
||||
{ label: '5次', value: 5 },
|
||||
{ label: '6次', value: 6 },
|
||||
{ label: '7次', value: 7 },
|
||||
{ label: '8次', value: 8 },
|
||||
{ label: '9次', value: 9 },
|
||||
{ label: '10次', value: 10 },
|
||||
{ label: '11次', value: 11 },
|
||||
{ label: '12次', value: 12 },
|
||||
{ label: '13次', value: 13 },
|
||||
{ label: '14次', value: 14 },
|
||||
{ label: '15次', value: 15 },
|
||||
{ label: '16次', value: 16 },
|
||||
{ label: '17次', value: 17 },
|
||||
{ label: '18次', value: 18 },
|
||||
{ label: '19次', value: 19 },
|
||||
{ label: '20次', value: 20 },
|
||||
{ label: '21次', value: 21 },
|
||||
{ label: '22次', value: 22 },
|
||||
{ label: '23次', value: 23 },
|
||||
{ label: '24次', value: 24 },
|
||||
{ label: '25次', value: 25 },
|
||||
{ label: '26次', value: 26 },
|
||||
{ label: '27次', value: 27 },
|
||||
{ label: '28次', value: 28 },
|
||||
{ label: '29次', value: 29 },
|
||||
{ label: '30次', value: 30 },
|
||||
{ label: '31次', value: 31 },
|
||||
{ label: '32次', value: 32 },
|
||||
{ label: '33次', value: 33 },
|
||||
{ label: '34次', value: 34 },
|
||||
{ label: '35次', value: 35 },
|
||||
{ label: '36次', value: 36 },
|
||||
{ label: '37次', value: 37 },
|
||||
{ label: '38次', value: 38 },
|
||||
{ label: '39次', value: 39 },
|
||||
{ label: '40次', value: 40 },
|
||||
{ label: '41次', value: 41 },
|
||||
{ label: '42次', value: 42 },
|
||||
{ label: '43次', value: 43 },
|
||||
{ label: '44次', value: 44 },
|
||||
{ label: '45次', value: 45 },
|
||||
{ label: '46次', value: 46 },
|
||||
{ label: '47次', value: 47 },
|
||||
{ label: '48次', value: 48 },
|
||||
{ label: '49次', value: 49 },
|
||||
{ label: '50次', value: 50 }
|
||||
]
|
||||
//简谐波次数
|
||||
export const inharmonicOptions = [
|
||||
{ label: '0.5次', value: 1 },
|
||||
{ label: '1.5次', value: 2 },
|
||||
{ label: '2.5次', value: 3 },
|
||||
{ label: '3.5次', value: 4 },
|
||||
{ label: '4.5次', value: 5 },
|
||||
{ label: '5.5次', value: 6 },
|
||||
{ label: '6.5次', value: 7 },
|
||||
{ label: '7.5次', value: 8 },
|
||||
{ label: '8.5次', value: 9 },
|
||||
{ label: '9.5次', value: 10 },
|
||||
{ label: '10.5次', value: 11 },
|
||||
{ label: '11.5次', value: 12 },
|
||||
{ label: '12.5次', value: 13 },
|
||||
{ label: '13.5次', value: 14 },
|
||||
{ label: '14.5次', value: 15 },
|
||||
{ label: '15.5次', value: 16 },
|
||||
{ label: '16.5次', value: 17 },
|
||||
{ label: '17.5次', value: 18 },
|
||||
{ label: '18.5次', value: 19 },
|
||||
{ label: '19.5次', value: 20 },
|
||||
{ label: '20.5次', value: 21 },
|
||||
{ label: '21.5次', value: 22 },
|
||||
{ label: '22.5次', value: 23 },
|
||||
{ label: '23.5次', value: 24 },
|
||||
{ label: '24.5次', value: 25 },
|
||||
{ label: '25.5次', value: 26 },
|
||||
{ label: '26.5次', value: 27 },
|
||||
{ label: '27.5次', value: 28 },
|
||||
{ label: '28.5次', value: 29 },
|
||||
{ label: '29.5次', value: 30 },
|
||||
{ label: '30.5次', value: 31 },
|
||||
{ label: '31.5次', value: 32 },
|
||||
{ label: '32.5次', value: 33 },
|
||||
{ label: '33.5次', value: 34 },
|
||||
{ label: '34.5次', value: 35 },
|
||||
{ label: '35.5次', value: 36 },
|
||||
{ label: '36.5次', value: 37 },
|
||||
{ label: '37.5次', value: 38 },
|
||||
{ label: '38.5次', value: 39 },
|
||||
{ label: '39.5次', value: 40 },
|
||||
{ label: '40.5次', value: 41 },
|
||||
{ label: '41.5次', value: 42 },
|
||||
{ label: '42.5次', value: 43 },
|
||||
{ label: '43.5次', value: 44 },
|
||||
{ label: '44.5次', value: 45 },
|
||||
{ label: '45.5次', value: 46 },
|
||||
{ label: '46.5次', value: 47 },
|
||||
{ label: '47.5次', value: 48 },
|
||||
{ label: '48.5次', value: 49 },
|
||||
{ label: '49.5次', value: 50 },
|
||||
|
||||
|
||||
|
||||
]
|
||||
|
||||
//值类型
|
||||
export const typeOptions = [
|
||||
{ label: '平均值', value: 1 },
|
||||
{ label: '最小值', value: 2 },
|
||||
{ label: '最大值', value: 3 },
|
||||
{ label: 'cp95值', value: 4 }
|
||||
]
|
||||
//指标类型
|
||||
export const indexOptions = [
|
||||
{
|
||||
label: '电压趋势',
|
||||
options: [
|
||||
{
|
||||
value: '10',
|
||||
label: '相电压有效值'
|
||||
},
|
||||
{
|
||||
value: '11',
|
||||
label: '线电压有效值'
|
||||
},
|
||||
{
|
||||
value: '12',
|
||||
label: '电压偏差'
|
||||
},
|
||||
{
|
||||
value: '13',
|
||||
label: '三相电压不平衡'
|
||||
},
|
||||
{
|
||||
value: '14',
|
||||
label: '电压不平衡'
|
||||
},
|
||||
{
|
||||
value: '15',
|
||||
label: '电压总谐波畸变率'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '电流趋势',
|
||||
options: [
|
||||
{
|
||||
value: '20',
|
||||
label: '电流有效值'
|
||||
},
|
||||
{
|
||||
value: '21',
|
||||
label: '电流总谐波畸变率'
|
||||
},
|
||||
{
|
||||
value: '22',
|
||||
label: '负序电流'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '频率趋势',
|
||||
options: [
|
||||
{
|
||||
value: '30',
|
||||
label: '频率'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '谐波趋势',
|
||||
options: [
|
||||
{
|
||||
value: '40',
|
||||
label: '谐波电压含有率'
|
||||
},
|
||||
{
|
||||
value: '43',
|
||||
label: '谐波电流幅值'
|
||||
},
|
||||
{
|
||||
value: '44',
|
||||
label: '谐波电压相角'
|
||||
},
|
||||
{
|
||||
value: '45',
|
||||
label: '谐波电流相角'
|
||||
},
|
||||
{
|
||||
value: '46',
|
||||
label: '间谐波电压含有率'
|
||||
},
|
||||
// {
|
||||
// value: '47',
|
||||
// label: '间谐波电流含有率'
|
||||
// },
|
||||
// {
|
||||
// value: '48',
|
||||
// label: '间谐波电压幅值'
|
||||
// },
|
||||
{
|
||||
value: '49',
|
||||
label: '间谐波电流幅值'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '功率趋势',
|
||||
options: [
|
||||
{
|
||||
value: '50',
|
||||
label: '谐波有功功率'
|
||||
},
|
||||
{
|
||||
value: '51',
|
||||
label: '谐波无功功率'
|
||||
},
|
||||
{
|
||||
value: '52',
|
||||
label: '谐波视在功率'
|
||||
},
|
||||
{
|
||||
value: '53',
|
||||
label: '三相有功功率'
|
||||
},
|
||||
{
|
||||
value: '54',
|
||||
label: '三相无功功率'
|
||||
},
|
||||
{
|
||||
value: '55',
|
||||
label: '三相视在功率'
|
||||
},
|
||||
{
|
||||
value: '56',
|
||||
label: '三相总有功功率'
|
||||
},
|
||||
{
|
||||
value: '57',
|
||||
label: '三相总无功功率'
|
||||
},
|
||||
{
|
||||
value: '58',
|
||||
label: '三相总视在功率'
|
||||
},
|
||||
{
|
||||
value: '59',
|
||||
label: '视在功率因数'
|
||||
},
|
||||
{
|
||||
value: '591',
|
||||
label: '位移功率因数'
|
||||
},
|
||||
{
|
||||
value: '592',
|
||||
label: '总视在功率因数'
|
||||
},
|
||||
{
|
||||
value: '593',
|
||||
label: '总位移功率因数'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '闪变趋势',
|
||||
options: [
|
||||
{
|
||||
value: '60',
|
||||
label: '短时电压闪变'
|
||||
},
|
||||
{
|
||||
value: '61',
|
||||
label: '长时电压闪变'
|
||||
},
|
||||
{
|
||||
value: '62',
|
||||
label: '电压波动'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
//谐波次数
|
||||
export const harmonicOptions = [
|
||||
{ label: '基波', value: 1 },
|
||||
{ label: '2次', value: 2 },
|
||||
{ label: '3次', value: 3 },
|
||||
{ label: '4次', value: 4 },
|
||||
{ label: '5次', value: 5 },
|
||||
{ label: '6次', value: 6 },
|
||||
{ label: '7次', value: 7 },
|
||||
{ label: '8次', value: 8 },
|
||||
{ label: '9次', value: 9 },
|
||||
{ label: '10次', value: 10 },
|
||||
{ label: '11次', value: 11 },
|
||||
{ label: '12次', value: 12 },
|
||||
{ label: '13次', value: 13 },
|
||||
{ label: '14次', value: 14 },
|
||||
{ label: '15次', value: 15 },
|
||||
{ label: '16次', value: 16 },
|
||||
{ label: '17次', value: 17 },
|
||||
{ label: '18次', value: 18 },
|
||||
{ label: '19次', value: 19 },
|
||||
{ label: '20次', value: 20 },
|
||||
{ label: '21次', value: 21 },
|
||||
{ label: '22次', value: 22 },
|
||||
{ label: '23次', value: 23 },
|
||||
{ label: '24次', value: 24 },
|
||||
{ label: '25次', value: 25 },
|
||||
{ label: '26次', value: 26 },
|
||||
{ label: '27次', value: 27 },
|
||||
{ label: '28次', value: 28 },
|
||||
{ label: '29次', value: 29 },
|
||||
{ label: '30次', value: 30 },
|
||||
{ label: '31次', value: 31 },
|
||||
{ label: '32次', value: 32 },
|
||||
{ label: '33次', value: 33 },
|
||||
{ label: '34次', value: 34 },
|
||||
{ label: '35次', value: 35 },
|
||||
{ label: '36次', value: 36 },
|
||||
{ label: '37次', value: 37 },
|
||||
{ label: '38次', value: 38 },
|
||||
{ label: '39次', value: 39 },
|
||||
{ label: '40次', value: 40 },
|
||||
{ label: '41次', value: 41 },
|
||||
{ label: '42次', value: 42 },
|
||||
{ label: '43次', value: 43 },
|
||||
{ label: '44次', value: 44 },
|
||||
{ label: '45次', value: 45 },
|
||||
{ label: '46次', value: 46 },
|
||||
{ label: '47次', value: 47 },
|
||||
{ label: '48次', value: 48 },
|
||||
{ label: '49次', value: 49 },
|
||||
{ label: '50次', value: 50 }
|
||||
]
|
||||
export const harmonicOptions1 = [
|
||||
{ label: '2次', value: 2 },
|
||||
{ label: '3次', value: 3 },
|
||||
{ label: '4次', value: 4 },
|
||||
{ label: '5次', value: 5 },
|
||||
{ label: '6次', value: 6 },
|
||||
{ label: '7次', value: 7 },
|
||||
{ label: '8次', value: 8 },
|
||||
{ label: '9次', value: 9 },
|
||||
{ label: '10次', value: 10 },
|
||||
{ label: '11次', value: 11 },
|
||||
{ label: '12次', value: 12 },
|
||||
{ label: '13次', value: 13 },
|
||||
{ label: '14次', value: 14 },
|
||||
{ label: '15次', value: 15 },
|
||||
{ label: '16次', value: 16 },
|
||||
{ label: '17次', value: 17 },
|
||||
{ label: '18次', value: 18 },
|
||||
{ label: '19次', value: 19 },
|
||||
{ label: '20次', value: 20 },
|
||||
{ label: '21次', value: 21 },
|
||||
{ label: '22次', value: 22 },
|
||||
{ label: '23次', value: 23 },
|
||||
{ label: '24次', value: 24 },
|
||||
{ label: '25次', value: 25 },
|
||||
{ label: '26次', value: 26 },
|
||||
{ label: '27次', value: 27 },
|
||||
{ label: '28次', value: 28 },
|
||||
{ label: '29次', value: 29 },
|
||||
{ label: '30次', value: 30 },
|
||||
{ label: '31次', value: 31 },
|
||||
{ label: '32次', value: 32 },
|
||||
{ label: '33次', value: 33 },
|
||||
{ label: '34次', value: 34 },
|
||||
{ label: '35次', value: 35 },
|
||||
{ label: '36次', value: 36 },
|
||||
{ label: '37次', value: 37 },
|
||||
{ label: '38次', value: 38 },
|
||||
{ label: '39次', value: 39 },
|
||||
{ label: '40次', value: 40 },
|
||||
{ label: '41次', value: 41 },
|
||||
{ label: '42次', value: 42 },
|
||||
{ label: '43次', value: 43 },
|
||||
{ label: '44次', value: 44 },
|
||||
{ label: '45次', value: 45 },
|
||||
{ label: '46次', value: 46 },
|
||||
{ label: '47次', value: 47 },
|
||||
{ label: '48次', value: 48 },
|
||||
{ label: '49次', value: 49 },
|
||||
{ label: '50次', value: 50 }
|
||||
]
|
||||
//简谐波次数
|
||||
export const inharmonicOptions = [
|
||||
{ label: '0.5次', value: 1 },
|
||||
{ label: '1.5次', value: 2 },
|
||||
{ label: '2.5次', value: 3 },
|
||||
{ label: '3.5次', value: 4 },
|
||||
{ label: '4.5次', value: 5 },
|
||||
{ label: '5.5次', value: 6 },
|
||||
{ label: '6.5次', value: 7 },
|
||||
{ label: '7.5次', value: 8 },
|
||||
{ label: '8.5次', value: 9 },
|
||||
{ label: '9.5次', value: 10 },
|
||||
{ label: '10.5次', value: 11 },
|
||||
{ label: '11.5次', value: 12 },
|
||||
{ label: '12.5次', value: 13 },
|
||||
{ label: '13.5次', value: 14 },
|
||||
{ label: '14.5次', value: 15 },
|
||||
{ label: '15.5次', value: 16 },
|
||||
{ label: '16.5次', value: 17 },
|
||||
{ label: '17.5次', value: 18 },
|
||||
{ label: '18.5次', value: 19 },
|
||||
{ label: '19.5次', value: 20 },
|
||||
{ label: '20.5次', value: 21 },
|
||||
{ label: '21.5次', value: 22 },
|
||||
{ label: '22.5次', value: 23 },
|
||||
{ label: '23.5次', value: 24 },
|
||||
{ label: '24.5次', value: 25 },
|
||||
{ label: '25.5次', value: 26 },
|
||||
{ label: '26.5次', value: 27 },
|
||||
{ label: '27.5次', value: 28 },
|
||||
{ label: '28.5次', value: 29 },
|
||||
{ label: '29.5次', value: 30 },
|
||||
{ label: '30.5次', value: 31 },
|
||||
{ label: '31.5次', value: 32 },
|
||||
{ label: '32.5次', value: 33 },
|
||||
{ label: '33.5次', value: 34 },
|
||||
{ label: '34.5次', value: 35 },
|
||||
{ label: '35.5次', value: 36 },
|
||||
{ label: '36.5次', value: 37 },
|
||||
{ label: '37.5次', value: 38 },
|
||||
{ label: '38.5次', value: 39 },
|
||||
{ label: '39.5次', value: 40 },
|
||||
{ label: '40.5次', value: 41 },
|
||||
{ label: '41.5次', value: 42 },
|
||||
{ label: '42.5次', value: 43 },
|
||||
{ label: '43.5次', value: 44 },
|
||||
{ label: '44.5次', value: 45 },
|
||||
{ label: '45.5次', value: 46 },
|
||||
{ label: '46.5次', value: 47 },
|
||||
{ label: '47.5次', value: 48 },
|
||||
{ label: '48.5次', value: 49 },
|
||||
{ label: '49.5次', value: 50 },
|
||||
|
||||
|
||||
|
||||
]
|
||||
|
||||
//值类型
|
||||
export const typeOptions = [
|
||||
{ label: '平均值', value: 1 },
|
||||
{ label: '最小值', value: 2 },
|
||||
{ label: '最大值', value: 3 },
|
||||
{ label: 'cp95值', value: 4 }
|
||||
]
|
||||
|
||||
@@ -11,6 +11,7 @@ const calculateValue = (o: number, value: number, num: number, isMin: boolean) =
|
||||
} else if (value > -1 && value < 0 && isMin == false) {
|
||||
return 0
|
||||
}
|
||||
|
||||
let base
|
||||
if (Math.abs(o) >= 100) {
|
||||
base = 100
|
||||
@@ -19,8 +20,11 @@ const calculateValue = (o: number, value: number, num: number, isMin: boolean) =
|
||||
} else if (Math.abs(o) >= 1) {
|
||||
base = 1
|
||||
} else {
|
||||
base = 0.1
|
||||
const multiple = 1 / 0.1
|
||||
|
||||
base = Math.ceil(Math.abs(o) * multiple) / multiple
|
||||
}
|
||||
|
||||
let calculatedValue
|
||||
if (isMin) {
|
||||
if (value < 0) {
|
||||
@@ -35,98 +39,37 @@ const calculateValue = (o: number, value: number, num: number, isMin: boolean) =
|
||||
calculatedValue = value + num * value
|
||||
}
|
||||
}
|
||||
|
||||
if (base === 0.1) {
|
||||
return parseFloat(calculatedValue.toFixed(1))
|
||||
// return parseFloat(calculatedValue.toFixed(1))
|
||||
return Math.ceil(calculatedValue * 10) / 10
|
||||
} else if (isMin) {
|
||||
return Math.floor(calculatedValue / base) * base
|
||||
} else {
|
||||
return Math.ceil(calculatedValue / base) * base
|
||||
}
|
||||
}
|
||||
|
||||
// 处理y轴最大最小值
|
||||
export const yMethod = (arr: any) => {
|
||||
let num = 0.1
|
||||
let num = 0.2
|
||||
let numList = dataProcessing(arr)
|
||||
let maxValue = 0
|
||||
let minValue = 0
|
||||
let max = 0
|
||||
let min = 0
|
||||
maxValue = Math.max(...numList)
|
||||
minValue = Math.min(...numList)
|
||||
const o = maxValue - minValue
|
||||
if (Math.abs(o) >= 300) {
|
||||
num = 0.02
|
||||
if (numList.length === 0) {
|
||||
return [0, 0]
|
||||
}
|
||||
const maxValue = Math.max(...numList)
|
||||
const minValue = Math.min(...numList)
|
||||
let min = 0
|
||||
let max = 0
|
||||
|
||||
min = calculateValue(o, minValue, num, true)
|
||||
max = calculateValue(o, maxValue, num, false)
|
||||
// if (-100 >= minValue) {
|
||||
// min = Math.floor((minValue + num * minValue) / 100) * 100
|
||||
// } else if (-10 >= minValue && minValue > -100) {
|
||||
// min = Math.floor((minValue + num * minValue) / 10) * 10
|
||||
// } else if (-1 >= minValue && minValue > -10) {
|
||||
// min = Math.floor(minValue + num * minValue)
|
||||
// } else if (0 > minValue && minValue > -1) {
|
||||
// min = parseFloat((minValue + num * minValue).toFixed(1))
|
||||
// } else if (minValue == 0) {
|
||||
// min = 0
|
||||
// } else if (0 < minValue && minValue < 1) {
|
||||
// min = parseFloat((minValue - num * minValue).toFixed(1))
|
||||
// } else if (1 <= minValue && minValue < 10) {
|
||||
// min = Math.floor(minValue - num * minValue)
|
||||
// } else if (10 <= minValue && minValue < 100) {
|
||||
// min = Math.floor((minValue - num * minValue) / 10) * 10
|
||||
// } else if (100 <= minValue) {
|
||||
// min = Math.floor((minValue - num * minValue) / 100) * 100
|
||||
// }
|
||||
|
||||
// if (-100 >= maxValue) {
|
||||
// max = Math.ceil((maxValue - num * maxValue) / 100) * 100
|
||||
// } else if (-10 >= maxValue && maxValue > -100) {
|
||||
// max = Math.ceil((maxValue - num * maxValue) / 10) * 10
|
||||
// } else if (-1 >= maxValue && maxValue > -10) {
|
||||
// max = Math.ceil(maxValue - num * maxValue)
|
||||
// } else if (0 > maxValue && maxValue > -1) {
|
||||
// max = parseFloat((maxValue - num * maxValue).toFixed(1))
|
||||
// } else if (maxValue == 0) {
|
||||
// max = 0
|
||||
// } else if (0 < maxValue && maxValue < 1) {
|
||||
// max = parseFloat((maxValue + num * maxValue).toFixed(1))
|
||||
// } else if (1 <= maxValue && maxValue < 10) {
|
||||
// max = Math.ceil(maxValue + num * maxValue)
|
||||
// } else if (10 <= maxValue && maxValue < 100) {
|
||||
// max = Math.ceil((maxValue + num * maxValue) / 10) * 10
|
||||
// } else if (100 <= maxValue) {
|
||||
// max = Math.ceil((maxValue + num * maxValue) / 100) * 100
|
||||
// }
|
||||
|
||||
// if (maxValue > 1000 || minValue < -1000) {
|
||||
// max = Math.ceil(maxValue / 100) * 100
|
||||
// if (minValue == 0) {
|
||||
// min = 0
|
||||
// } else {
|
||||
// min = Math.floor(minValue / 100) * 100
|
||||
// }
|
||||
// } else if (maxValue < 60 && minValue > 40) {
|
||||
// max = 60
|
||||
// min = 40
|
||||
// } else if (maxValue == minValue && maxValue < 10 && minValue > 0) {
|
||||
// max = Math.ceil(maxValue / 10) * 10
|
||||
// min = Math.floor(minValue / 10) * 10
|
||||
// } else if (maxValue == minValue && maxValue != 0 && minValue != 0) {
|
||||
// max = Math.ceil(maxValue / 10 + 1) * 10
|
||||
// min = Math.floor(minValue / 10 - 1) * 10
|
||||
// } else {
|
||||
// max = Math.ceil(maxValue / 10) * 10
|
||||
// min = Math.floor(minValue / 10) * 10
|
||||
// }
|
||||
|
||||
// if (maxValue > 0 && maxValue < 1) {
|
||||
// max = 1
|
||||
// } else if (max == 0 && minValue > -1 && minValue < 0) {
|
||||
// min = -1
|
||||
// }
|
||||
// 一正一负时各自按绝对值范围计算,不用 max - min 作为跨度
|
||||
if (maxValue > 0 && minValue < 0) {
|
||||
min = calculateValue(Math.abs(minValue), minValue, num, true)
|
||||
max = calculateValue(Math.abs(maxValue), maxValue, num, false)
|
||||
} else {
|
||||
const o = maxValue - minValue === 0 ? maxValue : maxValue - minValue
|
||||
min = calculateValue(o, minValue, num, true)
|
||||
max = calculateValue(o, maxValue, num, false)
|
||||
}
|
||||
|
||||
return [min, max]
|
||||
}
|
||||
@@ -158,8 +101,6 @@ export const exportCSV = (title: object, data: any, filename: string) => {
|
||||
URL.revokeObjectURL(link.href)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 补全时间序列数据中缺失的条目
|
||||
* @param rawData 原始数据,格式为 [["时间字符串", "数值", "单位", "类型"], ...]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { downloadFile } from '@/api/system-boot/file'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
const sanitizeUrl = (url: string): string => {
|
||||
return url.replace(/\[/g, '(').replace(/\]/g, ')')
|
||||
@@ -7,7 +8,7 @@ const sanitizeUrl = (url: string): string => {
|
||||
// 下载文件
|
||||
export const download = (urls: string) => {
|
||||
//console.log('下载', urls)
|
||||
|
||||
ElMessage.info('下载中...')
|
||||
downloadFile({ filePath: urls })
|
||||
.then((res: any) => {
|
||||
// 1. 确定文件MIME类型(优化:用更简洁的方式)
|
||||
@@ -26,9 +27,9 @@ export const download = (urls: string) => {
|
||||
}
|
||||
return mimeMap[ext] || ''
|
||||
}
|
||||
|
||||
|
||||
const blob = new Blob([res], { type: getFileType(urls) })
|
||||
|
||||
|
||||
// 2. 提取文件名并保留原生后缀(核心修复点)
|
||||
const fileName = urls.split('/').at(-1) || '下载文件' // 先提取URL最后一段(文件名)
|
||||
|
||||
@@ -43,8 +44,12 @@ export const download = (urls: string) => {
|
||||
// 4. 清理资源(优化)
|
||||
link.remove()
|
||||
window.URL.revokeObjectURL(url) // 释放blob URL
|
||||
setTimeout(() => {
|
||||
ElMessage.success('下载成功')
|
||||
}, 1000)
|
||||
})
|
||||
.catch(err => {
|
||||
ElMessage.warning('下载失败:', err)
|
||||
console.error('下载失败:', err)
|
||||
// 可添加错误提示(如Toast)
|
||||
})
|
||||
@@ -61,7 +66,7 @@ export const previewFile = async (urls: any) => {
|
||||
//console.log('预览', urls)
|
||||
let url = ''
|
||||
await downloadFile({ filePath: decodeURI(urls) })
|
||||
.then((res: any) => {
|
||||
.then((res: any) => {
|
||||
// 1. 确定文件MIME类型(优化:用更简洁的方式)
|
||||
const getFileType = (url: string) => {
|
||||
const ext = url.split('.').pop()?.toLowerCase() || ''
|
||||
@@ -77,7 +82,7 @@ export const previewFile = async (urls: any) => {
|
||||
jpg: 'image/jpg'
|
||||
}
|
||||
return mimeMap[ext] || ''
|
||||
}
|
||||
}
|
||||
const blob = new Blob([res], { type: getFileType(decodeURI(urls)) })
|
||||
// 3. 创建下载链接
|
||||
url = window.URL.createObjectURL(blob)
|
||||
|
||||
@@ -27,8 +27,8 @@ class MQTT {
|
||||
clean: true,
|
||||
connectTimeout: 30 * 1000,
|
||||
clientId: `mqttjs_${Math.random().toString(16).substr(2, 8)}`,
|
||||
username: 't_user',
|
||||
password: 'njcnpqs',
|
||||
username: '',
|
||||
password: '',
|
||||
reconnectPeriod: 1000, // 默认1秒重试一次
|
||||
maxReconnectTimes: 3 // 默认最大重连5次
|
||||
}
|
||||
@@ -50,14 +50,17 @@ class MQTT {
|
||||
if (this.client) {
|
||||
throw new Error('MQTT 客户端已初始化')
|
||||
}
|
||||
|
||||
const mqttUrl = localStorage.getItem('MqttUrl')
|
||||
console.log('MQTT URL:', mqttUrl)
|
||||
if (!mqttUrl || mqttUrl === 'null') {
|
||||
return Promise.resolve()
|
||||
}
|
||||
try {
|
||||
// const mqttUrl =
|
||||
// localStorage.getItem('MqttUrl') == 'null'
|
||||
// ? 'ws://192.168.1.68:8083/mqtt'
|
||||
// : localStorage.getItem('MqttUrl')
|
||||
const mqttUrl = localStorage.getItem('MqttUrl')
|
||||
if (mqttUrl == 'null' || mqttUrl == null) return
|
||||
|
||||
this.client = mqtt.connect(mqttUrl, this.defaultOptions as IClientOptions)
|
||||
this.setupEventListeners()
|
||||
|
||||
@@ -78,12 +81,12 @@ class MQTT {
|
||||
|
||||
this.client?.on('error', error => {
|
||||
clearTimeout(timeout)
|
||||
console.error('MQTT 连接错误:', error)
|
||||
console.log('MQTT 连接错误:', error)
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('初始化 MQTT 失败:', error)
|
||||
// console.log('初始化 MQTT 失败:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
@@ -132,7 +135,7 @@ class MQTT {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.client?.subscribe(this.topic, { qos: this.defaultOptions.qos, ...subscribeOptions }, error => {
|
||||
if (error) {
|
||||
console.error('订阅失败:', error)
|
||||
console.log('订阅失败:', error)
|
||||
reject(error)
|
||||
} else {
|
||||
console.log('订阅成功')
|
||||
@@ -154,7 +157,7 @@ class MQTT {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.client?.unsubscribe(this.topic, error => {
|
||||
if (error) {
|
||||
console.error('取消订阅失败:', error)
|
||||
console.log('取消订阅失败:', error)
|
||||
reject(error)
|
||||
} else {
|
||||
console.log('取消订阅成功')
|
||||
@@ -189,7 +192,7 @@ class MQTT {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.client?.publish(this.topic, message, { qos: this.defaultOptions.qos, ...options }, error => {
|
||||
if (error) {
|
||||
console.error('消息发布失败:', error)
|
||||
console.log('消息发布失败:', error)
|
||||
reject(error)
|
||||
} else {
|
||||
console.log('消息发布成功')
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import type { AxiosRequestConfig, Method } from 'axios'
|
||||
import axios from 'axios'
|
||||
import { ElLoading, ElNotification, type LoadingOptions } from 'element-plus'
|
||||
import { refreshToken } from '@/api/user-boot/user'
|
||||
import { lnRefreshToken, lnRefreshTokenTo, refreshToken } from '@/api/user-boot/user'
|
||||
import router from '@/router/index'
|
||||
import { useAdminInfo } from '@/stores/adminInfo'
|
||||
import { debounce } from 'lodash-es'
|
||||
const IS_LN_VERSION = import.meta.env.VITE_NAME === 'LNqr'
|
||||
let loginExpireTimer: any = null
|
||||
window.requests = []
|
||||
window.tokenRefreshing = false
|
||||
@@ -104,11 +105,16 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
|
||||
if (token) {
|
||||
;(config.headers as anyObj).Authorization = token
|
||||
} else {
|
||||
config.headers.Authorization = 'Basic bmpjbnRlc3Q6bmpjbnBxcw=='
|
||||
config.headers.Authorization = 'Basic bmpjbjpuamNucHFz'
|
||||
}
|
||||
}
|
||||
if (config.url == '/user-boot/user/generateSm2Key' || config.url == '/pqs-auth/oauth/token') {
|
||||
config.headers.Authorization = 'Basic bmpjbnRlc3Q6bmpjbnBxcw=='
|
||||
if (
|
||||
config.url == '/user-boot/user/generateSm2Key' ||
|
||||
config.url == '/pqs-auth/oauth/token' ||
|
||||
config.url == '/pqs-auth/oauth/lnLogin' ||
|
||||
config.url == '/pqs-auth/oauth/lnRefreshToken'
|
||||
) {
|
||||
config.headers.Authorization = 'Basic bmpjbjpuamNucHFz'
|
||||
}
|
||||
|
||||
return config
|
||||
@@ -142,22 +148,46 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
|
||||
if (!window.tokenRefreshing) {
|
||||
window.tokenRefreshing = true
|
||||
|
||||
return refreshToken()
|
||||
.then(res => {
|
||||
adminInfo.setToken(res.data.access_token, 'auth')
|
||||
window.requests.forEach(cb => cb(res.data.access_token))
|
||||
window.requests = []
|
||||
if (IS_LN_VERSION) {
|
||||
//辽宁版本
|
||||
return lnRefreshTokenTo()
|
||||
.then(res => {
|
||||
adminInfo.setToken(res.data.access_token, 'auth')
|
||||
adminInfo.setToken(res.data.refresh_token, 'refresh')
|
||||
window.requests.forEach(cb => cb(res.data.access_token))
|
||||
window.requests = []
|
||||
|
||||
return Axios(response.config)
|
||||
})
|
||||
.catch(err => {
|
||||
adminInfo.removeToken()
|
||||
router.push({ name: 'login' })
|
||||
return Promise.reject(err)
|
||||
})
|
||||
.finally(() => {
|
||||
window.tokenRefreshing = false
|
||||
})
|
||||
return Axios(response.config)
|
||||
})
|
||||
.catch(err => {
|
||||
// refresh_token + CAS 都过期 → 重新走CAS登录
|
||||
//window.location.href = '/api/pqs-auth/oauth/lnCheck'
|
||||
return Promise.reject(err)
|
||||
})
|
||||
.finally(() => {
|
||||
window.tokenRefreshing = false
|
||||
})
|
||||
} else {
|
||||
//通用版本
|
||||
return refreshToken()
|
||||
.then(res => {
|
||||
adminInfo.setToken(res.data.access_token, 'auth')
|
||||
adminInfo.setToken(res.data.refresh_token, 'refresh')
|
||||
window.requests.forEach(cb => cb(res.data.access_token))
|
||||
window.requests = []
|
||||
|
||||
return Axios(response.config)
|
||||
})
|
||||
.catch(err => {
|
||||
window.location.reload()
|
||||
adminInfo.removeToken()
|
||||
router.push({ name: 'login' })
|
||||
return Promise.reject(err)
|
||||
})
|
||||
.finally(() => {
|
||||
window.tokenRefreshing = false
|
||||
})
|
||||
}
|
||||
} else {
|
||||
return new Promise(resolve => {
|
||||
// 用函数形式将 resolve 存入,等待刷新后再执行
|
||||
@@ -183,6 +213,17 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
|
||||
loginExpireTimer = null // 执行后清空定时器
|
||||
}, 100) // 可根据实际情况调整延迟时间
|
||||
return Promise.reject(response.data)
|
||||
} else if (response.data.code == 'A0121') {
|
||||
//统一认证过期
|
||||
//const casLogoutUrl = 'http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas/login?service=http://PQMonitoring.dcloud.ln.dc.sgcc.com.cn'
|
||||
// 1. 清空本地失效token、用户信息
|
||||
adminInfo.removeToken()
|
||||
adminInfo.reset()
|
||||
// 2. 跳转统一鉴权中转接口
|
||||
const authCheckUrl = '/api/pqs-auth/oauth/lnCheck'
|
||||
window.location.href = authCheckUrl
|
||||
// 中断请求
|
||||
return Promise.reject(response.data)
|
||||
} else {
|
||||
if (options.showCodeMessage) {
|
||||
ElNotification({
|
||||
|
||||
@@ -10,7 +10,6 @@ import { compact, isEmpty, reverse } from 'lodash-es'
|
||||
import { getRouteMenu, dictDataCache } from '@/api/auth'
|
||||
import { isAdminApp } from '@/utils/common'
|
||||
import { adminBaseRoutePath } from '@/router/static'
|
||||
const route:any = useRouter()
|
||||
/**
|
||||
* 导航失败有错误消息的路由push
|
||||
* @param to — 导航位置,同 router.push
|
||||
@@ -319,8 +318,9 @@ export const getMenu = () => {
|
||||
}
|
||||
handlerMenu(res.data)
|
||||
handleAdminRoute(res.data)
|
||||
if (route?.params.to) {
|
||||
const lastRoute = JSON.parse(route.params.to as string)
|
||||
const currentRoute = router.currentRoute.value
|
||||
if (currentRoute?.params.to) {
|
||||
const lastRoute = JSON.parse(currentRoute.params.to as string)
|
||||
if (lastRoute.path != adminBaseRoutePath) {
|
||||
let query = !isEmpty(lastRoute.query) ? lastRoute.query : {}
|
||||
routePush({ path: lastRoute.path, query: query })
|
||||
|
||||
@@ -48,6 +48,7 @@ export default class TableStore {
|
||||
filename: null,
|
||||
loading: true,
|
||||
exportLoading: false,
|
||||
customColumnInHeader: false,
|
||||
column: [],
|
||||
loadCallback: null,
|
||||
exportProcessingData: null,
|
||||
@@ -77,6 +78,7 @@ export default class TableStore {
|
||||
}
|
||||
|
||||
index() {
|
||||
|
||||
this.table.beforeSearchFun && this.table.beforeSearchFun()
|
||||
this.table.data = []
|
||||
this.table.loading = true
|
||||
@@ -97,10 +99,12 @@ export default class TableStore {
|
||||
url: this.url,
|
||||
method: this.method
|
||||
},
|
||||
|
||||
requestPayload(this.method, this.table.params, this.paramsPOST)
|
||||
)
|
||||
)
|
||||
.then((res: any) => {
|
||||
|
||||
if (res.data) {
|
||||
this.table.data = res.data.records || res.data
|
||||
this.table.total = res.data?.total || res.data.length || 0
|
||||
@@ -129,13 +133,15 @@ export default class TableStore {
|
||||
* @param data 携带数据
|
||||
*/
|
||||
onTableAction = (event: string, data: anyObj) => {
|
||||
|
||||
const actionFun = new Map([
|
||||
[
|
||||
'search',
|
||||
() => {
|
||||
|
||||
|
||||
this.table.params.pageNum = 1
|
||||
this.index()
|
||||
|
||||
}
|
||||
],
|
||||
[
|
||||
@@ -201,9 +207,10 @@ export default class TableStore {
|
||||
[
|
||||
'export',
|
||||
() => {
|
||||
|
||||
this.table.exportLoading = true
|
||||
// this.index()
|
||||
//console.log('export')
|
||||
|
||||
let params = { ...this.table.params, pageNum: 1, pageSize: this.table.total }
|
||||
createAxios(
|
||||
Object.assign(
|
||||
@@ -219,7 +226,7 @@ export default class TableStore {
|
||||
this.table.exportProcessingData && this.table.exportProcessingData()
|
||||
this.table.allFlag = data.showAllFlag || true
|
||||
this.table.exportLoading = false
|
||||
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
this.table.exportLoading = false
|
||||
|
||||
@@ -1,400 +1,432 @@
|
||||
interface TreeHelperConfig {
|
||||
id: string
|
||||
children: string
|
||||
pid: string
|
||||
}
|
||||
|
||||
const DEFAULT_CONFIG: TreeHelperConfig = {
|
||||
id: 'id',
|
||||
children: 'children',
|
||||
pid: 'pid'
|
||||
}
|
||||
export const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id',
|
||||
isLeaf: 'leaf',
|
||||
emitPath: false // 用于 cascader 组件:在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置 false,则只返回该节点的值
|
||||
}
|
||||
|
||||
const getConfig = (config: Partial<TreeHelperConfig>) => Object.assign({}, DEFAULT_CONFIG, config)
|
||||
|
||||
// tree from list
|
||||
export const listToTree = <T = any>(list: any[], config: Partial<TreeHelperConfig> = {}): T[] => {
|
||||
const conf = getConfig(config) as TreeHelperConfig
|
||||
const nodeMap = new Map()
|
||||
const result: T[] = []
|
||||
const { id, children, pid } = conf
|
||||
|
||||
for (const node of list) {
|
||||
node[children] = node[children] || []
|
||||
nodeMap.set(node[id], node)
|
||||
}
|
||||
for (const node of list) {
|
||||
const parent = nodeMap.get(node[pid])
|
||||
;(parent ? parent.children : result).push(node)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const treeToList = <T = any>(tree: any, config: Partial<TreeHelperConfig> = {}): T => {
|
||||
config = getConfig(config)
|
||||
const { children } = config
|
||||
const result: any = [...tree]
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
if (!result[i][children!]) continue
|
||||
result.splice(i + 1, 0, ...result[i][children!])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const findNode = <T = any>(
|
||||
tree: any,
|
||||
func: Fn,
|
||||
config: Partial<TreeHelperConfig> = {}
|
||||
): T | null => {
|
||||
config = getConfig(config)
|
||||
const { children } = config
|
||||
const list = [...tree]
|
||||
for (const node of list) {
|
||||
if (func(node)) return node
|
||||
node[children!] && list.push(...node[children!])
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const findNodeAll = <T = any>(
|
||||
tree: any,
|
||||
func: Fn,
|
||||
config: Partial<TreeHelperConfig> = {}
|
||||
): T[] => {
|
||||
config = getConfig(config)
|
||||
const { children } = config
|
||||
const list = [...tree]
|
||||
const result: T[] = []
|
||||
for (const node of list) {
|
||||
func(node) && result.push(node)
|
||||
node[children!] && list.push(...node[children!])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const findPath = <T = any>(
|
||||
tree: any,
|
||||
func: Fn,
|
||||
config: Partial<TreeHelperConfig> = {}
|
||||
): T | T[] | null => {
|
||||
config = getConfig(config)
|
||||
const path: T[] = []
|
||||
const list = [...tree]
|
||||
const visitedSet = new Set()
|
||||
const { children } = config
|
||||
while (list.length) {
|
||||
const node = list[0]
|
||||
if (visitedSet.has(node)) {
|
||||
path.pop()
|
||||
list.shift()
|
||||
} else {
|
||||
visitedSet.add(node)
|
||||
node[children!] && list.unshift(...node[children!])
|
||||
path.push(node)
|
||||
if (func(node)) {
|
||||
return path
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const findPathAll = (tree: any, func: Fn, config: Partial<TreeHelperConfig> = {}) => {
|
||||
config = getConfig(config)
|
||||
const path: any[] = []
|
||||
const list = [...tree]
|
||||
const result: any[] = []
|
||||
const visitedSet = new Set(),
|
||||
{ children } = config
|
||||
while (list.length) {
|
||||
const node = list[0]
|
||||
if (visitedSet.has(node)) {
|
||||
path.pop()
|
||||
list.shift()
|
||||
} else {
|
||||
visitedSet.add(node)
|
||||
node[children!] && list.unshift(...node[children!])
|
||||
path.push(node)
|
||||
func(node) && result.push([...path])
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const filter = <T = any>(
|
||||
tree: T[],
|
||||
func: (n: T) => boolean,
|
||||
config: Partial<TreeHelperConfig> = {}
|
||||
): T[] => {
|
||||
config = getConfig(config)
|
||||
const children = config.children as string
|
||||
|
||||
function listFilter(list: T[]) {
|
||||
return list
|
||||
.map((node: any) => ({ ...node }))
|
||||
.filter((node) => {
|
||||
node[children] = node[children] && listFilter(node[children])
|
||||
return func(node) || (node[children] && node[children].length)
|
||||
})
|
||||
}
|
||||
|
||||
return listFilter(tree)
|
||||
}
|
||||
|
||||
export const forEach = <T = any>(
|
||||
tree: T[],
|
||||
func: (n: T) => any,
|
||||
config: Partial<TreeHelperConfig> = {}
|
||||
): void => {
|
||||
config = getConfig(config)
|
||||
const list: any[] = [...tree]
|
||||
const { children } = config
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
// func 返回true就终止遍历,避免大量节点场景下无意义循环,引起浏览器卡顿
|
||||
if (func(list[i])) {
|
||||
return
|
||||
}
|
||||
children && list[i][children] && list.splice(i + 1, 0, ...list[i][children])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Extract tree specified structure
|
||||
*/
|
||||
export const treeMap = <T = any>(
|
||||
treeData: T[],
|
||||
opt: { children?: string; conversion: Fn }
|
||||
): T[] => {
|
||||
return treeData.map((item) => treeMapEach(item, opt))
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Extract tree specified structure
|
||||
*/
|
||||
export const treeMapEach = (
|
||||
data: any,
|
||||
{ children = 'children', conversion }: { children?: string; conversion: Fn }
|
||||
) => {
|
||||
const haveChildren = Array.isArray(data[children]) && data[children].length > 0
|
||||
const conversionData = conversion(data) || {}
|
||||
if (haveChildren) {
|
||||
return {
|
||||
...conversionData,
|
||||
[children]: data[children].map((i: number) =>
|
||||
treeMapEach(i, {
|
||||
children,
|
||||
conversion
|
||||
})
|
||||
)
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
...conversionData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归遍历树结构
|
||||
* @param treeDatas 树
|
||||
* @param callBack 回调
|
||||
* @param parentNode 父节点
|
||||
*/
|
||||
export const eachTree = (treeDatas: any[], callBack: Fn, parentNode = {}) => {
|
||||
treeDatas.forEach((element) => {
|
||||
const newNode = callBack(element, parentNode) || element
|
||||
if (element.children) {
|
||||
eachTree(element.children, callBack, newNode)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造树型结构数据
|
||||
* @param {*} data 数据源
|
||||
* @param {*} id id字段 默认 'id'
|
||||
* @param {*} parentId 父节点字段 默认 'parentId'
|
||||
* @param {*} children 孩子节点字段 默认 'children'
|
||||
*/
|
||||
export const handleTree = (data: any[], id?: string, parentId?: string, children?: string) => {
|
||||
if (!Array.isArray(data)) {
|
||||
console.warn('data must be an array')
|
||||
return []
|
||||
}
|
||||
const config = {
|
||||
id: id || 'id',
|
||||
parentId: parentId || 'parentId',
|
||||
childrenList: children || 'children'
|
||||
}
|
||||
|
||||
const childrenListMap = {}
|
||||
const nodeIds = {}
|
||||
const tree: any[] = []
|
||||
|
||||
for (const d of data) {
|
||||
const parentId = d[config.parentId]
|
||||
if (childrenListMap[parentId] == null) {
|
||||
childrenListMap[parentId] = []
|
||||
}
|
||||
nodeIds[d[config.id]] = d
|
||||
childrenListMap[parentId].push(d)
|
||||
}
|
||||
|
||||
for (const d of data) {
|
||||
const parentId = d[config.parentId]
|
||||
if (nodeIds[parentId] == null) {
|
||||
tree.push(d)
|
||||
}
|
||||
}
|
||||
|
||||
for (const t of tree) {
|
||||
adaptToChildrenList(t)
|
||||
}
|
||||
|
||||
function adaptToChildrenList(o) {
|
||||
if (childrenListMap[o[config.id]] !== null) {
|
||||
o[config.childrenList] = childrenListMap[o[config.id]]
|
||||
}
|
||||
if (o[config.childrenList]) {
|
||||
for (const c of o[config.childrenList]) {
|
||||
adaptToChildrenList(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tree
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造树型结构数据
|
||||
* @param {*} data 数据源
|
||||
* @param {*} id id字段 默认 'id'
|
||||
* @param {*} parentId 父节点字段 默认 'parentId'
|
||||
* @param {*} children 孩子节点字段 默认 'children'
|
||||
* @param {*} rootId 根Id 默认 0
|
||||
*/
|
||||
// @ts-ignore
|
||||
export const handleTree2 = (data, id, parentId, children, rootId) => {
|
||||
id = id || 'id'
|
||||
parentId = parentId || 'parentId'
|
||||
// children = children || 'children'
|
||||
rootId =
|
||||
rootId ||
|
||||
Math.min(
|
||||
...data.map((item) => {
|
||||
return item[parentId]
|
||||
})
|
||||
) ||
|
||||
0
|
||||
// 对源数据深度克隆
|
||||
const cloneData = JSON.parse(JSON.stringify(data))
|
||||
// 循环所有项
|
||||
const treeData = cloneData.filter((father) => {
|
||||
const branchArr = cloneData.filter((child) => {
|
||||
// 返回每一项的子级数组
|
||||
return father[id] === child[parentId]
|
||||
})
|
||||
branchArr.length > 0 ? (father.children = branchArr) : ''
|
||||
// 返回第一层
|
||||
return father[parentId] === rootId
|
||||
})
|
||||
return treeData !== '' ? treeData : data
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验选中的节点,是否为指定 level
|
||||
*
|
||||
* @param tree 要操作的树结构数据
|
||||
* @param nodeId 需要判断在什么层级的数据
|
||||
* @param level 检查的级别, 默认检查到二级
|
||||
* @return true 是;false 否
|
||||
*/
|
||||
export const checkSelectedNode = (tree: any[], nodeId: any, level = 2): boolean => {
|
||||
if (typeof tree === 'undefined' || !Array.isArray(tree) || tree.length === 0) {
|
||||
console.warn('tree must be an array')
|
||||
return false
|
||||
}
|
||||
|
||||
// 校验是否是一级节点
|
||||
if (tree.some((item) => item.id === nodeId)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 递归计数
|
||||
let count = 1
|
||||
|
||||
// 深层次校验
|
||||
function performAThoroughValidation(arr: any[]): boolean {
|
||||
count += 1
|
||||
for (const item of arr) {
|
||||
if (item.id === nodeId) {
|
||||
return true
|
||||
} else if (typeof item.children !== 'undefined' && item.children.length !== 0) {
|
||||
if (performAThoroughValidation(item.children)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for (const item of tree) {
|
||||
count = 1
|
||||
if (performAThoroughValidation(item.children)) {
|
||||
// 找到后对比是否是期望的层级
|
||||
if (count >= level) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取节点的完整结构
|
||||
* @param tree 树数据
|
||||
* @param nodeId 节点 id
|
||||
*/
|
||||
export const treeToString = (tree: any[], nodeId) => {
|
||||
if (typeof tree === 'undefined' || !Array.isArray(tree) || tree.length === 0) {
|
||||
console.warn('tree must be an array')
|
||||
return ''
|
||||
}
|
||||
// 校验是否是一级节点
|
||||
const node = tree.find((item) => item.id === nodeId)
|
||||
if (typeof node !== 'undefined') {
|
||||
return node.name
|
||||
}
|
||||
let str = ''
|
||||
|
||||
function performAThoroughValidation(arr) {
|
||||
for (const item of arr) {
|
||||
if (item.id === nodeId) {
|
||||
str += ` / ${item.name}`
|
||||
return true
|
||||
} else if (typeof item.children !== 'undefined' && item.children.length !== 0) {
|
||||
str += ` / ${item.name}`
|
||||
if (performAThoroughValidation(item.children)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for (const item of tree) {
|
||||
str = `${item.name}`
|
||||
if (performAThoroughValidation(item.children)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return str
|
||||
}
|
||||
interface TreeHelperConfig {
|
||||
id: string
|
||||
children: string
|
||||
pid: string
|
||||
}
|
||||
|
||||
const DEFAULT_CONFIG: TreeHelperConfig = {
|
||||
id: 'id',
|
||||
children: 'children',
|
||||
pid: 'pid'
|
||||
}
|
||||
export const defaultProps = {
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id',
|
||||
isLeaf: 'leaf',
|
||||
emitPath: false // 用于 cascader 组件:在选中节点改变时,是否返回由该节点所在的各级菜单的值所组成的数组,若设置 false,则只返回该节点的值
|
||||
}
|
||||
|
||||
const getConfig = (config: Partial<TreeHelperConfig>) => Object.assign({}, DEFAULT_CONFIG, config)
|
||||
|
||||
// tree from list
|
||||
export const listToTree = <T = any>(list: any[], config: Partial<TreeHelperConfig> = {}): T[] => {
|
||||
const conf = getConfig(config) as TreeHelperConfig
|
||||
const nodeMap = new Map()
|
||||
const result: T[] = []
|
||||
const { id, children, pid } = conf
|
||||
|
||||
for (const node of list) {
|
||||
node[children] = node[children] || []
|
||||
nodeMap.set(node[id], node)
|
||||
}
|
||||
for (const node of list) {
|
||||
const parent = nodeMap.get(node[pid])
|
||||
;(parent ? parent.children : result).push(node)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const treeToList = <T = any>(tree: any, config: Partial<TreeHelperConfig> = {}): T => {
|
||||
config = getConfig(config)
|
||||
const { children } = config
|
||||
const result: any = [...tree]
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
if (!result[i][children!]) continue
|
||||
result.splice(i + 1, 0, ...result[i][children!])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const findNode = <T = any>(
|
||||
tree: any,
|
||||
func: Fn,
|
||||
config: Partial<TreeHelperConfig> = {}
|
||||
): T | null => {
|
||||
config = getConfig(config)
|
||||
const { children } = config
|
||||
const list = [...tree]
|
||||
for (const node of list) {
|
||||
if (func(node)) return node
|
||||
node[children!] && list.push(...node[children!])
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const findNodeAll = <T = any>(
|
||||
tree: any,
|
||||
func: Fn,
|
||||
config: Partial<TreeHelperConfig> = {}
|
||||
): T[] => {
|
||||
config = getConfig(config)
|
||||
const { children } = config
|
||||
const list = [...tree]
|
||||
const result: T[] = []
|
||||
for (const node of list) {
|
||||
func(node) && result.push(node)
|
||||
node[children!] && list.push(...node[children!])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const findPath = <T = any>(
|
||||
tree: any,
|
||||
func: Fn,
|
||||
config: Partial<TreeHelperConfig> = {}
|
||||
): T | T[] | null => {
|
||||
config = getConfig(config)
|
||||
const path: T[] = []
|
||||
const list = [...tree]
|
||||
const visitedSet = new Set()
|
||||
const { children } = config
|
||||
while (list.length) {
|
||||
const node = list[0]
|
||||
if (visitedSet.has(node)) {
|
||||
path.pop()
|
||||
list.shift()
|
||||
} else {
|
||||
visitedSet.add(node)
|
||||
node[children!] && list.unshift(...node[children!])
|
||||
path.push(node)
|
||||
if (func(node)) {
|
||||
return path
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export const findPathAll = (tree: any, func: Fn, config: Partial<TreeHelperConfig> = {}) => {
|
||||
config = getConfig(config)
|
||||
const path: any[] = []
|
||||
const list = [...tree]
|
||||
const result: any[] = []
|
||||
const visitedSet = new Set(),
|
||||
{ children } = config
|
||||
while (list.length) {
|
||||
const node = list[0]
|
||||
if (visitedSet.has(node)) {
|
||||
path.pop()
|
||||
list.shift()
|
||||
} else {
|
||||
visitedSet.add(node)
|
||||
node[children!] && list.unshift(...node[children!])
|
||||
path.push(node)
|
||||
func(node) && result.push([...path])
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const filter = <T = any>(
|
||||
tree: T[],
|
||||
func: (n: T) => boolean,
|
||||
config: Partial<TreeHelperConfig> = {}
|
||||
): T[] => {
|
||||
config = getConfig(config)
|
||||
const children = config.children as string
|
||||
|
||||
function listFilter(list: T[]) {
|
||||
return list
|
||||
.map((node: any) => ({ ...node }))
|
||||
.filter((node) => {
|
||||
node[children] = node[children] && listFilter(node[children])
|
||||
return func(node) || (node[children] && node[children].length)
|
||||
})
|
||||
}
|
||||
|
||||
return listFilter(tree)
|
||||
}
|
||||
export const filterTree = <T = any>(
|
||||
tree: T[],
|
||||
func: (n: T) => boolean,
|
||||
config: Partial<TreeHelperConfig> = {}
|
||||
): T[] => {
|
||||
config = getConfig(config)
|
||||
const children = config.children as string
|
||||
|
||||
function listFilter(list: T[]) {
|
||||
return list
|
||||
.map((node: any) => ({ ...node }))
|
||||
.filter((node) => {
|
||||
// 1. 如果当前节点匹配 → 直接保留【所有子节点】,不再过滤下级
|
||||
if (func(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2. 如果当前节点不匹配,递归过滤子节点
|
||||
if (node[children]) {
|
||||
const filteredChildren = listFilter(node[children]);
|
||||
if (filteredChildren.length > 0) {
|
||||
node[children] = filteredChildren;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 都不匹配,过滤掉
|
||||
return false;
|
||||
})
|
||||
}
|
||||
|
||||
return listFilter(tree)
|
||||
}
|
||||
export const forEach = <T = any>(
|
||||
tree: T[],
|
||||
func: (n: T) => any,
|
||||
config: Partial<TreeHelperConfig> = {}
|
||||
): void => {
|
||||
config = getConfig(config)
|
||||
const list: any[] = [...tree]
|
||||
const { children } = config
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
// func 返回true就终止遍历,避免大量节点场景下无意义循环,引起浏览器卡顿
|
||||
if (func(list[i])) {
|
||||
return
|
||||
}
|
||||
children && list[i][children] && list.splice(i + 1, 0, ...list[i][children])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Extract tree specified structure
|
||||
*/
|
||||
export const treeMap = <T = any>(
|
||||
treeData: T[],
|
||||
opt: { children?: string; conversion: Fn }
|
||||
): T[] => {
|
||||
return treeData.map((item) => treeMapEach(item, opt))
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Extract tree specified structure
|
||||
*/
|
||||
export const treeMapEach = (
|
||||
data: any,
|
||||
{ children = 'children', conversion }: { children?: string; conversion: Fn }
|
||||
) => {
|
||||
const haveChildren = Array.isArray(data[children]) && data[children].length > 0
|
||||
const conversionData = conversion(data) || {}
|
||||
if (haveChildren) {
|
||||
return {
|
||||
...conversionData,
|
||||
[children]: data[children].map((i: number) =>
|
||||
treeMapEach(i, {
|
||||
children,
|
||||
conversion
|
||||
})
|
||||
)
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
...conversionData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归遍历树结构
|
||||
* @param treeDatas 树
|
||||
* @param callBack 回调
|
||||
* @param parentNode 父节点
|
||||
*/
|
||||
export const eachTree = (treeDatas: any[], callBack: Fn, parentNode = {}) => {
|
||||
treeDatas.forEach((element) => {
|
||||
const newNode = callBack(element, parentNode) || element
|
||||
if (element.children) {
|
||||
eachTree(element.children, callBack, newNode)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造树型结构数据
|
||||
* @param {*} data 数据源
|
||||
* @param {*} id id字段 默认 'id'
|
||||
* @param {*} parentId 父节点字段 默认 'parentId'
|
||||
* @param {*} children 孩子节点字段 默认 'children'
|
||||
*/
|
||||
export const handleTree = (data: any[], id?: string, parentId?: string, children?: string) => {
|
||||
if (!Array.isArray(data)) {
|
||||
console.warn('data must be an array')
|
||||
return []
|
||||
}
|
||||
const config = {
|
||||
id: id || 'id',
|
||||
parentId: parentId || 'parentId',
|
||||
childrenList: children || 'children'
|
||||
}
|
||||
|
||||
const childrenListMap = {}
|
||||
const nodeIds = {}
|
||||
const tree: any[] = []
|
||||
|
||||
for (const d of data) {
|
||||
const parentId = d[config.parentId]
|
||||
if (childrenListMap[parentId] == null) {
|
||||
childrenListMap[parentId] = []
|
||||
}
|
||||
nodeIds[d[config.id]] = d
|
||||
childrenListMap[parentId].push(d)
|
||||
}
|
||||
|
||||
for (const d of data) {
|
||||
const parentId = d[config.parentId]
|
||||
if (nodeIds[parentId] == null) {
|
||||
tree.push(d)
|
||||
}
|
||||
}
|
||||
|
||||
for (const t of tree) {
|
||||
adaptToChildrenList(t)
|
||||
}
|
||||
|
||||
function adaptToChildrenList(o) {
|
||||
if (childrenListMap[o[config.id]] !== null) {
|
||||
o[config.childrenList] = childrenListMap[o[config.id]]
|
||||
}
|
||||
if (o[config.childrenList]) {
|
||||
for (const c of o[config.childrenList]) {
|
||||
adaptToChildrenList(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tree
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造树型结构数据
|
||||
* @param {*} data 数据源
|
||||
* @param {*} id id字段 默认 'id'
|
||||
* @param {*} parentId 父节点字段 默认 'parentId'
|
||||
* @param {*} children 孩子节点字段 默认 'children'
|
||||
* @param {*} rootId 根Id 默认 0
|
||||
*/
|
||||
// @ts-ignore
|
||||
export const handleTree2 = (data, id, parentId, children, rootId) => {
|
||||
id = id || 'id'
|
||||
parentId = parentId || 'parentId'
|
||||
// children = children || 'children'
|
||||
rootId =
|
||||
rootId ||
|
||||
Math.min(
|
||||
...data.map((item) => {
|
||||
return item[parentId]
|
||||
})
|
||||
) ||
|
||||
0
|
||||
// 对源数据深度克隆
|
||||
const cloneData = JSON.parse(JSON.stringify(data))
|
||||
// 循环所有项
|
||||
const treeData = cloneData.filter((father) => {
|
||||
const branchArr = cloneData.filter((child) => {
|
||||
// 返回每一项的子级数组
|
||||
return father[id] === child[parentId]
|
||||
})
|
||||
branchArr.length > 0 ? (father.children = branchArr) : ''
|
||||
// 返回第一层
|
||||
return father[parentId] === rootId
|
||||
})
|
||||
return treeData !== '' ? treeData : data
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验选中的节点,是否为指定 level
|
||||
*
|
||||
* @param tree 要操作的树结构数据
|
||||
* @param nodeId 需要判断在什么层级的数据
|
||||
* @param level 检查的级别, 默认检查到二级
|
||||
* @return true 是;false 否
|
||||
*/
|
||||
export const checkSelectedNode = (tree: any[], nodeId: any, level = 2): boolean => {
|
||||
if (typeof tree === 'undefined' || !Array.isArray(tree) || tree.length === 0) {
|
||||
console.warn('tree must be an array')
|
||||
return false
|
||||
}
|
||||
|
||||
// 校验是否是一级节点
|
||||
if (tree.some((item) => item.id === nodeId)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 递归计数
|
||||
let count = 1
|
||||
|
||||
// 深层次校验
|
||||
function performAThoroughValidation(arr: any[]): boolean {
|
||||
count += 1
|
||||
for (const item of arr) {
|
||||
if (item.id === nodeId) {
|
||||
return true
|
||||
} else if (typeof item.children !== 'undefined' && item.children.length !== 0) {
|
||||
if (performAThoroughValidation(item.children)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for (const item of tree) {
|
||||
count = 1
|
||||
if (performAThoroughValidation(item.children)) {
|
||||
// 找到后对比是否是期望的层级
|
||||
if (count >= level) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取节点的完整结构
|
||||
* @param tree 树数据
|
||||
* @param nodeId 节点 id
|
||||
*/
|
||||
export const treeToString = (tree: any[], nodeId) => {
|
||||
if (typeof tree === 'undefined' || !Array.isArray(tree) || tree.length === 0) {
|
||||
console.warn('tree must be an array')
|
||||
return ''
|
||||
}
|
||||
// 校验是否是一级节点
|
||||
const node = tree.find((item) => item.id === nodeId)
|
||||
if (typeof node !== 'undefined') {
|
||||
return node.name
|
||||
}
|
||||
let str = ''
|
||||
|
||||
function performAThoroughValidation(arr) {
|
||||
for (const item of arr) {
|
||||
if (item.id === nodeId) {
|
||||
str += ` / ${item.name}`
|
||||
return true
|
||||
} else if (typeof item.children !== 'undefined' && item.children.length !== 0) {
|
||||
str += ` / ${item.name}`
|
||||
if (performAThoroughValidation(item.children)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
for (const item of tree) {
|
||||
str = `${item.name}`
|
||||
if (performAThoroughValidation(item.children)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
50
src/utils/waveCache.ts
Normal file
50
src/utils/waveCache.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { getWaveRawList } from './waveRawStore'
|
||||
|
||||
const MAX_CACHE_SIZE = 6
|
||||
|
||||
const cache = new Map<string, unknown>()
|
||||
|
||||
function dataFingerprint(data: unknown[][] | undefined): string {
|
||||
if (!data?.length) return '0'
|
||||
const first = data[0]
|
||||
const last = data[data.length - 1]
|
||||
return `${data.length}:${first?.[0]}:${last?.[0]}`
|
||||
}
|
||||
|
||||
export function buildWaveCacheKey(
|
||||
type: 'shu' | 'rms',
|
||||
wp: Record<string, any> | undefined,
|
||||
value: number,
|
||||
isOpen: boolean,
|
||||
boxoList: Record<string, any>
|
||||
): string {
|
||||
if (!wp) return ''
|
||||
const rawList = wp.waveStoreKey
|
||||
? getWaveRawList(type, wp.waveStoreKey)
|
||||
: ((type === 'shu' ? wp.listWaveData : wp.listRmsData) as unknown[][] | undefined)
|
||||
const waveFp = dataFingerprint(rawList)
|
||||
const boxoFp = boxoList?.startTime ?? boxoList?.lineName ?? boxoList?.equipmentName ?? ''
|
||||
return `${type}|${wp.time}|${wp.waveType}|${wp.iphasic}|${value}|${isOpen}|${waveFp}|${boxoFp}`
|
||||
}
|
||||
|
||||
export function getWaveCache<T>(key: string): T | null {
|
||||
if (!key || !cache.has(key)) return null
|
||||
const value = cache.get(key) as T
|
||||
cache.delete(key)
|
||||
cache.set(key, value)
|
||||
return value
|
||||
}
|
||||
|
||||
export function setWaveCache(key: string, value: unknown): void {
|
||||
if (!key) return
|
||||
if (cache.has(key)) cache.delete(key)
|
||||
cache.set(key, value)
|
||||
while (cache.size > MAX_CACHE_SIZE) {
|
||||
const oldest = cache.keys().next().value
|
||||
if (oldest !== undefined) cache.delete(oldest)
|
||||
}
|
||||
}
|
||||
|
||||
export function clearWaveCache(): void {
|
||||
cache.clear()
|
||||
}
|
||||
59
src/utils/waveDisplayHelper.ts
Normal file
59
src/utils/waveDisplayHelper.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
const EMPTY_SERIES: number[][] = []
|
||||
|
||||
function ds(data: number[][] | undefined): number[][] {
|
||||
if (!data?.length) return EMPTY_SERIES
|
||||
return data
|
||||
}
|
||||
|
||||
/** Worker 完整计算后,剔除当前未使用的值类型,降低内存占用 */
|
||||
export function compactShuWaveResult(data: any, value: number) {
|
||||
const waveDatas = data.waveDatas.map((wd: any) => {
|
||||
if (value === 1) {
|
||||
return {
|
||||
...wd,
|
||||
shunshiF: {
|
||||
shunshiFA: ds(wd.shunshiF.shunshiFA),
|
||||
shunshiFB: ds(wd.shunshiF.shunshiFB),
|
||||
shunshiFC: ds(wd.shunshiF.shunshiFC)
|
||||
},
|
||||
shunshiS: { shunshiSA: EMPTY_SERIES, shunshiSB: EMPTY_SERIES, shunshiSC: EMPTY_SERIES }
|
||||
}
|
||||
}
|
||||
return {
|
||||
...wd,
|
||||
shunshiF: { shunshiFA: EMPTY_SERIES, shunshiFB: EMPTY_SERIES, shunshiFC: EMPTY_SERIES },
|
||||
shunshiS: {
|
||||
shunshiSA: ds(wd.shunshiS.shunshiSA),
|
||||
shunshiSB: ds(wd.shunshiS.shunshiSB),
|
||||
shunshiSC: ds(wd.shunshiS.shunshiSC)
|
||||
}
|
||||
}
|
||||
})
|
||||
return { ...data, waveDatas }
|
||||
}
|
||||
|
||||
export function compactRmsWaveResult(data: any, value: number) {
|
||||
const waveDatas = data.waveDatas.map((wd: any) => {
|
||||
if (value === 1) {
|
||||
return {
|
||||
...wd,
|
||||
RMSFWave: {
|
||||
rmsFA: ds(wd.RMSFWave.rmsFA),
|
||||
rmsFB: ds(wd.RMSFWave.rmsFB),
|
||||
rmsFC: ds(wd.RMSFWave.rmsFC)
|
||||
},
|
||||
RMSSWave: { rmsSA: EMPTY_SERIES, rmsSB: EMPTY_SERIES, rmsSC: EMPTY_SERIES }
|
||||
}
|
||||
}
|
||||
return {
|
||||
...wd,
|
||||
RMSFWave: { rmsFA: EMPTY_SERIES, rmsFB: EMPTY_SERIES, rmsFC: EMPTY_SERIES },
|
||||
RMSSWave: {
|
||||
rmsSA: ds(wd.RMSSWave.rmsSA),
|
||||
rmsSB: ds(wd.RMSSWave.rmsSB),
|
||||
rmsSC: ds(wd.RMSSWave.rmsSC)
|
||||
}
|
||||
}
|
||||
})
|
||||
return { ...data, waveDatas }
|
||||
}
|
||||
75
src/utils/waveRawStore.ts
Normal file
75
src/utils/waveRawStore.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
/** 原始波形数据存放于 Vue 响应式体系之外,避免大数组触发深度代理与重复持有 */
|
||||
|
||||
interface WaveRawEntry {
|
||||
listWaveData?: unknown[][]
|
||||
listRmsData?: unknown[][]
|
||||
waveTimeRange?: { min: number; max: number }
|
||||
}
|
||||
|
||||
const rawStore = new Map<string, WaveRawEntry>()
|
||||
|
||||
function calcTimeRange(data: unknown[][] | undefined): { min: number; max: number } | undefined {
|
||||
if (!data?.length) return undefined
|
||||
const first = data[0] as number[]
|
||||
const last = data[data.length - 1] as number[]
|
||||
return { min: first[0], max: last[0] + 1 }
|
||||
}
|
||||
|
||||
export function buildWaveStoreKey(boxoList: Record<string, any>): string {
|
||||
const id = boxoList?.eventId ?? boxoList?.id ?? ''
|
||||
return `${id}|${boxoList?.startTime ?? ''}`
|
||||
}
|
||||
|
||||
export function registerWaveRaw(storeKey: string, wp: Record<string, any>): void {
|
||||
if (!storeKey || !wp) return
|
||||
const entry: WaveRawEntry = rawStore.get(storeKey) ?? {}
|
||||
|
||||
if (wp.listWaveData?.length) {
|
||||
entry.listWaveData = wp.listWaveData
|
||||
entry.waveTimeRange = calcTimeRange(wp.listWaveData) ?? entry.waveTimeRange
|
||||
}
|
||||
if (wp.listRmsData?.length) {
|
||||
entry.listRmsData = wp.listRmsData
|
||||
entry.waveTimeRange = calcTimeRange(wp.listRmsData) ?? entry.waveTimeRange
|
||||
}
|
||||
|
||||
rawStore.set(storeKey, entry)
|
||||
}
|
||||
|
||||
export function getWaveRawList(type: 'shu' | 'rms', storeKey: string | undefined): unknown[][] | undefined {
|
||||
if (!storeKey) return undefined
|
||||
const entry = rawStore.get(storeKey)
|
||||
return type === 'shu' ? entry?.listWaveData : entry?.listRmsData
|
||||
}
|
||||
|
||||
export function getWaveTimeRange(storeKey: string | undefined): { min: number; max: number } | undefined {
|
||||
if (!storeKey) return undefined
|
||||
return rawStore.get(storeKey)?.waveTimeRange
|
||||
}
|
||||
|
||||
export function releaseWaveRaw(storeKey: string | undefined, type: 'shu' | 'rms' | 'all' = 'all'): void {
|
||||
if (!storeKey) return
|
||||
if (type === 'all') {
|
||||
rawStore.delete(storeKey)
|
||||
return
|
||||
}
|
||||
const entry = rawStore.get(storeKey)
|
||||
if (!entry) return
|
||||
if (type === 'shu') delete entry.listWaveData
|
||||
if (type === 'rms') delete entry.listRmsData
|
||||
if (!entry.listWaveData && !entry.listRmsData) {
|
||||
rawStore.delete(storeKey)
|
||||
} else {
|
||||
rawStore.set(storeKey, entry)
|
||||
}
|
||||
}
|
||||
|
||||
/** 构建不含大数组的 wp 对象,供子组件 props 使用 */
|
||||
export function buildSlimWp(wp: Record<string, any>, storeKey: string): Record<string, any> {
|
||||
const { listWaveData: _w, listRmsData: _r, ...rest } = wp
|
||||
return {
|
||||
...rest,
|
||||
waveStoreKey: storeKey,
|
||||
waveTimeRange: getWaveTimeRange(storeKey) ?? calcTimeRange(_w) ?? calcTimeRange(_r)
|
||||
}
|
||||
}
|
||||
98
src/utils/waveWorkerPool.ts
Normal file
98
src/utils/waveWorkerPool.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import { toRaw } from 'vue'
|
||||
import { getWaveRawList } from './waveRawStore'
|
||||
|
||||
type WorkerMessageHandler = (data: any) => void
|
||||
|
||||
let shuWorker: Worker | null = null
|
||||
let rmsWorker: Worker | null = null
|
||||
|
||||
/** 递归剥离 Vue 响应式代理,得到可 structuredClone 的纯对象 */
|
||||
export function toPlainDeep<T>(value: T): T {
|
||||
const raw = toRaw(value as object) as T
|
||||
if (Array.isArray(raw)) {
|
||||
return raw.map(item => toPlainDeep(item)) as T
|
||||
}
|
||||
if (raw !== null && typeof raw === 'object') {
|
||||
const out: Record<string, unknown> = {}
|
||||
for (const [key, val] of Object.entries(raw)) {
|
||||
out[key] = toPlainDeep(val)
|
||||
}
|
||||
return out as T
|
||||
}
|
||||
return raw
|
||||
}
|
||||
|
||||
const BOXO_LIST_KEYS = [
|
||||
'systemType',
|
||||
'powerStationName',
|
||||
'measurementPointName',
|
||||
'startTime',
|
||||
'featureAmplitude',
|
||||
'duration',
|
||||
'engineeringName',
|
||||
'equipmentName',
|
||||
'evtParamVVaDepth',
|
||||
'evtParamTm',
|
||||
'lineName',
|
||||
'persistTime',
|
||||
'subName'
|
||||
] as const
|
||||
|
||||
export function buildWorkerPayload(
|
||||
type: 'shu' | 'rms',
|
||||
wp: Record<string, any>,
|
||||
boxoList: Record<string, any>,
|
||||
extras: { requestId: number; value: number; isOpen: boolean; iphasic?: number }
|
||||
) {
|
||||
const plainWp = toPlainDeep(wp)
|
||||
const wpPayload: Record<string, unknown> = {
|
||||
pt: plainWp.pt,
|
||||
ct: plainWp.ct,
|
||||
waveTitle: plainWp.waveTitle,
|
||||
iphasic: plainWp.iphasic,
|
||||
time: plainWp.time,
|
||||
waveType: plainWp.waveType,
|
||||
yzd: plainWp.yzd
|
||||
}
|
||||
const storeKey = plainWp.waveStoreKey as string | undefined
|
||||
if (type === 'shu') {
|
||||
wpPayload.listWaveData = getWaveRawList('shu', storeKey) ?? plainWp.listWaveData
|
||||
} else {
|
||||
wpPayload.listRmsData = getWaveRawList('rms', storeKey) ?? plainWp.listRmsData
|
||||
}
|
||||
|
||||
const plainBoxo: Record<string, unknown> = {}
|
||||
const rawBoxo = toPlainDeep(boxoList)
|
||||
for (const key of BOXO_LIST_KEYS) {
|
||||
if (rawBoxo[key] !== undefined) {
|
||||
plainBoxo[key] = rawBoxo[key]
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
requestId: extras.requestId,
|
||||
value: extras.value,
|
||||
isOpen: extras.isOpen,
|
||||
iphasic: extras.iphasic,
|
||||
wp: wpPayload,
|
||||
boxoList: plainBoxo
|
||||
}
|
||||
}
|
||||
|
||||
export function getShuWorker(onMessage: WorkerMessageHandler): Worker {
|
||||
if (!shuWorker) {
|
||||
shuWorker = new Worker(new URL('../components/echarts/shuWorker.js', import.meta.url))
|
||||
}
|
||||
shuWorker.onmessage = e => onMessage(e.data)
|
||||
shuWorker.onerror = error => console.error('Shu worker error:', error)
|
||||
return shuWorker
|
||||
}
|
||||
|
||||
export function getRmsWorker(onMessage: WorkerMessageHandler): Worker {
|
||||
if (!rmsWorker) {
|
||||
rmsWorker = new Worker(new URL('../components/echarts/rmsWorker.js', import.meta.url))
|
||||
}
|
||||
rmsWorker.onmessage = e => onMessage(e.data)
|
||||
rmsWorker.onerror = error => console.error('Rms worker error:', error)
|
||||
return rmsWorker
|
||||
}
|
||||
@@ -43,13 +43,11 @@ export default class SocketService {
|
||||
console.log('您的浏览器不支持WebSocket')
|
||||
return
|
||||
}
|
||||
|
||||
console.log("🚀 ~ SocketService ~ connect ~ url:", url)
|
||||
if (url === null || (typeof url === 'string' && url.includes('null'))) return;
|
||||
|
||||
setTimeout(() => {
|
||||
// ws://192.168.1.69:10407/mgtt
|
||||
// const url =
|
||||
// (localStorage.getItem('WebSocketUrl') == 'null'
|
||||
// ? 'ws://192.168.1.130:10405'
|
||||
// : localStorage.getItem('WebSocketUrl')) + id
|
||||
this.ws = new WebSocket(url)
|
||||
|
||||
this.ws.onopen = () => this.handleOpen()
|
||||
@@ -58,10 +56,9 @@ export default class SocketService {
|
||||
this.ws.onmessage = event => this.handleMessage(event)
|
||||
}, 0)
|
||||
}
|
||||
|
||||
// 处理连接成功事件
|
||||
private handleOpen(): void {
|
||||
ElMessage.success('webSocket连接服务端成功了')
|
||||
// ElMessage.success('webSocket连接服务端成功了')
|
||||
console.log('连接服务端成功了')
|
||||
this.connected = true
|
||||
this.connectRetryCount = 0
|
||||
@@ -90,7 +87,7 @@ export default class SocketService {
|
||||
|
||||
if (event.data == '连接成功') {
|
||||
this.sendHeartbeat()
|
||||
} else if (event.data == 'connect') {
|
||||
} else if (event.data == 'over') {
|
||||
} else if (event.data.length > 10) {
|
||||
let message: MessageType
|
||||
try {
|
||||
@@ -104,7 +101,7 @@ export default class SocketService {
|
||||
|
||||
// 通过接受服务端发送的type字段来回调函数
|
||||
|
||||
if ((message.key || message.code) && this.callBackMapping['message']) {
|
||||
if ((message.key || message.code || message.time) && this.callBackMapping['message']) {
|
||||
this.callBackMapping['message']!(message)
|
||||
} else {
|
||||
console.log('抛弃====>')
|
||||
@@ -112,6 +109,8 @@ export default class SocketService {
|
||||
// 丢弃或继续写你的逻辑
|
||||
}
|
||||
} else {
|
||||
this.callBackMapping['message']!({ Flag: false })
|
||||
if(event.data == 'connect')return
|
||||
ElMessage.error(event.data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,423 +1,423 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<TableHeader datePicker theCurrentTime area ref="header">
|
||||
<!-- <template v-slot:select>
|
||||
|
||||
</template> -->
|
||||
</TableHeader>
|
||||
<div v-loading="tableStore.table.loading">
|
||||
<el-row :gutter="10" class="pd10">
|
||||
<el-col :span="11" style="position: relative">
|
||||
<el-card>
|
||||
<el-radio-group
|
||||
v-model="tableStore.table.params.type"
|
||||
class="group"
|
||||
@change="tableStore.index()"
|
||||
>
|
||||
<el-radio-button label="风电场" value="1" />
|
||||
<el-radio-button label="光伏电站" value="2" />
|
||||
</el-radio-group>
|
||||
<MyEchartMap
|
||||
ref="EchartMap"
|
||||
:options="echartMapList"
|
||||
class="map"
|
||||
@eliminate="eliminate"
|
||||
@getRegionByRegion="getRegionByRegion"
|
||||
@clickMap="clickMap"
|
||||
/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="13">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>暂降列表</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- <h3 class="mb10">暂降列表</h3> -->
|
||||
<div class="tall1">
|
||||
<vxe-table
|
||||
height="auto"
|
||||
auto-resize
|
||||
:data="distributionData"
|
||||
v-loading="loading"
|
||||
v-bind="defaultAttribute"
|
||||
>
|
||||
<vxe-column
|
||||
field="newStationName"
|
||||
title="新能源站名称"
|
||||
min-width="150px"
|
||||
show-overflow-tooltip
|
||||
></vxe-column>
|
||||
<vxe-column field="startTime" title="暂降发生时刻" min-width="150px"></vxe-column>
|
||||
<vxe-column
|
||||
field="featureAmplitude"
|
||||
title="暂降(骤升)幅值(%)"
|
||||
sortable
|
||||
min-width="150px"
|
||||
></vxe-column>
|
||||
<vxe-column
|
||||
field="advanceReason"
|
||||
title="暂降原因"
|
||||
sortable
|
||||
:formatter="formFilter"
|
||||
min-width="100px"
|
||||
></vxe-column>
|
||||
<vxe-column field="severity" title="严重度" min-width="100px" sortable></vxe-column>
|
||||
<vxe-column title="操作" width="80px">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="row.wavePath != null"
|
||||
size="small"
|
||||
link
|
||||
@click="boxi(row)"
|
||||
>
|
||||
查看波形
|
||||
</el-button>
|
||||
<el-button v-else disabled size="small" link>暂无波形</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="mt10">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>暂降波形</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="tall" v-loading="loading1">
|
||||
<!-- <h3 class="mb10">暂降波形</h3> -->
|
||||
<div v-if="wp != null">
|
||||
<rmsboxi :value="1" :height="height" :boxoList="boxoList" :wp="wp" />
|
||||
</div>
|
||||
<el-empty v-else description="暂无数据" class="custom-empty" />
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import MyEchartMap from '@/components/echarts/MyEchartMap.vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import { voltageRideThroughEventQueryPage } from '@/api/event-boot/highAndLowPressure'
|
||||
import { getMonitorEventAnalyseWave, getTransientDetailById } from '@/api/event-boot/transient'
|
||||
import rmsboxi from '@/components/echarts/rmsboxi.vue'
|
||||
import { ref, onMounted, provide } from 'vue'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { FormItem } from 'vxe-table'
|
||||
defineOptions({
|
||||
name: 'newEnergy/highAndLowPressure'
|
||||
})
|
||||
const EchartMap = ref()
|
||||
const dictData = useDictData()
|
||||
const reason = dictData.getBasicData('Event_Reason')
|
||||
const triggerType = dictData.getBasicData('Event_Statis')
|
||||
const echartMapList: any = ref({})
|
||||
const header = ref()
|
||||
const distributionData: any = ref([])
|
||||
const loading = ref(false)
|
||||
const loading1 = ref(false)
|
||||
const boxoList = ref(null)
|
||||
const wp = ref(null)
|
||||
const tableStore = new TableStore({
|
||||
url: '/event-boot/voltageRideThrough/view',
|
||||
method: 'POST',
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.areaId = tableStore.table.params.deptIndex
|
||||
},
|
||||
loadCallback: () => {
|
||||
// 处理地图数据
|
||||
map(tableStore.table.data)
|
||||
// tabulation(tableStore.table.data)
|
||||
EchartMap.value.GetEchar(header.value.areaRef.areaName)
|
||||
if (tableStore.table.data.length > 0) {
|
||||
tabulation({ data: tableStore.table.data[0], seriesName: '高压' })
|
||||
}
|
||||
}
|
||||
})
|
||||
const height = mainHeight(200, 2).height
|
||||
provide('tableStore', tableStore)
|
||||
tableStore.table.params.type = '1'
|
||||
|
||||
// 地图点击事件
|
||||
const getRegionByRegion = (list: any) => {
|
||||
tableStore.table.params.deptIndex = list.id
|
||||
tableStore.onTableAction('search', {})
|
||||
}
|
||||
// 消除点
|
||||
const eliminate = (name: string) => {
|
||||
echartMapList.value.options.series = []
|
||||
EchartMap.value.GetEchar(name)
|
||||
}
|
||||
|
||||
// 地图数处理
|
||||
const map = (res: any) => {
|
||||
echartMapList.value = {
|
||||
title: {
|
||||
text: '高/低电压穿越'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: function (params) {
|
||||
if (params.seriesType == 'bar3D') {
|
||||
return [params.seriesName, params.name + ':' + params.value[2] + (params.value[3] || '')].join(
|
||||
'<br />'
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
legend: {
|
||||
selectedMode: false
|
||||
},
|
||||
geo3D: {
|
||||
show: true,
|
||||
// name: '浙江',
|
||||
itemStyle: {
|
||||
color: getComputedStyle(document.documentElement).getPropertyValue('--el-color-primary-light-3'),
|
||||
borderWidth: 1,
|
||||
borderColor: '#fff'
|
||||
},
|
||||
emphasis: {
|
||||
label: { show: true, fontSize: 16 },
|
||||
itemStyle: {
|
||||
color: getComputedStyle(document.documentElement).getPropertyValue('--el-color-primary-light-7')
|
||||
}
|
||||
},
|
||||
viewControl: {
|
||||
alpha: 60,
|
||||
distance: 120,
|
||||
panMouseButton: 'right', //平移操作使用的鼠标按键
|
||||
rotateMouseButton: 'left' //旋转操作使用的鼠标按键
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
color: '#000',
|
||||
fontSize: 14,
|
||||
distance: 0,
|
||||
textStyle: {
|
||||
color: '#000',
|
||||
backgroundColor: '#000'
|
||||
}
|
||||
},
|
||||
|
||||
data: [
|
||||
{ name: '低压', field: 'lowPressure', unit: '次' },
|
||||
{ name: '高压', field: 'highPressure', unit: '次' }
|
||||
]
|
||||
},
|
||||
options: {
|
||||
series: [
|
||||
{
|
||||
name: '低压',
|
||||
type: 'bar3D',
|
||||
coordinateSystem: 'geo3D',
|
||||
shading: 'lambert',
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: params => {
|
||||
return params.value[2]
|
||||
}
|
||||
},
|
||||
|
||||
data:
|
||||
res.length == 0
|
||||
? []
|
||||
: res.map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
value: [item.lng, item.lat, item.lowPressure || 0]
|
||||
}
|
||||
}),
|
||||
// data:[],
|
||||
barSize: 1,
|
||||
minHeight: 1,
|
||||
itemStyle: {
|
||||
color: '#77DA63'
|
||||
},
|
||||
emphasis: {
|
||||
label: { show: true }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '高压',
|
||||
type: 'bar3D',
|
||||
coordinateSystem: 'geo3D',
|
||||
shading: 'lambert',
|
||||
label: {
|
||||
show: true,
|
||||
// position: 'top',
|
||||
formatter: params => {
|
||||
return params.value[2]
|
||||
}
|
||||
},
|
||||
|
||||
data:
|
||||
res.length == 0
|
||||
? []
|
||||
: res.map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
value: [item.lng - 0.1, item.lat, item.highPressure || 0]
|
||||
}
|
||||
}),
|
||||
// [
|
||||
|
||||
// {
|
||||
// adcode: 330400,
|
||||
// name: '大连',
|
||||
|
||||
// wcs: 10,
|
||||
// mbs: 40,
|
||||
// wcl: 100,
|
||||
// value: [121.67391, 38.947468, 40, '']
|
||||
// }
|
||||
// ],
|
||||
barSize: 1,
|
||||
minHeight: 1,
|
||||
itemStyle: {
|
||||
color: '#FFBF00'
|
||||
},
|
||||
emphasis: {
|
||||
label: { show: true }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 点击地图
|
||||
const clickMap = (e: any) => {
|
||||
tabulation(e)
|
||||
}
|
||||
// 表格数据处理
|
||||
const tabulation = (e: any) => {
|
||||
console.log()
|
||||
|
||||
loading.value = true
|
||||
voltageRideThroughEventQueryPage({
|
||||
...tableStore.table.params,
|
||||
areaId: e.data.id,
|
||||
frequencyType:
|
||||
e.seriesName == '高压'
|
||||
? triggerType.filter(item => item.code == 'Voltage_Rise')[0].id
|
||||
: triggerType.filter(item => item.code == 'Voltage_Dip')[0].id
|
||||
})
|
||||
.then(res => {
|
||||
distributionData.value = res.data
|
||||
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
if (res.data[i].wavePath != null) {
|
||||
boxi(res.data[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// res.data.forEach((item: any) => {
|
||||
// if (item.wavePath != null) {
|
||||
// boxi(item)
|
||||
// return
|
||||
// }
|
||||
// })
|
||||
// 。wavePath
|
||||
loading.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const formFilter = (row: any) => {
|
||||
if (row.column.property == 'advanceReason') {
|
||||
let title = ''
|
||||
reason.forEach(item => {
|
||||
if (item.id == row.row.advanceReason) {
|
||||
title = item.name
|
||||
} else if (row.row.advanceReason == null || row.row.advanceReason == '') {
|
||||
title = '/'
|
||||
}
|
||||
})
|
||||
return title
|
||||
} else {
|
||||
return row.row[row.column.property]
|
||||
}
|
||||
}
|
||||
// 查看波形数据
|
||||
const boxi = async (row: any) => {
|
||||
loading1.value = true
|
||||
wp.value = null
|
||||
await getTransientDetailById({
|
||||
eventId: row.eventId,
|
||||
sysType: 0,
|
||||
smallType: 0
|
||||
}).then(res => {
|
||||
boxoList.value = res.data
|
||||
})
|
||||
|
||||
await getMonitorEventAnalyseWave({
|
||||
id: row.eventId,
|
||||
systemType: 0,
|
||||
type: 0
|
||||
}).then(res => {
|
||||
if (res != undefined) {
|
||||
wp.value = res.data
|
||||
}
|
||||
loading1.value = false
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
const layout = mainHeight(83) as any
|
||||
const layout1 = mainHeight(93) as any
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.map {
|
||||
height: calc(v-bind('layout1.height') - 30px);
|
||||
}
|
||||
.tall {
|
||||
height: calc((v-bind('layout1.height') - 100px) / 2);
|
||||
}
|
||||
.tall1 {
|
||||
height: calc((v-bind('layout1.height') - 100px) / 2 - 50px);
|
||||
}
|
||||
|
||||
.group {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 20px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
:deep(.el-card__body) {
|
||||
padding: 10px;
|
||||
}
|
||||
/* 自定义 el-empty 的样式 */
|
||||
:deep(.custom-empty) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%; /* 调整高度 */
|
||||
padding: 20px; /* 调整内边距 */
|
||||
.el-empty__image {
|
||||
display: none; /* 隐藏默认图片 */
|
||||
}
|
||||
.el-empty__description {
|
||||
font-size: 14px; /* 调整字体大小 */
|
||||
color: var(--vxe-font-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<TableHeader datePicker theCurrentTime area ref="header">
|
||||
<!-- <template v-slot:select>
|
||||
|
||||
</template> -->
|
||||
</TableHeader>
|
||||
<div v-loading="tableStore.table.loading">
|
||||
<el-row :gutter="10" class="pd10">
|
||||
<el-col :span="11" style="position: relative">
|
||||
<el-card>
|
||||
<el-radio-group
|
||||
v-model="tableStore.table.params.type"
|
||||
class="group"
|
||||
@change="tableStore.index()"
|
||||
>
|
||||
<el-radio-button label="风电场" value="1" />
|
||||
<el-radio-button label="光伏电站" value="2" />
|
||||
</el-radio-group>
|
||||
<MyEchartMap
|
||||
ref="EchartMap"
|
||||
:options="echartMapList"
|
||||
class="map"
|
||||
@eliminate="eliminate"
|
||||
@getRegionByRegion="getRegionByRegion"
|
||||
@clickMap="clickMap"
|
||||
/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="13">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>暂降列表</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- <h3 class="mb10">暂降列表</h3> -->
|
||||
<div class="tall1">
|
||||
<vxe-table
|
||||
height="auto"
|
||||
auto-resize
|
||||
:data="distributionData"
|
||||
v-loading="loading"
|
||||
v-bind="defaultAttribute"
|
||||
>
|
||||
<vxe-column
|
||||
field="newStationName"
|
||||
title="新能源站名称"
|
||||
min-width="150px"
|
||||
show-overflow-tooltip
|
||||
></vxe-column>
|
||||
<vxe-column field="startTime" title="暂降发生时刻" min-width="180px" sortable></vxe-column>
|
||||
<vxe-column
|
||||
field="featureAmplitude"
|
||||
title="暂降(骤升)幅值(%)"
|
||||
sortable
|
||||
min-width="160px"
|
||||
></vxe-column>
|
||||
<vxe-column
|
||||
field="advanceReason"
|
||||
title="暂降原因"
|
||||
sortable
|
||||
:formatter="formFilter"
|
||||
min-width="100px"
|
||||
></vxe-column>
|
||||
<vxe-column field="severity" title="严重度" min-width="100px" sortable></vxe-column>
|
||||
<vxe-column title="操作" width="80px">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="row.wavePath != null"
|
||||
size="small"
|
||||
link
|
||||
@click="boxi(row)"
|
||||
>
|
||||
查看波形
|
||||
</el-button>
|
||||
<el-button v-else disabled size="small" link>暂无波形</el-button>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="mt10">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>暂降波形</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="tall" v-loading="loading1">
|
||||
<!-- <h3 class="mb10">暂降波形</h3> -->
|
||||
<div v-if="wp != null">
|
||||
<rmsboxi :value="1" :height="height" :boxoList="boxoList" :wp="wp" />
|
||||
</div>
|
||||
<el-empty v-else description="暂无数据" class="custom-empty" />
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import MyEchartMap from '@/components/echarts/MyEchartMap.vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import { voltageRideThroughEventQueryPage } from '@/api/event-boot/highAndLowPressure'
|
||||
import { getMonitorEventAnalyseWave, getTransientDetailById } from '@/api/event-boot/transient'
|
||||
import rmsboxi from '@/components/echarts/rmsboxi.vue'
|
||||
import { ref, onMounted, provide } from 'vue'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { FormItem } from 'vxe-table'
|
||||
defineOptions({
|
||||
name: 'newEnergy/highAndLowPressure'
|
||||
})
|
||||
const EchartMap = ref()
|
||||
const dictData = useDictData()
|
||||
const reason = dictData.getBasicData('Event_Reason')
|
||||
const triggerType = dictData.getBasicData('Event_Statis')
|
||||
const echartMapList: any = ref({})
|
||||
const header = ref()
|
||||
const distributionData: any = ref([])
|
||||
const loading = ref(false)
|
||||
const loading1 = ref(false)
|
||||
const boxoList = ref(null)
|
||||
const wp = ref(null)
|
||||
const tableStore = new TableStore({
|
||||
url: '/event-boot/voltageRideThrough/view',
|
||||
method: 'POST',
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.areaId = tableStore.table.params.deptIndex
|
||||
},
|
||||
loadCallback: () => {
|
||||
// 处理地图数据
|
||||
map(tableStore.table.data)
|
||||
// tabulation(tableStore.table.data)
|
||||
EchartMap.value.GetEchar(header.value.areaRef.areaName)
|
||||
if (tableStore.table.data.length > 0) {
|
||||
tabulation({ data: tableStore.table.data[0], seriesName: '高压' })
|
||||
}
|
||||
}
|
||||
})
|
||||
const height = mainHeight(200, 2).height
|
||||
provide('tableStore', tableStore)
|
||||
tableStore.table.params.type = '1'
|
||||
|
||||
// 地图点击事件
|
||||
const getRegionByRegion = (list: any) => {
|
||||
tableStore.table.params.deptIndex = list.id
|
||||
tableStore.onTableAction('search', {})
|
||||
}
|
||||
// 消除点
|
||||
const eliminate = (name: string) => {
|
||||
echartMapList.value.options.series = []
|
||||
EchartMap.value.GetEchar(name)
|
||||
}
|
||||
|
||||
// 地图数处理
|
||||
const map = (res: any) => {
|
||||
echartMapList.value = {
|
||||
title: {
|
||||
text: '高/低电压穿越'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: function (params) {
|
||||
if (params.seriesType == 'bar3D') {
|
||||
return [params.seriesName, params.name + ':' + params.value[2] + (params.value[3] || '')].join(
|
||||
'<br />'
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
legend: {
|
||||
selectedMode: false
|
||||
},
|
||||
geo3D: {
|
||||
show: true,
|
||||
// name: '浙江',
|
||||
itemStyle: {
|
||||
color: getComputedStyle(document.documentElement).getPropertyValue('--el-color-primary-light-3'),
|
||||
borderWidth: 1,
|
||||
borderColor: '#fff'
|
||||
},
|
||||
emphasis: {
|
||||
label: { show: true, fontSize: 16 },
|
||||
itemStyle: {
|
||||
color: getComputedStyle(document.documentElement).getPropertyValue('--el-color-primary-light-7')
|
||||
}
|
||||
},
|
||||
viewControl: {
|
||||
alpha: 60,
|
||||
distance: 120,
|
||||
panMouseButton: 'right', //平移操作使用的鼠标按键
|
||||
rotateMouseButton: 'left' //旋转操作使用的鼠标按键
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
color: '#000',
|
||||
fontSize: 14,
|
||||
distance: 0,
|
||||
textStyle: {
|
||||
color: '#000',
|
||||
backgroundColor: '#000'
|
||||
}
|
||||
},
|
||||
|
||||
data: [
|
||||
{ name: '低压', field: 'lowPressure', unit: '次' },
|
||||
{ name: '高压', field: 'highPressure', unit: '次' }
|
||||
]
|
||||
},
|
||||
options: {
|
||||
series: [
|
||||
{
|
||||
name: '低压',
|
||||
type: 'bar3D',
|
||||
coordinateSystem: 'geo3D',
|
||||
shading: 'lambert',
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
formatter: params => {
|
||||
return params.value[2]
|
||||
}
|
||||
},
|
||||
|
||||
data:
|
||||
res.length == 0
|
||||
? []
|
||||
: res.map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
value: [item.lng, item.lat, item.lowPressure || 0]
|
||||
}
|
||||
}),
|
||||
// data:[],
|
||||
barSize: 1,
|
||||
minHeight: 1,
|
||||
itemStyle: {
|
||||
color: '#77DA63'
|
||||
},
|
||||
emphasis: {
|
||||
label: { show: true }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '高压',
|
||||
type: 'bar3D',
|
||||
coordinateSystem: 'geo3D',
|
||||
shading: 'lambert',
|
||||
label: {
|
||||
show: true,
|
||||
// position: 'top',
|
||||
formatter: params => {
|
||||
return params.value[2]
|
||||
}
|
||||
},
|
||||
|
||||
data:
|
||||
res.length == 0
|
||||
? []
|
||||
: res.map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
value: [item.lng - 0.1, item.lat, item.highPressure || 0]
|
||||
}
|
||||
}),
|
||||
// [
|
||||
|
||||
// {
|
||||
// adcode: 330400,
|
||||
// name: '大连',
|
||||
|
||||
// wcs: 10,
|
||||
// mbs: 40,
|
||||
// wcl: 100,
|
||||
// value: [121.67391, 38.947468, 40, '']
|
||||
// }
|
||||
// ],
|
||||
barSize: 1,
|
||||
minHeight: 1,
|
||||
itemStyle: {
|
||||
color: '#FFBF00'
|
||||
},
|
||||
emphasis: {
|
||||
label: { show: true }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 点击地图
|
||||
const clickMap = (e: any) => {
|
||||
tabulation(e)
|
||||
}
|
||||
// 表格数据处理
|
||||
const tabulation = (e: any) => {
|
||||
console.log()
|
||||
|
||||
loading.value = true
|
||||
voltageRideThroughEventQueryPage({
|
||||
...tableStore.table.params,
|
||||
areaId: e.data.id,
|
||||
frequencyType:
|
||||
e.seriesName == '高压'
|
||||
? triggerType.filter(item => item.code == 'Voltage_Rise')[0].id
|
||||
: triggerType.filter(item => item.code == 'Voltage_Dip')[0].id
|
||||
})
|
||||
.then(res => {
|
||||
distributionData.value = res.data
|
||||
|
||||
for (let i = 0; i < res.data.length; i++) {
|
||||
if (res.data[i].wavePath != null) {
|
||||
boxi(res.data[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// res.data.forEach((item: any) => {
|
||||
// if (item.wavePath != null) {
|
||||
// boxi(item)
|
||||
// return
|
||||
// }
|
||||
// })
|
||||
// 。wavePath
|
||||
loading.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const formFilter = (row: any) => {
|
||||
if (row.column.property == 'advanceReason') {
|
||||
let title = ''
|
||||
reason.forEach(item => {
|
||||
if (item.id == row.row.advanceReason) {
|
||||
title = item.name
|
||||
} else if (row.row.advanceReason == null || row.row.advanceReason == '') {
|
||||
title = '/'
|
||||
}
|
||||
})
|
||||
return title
|
||||
} else {
|
||||
return row.row[row.column.property]
|
||||
}
|
||||
}
|
||||
// 查看波形数据
|
||||
const boxi = async (row: any) => {
|
||||
loading1.value = true
|
||||
wp.value = null
|
||||
await getTransientDetailById({
|
||||
eventId: row.eventId,
|
||||
sysType: 0,
|
||||
smallType: 0
|
||||
}).then(res => {
|
||||
boxoList.value = res.data
|
||||
})
|
||||
|
||||
await getMonitorEventAnalyseWave({
|
||||
id: row.eventId,
|
||||
systemType: 0,
|
||||
type: 0
|
||||
}).then(res => {
|
||||
if (res != undefined) {
|
||||
wp.value = res.data
|
||||
}
|
||||
loading1.value = false
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
const layout = mainHeight(83) as any
|
||||
const layout1 = mainHeight(93) as any
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.map {
|
||||
height: calc(v-bind('layout1.height') - 30px);
|
||||
}
|
||||
.tall {
|
||||
height: calc((v-bind('layout1.height') - 100px) / 2);
|
||||
}
|
||||
.tall1 {
|
||||
height: calc((v-bind('layout1.height') - 100px) / 2 - 50px);
|
||||
}
|
||||
|
||||
.group {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 20px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
:deep(.el-card__body) {
|
||||
padding: 10px;
|
||||
}
|
||||
/* 自定义 el-empty 的样式 */
|
||||
:deep(.custom-empty) {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%; /* 调整高度 */
|
||||
padding: 20px; /* 调整内边距 */
|
||||
.el-empty__image {
|
||||
display: none; /* 隐藏默认图片 */
|
||||
}
|
||||
.el-empty__description {
|
||||
font-size: 14px; /* 调整字体大小 */
|
||||
color: var(--vxe-font-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,119 +1,119 @@
|
||||
<template>
|
||||
<div class="dictiontary-list-detail child-router">
|
||||
<TableHeader :showSearch="false">
|
||||
<template #select>
|
||||
<el-form-item label="">
|
||||
<span class="text-large font-600 mr-3">{{ props.timePopUpBox.time }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio-group v-model="radio2" @change="tableStore.index()">
|
||||
<el-radio-button label="基础数据" value="1" />
|
||||
<el-radio-button label="谐波电压" value="2" />
|
||||
<el-radio-button label="谐波电流" value="3" />
|
||||
<el-radio-button label="间谐波电压" value="4" />
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #operation>
|
||||
<el-button icon="el-icon-Back" @click="$emit('close')">返回</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<Table ref="tableRef" isGroup />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { dictDataDelete } from '@/api/system-boot/dicData'
|
||||
|
||||
defineOptions({
|
||||
name: 'setting/dictionary/list/detail'
|
||||
})
|
||||
const radio2 = ref('1')
|
||||
interface Props {
|
||||
timePopUpBox: anyObj
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
timePopUpBox: () => {
|
||||
return {}
|
||||
}
|
||||
})
|
||||
const popupEditRef = ref()
|
||||
const tableStore = new TableStore({
|
||||
url: '/harmonic-boot/powerStatistics/getTargetByTime',
|
||||
method: 'POST',
|
||||
showPage: false,
|
||||
column: [
|
||||
{
|
||||
title: '指标',
|
||||
field: 'anotherName',
|
||||
minWidth: '120px',
|
||||
formatter: row => {
|
||||
row.column.title =
|
||||
radio2.value == '1' ? '指标' : (row.column.title = radio2.value == '4' ? '间谐波次数' : '谐波次数')
|
||||
return row.cellValue
|
||||
}
|
||||
},
|
||||
{ title: '单位', field: 'unit' },
|
||||
{
|
||||
title: '最小值',
|
||||
field: 'min',
|
||||
children: [
|
||||
{
|
||||
title: 'A',
|
||||
field: 'minphaseA',
|
||||
formatter: row => formatter(row)
|
||||
},
|
||||
{ title: 'B', field: 'minphaseB', formatter: row => formatter(row) },
|
||||
{ title: 'C', field: 'minphaseC', formatter: row => formatter(row) }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '最大值',
|
||||
field: 'max',
|
||||
children: [
|
||||
{ title: 'A', field: 'maxphaseA', formatter: row => formatter(row) },
|
||||
{ title: 'B', field: 'maxphaseB', formatter: row => formatter(row) },
|
||||
{ title: 'C', field: 'maxphaseC', formatter: row => formatter(row) }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '平均值',
|
||||
field: 'avg',
|
||||
children: [
|
||||
{ title: 'A', field: 'avgphaseA', formatter: row => formatter(row) },
|
||||
{ title: 'B', field: 'avgphaseB', formatter: row => formatter(row) },
|
||||
{ title: 'C', field: 'avgphaseC', formatter: row => formatter(row) }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'cp95值',
|
||||
field: 'cp95',
|
||||
children: [
|
||||
{ title: 'A', field: 'cp95PhaseA', formatter: row => formatter(row) },
|
||||
{ title: 'B', field: 'cp95PhaseB', formatter: row => formatter(row) },
|
||||
{ title: 'C', field: 'cp95PhaseC', formatter: row => formatter(row) }
|
||||
]
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.field = props.timePopUpBox.field
|
||||
tableStore.table.params.lineId = props.timePopUpBox.lineId
|
||||
tableStore.table.params.searchBeginTime = props.timePopUpBox.time
|
||||
tableStore.table.params.searchEndTime = props.timePopUpBox.time
|
||||
tableStore.table.params.statisticalId = radio2.value
|
||||
},
|
||||
loadCallback: () => {}
|
||||
})
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
const formatter = (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<div class="dictiontary-list-detail child-router">
|
||||
<TableHeader :showSearch="false" showCustomColumn>
|
||||
<template #select>
|
||||
<el-form-item label="">
|
||||
<span class="text-large font-600 mr-3">{{ props.timePopUpBox.time }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-radio-group v-model="radio2" @change="tableStore.index()">
|
||||
<el-radio-button label="基础数据" value="1" />
|
||||
<el-radio-button label="谐波电压" value="2" />
|
||||
<el-radio-button label="谐波电流" value="3" />
|
||||
<el-radio-button label="间谐波电压" value="4" />
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #operation>
|
||||
<el-button icon="el-icon-Back" @click="$emit('close')">返回</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<Table ref="tableRef" isGroup />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { dictDataDelete } from '@/api/system-boot/dicData'
|
||||
|
||||
defineOptions({
|
||||
name: 'setting/dictionary/list/detail'
|
||||
})
|
||||
const radio2 = ref('1')
|
||||
interface Props {
|
||||
timePopUpBox: anyObj
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
timePopUpBox: () => {
|
||||
return {}
|
||||
}
|
||||
})
|
||||
const popupEditRef = ref()
|
||||
const tableStore = new TableStore({
|
||||
url: '/harmonic-boot/powerStatistics/getTargetByTime',
|
||||
method: 'POST',
|
||||
showPage: false,
|
||||
column: [
|
||||
{
|
||||
title: '指标',
|
||||
field: 'anotherName',
|
||||
minWidth: '120px',
|
||||
formatter: row => {
|
||||
row.column.title =
|
||||
radio2.value == '1' ? '指标' : (row.column.title = radio2.value == '4' ? '间谐波次数' : '谐波次数')
|
||||
return row.cellValue
|
||||
}
|
||||
},
|
||||
{ title: '单位', field: 'unit' },
|
||||
{
|
||||
title: '最小值',
|
||||
field: 'min',
|
||||
children: [
|
||||
{
|
||||
title: 'A',
|
||||
field: 'minphaseA',
|
||||
formatter: row => formatter(row)
|
||||
},
|
||||
{ title: 'B', field: 'minphaseB', formatter: row => formatter(row) },
|
||||
{ title: 'C', field: 'minphaseC', formatter: row => formatter(row) }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '最大值',
|
||||
field: 'max',
|
||||
children: [
|
||||
{ title: 'A', field: 'maxphaseA', formatter: row => formatter(row) },
|
||||
{ title: 'B', field: 'maxphaseB', formatter: row => formatter(row) },
|
||||
{ title: 'C', field: 'maxphaseC', formatter: row => formatter(row) }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '平均值',
|
||||
field: 'avg',
|
||||
children: [
|
||||
{ title: 'A', field: 'avgphaseA', formatter: row => formatter(row) },
|
||||
{ title: 'B', field: 'avgphaseB', formatter: row => formatter(row) },
|
||||
{ title: 'C', field: 'avgphaseC', formatter: row => formatter(row) }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'cp95值',
|
||||
field: 'cp95',
|
||||
children: [
|
||||
{ title: 'A', field: 'cp95PhaseA', formatter: row => formatter(row) },
|
||||
{ title: 'B', field: 'cp95PhaseB', formatter: row => formatter(row) },
|
||||
{ title: 'C', field: 'cp95PhaseC', formatter: row => formatter(row) }
|
||||
]
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.field = props.timePopUpBox.field
|
||||
tableStore.table.params.lineId = props.timePopUpBox.lineId
|
||||
tableStore.table.params.searchBeginTime = props.timePopUpBox.time
|
||||
tableStore.table.params.searchEndTime = props.timePopUpBox.time
|
||||
tableStore.table.params.statisticalId = radio2.value
|
||||
},
|
||||
loadCallback: () => {}
|
||||
})
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
const formatter = (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -779,6 +779,7 @@ const analyseList = (e: string) => {
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
onMounted(() => {
|
||||
TableHeaderRef.value.setTheDate(4)
|
||||
const dom = document.getElementById('navigation-splitpanes')
|
||||
if (dom) {
|
||||
size.value = Math.round((180 / dom.offsetHeight) * 120)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<TableHeader ref="TableHeaderRef">
|
||||
<TableHeader ref="TableHeaderRef" showCustomColumn>
|
||||
<template #select>
|
||||
<el-form-item label="新能源场站名称">
|
||||
<el-input v-model="tableStore.table.params.name" clearable placeholder="输入关键字筛选" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<div v-show="flg">
|
||||
<TableHeader datePicker showExport ref="TableHeaderRef">
|
||||
<TableHeader datePicker showExport ref="TableHeaderRef" showCustomColumn>
|
||||
<template v-slot:select>
|
||||
<el-form :inline="true" label-width="90px" class="">
|
||||
<el-form-item label="用户名:">
|
||||
@@ -90,7 +90,6 @@ const loading = ref(false)
|
||||
const statistics = ref()
|
||||
|
||||
const flg = ref(true)
|
||||
const showMqtt = ref(false)
|
||||
const zoom = ref('') //图表焦点校验
|
||||
|
||||
const resultList = ref([
|
||||
|
||||
@@ -183,7 +183,7 @@ import TableHeader from '@/components/table/header/index.vue'
|
||||
import MyEChart from '@/components/echarts/MyEchart.vue'
|
||||
import { useMonitoringPoint } from '@/stores/monitoringPoint'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import { harmonicOptions } from '@/utils/dictionary'
|
||||
import { harmonicOptions1 } from '@/utils/dictionary'
|
||||
import { Select } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import {
|
||||
@@ -202,7 +202,7 @@ import html2canvas from 'html2canvas'
|
||||
import { yMethod } from '@/utils/echartMethod'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
const props = defineProps(['rowList'])
|
||||
const harmonic = harmonicOptions.filter(item => item.value < 26)
|
||||
const harmonic = harmonicOptions1.filter(item => item.value < 26)
|
||||
const currentLod = ref(false)
|
||||
const monitoringPoint = useMonitoringPoint()
|
||||
const size = ref(19)
|
||||
@@ -844,7 +844,7 @@ onMounted(() => {
|
||||
}
|
||||
.btnBox {
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
:deep(.vxe-table--header thead tr:first-of-type th:first-of-type) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<div v-show="addedShow">
|
||||
<TableHeader datePicker showExport ref="TableHeaderRef">
|
||||
<TableHeader datePicker showExport ref="TableHeaderRef" showCustomColumn>
|
||||
<template #select>
|
||||
<el-form-item label="评估类型">
|
||||
<el-select
|
||||
@@ -157,7 +157,7 @@ const tableStore: any = new TableStore({
|
||||
},
|
||||
{
|
||||
name: 'del',
|
||||
text: '禁止接入',
|
||||
text: '删除',
|
||||
type: 'danger',
|
||||
icon: 'el-icon-Delete',
|
||||
render: 'confirmButton',
|
||||
@@ -165,11 +165,11 @@ const tableStore: any = new TableStore({
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
confirmButtonType: 'danger',
|
||||
title: '确定禁止接入?'
|
||||
title: '确定删除?'
|
||||
},
|
||||
click: row => {
|
||||
remove({ ids: row.id }).then(() => {
|
||||
ElMessage.success('禁止接入成功')
|
||||
ElMessage.success('删除成功')
|
||||
tableStore.index()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,163 +1,163 @@
|
||||
<template>
|
||||
<el-dialog draggable class="cn-operate-dialog" v-model="dialogVisible" title="设备">
|
||||
<div class="formBox mb10"><el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button></div>
|
||||
|
||||
<vxe-table v-bind="defaultAttribute" v-loading="loading" height="500px" ref="xTable" :data="userData">
|
||||
<vxe-column field="devName" title="设备名称"></vxe-column>
|
||||
<vxe-column field="devScale" title="电压等级" :formatter="formatter"></vxe-column>
|
||||
<vxe-column field="protocolCapacity" title="设备容量(MVA)"></vxe-column>
|
||||
<vxe-column title="操作" width="120px">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" size="small" link @click="revise(row)">修改</el-button>
|
||||
|
||||
<el-popconfirm @confirm="deleteD(row)" title="确认删除设备?">
|
||||
<template #reference>
|
||||
<el-button type="danger" size="small" link>删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</el-dialog>
|
||||
<el-dialog draggable v-model="addShow" width="400px" :title="title" :before-close="handleClose">
|
||||
<el-form :model="form" ref="formRef" :rules="rules" label-width="auto">
|
||||
<el-form-item label="设备名称" prop="devName">
|
||||
<el-input
|
||||
v-model.trim="form.devName"
|
||||
placeholder="请输入设备名称"
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="电压等级" prop="devScale">
|
||||
<el-select v-model="form.devScale" clearable placeholder="请选择电压等级">
|
||||
<el-option v-for="item in levelList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备容量(MVA)" prop="protocolCapacity">
|
||||
<el-input-number
|
||||
v-model="form.protocolCapacity"
|
||||
style="width: 100%"
|
||||
:min="0"
|
||||
:max="10000000"
|
||||
placeholder="请选择设备容量"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { queyDeviceList, addDev, updateDev, removeDev } from '@/api/advance-boot/bearingCapacity'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { ElMessage } from 'element-plus'
|
||||
const dictData = useDictData()
|
||||
const levelList = dictData.getBasicData('Dev_Voltage_Stand')
|
||||
const dialogVisible = ref(false)
|
||||
const addShow = ref(false)
|
||||
const loading = ref(false)
|
||||
const userData = ref([])
|
||||
const rowList = ref([])
|
||||
const title = ref('')
|
||||
const formRef = ref()
|
||||
|
||||
const form: any = ref({
|
||||
devName: '',
|
||||
devScale: '',
|
||||
protocolCapacity: 0,
|
||||
userId: ''
|
||||
})
|
||||
const rules = {
|
||||
devName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
|
||||
devScale: [{ required: true, message: '请输入设备名称', trigger: 'change' }],
|
||||
protocolCapacity: [{ required: true, message: '请输入设备名称', trigger: 'blur' }]
|
||||
}
|
||||
const open = (row: any) => {
|
||||
dialogVisible.value = true
|
||||
loading.value = true
|
||||
rowList.value = row
|
||||
queyDeviceList({
|
||||
userId: row.userId
|
||||
}).then(res => {
|
||||
loading.value = false
|
||||
userData.value = res.data
|
||||
})
|
||||
}
|
||||
// 新增
|
||||
const add = () => {
|
||||
addShow.value = true
|
||||
title.value = '新增设备'
|
||||
}
|
||||
|
||||
// 过滤数据
|
||||
const formatter = (row: any) => {
|
||||
if (row.column.field == 'devScale') {
|
||||
return levelList.filter(item => item.id == row.cellValue)[0].name
|
||||
} else {
|
||||
return row.cellValue
|
||||
}
|
||||
}
|
||||
// 修改
|
||||
const revise = (row: any) => {
|
||||
form.value = JSON.parse(JSON.stringify(row))
|
||||
title.value = '修改设备'
|
||||
addShow.value = true
|
||||
}
|
||||
// 关闭弹框
|
||||
const handleClose = () => {
|
||||
addShow.value = false
|
||||
form.value = {
|
||||
devName: '',
|
||||
devScale: '',
|
||||
protocolCapacity: 0,
|
||||
userId: ''
|
||||
}
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
// 新增设备
|
||||
const submitForm = async () => {
|
||||
await formRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
if (title.value == '新增设备') {
|
||||
form.value.userId = rowList.value.userId
|
||||
addDev(form.value).then(res => {
|
||||
ElMessage.success('新增成功!')
|
||||
open(rowList.value)
|
||||
handleClose()
|
||||
})
|
||||
} else {
|
||||
updateDev(form.value).then(res => {
|
||||
ElMessage.success('修改成功!')
|
||||
open(rowList.value)
|
||||
handleClose()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 删除设备
|
||||
const deleteD = row => {
|
||||
removeDev({ devIds: row.devId }).then(res => {
|
||||
ElMessage.success('删除设备成功!')
|
||||
open(rowList.value)
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.formBox{
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
</style>
|
||||
<template>
|
||||
<el-dialog draggable class="cn-operate-dialog" v-model="dialogVisible" title="设备">
|
||||
<div class="formBox mb10"><el-button icon="el-icon-Plus" type="primary" @click="add">新增</el-button></div>
|
||||
|
||||
<vxe-table v-bind="defaultAttribute" v-loading="loading" height="500px" ref="xTable" :data="userData">
|
||||
<vxe-column field="devName" title="设备名称"></vxe-column>
|
||||
<vxe-column field="devScale" title="电压等级" :formatter="formatter"></vxe-column>
|
||||
<vxe-column field="protocolCapacity" title="设备容量(MVA)"></vxe-column>
|
||||
<vxe-column title="操作" width="120px">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" size="small" link @click="revise(row)">修改</el-button>
|
||||
|
||||
<el-popconfirm @confirm="deleteD(row)" title="确认删除设备?">
|
||||
<template #reference>
|
||||
<el-button type="danger" size="small" link>删除</el-button>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</el-dialog>
|
||||
<el-dialog draggable v-model="addShow" width="400px" :title="title" :before-close="handleClose">
|
||||
<el-form :model="form" ref="formRef" :rules="rules" label-width="auto">
|
||||
<el-form-item label="设备名称" prop="devName">
|
||||
<el-input
|
||||
v-model.trim="form.devName"
|
||||
placeholder="请输入设备名称"
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="电压等级" prop="devScale">
|
||||
<el-select v-model="form.devScale" clearable placeholder="请选择电压等级">
|
||||
<el-option v-for="item in levelList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备容量(MVA)" prop="protocolCapacity">
|
||||
<el-input-number
|
||||
v-model="form.protocolCapacity"
|
||||
style="width: 100%"
|
||||
:min="0"
|
||||
:max="10000000"
|
||||
placeholder="请选择设备容量"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
<el-button type="primary" @click="submitForm">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { queyDeviceList, addDev, updateDev, removeDev } from '@/api/advance-boot/bearingCapacity'
|
||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { ElMessage } from 'element-plus'
|
||||
const dictData = useDictData()
|
||||
const levelList = dictData.getBasicData('Dev_Voltage_Stand')
|
||||
const dialogVisible = ref(false)
|
||||
const addShow = ref(false)
|
||||
const loading = ref(false)
|
||||
const userData = ref([])
|
||||
const rowList = ref([])
|
||||
const title = ref('')
|
||||
const formRef = ref()
|
||||
|
||||
const form: any = ref({
|
||||
devName: '',
|
||||
devScale: '',
|
||||
protocolCapacity: 0,
|
||||
userId: ''
|
||||
})
|
||||
const rules = {
|
||||
devName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
|
||||
devScale: [{ required: true, message: '请输入设备名称', trigger: 'change' }],
|
||||
protocolCapacity: [{ required: true, message: '请输入设备名称', trigger: 'blur' }]
|
||||
}
|
||||
const open = (row: any) => {
|
||||
dialogVisible.value = true
|
||||
loading.value = true
|
||||
rowList.value = row
|
||||
queyDeviceList({
|
||||
userId: row.userId
|
||||
}).then(res => {
|
||||
loading.value = false
|
||||
userData.value = res.data
|
||||
})
|
||||
}
|
||||
// 新增
|
||||
const add = () => {
|
||||
addShow.value = true
|
||||
title.value = '新增设备'
|
||||
}
|
||||
|
||||
// 过滤数据
|
||||
const formatter = (row: any) => {
|
||||
if (row.column.field == 'devScale') {
|
||||
return levelList.filter(item => item.id == row.cellValue)[0].name
|
||||
} else {
|
||||
return row.cellValue
|
||||
}
|
||||
}
|
||||
// 修改
|
||||
const revise = (row: any) => {
|
||||
form.value = JSON.parse(JSON.stringify(row))
|
||||
title.value = '修改设备'
|
||||
addShow.value = true
|
||||
}
|
||||
// 关闭弹框
|
||||
const handleClose = () => {
|
||||
addShow.value = false
|
||||
form.value = {
|
||||
devName: '',
|
||||
devScale: '',
|
||||
protocolCapacity: 0,
|
||||
userId: ''
|
||||
}
|
||||
formRef.value.resetFields()
|
||||
}
|
||||
// 新增设备
|
||||
const submitForm = async () => {
|
||||
await formRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
if (title.value == '新增设备') {
|
||||
form.value.userId = rowList.value.userId
|
||||
addDev(form.value).then(res => {
|
||||
ElMessage.success('新增成功!')
|
||||
open(rowList.value)
|
||||
handleClose()
|
||||
})
|
||||
} else {
|
||||
updateDev(form.value).then(res => {
|
||||
ElMessage.success('修改成功!')
|
||||
open(rowList.value)
|
||||
handleClose()
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 删除设备
|
||||
const deleteD = row => {
|
||||
removeDev({ devIds: row.devId }).then(res => {
|
||||
ElMessage.success('删除设备成功!')
|
||||
open(rowList.value)
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.formBox{
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<div>
|
||||
<TableHeader :showTimeAll="false" showExport ref="TableHeaderRef">
|
||||
<TableHeader :showTimeAll="false" showExport ref="TableHeaderRef" showCustomColumn>
|
||||
<template #select>
|
||||
<el-form-item label="用户类型">
|
||||
<el-select
|
||||
@@ -57,9 +57,15 @@
|
||||
|
||||
<el-form-item label="区域" prop="regionList">
|
||||
<!-- <el-cascader v-model="form.regionList" style="width: 100%" :props="props" :options="areaList" /> -->
|
||||
<el-cascader v-model="form.regionList" :props="props" :options="areaList" style="width: 100%" placeholder="请选择区域" />
|
||||
<el-cascader
|
||||
v-model="form.regionList"
|
||||
:props="props"
|
||||
:options="areaList"
|
||||
style="width: 100%"
|
||||
placeholder="请选择区域"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="详细地址:" prop="area">
|
||||
<el-input
|
||||
clearable
|
||||
@@ -95,7 +101,7 @@ import { mainHeight } from '@/utils/layout'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import equipment from './equipment.vue'
|
||||
import { addUse, updateUse, removeUse } from '@/api/advance-boot/bearingCapacity'
|
||||
import { getAreaDept } from '@/api/harmonic-boot/area'
|
||||
import { getAreaDept, getAreaDeptRemoveMode } from '@/api/harmonic-boot/area'
|
||||
|
||||
defineOptions({
|
||||
name: 'estimate/photovoltaic'
|
||||
@@ -108,8 +114,9 @@ const disabled = ref(false)
|
||||
const TableHeaderRef = ref()
|
||||
const equipmentRef = ref()
|
||||
const title = ref('')
|
||||
const VITE_FLAG = import.meta.env.VITE_NAME == 'removeMode'
|
||||
//const areaList: any = dictData.areaSelect()
|
||||
const areaList = ref([])
|
||||
const areaList: any = ref([])
|
||||
const userShow: any = ref('Power_Station_Users')
|
||||
|
||||
const form = ref({
|
||||
@@ -187,7 +194,8 @@ const tableStore: any = new TableStore({
|
||||
{ field: 'createBy', title: '创建者' },
|
||||
{ field: 'createTime', title: '创建日期' },
|
||||
{
|
||||
title: '操作',fixed: 'right',
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
width: '180',
|
||||
render: 'buttons',
|
||||
buttons: [
|
||||
@@ -258,9 +266,7 @@ const tableStore: any = new TableStore({
|
||||
}
|
||||
],
|
||||
|
||||
loadCallback: () => {
|
||||
|
||||
}
|
||||
loadCallback: () => {}
|
||||
})
|
||||
|
||||
tableStore.table.params.userType = ''
|
||||
@@ -268,8 +274,6 @@ tableStore.table.params.userType = ''
|
||||
provide('tableStore', tableStore)
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
|
||||
|
||||
})
|
||||
const useChange = (e: string) => {
|
||||
userShow.value = uesrList.filter(item => item.id == e)[0].code
|
||||
@@ -278,10 +282,14 @@ const useChange = (e: string) => {
|
||||
const add = async () => {
|
||||
disabled.value = false
|
||||
title.value = '新增承载能力待评估用户'
|
||||
if (VITE_FLAG) {
|
||||
areaList.value = dictData.state.areaTree
|
||||
} else {
|
||||
await getAreaDept().then(res => {
|
||||
areaList.value = JSON.parse(JSON.stringify(res.data))
|
||||
})
|
||||
}
|
||||
|
||||
await getAreaDept().then(res => {
|
||||
areaList.value = JSON.parse(JSON.stringify(res.data))
|
||||
})
|
||||
dialogVisible.value = true
|
||||
}
|
||||
// 保存
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<!-- 新增 -->
|
||||
<el-dialog draggable title="详情" v-model="dialogVisible" width="1200px">
|
||||
<TableHeader datePicker showExport :showReset="false">
|
||||
<TableHeader datePicker showExport :showReset="false" >
|
||||
<template v-slot:select>
|
||||
<el-form-item label="筛选数据">
|
||||
<el-input v-model="tableStore.table.params.searchValue" placeholder="请输入筛选数据" clearable maxlength="32" show-word-limit/>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<TableHeader datePicker showExport>
|
||||
<TableHeader datePicker showExport showCustomColumn>
|
||||
<template v-slot:select>
|
||||
<el-form-item label="筛选数据">
|
||||
<el-input v-model="tableStore.table.params.searchValue" placeholder="请输入筛选数据" clearable maxlength="32" show-word-limit/>
|
||||
|
||||
@@ -40,7 +40,14 @@
|
||||
></Table>
|
||||
</div>
|
||||
<div class="pd10" style="width: 400px" v-loading="loading">
|
||||
<el-input v-model="filterText" placeholder="请输入内容" clearable maxlength="32" show-word-limit @input="change">
|
||||
<el-input
|
||||
v-model="filterText"
|
||||
placeholder="请输入内容"
|
||||
clearable
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
@input="change"
|
||||
>
|
||||
<template #prefix>
|
||||
<Icon name="el-icon-Search" style="font-size: 16px" />
|
||||
</template>
|
||||
@@ -139,7 +146,7 @@
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="最大终端数:" prop="nodeDevNum" class="top" >
|
||||
<el-form-item label="最大终端数:" prop="nodeDevNum" class="top">
|
||||
<el-input
|
||||
v-model.trim.number="formData.nodeDevNum"
|
||||
onkeyup="value = value.replace(/[^0-9]/g,'')"
|
||||
@@ -273,7 +280,7 @@ const tableStore = new TableStore({
|
||||
method: 'POST',
|
||||
column: [
|
||||
{ title: '名称', field: 'name' },
|
||||
{ title: 'IP', field: 'ip' ,width:'120px' },
|
||||
{ title: 'IP', field: 'ip', width: '120px' },
|
||||
{
|
||||
title: '等级',
|
||||
field: 'nodeGrade',
|
||||
@@ -317,7 +324,8 @@ const tableStore = new TableStore({
|
||||
{ title: '描述', field: 'remark' },
|
||||
|
||||
{
|
||||
title: '操作',fixed: 'right',
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
width: '180',
|
||||
render: 'buttons',
|
||||
@@ -376,8 +384,8 @@ const tableStore = new TableStore({
|
||||
},
|
||||
click: row => {
|
||||
if (hasDevices.value) {
|
||||
ElMessage.warning('此前置机绑定了设备,无法删除!');
|
||||
return;
|
||||
ElMessage.warning('此前置机绑定了设备,无法删除!')
|
||||
return
|
||||
}
|
||||
|
||||
delNode(row.id).then(res => {
|
||||
@@ -386,7 +394,7 @@ const tableStore = new TableStore({
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
name: 'edit',
|
||||
title: '分配终端',
|
||||
type: 'primary',
|
||||
@@ -399,10 +407,10 @@ const tableStore = new TableStore({
|
||||
title: '确定分配终端吗?'
|
||||
},
|
||||
click: row => {
|
||||
if (!hasDevices.value) {
|
||||
ElMessage.warning('此前置机下无设备,无法分配终端!');
|
||||
return;
|
||||
}
|
||||
// if (!hasDevices.value) {
|
||||
// ElMessage.warning('此前置机下无设备,无法分配终端!')
|
||||
// return
|
||||
// }
|
||||
allotTerminal({
|
||||
nodeId: row.id
|
||||
}).then(res => {
|
||||
@@ -410,7 +418,7 @@ const tableStore = new TableStore({
|
||||
tableStore.index()
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -448,26 +456,25 @@ const currentChangeEvent = () => {
|
||||
// 检查返回的数据是否存在且不为空
|
||||
if (res.data && res.data.processDeviceList) {
|
||||
// 检查是否有设备绑定
|
||||
const hasAnyDevices = res.data.processDeviceList.some(item =>
|
||||
item.deviceInfoList && item.deviceInfoList.length > 0
|
||||
);
|
||||
hasDevices.value = hasAnyDevices;
|
||||
|
||||
const hasAnyDevices = res.data.processDeviceList.some(
|
||||
item => item.deviceInfoList && item.deviceInfoList.length > 0
|
||||
)
|
||||
hasDevices.value = hasAnyDevices
|
||||
|
||||
dataSource.value = res.data.processDeviceList.filter(item => {
|
||||
item.name = item.processNo + '';
|
||||
return true; // 保持原有的过滤逻辑
|
||||
});
|
||||
item.name = item.processNo + '号进程'
|
||||
return true // 保持原有的过滤逻辑
|
||||
})
|
||||
} else {
|
||||
dataSource.value = []
|
||||
hasDevices.value = false;
|
||||
hasDevices.value = false
|
||||
}
|
||||
loading.value = false
|
||||
|
||||
})
|
||||
.catch(() => {
|
||||
// 添加错误处理,确保 loading 状态也能关闭
|
||||
dataSource.value = []
|
||||
hasDevices.value = false;
|
||||
hasDevices.value = false
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
@@ -476,7 +483,7 @@ const currentChangeEvent = () => {
|
||||
|
||||
// 重启进程
|
||||
const restart = (data: any) => {
|
||||
// console.log('🚀 ~ restart ~ data:', data)
|
||||
// console.log('🚀 ~ restart ~ data:', data)
|
||||
askRestartProcess({
|
||||
deviceRebootType: null,
|
||||
nodeId: nodeId.value,
|
||||
@@ -518,7 +525,7 @@ const filterNode = (value: string, data: any, node: any) => {
|
||||
|
||||
// 过滤父节点 / 子节点 (如果输入的参数是父节点且能匹配,则返回该节点以及其下的所有子节点;如果参数是子节点,则返回该节点的父节点。name是中文字符,enName是英文字符.
|
||||
const chooseNode = (value: string, data: any, node: any) => {
|
||||
if (data.name.indexOf(value) !== -1) {
|
||||
if ((data.subName + data.name).indexOf(value) !== -1) {
|
||||
return true
|
||||
}
|
||||
const level = node.level
|
||||
@@ -629,7 +636,7 @@ const addMenu = () => {}
|
||||
:deep(.default) {
|
||||
display: flex;
|
||||
.row--current {
|
||||
// background-color: var(--el-color-primary-light-8) !important;
|
||||
// background-color: var(--el-color-primary-light-8) !important;
|
||||
}
|
||||
}
|
||||
.custom-tree-node {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<TableHeader>
|
||||
<template #select>
|
||||
<el-form-item label="终端型号">
|
||||
<el-select v-model="tableStore.table.params.teriminal" clearable placeholder="请选择终端型号">
|
||||
<el-select v-model="tableStore.table.params.devType" clearable placeholder="请选择终端型号">
|
||||
<el-option
|
||||
v-for="item in teriminaloption"
|
||||
:key="item.id"
|
||||
@@ -13,7 +13,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="终端状态">
|
||||
<el-select v-model="tableStore.table.params.teriminalstatus" clearable placeholder="请选择终端状态">
|
||||
<el-select v-model="tableStore.table.params.runFlag" clearable placeholder="请选择终端状态">
|
||||
<el-option
|
||||
v-for="item in teriminalstatusoption"
|
||||
:key="item.id"
|
||||
@@ -23,7 +23,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="通讯状态">
|
||||
<el-select v-model="tableStore.table.params.state" clearable placeholder="请选择通讯状态">
|
||||
<el-select v-model="tableStore.table.params.comFlag" clearable placeholder="请选择通讯状态">
|
||||
<el-option
|
||||
v-for="item in stateoption"
|
||||
:key="item.id"
|
||||
@@ -42,7 +42,7 @@
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="筛选数据">
|
||||
<!-- <el-form-item label="筛选数据">
|
||||
<el-input
|
||||
v-model="tableStore.table.params.filterName"
|
||||
@keyup="searchEvent"
|
||||
@@ -50,7 +50,7 @@
|
||||
show-word-limit
|
||||
placeholder="输入关键字筛选"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
</template>
|
||||
<!-- <template #operation>
|
||||
<el-button icon="el-icon-Download" @click="add">导出</el-button>
|
||||
@@ -252,9 +252,9 @@ const tableStore = new TableStore({
|
||||
}, 0)
|
||||
}
|
||||
})
|
||||
tableStore.table.params.teriminal = ''
|
||||
tableStore.table.params.teriminalstatus = ''
|
||||
tableStore.table.params.state = ''
|
||||
tableStore.table.params.devType = ''
|
||||
tableStore.table.params.runFlag = ''
|
||||
tableStore.table.params.comFlag = ''
|
||||
tableStore.table.params.program = ''
|
||||
tableStore.table.params.searchEvent = ''
|
||||
tableStore.table.params.filterName = ''
|
||||
|
||||
@@ -1107,7 +1107,7 @@
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
class="form-item"
|
||||
label="测量点性质:"
|
||||
label="电网标志:"
|
||||
:prop="
|
||||
'deviceParam.' +
|
||||
[deviceIndex] +
|
||||
@@ -1119,14 +1119,14 @@
|
||||
"
|
||||
:rules="{
|
||||
required: true,
|
||||
message: '请选择测量点性质',
|
||||
message: '请选择电网标志',
|
||||
trigger: 'blur'
|
||||
}"
|
||||
>
|
||||
<el-select
|
||||
filterable
|
||||
v-model="lineItem.powerFlag"
|
||||
placeholder="请选择测量点性质"
|
||||
placeholder="请选择电网标志"
|
||||
:disabled="pageStatus == 1"
|
||||
@change="lineItem.objId = ''"
|
||||
>
|
||||
@@ -1140,14 +1140,15 @@
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
class="form-item"
|
||||
label="用户名称:"
|
||||
label="监测对象名称:"
|
||||
v-if="lineItem.powerFlag == 1"
|
||||
>
|
||||
<el-select
|
||||
filterable
|
||||
v-model="lineItem.objId"
|
||||
placeholder="请选择用户名称"
|
||||
placeholder="请选择对象名称"
|
||||
:disabled="pageStatus == 1"
|
||||
@change="(val) => handleSelect(lineItem, val)"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
@@ -1355,7 +1356,7 @@
|
||||
lIndex +
|
||||
'.bigObjType'
|
||||
"
|
||||
:rules="{ required: true, message: '请选择对象大类', trigger: 'blur' }"
|
||||
|
||||
>
|
||||
<el-select
|
||||
filterable
|
||||
@@ -1384,7 +1385,7 @@
|
||||
lIndex +
|
||||
'.smallObjType'
|
||||
"
|
||||
:rules="{ required: true, message: '请选择对象小类', trigger: 'blur' }"
|
||||
|
||||
>
|
||||
<el-select
|
||||
filterable
|
||||
@@ -1740,8 +1741,8 @@ const optionarr = ref([
|
||||
])
|
||||
/**母线类型 */
|
||||
const busBarType = ref([
|
||||
{ name: '实际母线', value: 0 },
|
||||
{ name: '虚拟母线', value: 1 }
|
||||
{ name: '真实母线', value: 1 },
|
||||
{ name: '虚拟母线', value: 0 }
|
||||
])
|
||||
const bigList: any = ref([])
|
||||
const smallList: any = ref([])
|
||||
@@ -1811,7 +1812,7 @@ const busBarDetail = ref({
|
||||
/**电压等级 */
|
||||
scale: '',
|
||||
/**母线类型 */
|
||||
model: 0,
|
||||
model: 1,
|
||||
/**母线id */
|
||||
subvIndex: '',
|
||||
/**监测点 */
|
||||
@@ -2202,6 +2203,22 @@ const category = () => {
|
||||
bigList.value = convertToTree(res.data)
|
||||
})
|
||||
}
|
||||
|
||||
//用户对象chage事件
|
||||
const handleSelect = (item, selectedId) => {
|
||||
// 清空选择
|
||||
if (!selectedId) {
|
||||
item.projectName = ''
|
||||
return
|
||||
}
|
||||
// 过滤当前下拉数据源
|
||||
|
||||
const options = newStationIdArr.value.find(i => i.id === selectedId)
|
||||
if (options) {
|
||||
item.objName = options.projectName
|
||||
}
|
||||
}
|
||||
|
||||
// 组装用户大小类
|
||||
const convertToTree = (data: any) => {
|
||||
const nodeMap: any = {}
|
||||
@@ -2911,7 +2928,7 @@ const selectChanged = async (value: any) => {
|
||||
capacity = 750
|
||||
break
|
||||
case '35':
|
||||
capacity = 259
|
||||
capacity = 250
|
||||
break
|
||||
case '10':
|
||||
capacity = 100
|
||||
@@ -2931,9 +2948,9 @@ const selectChanged = async (value: any) => {
|
||||
case '750':
|
||||
capacity = 7000
|
||||
break
|
||||
case '800':
|
||||
capacity = 7000
|
||||
break
|
||||
// case '800':
|
||||
// capacity = 7000
|
||||
// break
|
||||
case '1000':
|
||||
capacity = 9000
|
||||
break
|
||||
|
||||
107
src/views/pqs/business/terminal/sensitiveLoadMange/detail.vue
Normal file
107
src/views/pqs/business/terminal/sensitiveLoadMange/detail.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<el-dialog class="cn-operate-dialog" width="600px" v-model.trim="dialogVisible" :title="title">
|
||||
<el-form :model="form" class="form-one" label-width="auto" ref="formRef" :rules="rules">
|
||||
<el-form-item label="所属厂站名称" prop="substationName">
|
||||
<el-input v-model.trim="form.substationName" placeholder="请输入所属厂站名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="敏感用户名称" prop="name">
|
||||
<el-input v-model.trim="form.name" placeholder="请输入敏感用户名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="敏感负荷类型" prop="loadType">
|
||||
<el-select v-model.trim="form.loadType" filterable clearable placeholder="请选择数据分类">
|
||||
<el-option
|
||||
v-for="item in DataTypeSelect"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户协议容量(MVA)" prop="userAgreementCapacity">
|
||||
<el-input-number style="width: 100%;" :min="0" maxlength="32" show-word-limit v-model.number="form.userAgreementCapacity" placeholder="请输入用户协议容量"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="装机容量(MW)" prop="installedCapacity">
|
||||
<el-input-number style="width: 100%;" :min="0" maxlength="32" show-word-limit v-model.number="form.installedCapacity" placeholder="请输入装机容量"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number style="width: 100%;" :min="0" maxlength="32" show-word-limit v-model.number="form.sort" placeholder="请输入排序"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submit">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref,inject } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree'
|
||||
import { saveUser, updateUser } from '@/api/device-boot/sensitiveLoadMange'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
|
||||
const TypeOptions = ref()
|
||||
|
||||
const dictData = useDictData()
|
||||
const DataTypeSelect = dictData.getBasicData('Interference_Source')
|
||||
|
||||
const tableStore = inject('tableStore') as TableStore
|
||||
|
||||
const formRef = ref()
|
||||
const form = reactive<any>({
|
||||
loadType: [],
|
||||
substationName: null,
|
||||
installedCapacity: null,
|
||||
name: null,
|
||||
userAgreementCapacity:null,
|
||||
id: null,
|
||||
sort:100
|
||||
})
|
||||
const rules = {
|
||||
substationName: [{ required: true, message: '请输入所属厂站名称', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '请输入敏感用户名称', trigger: 'blur' }],
|
||||
loadType: [{ required: true, message: '请输入请选择敏感负荷类型', trigger: 'blur' }],
|
||||
installedCapacity: [{ required: true, message: '请输入用户协议容量', trigger: 'blur' }],
|
||||
userAgreementCapacity: [{ required: true, message: '请输入装机容量', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('新增')
|
||||
const open = (text: string, data?: anyObj) => {
|
||||
formRef.value?.resetFields()
|
||||
title.value = text
|
||||
dialogVisible.value = true
|
||||
if (data) {
|
||||
for (let key in form) {
|
||||
form[key] = data[key]
|
||||
}
|
||||
} else {
|
||||
for (let key in form) {
|
||||
form[key] = null
|
||||
form.sort = 100
|
||||
}
|
||||
}
|
||||
}
|
||||
const submit = () => {
|
||||
formRef.value.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
if (form.id) {
|
||||
await updateUser(form)
|
||||
} else {
|
||||
await saveUser(form)
|
||||
}
|
||||
ElMessage.success('操作成功')
|
||||
tableStore.index()
|
||||
dialogVisible.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
117
src/views/pqs/business/terminal/sensitiveLoadMange/index.vue
Normal file
117
src/views/pqs/business/terminal/sensitiveLoadMange/index.vue
Normal file
@@ -0,0 +1,117 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<TableHeader :showReset="false" showExport showCustomColumn>
|
||||
<template #select>
|
||||
<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>
|
||||
</template>
|
||||
<template #operation>
|
||||
<el-button :icon="Plus" type="primary" @click="addMenu" class="ml10">新增</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<Table ref="tableRef" />
|
||||
<detail ref="detail"></detail>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import Detail from './detail.vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { deleteUser } from '@/api/device-boot/sensitiveLoadMange'
|
||||
import { Plus } from '@element-plus/icons-vue'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
|
||||
defineOptions({
|
||||
name: 'govern/sensitiveLoadMange/index'
|
||||
})
|
||||
const detail = ref()
|
||||
|
||||
const dictData = useDictData()
|
||||
const interferenceType = dictData.getBasicData('Interference_Source')
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/device-boot/pqSensitiveUser/getList',
|
||||
method: 'POST',
|
||||
column: [
|
||||
{
|
||||
title: '序号',
|
||||
width: 80,
|
||||
formatter: (row: any) => {
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '所属厂站名称', field: 'substationName', minWidth: 180 },
|
||||
{ title: '敏感用户名称', field: 'name', minWidth: 180 },
|
||||
{
|
||||
title: '敏感负荷类型',
|
||||
field: 'loadType',
|
||||
minWidth: 120,
|
||||
formatter: row => {
|
||||
return interferenceType.filter(item => item.id == row.cellValue)[0]?.name
|
||||
}
|
||||
},
|
||||
{ title: '用户协议容量(MVA)', field: 'userAgreementCapacity', minWidth: 100 },
|
||||
{ title: '装机容量(MW)', field: 'installedCapacity', minWidth: 100 },
|
||||
{
|
||||
title: '操作', fixed: 'right',
|
||||
align: 'center',
|
||||
width: '180',
|
||||
|
||||
render: 'buttons',
|
||||
buttons: [
|
||||
{
|
||||
name: 'edit',
|
||||
title: '编辑',
|
||||
type: 'primary',
|
||||
icon: 'el-icon-EditPen',
|
||||
render: 'basicButton',
|
||||
click: row => {
|
||||
detail.value.open('编辑', row)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'del',
|
||||
title: '删除',
|
||||
type: 'danger',
|
||||
icon: 'el-icon-Delete',
|
||||
render: 'confirmButton',
|
||||
popconfirm: {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
confirmButtonType: 'danger',
|
||||
title: '确定删除吗?'
|
||||
},
|
||||
click: row => {
|
||||
deleteUser([row.id]).then(res => {
|
||||
ElMessage.success('删除成功')
|
||||
tableStore.index()
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
loadCallback: () => {}
|
||||
})
|
||||
|
||||
tableStore.table.params.searchValue = ''
|
||||
provide('tableStore', tableStore)
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
|
||||
const addMenu = () => {
|
||||
detail.value.open('新增')
|
||||
}
|
||||
</script>
|
||||
185
src/views/pqs/business/terminal/terminaCkeck/components/form.vue
Normal file
185
src/views/pqs/business/terminal/terminaCkeck/components/form.vue
Normal file
@@ -0,0 +1,185 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:title="dialogMode === 'detail' ? '定检详情' : '上传周期检测报告'"
|
||||
:width="dialogMode === 'detail' ? '1000px' : '600px'"
|
||||
v-model="dialogShow"
|
||||
v-if="dialogShow"
|
||||
>
|
||||
<!-- 详情区域 -->
|
||||
<div v-if="dialogMode === 'detail'">
|
||||
</div>
|
||||
<!-- 上传报告表单区域 -->
|
||||
<div v-if="dialogMode === 'upload'">
|
||||
<el-form ref="uploadFormRef" :model="uploadForm" :rules="uploadRules" label-width="120px">
|
||||
<el-form-item label="定检日期" prop="thisCheckTime">
|
||||
<el-date-picker
|
||||
v-model="uploadForm.thisCheckTime"
|
||||
type="date"
|
||||
placeholder="请选择定检日期"
|
||||
@change="calcNextCheckTime"
|
||||
style="width:100%"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="下次定检日期" prop="nextCheckTime">
|
||||
<el-date-picker
|
||||
v-model="uploadForm.nextCheckTime"
|
||||
type="date"
|
||||
placeholder="请选择下次定检日期"
|
||||
style="width:100%"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="uploadFile" for="-" label="设备检测报告:">
|
||||
<el-upload
|
||||
v-model:file-list="uploadForm.checkUrl"
|
||||
ref="uploadRef"
|
||||
action=""
|
||||
:accept="acceptType"
|
||||
:limit="1"
|
||||
:on-change="(file) => choose(file, 'checkUrl')"
|
||||
:auto-upload="false"
|
||||
:on-remove="removeFile('checkUrl')"
|
||||
>
|
||||
<template #trigger>
|
||||
<el-button type="primary">上传文件</el-button>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<el-button v-if="dialogMode === 'upload'" @click="dialogShow = false">取消</el-button>
|
||||
<el-button
|
||||
v-if="dialogMode === 'upload'"
|
||||
type="primary"
|
||||
:loading="submitLoading"
|
||||
@click="submitUploadReport"
|
||||
>
|
||||
提交
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import type { UploadFile } from 'element-plus'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { uploadFile } from '@/api/system-boot/file'
|
||||
import { userCheckUpload } from '@/api/device-boot/device'
|
||||
|
||||
const emit = defineEmits(['onSubmit'])
|
||||
|
||||
const acceptType = '.pdf,.docx'
|
||||
|
||||
const detailId = ref('')
|
||||
const dialogShow = ref(false)
|
||||
const dialogMode = ref<'detail' | 'upload'>('detail')
|
||||
const submitLoading = ref(false)
|
||||
|
||||
const uploadFormRef = ref()
|
||||
const uploadForm = reactive({
|
||||
thisCheckTime: '',
|
||||
nextCheckTime: '',
|
||||
checkUrl: [] as any[],
|
||||
devId: '',
|
||||
objId: ''
|
||||
})
|
||||
const checkUrlFile = ref('')
|
||||
|
||||
const calcNextCheckTime = (dateVal: string) => {
|
||||
if (!dateVal) {
|
||||
uploadForm.nextCheckTime = ''
|
||||
return
|
||||
}
|
||||
const date = new Date(dateVal)
|
||||
date.setFullYear(date.getFullYear() + 3)
|
||||
const y = date.getFullYear()
|
||||
const m = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const d = String(date.getDate()).padStart(2, '0')
|
||||
uploadForm.nextCheckTime = `${y}-${m}-${d}`
|
||||
}
|
||||
|
||||
const uploadRules = reactive({
|
||||
thisCheckTime: [{ required: true, message: '请选择定检日期', trigger: 'change' }],
|
||||
checkUrl: [{ required: true, message: '请上传设备检测报告', trigger: 'change' }]
|
||||
})
|
||||
|
||||
const submitUploadReport = async () => {
|
||||
await uploadFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
submitLoading.value = true
|
||||
try {
|
||||
const params = {
|
||||
devId: uploadForm.devId,
|
||||
objId: uploadForm.objId,
|
||||
thisCheckTime: uploadForm.thisCheckTime,
|
||||
nextCheckTime: uploadForm.nextCheckTime,
|
||||
checkUrl: checkUrlFile.value
|
||||
}
|
||||
const res = await userCheckUpload(params)
|
||||
if (res.code === 'A0000') {
|
||||
ElMessage.success('提交成功')
|
||||
dialogShow.value = false
|
||||
emit('onSubmit')
|
||||
}
|
||||
} catch (err: any) {
|
||||
ElMessage.error(err.msg || '提交失败')
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getFileName = (filePath: string) => {
|
||||
if (!filePath) return ''
|
||||
const parts = filePath.split('/')
|
||||
return parts[parts.length - 1] || filePath.replace(/^.*?\/(.*?)\//, '')
|
||||
}
|
||||
|
||||
const openUpload = (row: any) => {
|
||||
uploadForm.devId = row.devId
|
||||
uploadForm.objId = row.objId
|
||||
uploadForm.thisCheckTime = row.thisCheckTime || ''
|
||||
uploadForm.nextCheckTime = row.nextCheckTime || ''
|
||||
if (row.checkUrl) {
|
||||
checkUrlFile.value = row.checkUrl
|
||||
uploadForm.checkUrl = [{ name: getFileName(row.checkUrl), url: row.checkUrl }]
|
||||
} else {
|
||||
checkUrlFile.value = ''
|
||||
uploadForm.checkUrl = []
|
||||
}
|
||||
dialogMode.value = 'upload'
|
||||
dialogShow.value = true
|
||||
nextTick(() => {
|
||||
uploadFormRef.value?.clearValidate()
|
||||
})
|
||||
}
|
||||
|
||||
const openDetail = (id: string) => {
|
||||
detailId.value = id
|
||||
dialogMode.value = 'detail'
|
||||
dialogShow.value = true
|
||||
}
|
||||
|
||||
const removeFile = (val: string) => {
|
||||
return (_file: UploadFile, fileList: UploadFile[]) => {
|
||||
if (val === 'checkUrl') {
|
||||
checkUrlFile.value = ''
|
||||
}
|
||||
uploadForm[val] = fileList
|
||||
}
|
||||
}
|
||||
|
||||
const choose = (e: any, field: string) => {
|
||||
uploadFile(e.raw, '/supervision/').then(res => {
|
||||
if (field === 'checkUrl') {
|
||||
checkUrlFile.value = res.data.name
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ openUpload, openDetail })
|
||||
</script>
|
||||
205
src/views/pqs/business/terminal/terminaCkeck/index.vue
Normal file
205
src/views/pqs/business/terminal/terminaCkeck/index.vue
Normal file
@@ -0,0 +1,205 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<TableHeader ref="TableHeaderRef" showExport>
|
||||
<template #select>
|
||||
<el-form-item label="地市">
|
||||
<el-select v-model="tableStore.table.params.city" clearable placeholder="请选择地市">
|
||||
<el-option
|
||||
v-for="item in areaOptionList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.name"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="监测对象">
|
||||
<el-input
|
||||
style="width: 200px"
|
||||
placeholder="请输入监测对象名称"
|
||||
v-model="tableStore.table.params.searchValue"
|
||||
clearable
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #operation>
|
||||
<!-- <el-button icon="el-icon-Plus" type="primary" @click="addFormModel">新增定检记录</el-button>-->
|
||||
</template>
|
||||
</TableHeader>
|
||||
<Table ref="tableRef" @cell-click="cellClickEvent" />
|
||||
|
||||
<checkForm ref="checkFormRef" @onSubmit="tableStore.index()" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, watch } from 'vue'
|
||||
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import checkForm from './components/form.vue'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { useAdminInfo } from '@/stores/adminInfo'
|
||||
import { download } from '@/utils/fileDownLoad'
|
||||
defineOptions({
|
||||
name: 'terminal/terminaCkeck'
|
||||
})
|
||||
|
||||
// 公共依赖
|
||||
const TableHeaderRef = ref()
|
||||
const checkFormRef = ref()
|
||||
const dictData = useDictData()
|
||||
const adminInfo = useAdminInfo()
|
||||
// 地区字典(和你原有地市下拉同源)
|
||||
const areaOptionList = dictData.getBasicData('jibei_area')
|
||||
|
||||
// TableStore 表格配置(仅修改字段映射,其余不动)
|
||||
const tableStore = new TableStore({
|
||||
url: '/device-boot/alarm/terminalCheckPage',
|
||||
method: 'POST',
|
||||
column: [
|
||||
// 多选框
|
||||
{
|
||||
width: '60',
|
||||
type: 'checkbox'
|
||||
},
|
||||
// 序号(分页自增,和你现有逻辑一致)
|
||||
{
|
||||
title: '序号',
|
||||
width: 70,
|
||||
formatter: (row: any) => {
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ field: 'areaName', title: '所在地市', minWidth: 100 },
|
||||
{ field: 'bdName', title: '变电站', minWidth: 150 },
|
||||
{ field: 'objName', title: '监测对象', minWidth: 180 },
|
||||
{ field: 'devName', title: '终端名称', minWidth: 180 },
|
||||
{ field: 'loginDate', title: '投运时间', minWidth: 120 },
|
||||
{ field: 'thisCheckTime', title: '本次定检时间', minWidth: 120 },
|
||||
{ field: 'nextCheckTime', title: '下次定检时间', minWidth: 120 },
|
||||
{
|
||||
title: '是否逾期',
|
||||
field: 'checkStatus',
|
||||
align: 'center',
|
||||
width: 80,
|
||||
render: 'customRender',
|
||||
customRender: props => {
|
||||
const val = props.renderValue
|
||||
let text = ''
|
||||
let color = ''
|
||||
if (val === 1) {
|
||||
text = '是'
|
||||
color = '#f56c6c'
|
||||
} else if (val === 0) {
|
||||
text = '否'
|
||||
color = '#67c23a'
|
||||
}
|
||||
return h('span', { style: { color, fontWeight: 'bold' } }, text)
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'overdueDay',
|
||||
title: '逾期天数',
|
||||
minWidth: 80,
|
||||
render: 'customRender',
|
||||
customRender: props => {
|
||||
const val = props.renderValue
|
||||
let text = ''
|
||||
let color = ''
|
||||
if (val > 0) {
|
||||
text = val
|
||||
color = '#f56c6c'
|
||||
} else if (val > -30) {
|
||||
text = Math.abs(val).toString() + '天后将逾期'
|
||||
color = '#e6a23c'
|
||||
} else {
|
||||
text = '/'
|
||||
}
|
||||
return h('span', { style: { color, fontWeight: 'bold' } }, text)
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'checkUrl',
|
||||
title: '周期检测报告',
|
||||
minWidth: 160,
|
||||
render: 'customRender',
|
||||
customRender: props => {
|
||||
const val = props.renderValue?.replace(/^.*?\/(.*?)\//, '') || ''
|
||||
return val ? h('span', { style: { color: 'var(--el-color-primary)', cursor: 'pointer' } }, val) : '/'
|
||||
}
|
||||
},
|
||||
// 操作列固定右侧
|
||||
{
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
minWidth: 160,
|
||||
render: 'buttons',
|
||||
buttons: [
|
||||
// {
|
||||
// name: 'detail',
|
||||
// title: '详情',
|
||||
// type: 'primary',
|
||||
// icon: 'el-icon-EditPen',
|
||||
// render: 'basicButton',
|
||||
// click: row => {
|
||||
// checkFormRef.value.openDetail(row.devId)
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: 'edit',
|
||||
title: '上传周期检测报告',
|
||||
type: 'primary',
|
||||
icon: 'el-icon-Open',
|
||||
render: 'basicButton',
|
||||
click: row => {
|
||||
checkFormRef.value.openUpload(row)
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
// 携带当前登录人部门ID
|
||||
tableStore.table.params.orgId = adminInfo.$state.deptId
|
||||
}
|
||||
})
|
||||
|
||||
// 初始化查询参数
|
||||
tableStore.table.params.city = ''
|
||||
tableStore.table.params.substation = ''
|
||||
tableStore.table.params.terminalName = ''
|
||||
tableStore.table.params.orgId = adminInfo.$state.deptId
|
||||
|
||||
// 路由跳转带ID回显编辑(复用你原有路由传参逻辑)
|
||||
const props = defineProps({
|
||||
id: { type: String, default: 'null' }
|
||||
})
|
||||
watch(
|
||||
() => props.id,
|
||||
async newVal => {
|
||||
if (newVal === 'null') return
|
||||
const fullId = newVal.split('@')[0]
|
||||
const routeTime = Number(newVal.split('@')[1])
|
||||
if (isNaN(routeTime) || Date.now() - routeTime > import.meta.env.VITE_ROUTE_TIME_OUT) return
|
||||
const res = await getPqCheckById(fullId)
|
||||
if (res.code === 'A0000') {
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
// 点击行
|
||||
const cellClickEvent = ({ row, column }: any) => {
|
||||
if (column.field == 'checkUrl') {
|
||||
row.checkUrl ? download(row.checkUrl) : ''
|
||||
}
|
||||
}
|
||||
provide('tableStore', tableStore)
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -41,7 +41,7 @@
|
||||
</el-col>
|
||||
<el-col :span="19">
|
||||
<div class="mt10">
|
||||
<TableHeader showExport :showSearch="false" ref="TableHeaderRef">
|
||||
<TableHeader showExport :showSearch="false" ref="TableHeaderRef" showCustomColumn>
|
||||
<template v-slot:select>
|
||||
<span style="font-size: 14px; line-height: 40px; color: red;">
|
||||
所选变电站:
|
||||
@@ -504,14 +504,16 @@ const maintenance = (val: any) => {
|
||||
id: val.tfIndex,
|
||||
subId: val.subIndex
|
||||
}).then(res => {
|
||||
|
||||
bind.value = res.data.bind
|
||||
treeMenuLeftData.value = res.data.upNode
|
||||
treeMenuRightData.value = res.data.downNode
|
||||
|
||||
setDisabled(treeMenuRightData.value)
|
||||
setDisabled(treeMenuLeftData.value)
|
||||
isLoading3.value = false
|
||||
if (treeMenuLeftData.value && treeMenuLeftData.value.length > 0) {
|
||||
treeMenuLeftData.value[0].children?.forEach(item => {
|
||||
/* treeMenuLeftData.value[0].children?.forEach(item => {
|
||||
item.children?.forEach(item1 => {
|
||||
item1.children?.forEach(item2 => {
|
||||
item2.children?.forEach(item3 => {
|
||||
@@ -523,21 +525,25 @@ const maintenance = (val: any) => {
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})*/
|
||||
menuTreeLeft.value?.setCheckedKeys([bind.value[0]])
|
||||
maintenanceData.upNode = bind.value[0]
|
||||
bindLevel.value = 5
|
||||
}
|
||||
if (treeMenuRightData.value && treeMenuRightData.value.length > 0) {
|
||||
treeMenuRightData.value[0].children?.forEach(item => {
|
||||
/* treeMenuRightData.value[0].children?.forEach(item => {
|
||||
item.children?.forEach(item1 => {
|
||||
item1.children?.forEach(item2 => {
|
||||
item2.children?.forEach(item3 => {
|
||||
if (item3.level != null) {
|
||||
menuTreeRight.value?.setCheckedKeys([item3.id])
|
||||
maintenanceData.downNode = item3.id
|
||||
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})*/
|
||||
menuTreeRight.value?.setCheckedKeys([bind.value[1]])
|
||||
maintenanceData.downNode = bind.value[1]
|
||||
}
|
||||
nodemaintenanceInformation.value = true
|
||||
})
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
<el-form-item for="-" v-if="form.userType != '0' && form.userType != '1'" label="PCC点:">
|
||||
<el-input v-model.trim="form.pccPoint" autocomplete="off" placeholder="请输入PCC点" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
<!-- <el-form-item
|
||||
for="-"
|
||||
v-if="form.userType == '2' || form.userType == '3' || form.userType == '4' || form.userType == '5'"
|
||||
label="基准短路容量:"
|
||||
@@ -273,7 +273,7 @@
|
||||
>
|
||||
<template #append>MVA</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form-item>-->
|
||||
<el-form-item for="-" v-if="form.userType == '6'" label="行业:">
|
||||
<el-select v-model="form.industry" placeholder="请选择行业">
|
||||
<el-option v-for="(item, index) in industryList" :label="item.name" :value="item.id" :key="index" />
|
||||
@@ -368,6 +368,48 @@
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
class="uploadFile"
|
||||
for="-"
|
||||
label="设备检测报告:"
|
||||
prop="checkUrl"
|
||||
>
|
||||
<el-upload
|
||||
v-model:file-list="form.checkUrl"
|
||||
ref="uploadRef"
|
||||
action=""
|
||||
:accept="acceptType"
|
||||
:limit="1"
|
||||
:on-change="(file) => choose(file, 'checkUrl')"
|
||||
:auto-upload="false"
|
||||
:on-remove="removeFile('checkUrl')"
|
||||
>
|
||||
<template #trigger>
|
||||
<el-button type="primary" >上传文件</el-button>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
class="uploadFile"
|
||||
for="-"
|
||||
label="电能质量评估报告:"
|
||||
prop="evaluation"
|
||||
>
|
||||
<el-upload
|
||||
v-model:file-list="form.assessUrl"
|
||||
ref="uploadRef"
|
||||
action=""
|
||||
:accept="acceptType"
|
||||
:limit="1"
|
||||
:on-change="(file) => choose(file, 'assessUrl')"
|
||||
:auto-upload="false"
|
||||
:on-remove="removeFile('assessUrl')"
|
||||
>
|
||||
<template #trigger>
|
||||
<el-button type="primary">上传文件</el-button>
|
||||
</template>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
<el-form-item for="-" label="预测评估结论:" style="width: 100%">
|
||||
<el-input
|
||||
type="textarea"
|
||||
@@ -390,7 +432,7 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, reactive, defineExpose, defineProps, defineEmits, watch, onUnmounted } from 'vue'
|
||||
// import { upload, insertTerminal, updateTerminal } from '@/api/process-boot/terminal'
|
||||
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
|
||||
import type { UploadFile, UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
|
||||
import { genFileId, ElMessage } from 'element-plus'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import type { ComponentSize, FormInstance, FormRules } from 'element-plus'
|
||||
@@ -400,13 +442,12 @@ import { uploadFile } from '@/api/system-boot/file'
|
||||
import {
|
||||
submitFormData,
|
||||
getById,
|
||||
updateFormData,
|
||||
addEditor,
|
||||
resend,
|
||||
getByDeptDevLine
|
||||
} from '@/api/supervision-boot/interfere/index'
|
||||
getByDeptDevLine,
|
||||
getUserReportUpdateById
|
||||
} from '@/api/device-boot/sensitiveLoadMange'
|
||||
import { getSubstationSelect } from '@/api/device-boot/line'
|
||||
import { getUserReportUpdateById } from '@/api/supervision-boot/userReport/form'
|
||||
// import { getUserReportUpdateById } from '@/api/supervision-boot/userReport/form'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
@@ -436,10 +477,11 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
const emits = defineEmits(['onSubmit'])
|
||||
const IS_LN = import.meta.env.VITE_NAME == 'LN' || import.meta.env.VITE_NAME == 'LNqr'
|
||||
const dictData = useDictData()
|
||||
const dialogFormVisible = ref(false)
|
||||
// .doc,.docx,.xlsx,.xls,.pdf
|
||||
const acceptType = ''
|
||||
const acceptType = '.pdf,.docx'
|
||||
const form: any = ref({})
|
||||
const loading = ref(false)
|
||||
const control: any = ref(true)
|
||||
@@ -533,6 +575,10 @@ const defaultProps = {
|
||||
const nonlinearDeviceTypeList: any = ref('')
|
||||
//获取登陆用户姓名和部门
|
||||
const adminInfo = useAdminInfo()
|
||||
// 电能质量检测报告
|
||||
const checkUrlFile = ref('')
|
||||
// 电能质量评估报告
|
||||
const evaluationFile = ref('')
|
||||
const resetForm = () => {
|
||||
form.value = {
|
||||
reporter: '', //填报人 1
|
||||
@@ -559,6 +605,8 @@ const resetForm = () => {
|
||||
pccPoint: '', //PCC点 1
|
||||
evaluationType: evaluationTypeList[0].id, //评估类型 1
|
||||
evaluationChekDept: '', //预测评估审单位 1
|
||||
checkUrl: [], //电能质量检测报告
|
||||
assessUrl: [], //电能质量评估报告
|
||||
minShortCircuitCapacity: '', //系统最小短路容量(MVA) 1
|
||||
userAgreementCapacity: '', //用户用电协议容量(MVA) 1
|
||||
needGovernance: 0, //是否需要治理 1
|
||||
@@ -582,6 +630,8 @@ const resetForm = () => {
|
||||
delete form.value.loadLevel
|
||||
delete form.value.powerSupplyInfo
|
||||
}
|
||||
checkUrlFile.value = ''
|
||||
evaluationFile.value = ''
|
||||
}
|
||||
//初始化数据
|
||||
resetForm()
|
||||
@@ -695,7 +745,7 @@ const rules = ref({
|
||||
reporter: [{ required: true, message: '请输入填报人', trigger: 'blur' }],
|
||||
reportDate: [{ required: true, message: '请选择填报日期', trigger: 'change' }],
|
||||
orgId: [{ required: true, message: '请选择填报部门', trigger: 'change' }],
|
||||
stationId: [{ required: true, message: '请选择所属电站', trigger: 'change' }],
|
||||
//stationId: [{ required: true, message: '请选择所属电站', trigger: 'change' }],
|
||||
expectedProductionDate: [{ required: true, message: '请选择工程预期投产日期', trigger: 'change' }],
|
||||
userType: [{ required: true, message: '清选择用户性质', trigger: 'change' }],
|
||||
city: [{ required: true, message: '请选择所在地市', trigger: 'change' }],
|
||||
@@ -901,6 +951,10 @@ const open = async (row: any) => {
|
||||
} else {
|
||||
resendId.value = ''
|
||||
form.value.userType = userTypeList.value[0].value
|
||||
checkUrlFile.value = ''
|
||||
evaluationFile.value = ''
|
||||
form.value.checkUrl = []
|
||||
form.value.evaluation = []
|
||||
}
|
||||
await getSubstationSelect().then(res => {
|
||||
stationList.value = res.data
|
||||
@@ -918,18 +972,36 @@ async function handleResponse(data: any) {
|
||||
// userType logic is commented out; if needed, implement accordingly
|
||||
if (data.userReportProjectPO) {
|
||||
form.value = { ...data, ...data.userReportProjectPO }
|
||||
fileRaw(data, 'userReportProjectPO')
|
||||
} else if (data.userReportSubstationPO) {
|
||||
form.value = { ...data, ...data.userReportSubstationPO }
|
||||
fileRaw(data, 'userReportSubstationPO')
|
||||
} else if (data.userReportSensitivePO) {
|
||||
form.value = {
|
||||
...data,
|
||||
...data.userReportSensitivePO,
|
||||
energyQualityIndex: data.userReportSensitivePO.energyQualityIndex.split(', ')
|
||||
}
|
||||
fileRaw(data, 'userReportSensitivePO')
|
||||
}
|
||||
form.value.orgId = adminInfo.$state.deptName
|
||||
}
|
||||
|
||||
// 处理上传文件回显
|
||||
const fileRaw = (row: any, key: string) => {
|
||||
const fileFields = ['checkUrl', 'assessUrl']
|
||||
for (const field of fileFields) {
|
||||
const filePath = row[key]?.[field] ?? row[field]
|
||||
if (filePath != null && filePath.length > 0) {
|
||||
form.value[field] = [{ name: filePath.split('/')[2] }]
|
||||
} else {
|
||||
form.value[field] = []
|
||||
}
|
||||
}
|
||||
checkUrlFile.value = row[key]?.checkUrl ?? row.checkUrl ?? ''
|
||||
evaluationFile.value = row[key]?.assessUrl ?? row.assessUrl ?? ''
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
//重置表单内容
|
||||
//取消表单校验状态
|
||||
@@ -948,14 +1020,25 @@ const handleExceed: UploadProps['onExceed'] = files => {
|
||||
file.uid = genFileId()
|
||||
uploadRef.value!.handleStart(file)
|
||||
}
|
||||
let uploadName = ref('')
|
||||
//上传报告字段名称
|
||||
const uploadFileName = (val: any) => {
|
||||
uploadName.value = val
|
||||
}
|
||||
//移除文件上传
|
||||
const removeFile = (file: any, uploadFiles: any) => {
|
||||
console.log(file, uploadFiles)
|
||||
const removeFile = (val: string) => {
|
||||
return (_file: UploadFile, fileList: UploadFile[]) => {
|
||||
if (val === 'checkUrl') {
|
||||
checkUrlFile.value = ''
|
||||
} else if (val === 'assessUrl') {
|
||||
evaluationFile.value = ''
|
||||
}
|
||||
form.value[val] = fileList
|
||||
}
|
||||
}
|
||||
const choose = (e: any, field: string) => {
|
||||
uploadFile(e.raw, '/supervision/').then(res => {
|
||||
if (field === 'checkUrl') {
|
||||
checkUrlFile.value = res.data.name
|
||||
} else if (field === 'assessUrl') {
|
||||
evaluationFile.value = res.data.name
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 关联终端
|
||||
@@ -982,12 +1065,16 @@ const confirmForm = async (flag: boolean) => {
|
||||
subForm.value.reporter = adminInfo.$state.id
|
||||
subForm.value.orgId = adminInfo.$state.deptId
|
||||
let confirmFormData = JSON.parse(JSON.stringify(subForm.value))
|
||||
confirmFormData.checkUrl = checkUrlFile.value
|
||||
confirmFormData.assessUrl = evaluationFile.value
|
||||
//1.判断是否上传
|
||||
if (subForm.value.userType == '0' || subForm.value.userType == '1') {
|
||||
{
|
||||
//其他报告非必填
|
||||
confirmFormData.userReportProjectPO = {
|
||||
...confirmFormData.userReportProjectPO
|
||||
...confirmFormData.userReportProjectPO,
|
||||
checkUrl: checkUrlFile.value,
|
||||
assessUrl: evaluationFile.value
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1000,7 +1087,9 @@ const confirmForm = async (flag: boolean) => {
|
||||
) {
|
||||
{
|
||||
confirmFormData.userReportSubstationPO = {
|
||||
...confirmFormData.userReportSubstationPO
|
||||
...confirmFormData.userReportSubstationPO,
|
||||
checkUrl: checkUrlFile.value,
|
||||
assessUrl: evaluationFile.value
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1009,7 +1098,9 @@ const confirmForm = async (flag: boolean) => {
|
||||
{
|
||||
confirmFormData.userReportSensitivePO = {
|
||||
...confirmFormData.userReportSensitivePO,
|
||||
energyQualityIndex: confirmFormData.userReportSensitivePO.energyQualityIndex.join(', ')
|
||||
energyQualityIndex: confirmFormData.userReportSensitivePO.energyQualityIndex.join(', '),
|
||||
checkUrl: checkUrlFile.value,
|
||||
assessUrl: evaluationFile.value
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1061,8 +1152,6 @@ const filterUsers = (arr: any) => {
|
||||
userTypeList.value = userTypeList.value.filter(item => !arr.includes(item.value))
|
||||
}
|
||||
const setcontroFlag = () => {
|
||||
|
||||
|
||||
controFlag.value = true
|
||||
}
|
||||
defineExpose({ open, filterUsers, setcontroFlag })
|
||||
|
||||
@@ -1,217 +1,234 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<div v-if="detailLoading" class="loading">
|
||||
<div v-if="detailLoading" class="loading">
|
||||
<el-spin description="加载中..." />
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="所在地市">
|
||||
{{ detailData.city }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="项目名称">
|
||||
{{ detailData.projectName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="工程预期投产日期">
|
||||
{{ formatDate(detailData.expectedProductionDate, 'YYYY-MM-DD') }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="经纬度">
|
||||
{{ detailData.longitude }} {{ detailData.latitude }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户性质">
|
||||
{{
|
||||
userTypeList.find(item => {
|
||||
return item.value == detailData.userType
|
||||
})?.label
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions :column="2" border label-width="200px">
|
||||
<el-descriptions-item label="所在地市">
|
||||
{{ detailData.city }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="项目名称">
|
||||
{{ detailData.projectName }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="工程预期投产日期">
|
||||
{{ formatDate(detailData.expectedProductionDate, 'YYYY-MM-DD') }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="经纬度">
|
||||
{{ detailData.longitude }} {{ detailData.latitude }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户性质">
|
||||
{{
|
||||
userTypeList.find(item => {
|
||||
return item.value == detailData.userType
|
||||
})?.label
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="归口管理部门">
|
||||
{{ detailData.responsibleDepartment }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户状态">
|
||||
{{
|
||||
userStateList.find(item => {
|
||||
return item.value == detailData.userStatus
|
||||
})?.label
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="厂站名称">
|
||||
{{ detailData.substation }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="归口管理部门">
|
||||
{{ detailData.responsibleDepartment }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="用户状态">
|
||||
{{
|
||||
userStateList.find(item => {
|
||||
return item.value == detailData.userStatus
|
||||
})?.label
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="厂站名称">
|
||||
{{ detailData.substation }}
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="电压等级">
|
||||
{{
|
||||
voltageLevelList.find(item => {
|
||||
return item.id == detailData.voltageLevel
|
||||
})?.name
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="非线性终端类型" v-if="detailData.userType == 0 || detailData.userType == 1">
|
||||
{{ proviteData.nonlinearDeviceType ? proviteData.nonlinearDeviceType : '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="预测评估单位">
|
||||
{{ detailData.evaluationDept }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="预测评估结论" :span="2">
|
||||
{{ detailData.evaluationConclusion }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
:label="
|
||||
detailData.userType == '4' || detailData.userType == '5' ? '非线性设备类型: ' : '非线性负荷类型:'
|
||||
"
|
||||
v-if="
|
||||
detailData.userType == '2' ||
|
||||
detailData.userType == '3' ||
|
||||
detailData.userType == '4' ||
|
||||
detailData.userType == '5'
|
||||
"
|
||||
>
|
||||
{{ proviteData.nonlinearLoadType }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="是否需要治理">
|
||||
<span v-if="detailData.userType == 0 || detailData.userType == 1">
|
||||
{{ proviteData.needGovernance == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
<span
|
||||
<el-descriptions-item label="电压等级">
|
||||
{{
|
||||
voltageLevelList.find(item => {
|
||||
return item.id == detailData.voltageLevel
|
||||
})?.name
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="非线性终端类型"
|
||||
v-if="detailData.userType == 0 || detailData.userType == 1"
|
||||
>
|
||||
{{ proviteData.nonlinearDeviceType ? proviteData.nonlinearDeviceType : '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="预测评估单位">
|
||||
{{ detailData.evaluationDept }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="预测评估结论" :span="2">
|
||||
{{ detailData.evaluationConclusion }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
:label="
|
||||
detailData.userType == '4' || detailData.userType == '5'
|
||||
? '非线性设备类型: '
|
||||
: '非线性负荷类型:'
|
||||
"
|
||||
v-if="
|
||||
detailData.userType == 2 ||
|
||||
detailData.userType == 3 ||
|
||||
detailData.userType == 4 ||
|
||||
detailData.userType == 5
|
||||
detailData.userType == '2' ||
|
||||
detailData.userType == '3' ||
|
||||
detailData.userType == '4' ||
|
||||
detailData.userType == '5'
|
||||
"
|
||||
>
|
||||
{{ proviteData.needGovernance == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
<span v-if="detailData.userType == 6">{{ proviteData.needGovernance == 0 ? '否' : '是' }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="是否开展背景测试">
|
||||
<span v-if="detailData.userType == 0 || detailData.userType == 1">
|
||||
{{ proviteData.backgroundTestPerformed == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
<span
|
||||
{{ proviteData.nonlinearLoadType }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="是否需要治理">
|
||||
<span v-if="detailData.userType == 0 || detailData.userType == 1">
|
||||
{{ proviteData.needGovernance == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
<span
|
||||
v-if="
|
||||
detailData.userType == 2 ||
|
||||
detailData.userType == 3 ||
|
||||
detailData.userType == 4 ||
|
||||
detailData.userType == 5
|
||||
"
|
||||
>
|
||||
{{ proviteData.needGovernance == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
<span v-if="detailData.userType == 6">{{ proviteData.needGovernance == 0 ? '否' : '是' }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="是否开展背景测试">
|
||||
<span v-if="detailData.userType == 0 || detailData.userType == 1">
|
||||
{{ proviteData.backgroundTestPerformed == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
<span
|
||||
v-if="
|
||||
detailData.userType == 2 ||
|
||||
detailData.userType == 3 ||
|
||||
detailData.userType == 4 ||
|
||||
detailData.userType == 5
|
||||
"
|
||||
>
|
||||
{{ proviteData.backgroundTestPerformed == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
<span v-if="detailData.userType == 6">
|
||||
{{ proviteData.backgroundTestPerformed == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="是否开展抗扰度测试" v-if="detailData.userType == 6">
|
||||
<span>
|
||||
{{ proviteData.antiInterferenceTest == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="用户协议容量(MVA)"
|
||||
v-if="detailData.userType == 0 || detailData.userType == 1"
|
||||
>
|
||||
{{ proviteData.agreementCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="装机容量(MW)">
|
||||
{{ detailData?.ratePower }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="PCC供电设备容量(MVA)"
|
||||
v-if="
|
||||
detailData.userType == 2 ||
|
||||
detailData.userType == 3 ||
|
||||
detailData.userType == 4 ||
|
||||
detailData.userType == 5
|
||||
detailData.userType == '2' ||
|
||||
detailData.userType == '3' ||
|
||||
detailData.userType == '4' ||
|
||||
detailData.userType == '5'
|
||||
"
|
||||
>
|
||||
{{ proviteData.backgroundTestPerformed == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
<span v-if="detailData.userType == 6">
|
||||
{{ proviteData.backgroundTestPerformed == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="是否开展抗扰度测试" v-if="detailData.userType == 6">
|
||||
<span>
|
||||
{{ proviteData.antiInterferenceTest == 0 ? '否' : '是' }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="用户协议容量(MVA)"
|
||||
v-if="detailData.userType == 0 || detailData.userType == 1"
|
||||
>
|
||||
{{ proviteData.agreementCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="装机容量(MW)">
|
||||
{{ detailData?.ratePower }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="PCC供电设备容量(MVA)"
|
||||
v-if="
|
||||
detailData.userType == '2' ||
|
||||
detailData.userType == '3' ||
|
||||
detailData.userType == '4' ||
|
||||
detailData.userType == '5'
|
||||
"
|
||||
>
|
||||
{{ proviteData.pccEquipmentCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="基准短路容量(MVA)"
|
||||
v-if="
|
||||
detailData.userType == '2' ||
|
||||
detailData.userType == '3' ||
|
||||
detailData.userType == '4' ||
|
||||
detailData.userType == '5'
|
||||
"
|
||||
>
|
||||
{{ proviteData.baseShortCircuitCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="系统最小短路容量(MVA)"
|
||||
v-if="
|
||||
detailData.userType == '2' ||
|
||||
detailData.userType == '3' ||
|
||||
detailData.userType == '4' ||
|
||||
detailData.userType == '5'
|
||||
"
|
||||
>
|
||||
{{ proviteData?.minShortCircuitCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="用户用电协议容量(MVA)"
|
||||
v-if="
|
||||
detailData.userType == '2' ||
|
||||
detailData.userType == '3' ||
|
||||
detailData.userType == '4' ||
|
||||
detailData.userType == '5'
|
||||
"
|
||||
>
|
||||
{{ proviteData?.userAgreementCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="PCC点" v-if="detailData.userType != 0 && detailData.userType != 1">
|
||||
{{ proviteData?.pccPoint }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="评估类型" v-if="detailData.userType != 0 && detailData.userType != 1">
|
||||
{{
|
||||
evaluationTypeList.find(item => {
|
||||
return item.id == proviteData?.evaluationType
|
||||
})?.name
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="预测评估评审单位" v-if="detailData.userType != 0 && detailData.userType != 1">
|
||||
{{ proviteData?.evaluationChekDept }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="行业" v-if="detailData.userType == 6">
|
||||
{{
|
||||
industryList.find(item => {
|
||||
return item.id == proviteData.industry
|
||||
})?.name
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="敏感终端名称" v-if="detailData.userType == 6">
|
||||
{{ proviteData.deviceName }}
|
||||
</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="供电电源数量" v-if="detailData.userType == 6">-->
|
||||
<!-- {{ proviteData.powerSupplyCount }}-->
|
||||
<!-- </el-descriptions-item>-->
|
||||
<el-descriptions-item label="供电电源情况" v-if="detailData.userType == 6">
|
||||
{{
|
||||
powerSupplyInfoOptionList.find(item => {
|
||||
return item.id == proviteData.powerSupplyInfo
|
||||
})?.name
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="供电电源" :span="2" v-if="detailData.userType == 6">
|
||||
{{ proviteData.powerSupply }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="负荷级别" v-if="detailData.userType == 6">
|
||||
{{
|
||||
loadLevelOptionList.find(item => {
|
||||
return item.id == proviteData.loadLevel
|
||||
})?.name
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="敏感电能质量指标" v-if="detailData.userType == 6">
|
||||
{{
|
||||
energyQualityIndexList.find(item => {
|
||||
return item.id == proviteData.energyQualityIndex
|
||||
})?.name
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
{{ proviteData.pccEquipmentCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="基准短路容量(MVA)"
|
||||
v-if="
|
||||
detailData.userType == '2' ||
|
||||
detailData.userType == '3' ||
|
||||
detailData.userType == '4' ||
|
||||
detailData.userType == '5'
|
||||
"
|
||||
>
|
||||
{{ proviteData.baseShortCircuitCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="系统最小短路容量(MVA)"
|
||||
v-if="
|
||||
detailData.userType == '2' ||
|
||||
detailData.userType == '3' ||
|
||||
detailData.userType == '4' ||
|
||||
detailData.userType == '5'
|
||||
"
|
||||
>
|
||||
{{ proviteData?.minShortCircuitCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="用户用电协议容量(MVA)"
|
||||
v-if="
|
||||
detailData.userType == '2' ||
|
||||
detailData.userType == '3' ||
|
||||
detailData.userType == '4' ||
|
||||
detailData.userType == '5'
|
||||
"
|
||||
>
|
||||
{{ proviteData?.userAgreementCapacity }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="PCC点" v-if="detailData.userType != 0 && detailData.userType != 1">
|
||||
{{ proviteData?.pccPoint }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="评估类型" v-if="detailData.userType != 0 && detailData.userType != 1">
|
||||
{{
|
||||
evaluationTypeList.find(item => {
|
||||
return item.id == proviteData?.evaluationType
|
||||
})?.name
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
label="预测评估评审单位"
|
||||
v-if="detailData.userType != 0 && detailData.userType != 1"
|
||||
>
|
||||
{{ proviteData?.evaluationChekDept }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="行业" v-if="detailData.userType == 6">
|
||||
{{
|
||||
industryList.find(item => {
|
||||
return item.id == proviteData.industry
|
||||
})?.name
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="敏感终端名称" v-if="detailData.userType == 6">
|
||||
{{ proviteData.deviceName }}
|
||||
</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="供电电源数量" v-if="detailData.userType == 6">-->
|
||||
<!-- {{ proviteData.powerSupplyCount }}-->
|
||||
<!-- </el-descriptions-item>-->
|
||||
<el-descriptions-item label="供电电源情况" v-if="detailData.userType == 6">
|
||||
{{
|
||||
powerSupplyInfoOptionList.find(item => {
|
||||
return item.id == proviteData.powerSupplyInfo
|
||||
})?.name
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="供电电源" :span="2" v-if="detailData.userType == 6">
|
||||
{{ proviteData.powerSupply }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="负荷级别" v-if="detailData.userType == 6">
|
||||
{{
|
||||
loadLevelOptionList.find(item => {
|
||||
return item.id == proviteData.loadLevel
|
||||
})?.name
|
||||
}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="电能质量设备检测报告">
|
||||
<el-icon class="elView" v-if="detailData?.checkUrl">
|
||||
<View @click="openFile(detailData?.checkUrl)" />
|
||||
</el-icon>
|
||||
<span class="aLoad" @click="download(detailData.checkUrl)" target="_blank">
|
||||
{{ detailData.checkUrl?.replace(/^.*?\/(.*?)\//, '') || '' }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="电能质量评估报告">
|
||||
<el-icon class="elView" v-if="detailData?.assessUrl">
|
||||
<View @click="openFile(detailData?.assessUrl)" />
|
||||
</el-icon>
|
||||
<span class="aLoad" @click="download(detailData.assessUrl)" target="_blank">
|
||||
{{ detailData.assessUrl?.replace(/^.*?\/(.*?)\//, '') || '' }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -220,14 +237,13 @@ import { onMounted, ref, reactive, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { getUserReportById, getUserReportUpdateById } from '@/api/supervision-boot/userReport/form'
|
||||
import { getById, getUserReportUpdateById, getByDeptDevLine, getFileById } from '@/api/device-boot/sensitiveLoadMange'
|
||||
import { getDictTreeById } from '@/api/system-boot/dictTree'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { getFileNameAndFilePath } from '@/api/system-boot/file'
|
||||
import { Link, View } from '@element-plus/icons-vue'
|
||||
import PreviewFile from '@/components/PreviewFile/index.vue'
|
||||
import { getByDeptDevLine } from '@/api/supervision-boot/interfere/index'
|
||||
import { addOrUpdateFile, getFileById } from '@/api/supervision-boot/interfere/index'
|
||||
import { download } from '@/utils/fileDownLoad'
|
||||
// import { addOrUpdateFile, getFileById } from '@/api/supervision-boot/interfere/index'
|
||||
defineOptions({ name: 'BpmUserReportDetail' })
|
||||
|
||||
const { query } = useRoute() // 查询参数
|
||||
@@ -340,9 +356,9 @@ const getInfo = async () => {
|
||||
getProviteData()
|
||||
})
|
||||
} else {
|
||||
await getUserReportById(props.id || queryId).then(res => {
|
||||
await getById({ id: props.id || queryId }).then(res => {
|
||||
detailData.value = res.data
|
||||
|
||||
|
||||
getProviteData()
|
||||
})
|
||||
}
|
||||
@@ -385,7 +401,6 @@ const preview = (val: any, url: any) => {
|
||||
}
|
||||
//预测评估报告
|
||||
if (val == 'predictionEvaluationReport') {
|
||||
|
||||
predictionEvaluationReportRef?.value.open(url)
|
||||
}
|
||||
//预测评估评审意见报告
|
||||
@@ -416,11 +431,11 @@ const preview = (val: any, url: any) => {
|
||||
}
|
||||
|
||||
const queryFiles = () => {
|
||||
getFileById({ id: props.id }).then(res => {
|
||||
res.data.forEach((item: any) => {
|
||||
if (item.url.length > 0) getFileNamePaths(item.url, item.name)
|
||||
})
|
||||
})
|
||||
// getFileById({ id: props.id }).then(res => {
|
||||
// res.data.forEach((item: any) => {
|
||||
// if (item.url.length > 0) getFileNamePaths(item.url, item.name)
|
||||
// })
|
||||
// })
|
||||
}
|
||||
//判断userType选择取用的对象
|
||||
const getProviteData = async () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<TableHeader ref="TableHeaderRef">
|
||||
<TableHeader ref="TableHeaderRef" showExport showCustomColumn>
|
||||
<template #select>
|
||||
<el-form-item label="项目名称">
|
||||
<el-input
|
||||
@@ -32,20 +32,20 @@
|
||||
<el-button icon="el-icon-Upload" type="primary" @click="importUserData">批量导入</el-button> -->
|
||||
</template>
|
||||
</TableHeader>
|
||||
<Table ref="tableRef" />
|
||||
<Table ref="tableRef" @cell-click="cellClickEvent" />
|
||||
|
||||
<el-dialog title="详情" width="60%" v-model="dialogShow" v-if="dialogShow">
|
||||
<el-dialog title="详情" width="1000px" v-model="dialogShow" v-if="dialogShow">
|
||||
<DetailInfo :id="userId" :openType="'sourcesOfInterference'"></DetailInfo>
|
||||
</el-dialog>
|
||||
<!-- 批量导入 -->
|
||||
<sensitive-user-popup ref="sensitiveUserPopup" />
|
||||
<!-- 批量导入
|
||||
<sensitive-user-popup ref="sensitiveUserPopup" /> -->
|
||||
|
||||
<!-- 查看详情 detail 新增/修改 create-->
|
||||
<addForm ref="addForms" @onSubmit="tableStore.index()" :openType="'sourcesOfInterference'"></addForm>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, nextTick, watch } from 'vue'
|
||||
import { ref, onMounted, reactive, provide, nextTick, watch, onUnmounted } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
@@ -57,7 +57,8 @@ import { useRouter } from 'vue-router'
|
||||
import { downloadSensitiveReportTemplate } from '@/api/supervision-boot/userReport/form'
|
||||
import DetailInfo from './components/detail.vue'
|
||||
import { cancelFormData, getUserReportById } from '@/api/supervision-boot/interfere/index'
|
||||
import { deleteUserReport } from '@/api/supervision-boot/delete/index'
|
||||
import { deleteUserReport } from '@/api/device-boot/sensitiveLoadMange'
|
||||
import { download } from '@/utils/fileDownLoad'
|
||||
const addForms = ref()
|
||||
const dictData = useDictData()
|
||||
const sensitiveUserPopup = ref()
|
||||
@@ -73,7 +74,7 @@ defineOptions({
|
||||
//获取登陆用户姓名和部门
|
||||
const adminInfo = useAdminInfo()
|
||||
const tableStore = new TableStore({
|
||||
url: '/supervision-boot/userReport/getUserLedgerPage',
|
||||
url: '/device-boot/userReport/getUserLedgerPage',
|
||||
// publicHeight: 65,
|
||||
method: 'POST',
|
||||
column: [
|
||||
@@ -88,13 +89,13 @@ const tableStore = new TableStore({
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ field: 'city', title: '所在地市', minWidth: 80 },
|
||||
{ field: 'substation', title: '厂站名称', minWidth: 100 },
|
||||
{ field: 'projectName', title: '项目名称', minWidth: 170 },
|
||||
{ field: 'city', title: '所在地市', minWidth: 100 },
|
||||
/* { field: 'substation', title: '厂站名称', minWidth: 100 },*/
|
||||
{ field: 'projectName', title: '项目名称', minWidth: 150 },
|
||||
{
|
||||
field: 'userType',
|
||||
title: '用户性质',
|
||||
minWidth: 150,
|
||||
minWidth: 180,
|
||||
formatter: (obj: any) => {
|
||||
const userType = obj.row.userType
|
||||
return getUserTypeName(userType)
|
||||
@@ -102,19 +103,42 @@ const tableStore = new TableStore({
|
||||
},
|
||||
|
||||
// { field: 'responsibleDepartment', title: '归口管理部门', minWidth: 130 },
|
||||
{ field: 'ratePower', title: '装机容量(MW)', minWidth: 130 },
|
||||
{ field: 'ratePower', title: '装机容量(MW)', minWidth: 80 },
|
||||
{ field: 'stationId', title: '所属电站', minWidth: 150 },
|
||||
{
|
||||
field: 'checkUrl',
|
||||
title: '电能质量设备检测报告',
|
||||
minWidth: 160,
|
||||
render: 'customRender',
|
||||
customRender: props => {
|
||||
const val = props.renderValue?.replace(/^.*?\/(.*?)\//, '') || ''
|
||||
return val ? h('span', { style: { color: 'var(--el-color-primary)', cursor: 'pointer' } }, val) : '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'assessUrl',
|
||||
title: '电能质量评估报告',
|
||||
minWidth: 160,
|
||||
render: 'customRender',
|
||||
customRender: props => {
|
||||
const val = props.renderValue?.replace(/^.*?\/(.*?)\//, '') || ''
|
||||
return val ? h('span', { style: { color: 'var(--el-color-primary)', cursor: 'pointer' } }, val) : '/'
|
||||
}
|
||||
},
|
||||
|
||||
/* {
|
||||
field: 'createBy',
|
||||
title: '创建人',
|
||||
minWidth: 80,
|
||||
formatter: (row: any) => {
|
||||
return dictData.state.userList.filter(item => item.id == row.cellValue)[0]?.name
|
||||
}
|
||||
},
|
||||
},*/
|
||||
{
|
||||
title: '操作',fixed: 'right',
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
minWidth: 150,
|
||||
|
||||
|
||||
render: 'buttons',
|
||||
buttons: [
|
||||
{
|
||||
@@ -137,7 +161,6 @@ const tableStore = new TableStore({
|
||||
disabled: row => {
|
||||
return !(row.status == 0)
|
||||
},
|
||||
|
||||
|
||||
click: row => {
|
||||
addForms.value.filterUsers([6])
|
||||
@@ -147,9 +170,7 @@ const tableStore = new TableStore({
|
||||
row: row
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -208,27 +229,13 @@ const deleteEven = () => {
|
||||
})
|
||||
}
|
||||
}
|
||||
/**取消流程操作*/
|
||||
const cancelLeave = async (row: any) => {
|
||||
// 二次确认
|
||||
const { value } = await ElMessageBox.prompt('请输入取消原因', '取消流程', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
inputType: 'textarea',
|
||||
inputPattern: /^[\s\S]*.*\S[\s\S]*$/, // 判断非空,且非空格
|
||||
inputErrorMessage: '取消原因不能为空'
|
||||
})
|
||||
// 发起取消
|
||||
let data = {
|
||||
id: row.id,
|
||||
processInstanceId: row.processInstanceId,
|
||||
dataType: 1,
|
||||
reason: value
|
||||
// 点击行
|
||||
const cellClickEvent = ({ row, column }: any) => {
|
||||
if (column.field == 'checkUrl') {
|
||||
row.checkUrl ? download(row.checkUrl) : ''
|
||||
} else if (column.field == 'assessUrl') {
|
||||
row.assessUrl ? download(row.assessUrl) : ''
|
||||
}
|
||||
await cancelFormData(data)
|
||||
ElMessage.success('取消成功')
|
||||
// 加载数据
|
||||
tableStore.index()
|
||||
}
|
||||
|
||||
// 新增
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<TableHeader date-picker>
|
||||
<TableHeader date-picker showCustomColumn>
|
||||
<template v-slot:select>
|
||||
<!-- <el-form-item label="用户名">
|
||||
<el-select v-model="value" class="m-2" placeholder="Select" size="large">
|
||||
@@ -33,14 +33,22 @@ const tableStore = new TableStore({
|
||||
url: '/system-boot/audit/getAuditLog',
|
||||
method: 'POST',
|
||||
column: [
|
||||
{ title: '操作时间', field: 'time', align: 'center', width: 200 },
|
||||
{ title: '操作人员', field: 'userName', align: 'center', width: 120 },
|
||||
{ title: '操作类型', field: 'operate', align: 'center', width: 220 },
|
||||
{ title: '事件描述', field: 'describe', align: 'center', showOverflow: true,minWidth: 200 },
|
||||
{ title: '事件类型', field: 'type', align: 'center', width: 160 },
|
||||
{ title: '操作结果', field: 'type', align: 'center', width: 100 },
|
||||
{ title: '操作IP', field: 'ip', align: 'center', width: 120 },
|
||||
{ title: '事件等级', field: 'level', align: 'center', width: 100 }
|
||||
{
|
||||
title: '序号',
|
||||
field: 'index',
|
||||
minWidth: 80,
|
||||
formatter: (row: any) => {
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '操作时间', field: 'time', align: 'center', minWidth: 200 },
|
||||
{ title: '操作人员', field: 'userName', align: 'center', minWidth: 120 },
|
||||
{ title: '操作类型', field: 'operate', align: 'center', minWidth: 220 },
|
||||
{ title: '事件描述', field: 'describe', align: 'center', minWidth: 200 },
|
||||
{ title: '事件类型', field: 'type', align: 'center', minWidth: 160 },
|
||||
{ title: '操作结果', field: 'type', align: 'center', minWidth: 100 },
|
||||
{ title: '操作IP', field: 'ip', align: 'center', minWidth: 120 },
|
||||
{ title: '事件等级', field: 'level', align: 'center', minWidth: 100 }
|
||||
]
|
||||
})
|
||||
tableStore.table.params.loginName = ''
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</div>
|
||||
<el-collapse v-model="activeName" accordion>
|
||||
<!-- <el-collapse-item title="典型电能质量干扰源" name="1"></el-collapse-item> -->
|
||||
<el-collapse-item title="国家电网有限公司企业标准" name="2">
|
||||
<el-collapse-item title="电网有限公司企业标准" name="2">
|
||||
<!-- <el-empty description="暂无数据" class="custom-empty iframe" /> -->
|
||||
<div :style="`overflow: auto;`" class="iframe">
|
||||
<vue-office-docx v-if="urlKey.includes('.doc') || urlKey.includes('.docx')" :src="url" />
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<!-- 案例库 -->
|
||||
<TableHeader ref="TableHeaderRef">
|
||||
<template #select>
|
||||
<el-form-item label="名称">
|
||||
<el-form-item label="筛选数据">
|
||||
<el-input v-model="tableStore.table.params.searchValue" clearable placeholder="请输入搜索名称" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
@@ -2,32 +2,39 @@
|
||||
<div class="default-main" :style="height">
|
||||
<!-- 标准库 -->
|
||||
|
||||
<splitpanes style="height: 100%" class="default-theme" id="navigation-splitpanes">
|
||||
<splitpanes
|
||||
style="height: 100%"
|
||||
class="default-theme"
|
||||
id="navigation-splitpanes"
|
||||
@resize="onPaneResize"
|
||||
@resized="onPaneResized"
|
||||
>
|
||||
<pane :size="size">
|
||||
<standardTree ref="treeRef"
|
||||
:default-expanded-keys="monitoringPoint.state.lineId ? [monitoringPoint.state.lineId] : []"
|
||||
:current-node-key="monitoringPoint.state.lineId" @node-click="handleNodeClick"
|
||||
@init="handleNodeClick"></standardTree>
|
||||
</pane>
|
||||
<pane style="background: #fff" :style="height">
|
||||
<div class="pd10" style="display: flex; justify-content: end">
|
||||
<pane style="background: #fff" class="standard-pane">
|
||||
<div class="pd10 standard-pane__toolbar" style="display: flex; justify-content: end">
|
||||
<el-button icon="el-icon-Plus" type="primary" @click="addUser" v-if="information">新增</el-button>
|
||||
<el-button icon="el-icon-Edit" type="primary" @click="editUser" v-if="information">修改</el-button>
|
||||
<el-button icon="el-icon-Delete" type="primary" @click="deleteEven"
|
||||
v-if="information">删除</el-button>
|
||||
<el-button icon="el-icon-Download" type="primary" @click="download" v-if="flag">下载</el-button>
|
||||
</div>
|
||||
<el-empty v-if="url.length == 0" description="暂无数据" class="custom-empty"
|
||||
:style="`height: calc(${height.height} - 60px);`" />
|
||||
<div :style="`height: calc(${height.height} - 60px);overflow: auto;`" v-else>
|
||||
<vue-office-docx v-if="urlKey.includes('.doc') || urlKey.includes('.docx')" :src="url" />
|
||||
<vue-office-excel v-if="urlKey.includes('.xls') || urlKey.includes('.xlsx')" :src="url"
|
||||
:options="excelOptions" />
|
||||
<!-- <vue-office-pdf v-if="url.includes('.pdf')" :src="url"/> -->
|
||||
<iframe v-if="urlKey.includes('.pdf')" :src="url" style="width: 100%; height: 99%"></iframe>
|
||||
<img v-if="
|
||||
urlKey.includes('.png') || urlKey.includes('.jpg') || urlKey.includes('.gif') || urlKey.includes('.bmp')
|
||||
" :src="url" />
|
||||
<el-empty v-if="url.length == 0" description="暂无数据" class="custom-empty standard-pane__content" />
|
||||
<div v-else class="standard-pane__content">
|
||||
<div v-show="!isPaneResizing" class="standard-preview">
|
||||
<vue-office-docx v-if="urlKey.includes('.doc') || urlKey.includes('.docx')" :src="url" />
|
||||
<vue-office-excel v-if="urlKey.includes('.xls') || urlKey.includes('.xlsx')" :src="url"
|
||||
:options="excelOptions" />
|
||||
<!-- <vue-office-pdf v-if="url.includes('.pdf')" :src="url"/> -->
|
||||
<iframe v-if="urlKey.includes('.pdf')" :src="url" style="width: 100%; height: 100%"></iframe>
|
||||
<img v-if="
|
||||
urlKey.includes('.png') || urlKey.includes('.jpg') || urlKey.includes('.gif') || urlKey.includes('.bmp')
|
||||
" :src="url" />
|
||||
</div>
|
||||
</div>
|
||||
</pane>
|
||||
</splitpanes>
|
||||
@@ -70,7 +77,16 @@ const addTreeRef = ref()
|
||||
const url = ref('')
|
||||
const dotList: any = ref({})
|
||||
const flag: any = ref(false)
|
||||
const isPaneResizing = ref(false)
|
||||
const information = adminInfo.roleCode.includes('information_info')
|
||||
const onPaneResize = () => {
|
||||
isPaneResizing.value = true
|
||||
}
|
||||
const onPaneResized = () => {
|
||||
requestAnimationFrame(() => {
|
||||
isPaneResizing.value = false
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
const dom = document.getElementById('navigation-splitpanes')
|
||||
if (dom) {
|
||||
@@ -79,7 +95,7 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
const urlKey=ref('')
|
||||
const VITE_FLAG = import.meta.env.VITE_NAME == 'jibei'
|
||||
const VITE_FLAG = false//import.meta.env.VITE_NAME == 'jibei'
|
||||
const handleNodeClick = (data: any, node: any) => {
|
||||
// console.log("🚀 ~ handleNodeClick ~ data:", data)
|
||||
dotList.value = data
|
||||
@@ -166,6 +182,36 @@ const download = () => {
|
||||
background: #eaeef1;
|
||||
}
|
||||
|
||||
:deep(.splitpanes__pane) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.standard-pane {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.standard-pane__toolbar {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.standard-pane__content {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.standard-preview {
|
||||
height: 99%;
|
||||
min-height: 99%;
|
||||
}
|
||||
|
||||
:deep(.splitpanes--dragging) .standard-preview {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.grid-content {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<!-- 模版 -->
|
||||
<TableHeader ref="TableHeaderRef" >
|
||||
<template #select>
|
||||
<el-form-item label="名称">
|
||||
<el-form-item label="筛选数据">
|
||||
<el-input v-model="tableStore.table.params.searchValue" clearable
|
||||
placeholder="请输入搜索名称" maxlength="32" show-word-limit/>
|
||||
</el-form-item>
|
||||
|
||||
@@ -1,274 +1,289 @@
|
||||
<template>
|
||||
<div class="default-main online">
|
||||
<div class="online_header">
|
||||
<TableHeader date-picker area ref="tableHeaderRef">
|
||||
<template #select>
|
||||
<el-form-item label="统计类型:">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.statisticalType"
|
||||
placeholder="请选择统计类型"
|
||||
value-key="id"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in classificationData"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="电压等级:">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.scale"
|
||||
multiple
|
||||
collapse-tags
|
||||
clearable
|
||||
placeholder="请选择电压等级"
|
||||
style="width: 100%"
|
||||
value-key="id"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in voltageleveloption"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="电网标识">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.powerFlag"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
placeholder="请选择电网标识"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in powerFlagList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.algoDescribe"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="终端厂家:">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.manufacturer"
|
||||
multiple
|
||||
collapse-tags
|
||||
clearable
|
||||
placeholder="请选择终端厂家"
|
||||
style="width: 100%"
|
||||
value-key="id"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, index) in terminaloption"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:value="item"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="干扰源类型:">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.loadType"
|
||||
multiple
|
||||
collapse-tags
|
||||
clearable
|
||||
placeholder="请选择干扰源类型"
|
||||
style="width: 100%"
|
||||
value-key="id"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, index) in interfereoption"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:value="item"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</TableHeader>
|
||||
</div>
|
||||
<div class="online_main">
|
||||
<el-tabs v-model="activeName" type="border-card" @tab-click="handleClick">
|
||||
<el-tab-pane :name="0" :lazy="true" label="稳态指标符合性占比表格">
|
||||
<Table
|
||||
ref="tableRef"
|
||||
:tree-config="{ transform: true, parentField: 'uPid', rowField: 'uId' }"
|
||||
:scroll-y="{ enabled: true }"
|
||||
v-if="activeName == 0"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :name="1" :lazy="true" label="稳态指标符合性占比图">
|
||||
<charts v-if="activeName == 1" ref="chartsRef" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import { getAreaDept } from '@/api/harmonic-boot/area'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import charts from './components/charts.vue'
|
||||
defineOptions({
|
||||
name: 'harmonic-boot/area/SteadyState'
|
||||
})
|
||||
const tableRef = ref()
|
||||
const onlineChartsRef = ref()
|
||||
const dictData = useDictData()
|
||||
//字典获取电压等级
|
||||
const voltageleveloption = dictData.getBasicData('Dev_Voltage_Stand')
|
||||
//字典获取终端厂家
|
||||
const terminaloption = dictData.getBasicData('Dev_Manufacturers')
|
||||
//字典获取干扰源类型
|
||||
const interfereoption = dictData.getBasicData('Interference_Source')
|
||||
//字典获取统计类型
|
||||
const classificationData = dictData.getBasicData('Statistical_Type', ['Report_Type'])
|
||||
//字典获取监督对象类型
|
||||
const powerFlagList = dictData.getBasicData('power_flag')
|
||||
//调用区域接口获取区域
|
||||
const treeData = ref([])
|
||||
const idArr = ref([])
|
||||
const activeName = ref(0)
|
||||
const getTreeData = async () => {
|
||||
await getAreaDept().then(res => {
|
||||
var data = res.data
|
||||
data.forEach(element => {
|
||||
idArr.value.push(element.id)
|
||||
})
|
||||
treeData.value = JSON.parse(JSON.stringify(res.data))
|
||||
})
|
||||
}
|
||||
getTreeData()
|
||||
|
||||
const chartsRef = ref()
|
||||
const handleClick = (tab: any, e: any) => {
|
||||
// console.log(tab,e,"??????????");
|
||||
// if(activeName.value===1){
|
||||
tableStore.index()
|
||||
// }
|
||||
}
|
||||
|
||||
// const datePickerRef = ref()
|
||||
const tableHeaderRef = ref()
|
||||
const tableStore = new TableStore({
|
||||
publicHeight: 60,
|
||||
showPage: false,
|
||||
url: '/harmonic-boot/steadyExceedRate/getSteadyExceedRateData',
|
||||
method: 'POST',
|
||||
column: [
|
||||
{
|
||||
title: '',
|
||||
field: 'name',
|
||||
align: 'left',
|
||||
treeNode: true,
|
||||
width: 350
|
||||
},
|
||||
{
|
||||
title: '电压等级',
|
||||
field: 'voltageLevel',
|
||||
|
||||
formatter: function (row) {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '厂家',
|
||||
field: 'factoryName',
|
||||
|
||||
formatter: function (row) {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '网络参数',
|
||||
field: 'networkParam',
|
||||
|
||||
formatter: function (row) {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '监测点名称',
|
||||
field: 'lineName',
|
||||
|
||||
formatter: function (row) {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '符合性占比(%)',
|
||||
field: 'steadyExceedRate',
|
||||
|
||||
formatter: function (row) {
|
||||
return row.cellValue == 3.14159 ? '暂无数据' : row.cellValue
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
loadCallback: () => {
|
||||
tableStore.table.data = tree2List(tableStore.table.data, Math.random() * 1000)
|
||||
tableStore.table.column[0].title = tableStore.table.params.statisticalType.name
|
||||
|
||||
chartsRef.value && chartsRef.value.getTableStoreParams(tableStore.table.params)
|
||||
setTimeout(() => {
|
||||
activeName.value == 0 && tableRef.value && tableRef.value.getRef().setAllTreeExpand(true)
|
||||
}, 0)
|
||||
}
|
||||
})
|
||||
|
||||
tableStore.table.params.statisticalType = classificationData[0]
|
||||
tableStore.table.params.scale = []
|
||||
tableStore.table.params.manufacturer = []
|
||||
tableStore.table.params.loadType = []
|
||||
tableStore.table.params.powerFlag = 2
|
||||
tableStore.table.params.serverName = 'harmonicBoot'
|
||||
provide('tableStore', tableStore)
|
||||
const tree2List = (list: any, id?: string) => {
|
||||
//存储结果的数组
|
||||
let arr: any = []
|
||||
// 遍历 tree 数组
|
||||
list.forEach((item: any) => {
|
||||
item.uPid = id
|
||||
item.uId = Math.random() * 1000
|
||||
item.valueOver == 3.14159 ? 0 : item.valueOver >= 90 ? 1 : item.valueOver && item.valueOver < 90 ? 2 : 3
|
||||
// 判断item是否存在children
|
||||
if (!item.children) return arr.push(item)
|
||||
// 函数递归,对children数组进行tree2List的转换
|
||||
const children = tree2List(item.children, item.uId)
|
||||
// 删除item的children属性
|
||||
delete item.children
|
||||
// 把item和children数组添加至结果数组
|
||||
//..children: 意思是把children数组展开
|
||||
arr.push(item, ...children)
|
||||
})
|
||||
// 返回结果数组
|
||||
return arr
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// .online {
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// .online_header {
|
||||
// width: 100%;
|
||||
// max-height: 140px;
|
||||
// padding: 10px;
|
||||
// box-sizing: border-box;
|
||||
// }
|
||||
// .online_main {
|
||||
// padding: 0 10px;
|
||||
// }
|
||||
// }
|
||||
</style>
|
||||
<template>
|
||||
<div class="default-main online">
|
||||
<div class="online_header">
|
||||
<TableHeader date-picker area ref="tableHeaderRef">
|
||||
<template #select>
|
||||
<el-form-item label="统计类型">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.statisticalType"
|
||||
placeholder="请选择统计类型"
|
||||
value-key="id"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in classificationData"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="电压等级">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.scale"
|
||||
multiple
|
||||
collapse-tags
|
||||
clearable
|
||||
placeholder="请选择电压等级"
|
||||
style="width: 100%"
|
||||
value-key="id"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in voltageleveloption"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="电网标识">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.powerFlag"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
placeholder="请选择电网标识"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in powerFlagList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.algoDescribe"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="终端厂家">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.manufacturer"
|
||||
multiple
|
||||
collapse-tags
|
||||
clearable
|
||||
placeholder="请选择终端厂家"
|
||||
style="width: 100%"
|
||||
value-key="id"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, index) in terminaloption"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:value="item"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="干扰源类型:">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.loadType"
|
||||
multiple
|
||||
collapse-tags
|
||||
clearable
|
||||
placeholder="请选择干扰源类型"
|
||||
style="width: 100%"
|
||||
value-key="id"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, index) in interfereoption"
|
||||
:key="index"
|
||||
:label="item.name"
|
||||
:value="item"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="筛选数据">
|
||||
<el-input
|
||||
v-model.trim="tableStore.table.params.searchValue"
|
||||
clearable
|
||||
style="width: 200px"
|
||||
placeholder="请输入关键字筛选"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</TableHeader>
|
||||
</div>
|
||||
<div class="online_main">
|
||||
<el-tabs v-model="activeName" type="border-card" @tab-click="handleClick">
|
||||
<el-tab-pane :name="0" :lazy="true" label="稳态指标符合性占比表格">
|
||||
<Table
|
||||
ref="tableRef"
|
||||
:tree-config="{ transform: true, parentField: 'uPid', rowField: 'uId' }"
|
||||
:scroll-y="{ enabled: true }"
|
||||
v-if="activeName == 0"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :name="1" :lazy="true" label="稳态指标符合性占比图">
|
||||
<charts v-if="activeName == 1" ref="chartsRef" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import DatePicker from '@/components/form/datePicker/index.vue'
|
||||
import { getAreaDept } from '@/api/harmonic-boot/area'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import charts from './components/charts.vue'
|
||||
import { filterTree } from '@/utils/tree'
|
||||
defineOptions({
|
||||
name: 'harmonic-boot/area/SteadyState'
|
||||
})
|
||||
const tableRef = ref()
|
||||
const onlineChartsRef = ref()
|
||||
const dictData = useDictData()
|
||||
//字典获取电压等级
|
||||
const voltageleveloption = dictData.getBasicData('Dev_Voltage_Stand')
|
||||
//字典获取终端厂家
|
||||
const terminaloption = dictData.getBasicData('Dev_Manufacturers')
|
||||
//字典获取干扰源类型
|
||||
const interfereoption = dictData.getBasicData('Interference_Source')
|
||||
//字典获取统计类型
|
||||
const classificationData = dictData.getBasicData('Statistical_Type', ['Report_Type'])
|
||||
//字典获取监督对象类型
|
||||
const powerFlagList = dictData.getBasicData('power_flag')
|
||||
//调用区域接口获取区域
|
||||
const treeData = ref([])
|
||||
const idArr = ref([])
|
||||
const activeName = ref(0)
|
||||
const getTreeData = async () => {
|
||||
await getAreaDept().then(res => {
|
||||
var data = res.data
|
||||
data.forEach(element => {
|
||||
idArr.value.push(element.id)
|
||||
})
|
||||
treeData.value = JSON.parse(JSON.stringify(res.data))
|
||||
})
|
||||
}
|
||||
getTreeData()
|
||||
|
||||
const chartsRef = ref()
|
||||
const handleClick = (tab: any, e: any) => {
|
||||
// console.log(tab,e,"??????????");
|
||||
// if(activeName.value===1){
|
||||
tableStore.index()
|
||||
// }
|
||||
}
|
||||
|
||||
// const datePickerRef = ref()
|
||||
const tableHeaderRef = ref()
|
||||
const tableStore = new TableStore({
|
||||
publicHeight: 60,
|
||||
showPage: false,
|
||||
url: '/harmonic-boot/steadyExceedRate/getSteadyExceedRateData',
|
||||
method: 'POST',
|
||||
column: [
|
||||
{
|
||||
title: '',
|
||||
field: 'name',
|
||||
align: 'left',
|
||||
treeNode: true,
|
||||
width: 350
|
||||
},
|
||||
{
|
||||
title: '电压等级',
|
||||
field: 'voltageLevel',
|
||||
|
||||
formatter: function (row) {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '厂家',
|
||||
field: 'factoryName',
|
||||
|
||||
formatter: function (row) {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '网络参数',
|
||||
field: 'networkParam',
|
||||
|
||||
formatter: function (row) {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '监测点名称',
|
||||
field: 'lineName',
|
||||
|
||||
formatter: function (row) {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '符合性占比(%)',
|
||||
field: 'steadyExceedRate',
|
||||
|
||||
formatter: function (row) {
|
||||
return row.cellValue == 3.14159 ? '暂无数据' : row.cellValue
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
loadCallback: () => {
|
||||
tableStore.table.data = tree2List(
|
||||
filterTree(tableStore.table.data, node => {
|
||||
return node.name.includes(tableStore.table.params.searchValue)
|
||||
}),
|
||||
Math.random() * 1000
|
||||
)
|
||||
tableStore.table.column[0].title = tableStore.table.params.statisticalType.name
|
||||
|
||||
chartsRef.value && chartsRef.value.getTableStoreParams(tableStore.table.params)
|
||||
setTimeout(() => {
|
||||
activeName.value == 0 && tableRef.value && tableRef.value.getRef().setAllTreeExpand(true)
|
||||
}, 0)
|
||||
}
|
||||
})
|
||||
|
||||
tableStore.table.params.statisticalType = classificationData[0]
|
||||
tableStore.table.params.scale = []
|
||||
tableStore.table.params.manufacturer = []
|
||||
tableStore.table.params.loadType = []
|
||||
tableStore.table.params.powerFlag = 2
|
||||
tableStore.table.params.serverName = 'harmonicBoot'
|
||||
tableStore.table.params.searchValue = ''
|
||||
provide('tableStore', tableStore)
|
||||
const tree2List = (list: any, id?: string) => {
|
||||
//存储结果的数组
|
||||
let arr: any = []
|
||||
// 遍历 tree 数组
|
||||
list.forEach((item: any) => {
|
||||
item.uPid = id
|
||||
item.uId = Math.random() * 1000
|
||||
item.valueOver == 3.14159 ? 0 : item.valueOver >= 90 ? 1 : item.valueOver && item.valueOver < 90 ? 2 : 3
|
||||
// 判断item是否存在children
|
||||
if (!item.children) return arr.push(item)
|
||||
// 函数递归,对children数组进行tree2List的转换
|
||||
const children = tree2List(item.children, item.uId)
|
||||
// 删除item的children属性
|
||||
delete item.children
|
||||
// 把item和children数组添加至结果数组
|
||||
//..children: 意思是把children数组展开
|
||||
arr.push(item, ...children)
|
||||
})
|
||||
// 返回结果数组
|
||||
return arr
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// .online {
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// .online_header {
|
||||
// width: 100%;
|
||||
// max-height: 140px;
|
||||
// padding: 10px;
|
||||
// box-sizing: border-box;
|
||||
// }
|
||||
// .online_main {
|
||||
// padding: 0 10px;
|
||||
// }
|
||||
// }
|
||||
</style>
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
<template>
|
||||
<div class="default-main">
|
||||
<div v-show="view">
|
||||
<TableHeader datePicker area showExport>
|
||||
<TableHeader datePicker area showExport showCustomColumn>
|
||||
<template #select>
|
||||
<el-form-item label="筛选数据">
|
||||
<el-input v-model="tableStore.table.params.searchValue" placeholder="输入关键字筛选" clearable maxlength="32" show-word-limit/>
|
||||
<el-input
|
||||
v-model="tableStore.table.params.searchValue"
|
||||
placeholder="输入关键字筛选"
|
||||
clearable
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="统计类型:">
|
||||
<el-form-item label="统计类型">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.statisticalType"
|
||||
value-key="id"
|
||||
@@ -21,7 +27,7 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="电压等级:">
|
||||
<el-form-item label="电压等级">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.scale"
|
||||
multiple
|
||||
@@ -38,7 +44,7 @@
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="终端厂家:">
|
||||
<el-form-item label="终端厂家">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.manufacturer"
|
||||
multiple
|
||||
@@ -55,7 +61,7 @@
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="干扰源类型:">
|
||||
<el-form-item label="干扰源类型">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.loadType"
|
||||
multiple
|
||||
@@ -127,19 +133,11 @@ const tableStore = new TableStore({
|
||||
{ field: 'lineName', title: '监测点名称', minWidth: '180' },
|
||||
{ field: 'gdName', title: '供电公司', minWidth: '120' },
|
||||
{ field: 'subName', title: '变电站', minWidth: '150' },
|
||||
{ field: 'ip', title: '网络参数' ,width:'120px' },
|
||||
{ field: 'ip', title: '网络参数', width: '120px' },
|
||||
{ field: 'scale', title: '电压等级', minWidth: '110' },
|
||||
// {
|
||||
// field: 'advanceType',
|
||||
// title: '触发类型',
|
||||
// minWidth: '90',
|
||||
// formatter: (row: any) => {
|
||||
// return row.cellValue || '其他'
|
||||
// }
|
||||
// },
|
||||
{
|
||||
field: 'advanceReason',
|
||||
title: '暂降原因',
|
||||
field: 'advanceType',
|
||||
title: '暂降类型',
|
||||
minWidth: '90',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '其他'
|
||||
@@ -153,6 +151,15 @@ const tableStore = new TableStore({
|
||||
return eventList.filter(item => item.id === row.cellValue)[0]?.name
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'advanceReason',
|
||||
title: '暂降原因',
|
||||
minWidth: '90',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '其他'
|
||||
}
|
||||
},
|
||||
|
||||
// {
|
||||
// field: 'severity', title: '严重度', minWidth: "80", formatter: (row: any) => {
|
||||
// return row.cellValue.toFixed(2)
|
||||
@@ -179,7 +186,8 @@ const tableStore = new TableStore({
|
||||
{ field: 'duration', title: '持续时间(s)', minWidth: '100' },
|
||||
|
||||
{
|
||||
title: '操作',fixed: 'right',
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
width: '120',
|
||||
render: 'buttons',
|
||||
buttons: [
|
||||
@@ -277,6 +285,7 @@ const download = () => {
|
||||
document.body.appendChild(link)
|
||||
link.click() //执行下载
|
||||
document.body.removeChild(link) //释放标签
|
||||
ElMessage.success('波形下载成功')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<template>
|
||||
<div class="default-main online">
|
||||
|
||||
<div class="online_header">
|
||||
<TableHeader date-picker ref="tableHeaderRef">
|
||||
<TableHeader date-picker ref="tableHeaderRef" showCustomColumn>
|
||||
<template #select>
|
||||
<el-form-item label="统计类型:">
|
||||
<el-form-item label="统计类型">
|
||||
<el-select v-model="formData.statisticalType" placeholder="请选择统计类型" value-key="id"
|
||||
style="width: 100%">
|
||||
<el-option v-for="item in classificationData" :key="item.id" :label="item.name"
|
||||
:value="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="区域选择:">
|
||||
<el-form-item label="区域选择">
|
||||
<!-- <el-select ref="select1" v-model="deptName" placeholder="请选择所属部门区域" style="width: 100%">
|
||||
<el-option :value="formData.deptIndex" style="height: auto"> -->
|
||||
<!-- {{ formData.deptIndex }} -->
|
||||
@@ -33,27 +34,39 @@
|
||||
<!-- </el-option>
|
||||
</el-select> -->
|
||||
</el-form-item>
|
||||
<el-form-item label="电压等级:">
|
||||
<el-form-item label="电压等级">
|
||||
<el-select v-model="formData.scale" multiple collapse-tags clearable placeholder="请选择电压等级"
|
||||
style="width: 100%" value-key="id">
|
||||
<el-option v-for="item in voltageleveloption" :key="item.id" :label="item.name"
|
||||
:value="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="终端厂家:">
|
||||
<el-form-item label="终端厂家">
|
||||
<el-select v-model="formData.manufacturer" multiple collapse-tags clearable
|
||||
placeholder="请选择终端厂家" style="width: 100%" value-key="id">
|
||||
<el-option v-for="(item, index) in terminaloption" :key="index" :label="item.name"
|
||||
:value="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="干扰源类型:">
|
||||
<el-form-item label="干扰源类型">
|
||||
<el-select v-model="formData.loadType" multiple collapse-tags clearable placeholder="请选择干扰源类型"
|
||||
style="width: 100%" value-key="id">
|
||||
<el-option v-for="(item, index) in interfereoption" :key="index" :label="item.name"
|
||||
:value="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="通讯状态">
|
||||
<el-select v-model="tableStore.table.params.comFlagStatus" clearable placeholder="请选择通讯状态"
|
||||
style="width: 100%">
|
||||
<el-option label="正常" value="1" />
|
||||
<el-option label="中断" value="0" />
|
||||
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="筛选数据">
|
||||
<el-input v-model="tableStore.table.params.searchValue" clearable
|
||||
placeholder="请输入关键字"></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template #operation>
|
||||
<el-button type="primary" icon="el-icon-Tickets" @click="makeUp" v-if="!VITE_FLAG">补招</el-button>
|
||||
@@ -74,9 +87,10 @@
|
||||
</div>
|
||||
<el-dialog v-model="timePopUp" draggable title="补招" width="500">
|
||||
补招时间:
|
||||
<el-date-picker v-model="timeData" type="datetimerange" format="YYYY-MM-DD HH:mm:00"
|
||||
value-format="YYYY-MM-DD HH:mm:00" range-separator="至" date-format="YYYY-MM-DD" time-format="HH:mm:00"
|
||||
start-placeholder="开始日期" end-placeholder="结束日期" style="width: 400px" :disabledDate="disabledDate" />
|
||||
<el-date-picker v-model="timeData" type="datetimerange" format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss" range-separator="至" date-format="YYYY-MM-DD" time-format="HH:mm:ss"
|
||||
start-placeholder="开始日期" end-placeholder="结束日期" style="width: 400px" :disabledDate="disabledDate"
|
||||
:default-time="defaultTimeRange" />
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="timePopUp = false">取消</el-button>
|
||||
@@ -136,6 +150,10 @@ const classificationData = dictData.getBasicData('Statistical_Type', ['Report_Ty
|
||||
const treeData = ref([])
|
||||
const idArr = ref([])
|
||||
const timeData = ref([])
|
||||
const defaultTimeRange: [Date, Date] = [
|
||||
new Date(2000, 0, 1, 0, 0, 0),
|
||||
new Date(2000, 0, 1, 23, 59, 59)
|
||||
]
|
||||
const logList: any = ref([])
|
||||
const activeName = ref(0)
|
||||
const getTreeData = async () => {
|
||||
@@ -195,7 +213,7 @@ const tableStore = new TableStore({
|
||||
{
|
||||
title: '网络参数',
|
||||
field: 'ip',
|
||||
align: 'center',width:'120px',
|
||||
align: 'center', width: '120px',
|
||||
formatter: function (row) {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
@@ -285,7 +303,7 @@ const tableStore = new TableStore({
|
||||
// tableStore.table.params.searchEndTime = tableHeaderRef.value.datePickerRef.timeValue[1]
|
||||
},
|
||||
loadCallback: () => {
|
||||
tableStore.table.data = tree2List(tableStore.table.data, Math.random() * 1000)
|
||||
tableStore.table.data = tree2List(filterTreeByKeyword(tableStore.table.data, tableStore.table.params.searchValue), Math.random() * 1000)
|
||||
tableStore.table.column[0].title = formData.value.statisticalType.name
|
||||
|
||||
chartsRef.value && chartsRef.value.getTableStoreParams(tableStore.table.params)
|
||||
@@ -305,10 +323,12 @@ const tableStore = new TableStore({
|
||||
|
||||
tableStore.table.params.deptIndex = ''
|
||||
tableStore.table.params.filterName = ''
|
||||
tableStore.table.params.searchValue = ''
|
||||
tableStore.table.params.statisticalType = []
|
||||
tableStore.table.params.scale = []
|
||||
tableStore.table.params.manufacturer = []
|
||||
tableStore.table.params.loadType = []
|
||||
tableStore.table.params.comFlagStatus = ''
|
||||
provide('tableStore', tableStore)
|
||||
const tree2List = (list: any, id?: string) => {
|
||||
//存储结果的数组
|
||||
@@ -339,6 +359,78 @@ const tree2List = (list: any, id?: string) => {
|
||||
return arr
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 树形结构按名称筛选:保留匹配节点+所有上级+所有下级,保持原树形层级
|
||||
* @param {Array} treeData - 原始嵌套树形数据(根节点数组)
|
||||
* @param {string} keyword - 筛选关键词(name包含该关键词即匹配)
|
||||
* @returns {Array} 筛选后的嵌套树形数据,保持原层级
|
||||
*/
|
||||
function filterTreeByKeyword(treeData, keyword) {
|
||||
// 关键词为空,直接返回原树(深拷贝,避免修改原数据)
|
||||
if (!keyword || keyword.trim() === '') {
|
||||
return JSON.parse(JSON.stringify(treeData));
|
||||
}
|
||||
const targetKey = keyword.trim();
|
||||
// 存储需要保留的节点ID(匹配节点+所有上级+所有下级)
|
||||
const keepIdSet = new Set();
|
||||
|
||||
// 第一步:递归遍历树形,标记所有需要保留的节点ID
|
||||
const markKeepNodes = (node, parentNodes = []) => {
|
||||
// 1. 若当前节点名称包含关键词,标记自身+所有上级+所有下级
|
||||
const isMatch = node.name && node.name.includes(targetKey);
|
||||
if (isMatch) {
|
||||
// 标记自身
|
||||
keepIdSet.add(node.id);
|
||||
// 标记所有上级父节点
|
||||
parentNodes.forEach(pNode => keepIdSet.add(pNode.id));
|
||||
// 标记所有下级子节点(递归)
|
||||
const markChildren = (childNode) => {
|
||||
keepIdSet.add(childNode.id);
|
||||
if (childNode.children && childNode.children.length) {
|
||||
childNode.children.forEach(markChildren);
|
||||
}
|
||||
};
|
||||
if (node.children && node.children.length) {
|
||||
node.children.forEach(markChildren);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 递归遍历子节点,传递当前节点的上级链(parentNodes + 当前节点)
|
||||
if (node.children && node.children.length) {
|
||||
node.children.forEach(child => markKeepNodes(child, [...parentNodes, node]));
|
||||
}
|
||||
};
|
||||
|
||||
// 遍历根节点,开始标记
|
||||
treeData.forEach(rootNode => markKeepNodes(rootNode));
|
||||
|
||||
// 第二步:递归重构树形,只保留标记过的节点,保持层级
|
||||
const rebuildTree = (node) => {
|
||||
// 若当前节点无需保留,直接返回null
|
||||
if (!keepIdSet.has(node.id)) {
|
||||
return null;
|
||||
}
|
||||
// 深拷贝当前节点,避免修改原数据
|
||||
const newNode = { ...node };
|
||||
// 递归处理子节点,过滤掉无需保留的,只保留有效子节点
|
||||
if (newNode.children && newNode.children.length) {
|
||||
const newChildren = newNode.children.map(child => rebuildTree(child)).filter(Boolean);
|
||||
newNode.children = newChildren;
|
||||
} else {
|
||||
newNode.children = [];
|
||||
}
|
||||
return newNode;
|
||||
};
|
||||
|
||||
// 重构根节点,过滤掉null的根节点
|
||||
const filteredTree = treeData.map(rootNode => rebuildTree(rootNode)).filter(Boolean);
|
||||
return filteredTree;
|
||||
}
|
||||
|
||||
|
||||
// 禁用超过当前日期的选择
|
||||
const disabledDate = (date: Date) => {
|
||||
return date > new Date() // 如果日期大于当前日期,则禁用
|
||||
@@ -351,7 +443,9 @@ const makeUp = () => {
|
||||
tableRef.value
|
||||
.getRef()
|
||||
.getCheckboxRecords()
|
||||
.find((item: any) => item.level == '6') || []
|
||||
.filter((item: any) => item.level == '6') || []
|
||||
|
||||
|
||||
|
||||
if (list.length == 0) {
|
||||
return ElMessage({
|
||||
@@ -359,6 +453,16 @@ const makeUp = () => {
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
|
||||
// 检查是否有 comFlag 等于 0 的项
|
||||
const hasOfflineDevice = list.some((item: any) => item.comFlag === 0)
|
||||
|
||||
if (hasOfflineDevice) {
|
||||
return ElMessage({
|
||||
message: '请选择在线监测点进行补招',
|
||||
type: 'warning'
|
||||
})
|
||||
}
|
||||
timeData.value = []
|
||||
timePopUp.value = true
|
||||
}
|
||||
@@ -380,24 +484,29 @@ const makeUpSubmit = () => {
|
||||
reCallStartTime: timeData.value[0]
|
||||
}
|
||||
|
||||
socket(form)
|
||||
timePopUp.value = false
|
||||
logPopUp.value = true
|
||||
setTimeout(() => {
|
||||
socket(form)
|
||||
timePopUp.value = false
|
||||
logPopUp.value = true
|
||||
}, 500)
|
||||
}
|
||||
const socket = async (form: any) => {
|
||||
const url = (localStorage.getItem('WebSocketUrl2') || 'ws://192.168.1.67:10405/api/recell/')
|
||||
const url = (localStorage.getItem('WebSocketUrl2') || 'null')//'ws://192.168.1.68:10405/api/recell/')
|
||||
logList.value = []
|
||||
await dataSocket.socketServe.connect(`${url}${adminInfo.id}`)
|
||||
await dataSocket.socketServe.send(form)
|
||||
setTimeout(() => {
|
||||
dataSocket.socketServe.send(form)
|
||||
}, 500)
|
||||
logList.value.push({
|
||||
type: '',
|
||||
time: formatDate(new Date(), 'YYYY-MM-DD hh:mm:ss'),
|
||||
time: formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss'),
|
||||
name: '开始补召,请稍等...',
|
||||
})
|
||||
await dataSocket.socketServe.registerCallBack('message', (res: any) => {
|
||||
if (res.code == undefined) return
|
||||
logList.value.push({
|
||||
type: res.code == 500 ? 'error' : '',
|
||||
time: formatDate(new Date(), 'YYYY-MM-DD hh:mm:ss'),
|
||||
time: formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss'),
|
||||
name: res.message
|
||||
})
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user