Compare commits
103 Commits
f1439e0464
...
2026-01
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd0dab7643 | ||
|
|
cf4291ed9a | ||
|
|
46124f0ea5 | ||
|
|
def48e9c84 | ||
|
|
823d5f4475 | ||
|
|
c09e6f54dd | ||
|
|
5ceb9be9e2 | ||
|
|
054d84778b | ||
|
|
63433aa6dc | ||
|
|
e9d7231a75 | ||
|
|
08afdddc51 | ||
|
|
e21ae50e51 | ||
|
|
4cbd2e43cb | ||
|
|
4c9b677e81 | ||
|
|
0affb17e3a | ||
|
|
c2d0faea08 | ||
|
|
0d155c8680 | ||
|
|
3db01fe32d | ||
|
|
545e3836d1 | ||
|
|
02a95c1dcd | ||
|
|
7a81c008c3 | ||
|
|
5d3d16f8ec | ||
|
|
d25f16bcc7 | ||
|
|
75987c0c6f | ||
|
|
a765cdf9ee | ||
|
|
cc0f8bc8b6 | ||
|
|
7e4db9d4cd | ||
|
|
67e2fa57d0 | ||
|
|
ad1fc11e61 | ||
|
|
6824864db2 | ||
|
|
37ed693cea | ||
|
|
0419af8e50 | ||
|
|
5268b93dd0 | ||
|
|
4e6bd55089 | ||
|
|
4e0db29ab1 | ||
|
|
9b0fd76f48 | ||
|
|
f92b07c555 | ||
|
|
a77db278ac | ||
|
|
51a0ae49a9 | ||
|
|
814e9917d6 | ||
|
|
21f1c41196 | ||
|
|
c188446e76 | ||
|
|
e2a5d084a5 | ||
|
|
4ae27a9d6d | ||
|
|
7783569f91 | ||
|
|
f1ac67070f | ||
|
|
77a9a2adfc | ||
|
|
accc1f30f6 | ||
|
|
94649b3348 | ||
|
|
e3de350dc5 | ||
|
|
4963dd495a | ||
|
|
40fa6eba20 | ||
|
|
f32934e0e6 | ||
|
|
460962cead | ||
|
|
fa75fc2923 | ||
|
|
f953b560c7 | ||
|
|
8f3426eb1f | ||
|
|
c2a2a4afd6 | ||
|
|
d2357d4ad2 | ||
|
|
1b23355134 | ||
|
|
ce9caa8729 | ||
|
|
2d0349c1b6 | ||
|
|
8355fc6aed | ||
|
|
23bc2d8f05 | ||
|
|
43caddffa3 | ||
|
|
3accaf3079 | ||
|
|
5687367602 | ||
|
|
b8ee530557 | ||
|
|
0518127792 | ||
|
|
5db43cd4b1 | ||
|
|
bf0657cbbc | ||
|
|
bcb1535d4d | ||
|
|
aa07112605 | ||
|
|
c09bea9e04 | ||
|
|
22cd6088a3 | ||
|
|
faf7ba98a6 | ||
|
|
b90f70c72d | ||
|
|
d38b426527 | ||
|
|
79a246cd87 | ||
|
|
58ee36c6a5 | ||
|
|
515dcfe76c | ||
|
|
031fab286b | ||
|
|
58bc269940 | ||
|
|
80182cdc6f | ||
|
|
8ce2968bee | ||
|
|
1a146afcd7 | ||
|
|
800ec7f0cf | ||
|
|
e824f4823a | ||
|
|
2476d2401e | ||
|
|
f043b6dc1a | ||
|
|
09bf34700a | ||
|
|
f32673c92a | ||
|
|
2c7b5a8583 | ||
|
|
3745d91a9d | ||
|
|
9117a6e3c6 | ||
|
|
e759f443d3 | ||
|
|
af3f9fe607 | ||
|
|
d97e97f51c | ||
|
|
5e1a628d53 | ||
|
|
acc5e93731 | ||
|
|
93586255fc | ||
|
|
cf51ba9ff0 | ||
|
|
67d9aaf958 |
@@ -6,8 +6,10 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"dev:zl": "vite --mode zl",
|
||||
"dev:ypt": "vite --mode ypt",
|
||||
"build": "vite build",
|
||||
"build:zl": "vite build --mode zl",
|
||||
"build:ypt": "vite build --mode ypt",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -15,6 +15,13 @@ export function getLineTree() {
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
// 监测点列表治理
|
||||
export function objTree() {
|
||||
return createAxios({
|
||||
url: '/cs-device-boot/csLedger/objTree',
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//云设备录入树
|
||||
@@ -24,4 +31,11 @@ export function getCldTree() {
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
//报表树
|
||||
export function lineTree() {
|
||||
return createAxios({
|
||||
url: '/cs-device-boot/csLedger/lineTree',
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +1,82 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 新增程序版本
|
||||
export const addEdData = (data) => {
|
||||
export const addEdData = data => {
|
||||
return request({
|
||||
url: '/cs-device-boot/edData/addEdData',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
'Content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: data,
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export const auditEdData = (data) => {
|
||||
export const auditEdData = data => {
|
||||
return request({
|
||||
url: '/cs-device-boot/edData/auditEdData',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
'Content-Type': 'multipart/form-data'
|
||||
},
|
||||
data: data,
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 修改-删除工程
|
||||
export const auditEngineering = (data:any)=> {
|
||||
export const auditEngineering = (data: any) => {
|
||||
return request({
|
||||
url: '/cs-device-boot/engineering/auditEngineering',
|
||||
method: 'post',
|
||||
data: data,
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 修改项目
|
||||
export const updateProject = (data:any) => {
|
||||
export const updateProject = (data: any) => {
|
||||
return request({
|
||||
url: '/cs-device-boot/project/updateProject',
|
||||
method: 'post',
|
||||
|
||||
data: data,
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 新增工程
|
||||
export const addEngineering = (data: any) => {
|
||||
return request({
|
||||
url: '/cs-device-boot/engineeringProjectRelation/addEngineering',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 修改工程
|
||||
export const updateEngineering = (data: any) => {
|
||||
return request({
|
||||
url: '/cs-device-boot/engineeringProjectRelation/updateEngineering',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 刪除工程
|
||||
export const deleteEngineering = (data: any) => {
|
||||
return request({
|
||||
url: '/cs-device-boot/engineeringProjectRelation/deleteEngineering',
|
||||
method: 'post',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
// 刪除項目
|
||||
export const deleteProject = (data: any) => {
|
||||
return request({
|
||||
url: '/cs-device-boot/engineeringProjectRelation/deleteProject',
|
||||
method: 'post',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
// 新增项目
|
||||
export const addProject = (data: any) => {
|
||||
return request({
|
||||
url: '/cs-device-boot/engineeringProjectRelation/addProject',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
28
src/api/cs-device-boot/sensitiveLoadMange.ts
Normal file
28
src/api/cs-device-boot/sensitiveLoadMange.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 新增敏感用户
|
||||
export function saveUser(data: any) {
|
||||
return request({
|
||||
url: '/cs-harmonic-boot/pqSensitiveUser/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改敏感用户
|
||||
export function updateUser(data: any) {
|
||||
return request({
|
||||
url: '/cs-harmonic-boot/pqSensitiveUser/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除敏感用户
|
||||
export function deleteUser(data: any) {
|
||||
return request({
|
||||
url: '/cs-harmonic-boot/pqSensitiveUser/delete',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import createAxios from '@/utils/request'
|
||||
|
||||
import { genFileId, ElMessage, ElNotification } from 'element-plus'
|
||||
// 查询设备数据趋势
|
||||
export function getDeviceDataTrend(data: any) {
|
||||
return createAxios({
|
||||
@@ -9,8 +9,6 @@ export function getDeviceDataTrend(data: any) {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 波形下载
|
||||
export function getFileZip(params: any) {
|
||||
return createAxios({
|
||||
@@ -20,3 +18,42 @@ export function getFileZip(params: any) {
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
|
||||
export function exportModel(data: any) {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/exportmodel/exportModel',
|
||||
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
|
||||
}
|
||||
})
|
||||
}
|
||||
async function readJsonBlob(blob) {
|
||||
try {
|
||||
// 1. Blob.text() 读取二进制 → 直接转为 字符串(自动处理编码)
|
||||
const jsonStr = await blob.text()
|
||||
// 2. JSON.parse 解析字符串 → 得到可用的 JS 对象/数组
|
||||
const jsonData = JSON.parse(jsonStr)
|
||||
// 3. 拿到数据,后续随便用
|
||||
return {
|
||||
code: true,
|
||||
data: jsonData
|
||||
}
|
||||
} catch (err) {
|
||||
return {
|
||||
code: false,
|
||||
data: {}
|
||||
}
|
||||
// console.error('解析Blob的JSON数据失败:', err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,3 +48,20 @@ export function getztProjectTree() {
|
||||
method: 'post',
|
||||
})
|
||||
}
|
||||
|
||||
//根据用户id获取组件信息
|
||||
export function getByUserId(data: any) {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/cspage/getByUserId',
|
||||
method: 'post',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
//c保存组态界面与用户的关系
|
||||
export function savePageIdWithUser(data: any) {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/cspage/savePageIdWithUser',
|
||||
method: 'post',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import createAxios from '@/utils/request'
|
||||
// 获取设备补召页面数据
|
||||
export function getMakeUpData(data: any) {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/offlineDataUpload/makeUpData?lineId='+data,
|
||||
url: '/cs-harmonic-boot/offlineDataUpload/makeUpData?lineId=' + data,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
@@ -25,3 +25,19 @@ export function offlineDataUploadMakeUp(data: any) {
|
||||
data
|
||||
})
|
||||
}
|
||||
//设备补召操作
|
||||
// 根据id集合获取敏感负荷用户列表
|
||||
export function getListByIds() {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/pqSensitiveUser/getListByIds',
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
// 根据id集合获取敏感负荷用户列表
|
||||
export function getList(data) {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/pqSensitiveUser/getList',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
@@ -18,3 +18,13 @@ export function downLoadFile(filePath: any) {
|
||||
params: { filePath: filePath }
|
||||
})
|
||||
}
|
||||
|
||||
//获取文件的一个短期url
|
||||
export function getFileUrl(filePath: any) {
|
||||
return createAxios({
|
||||
url: '/system-boot/file/getFileUrl',
|
||||
method: 'get',
|
||||
// responseType: 'blob',
|
||||
params: { filePath: filePath }
|
||||
})
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
import { genFileId, ElMessage, ElNotification } from 'element-plus'
|
||||
// 主要监测点列表查询>>分页
|
||||
export function mainLineList(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/mainLine/list',
|
||||
url: '/cs-harmonic-boot/mainLine/list',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -11,7 +11,7 @@ export function mainLineList(data: any) {
|
||||
// 主要监测点指标越限详情
|
||||
export function statLimitRateDetails(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/mainLine/statLimitRateDetails',
|
||||
url: '/cs-harmonic-boot/mainLine/statLimitRateDetails',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -38,7 +38,7 @@ export function trendData(data: any) {
|
||||
// 每日越限占比统计
|
||||
export function totalLimitStatisticsDetails(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/totalLimitStatistics/details',
|
||||
url: '/cs-harmonic-boot/totalLimitStatistics/details',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -47,7 +47,7 @@ export function totalLimitStatisticsDetails(data: any) {
|
||||
// 总体指标越限统计列表
|
||||
export function totalLimitStatisticsList(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/totalLimitStatistics/list',
|
||||
url: '/cs-harmonic-boot/totalLimitStatistics/list',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -56,7 +56,7 @@ export function totalLimitStatisticsList(data: any) {
|
||||
// 总体指标越限统计数据
|
||||
export function totalLimitStatisticsData(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/totalLimitStatistics/data',
|
||||
url: '/cs-harmonic-boot/totalLimitStatistics/data',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -65,7 +65,7 @@ export function totalLimitStatisticsData(data: any) {
|
||||
// 指标越限程度数据
|
||||
export function limitExtentData(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/limitRateDetailD/limitExtentData',
|
||||
url: '/cs-harmonic-boot/limitRateDetailD/limitExtentData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -73,7 +73,7 @@ export function limitExtentData(data: any) {
|
||||
// 指标日趋势图数据
|
||||
export function limitExtentDayData(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/limitRateDetailD/limitExtentDayData',
|
||||
url: '/cs-harmonic-boot/limitRateDetailD/limitExtentDayData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -82,7 +82,7 @@ export function limitExtentDayData(data: any) {
|
||||
// 指标越限明细日历数据
|
||||
export function limitCalendarData(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/limitRateDetailD/limitCalendarData',
|
||||
url: '/cs-harmonic-boot/limitRateDetailD/limitCalendarData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -100,7 +100,7 @@ export function fittingData(data: any) {
|
||||
//指标越限时间概率分布
|
||||
export function limitTimeProbabilityData(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/limitRateDetailD/limitTimeProbabilityData',
|
||||
url: '/cs-harmonic-boot/limitRateDetailD/limitTimeProbabilityData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -109,17 +109,16 @@ export function limitTimeProbabilityData(data: any) {
|
||||
//指标越限程度概率分布
|
||||
export function limitProbabilityData(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/limitRateDetailD/limitProbabilityData',
|
||||
url: '/cs-harmonic-boot/limitRateDetailD/limitProbabilityData',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 电网侧指标越限统计列表
|
||||
export function gridSideLimitStatisticsList(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/gridSideLimitStatistics/list',
|
||||
url: '/cs-harmonic-boot/gridSideLimitStatistics/list',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -128,7 +127,7 @@ export function gridSideLimitStatisticsList(data: any) {
|
||||
// 电网侧指标越限统计数据
|
||||
export function gridSideLimitStatisticsData(data: any) {
|
||||
return request({
|
||||
url: '/harmonic-boot/gridSideLimitStatistics/data',
|
||||
url: '/cs-harmonic-boot/gridSideLimitStatistics/data',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -152,7 +151,6 @@ export function getListByIds(data: any) {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 上传治理报告
|
||||
export function uploadReport(data: any) {
|
||||
return request({
|
||||
@@ -234,4 +232,68 @@ export function netEventTable(data: any) {
|
||||
})
|
||||
}
|
||||
|
||||
// 分页查询暂降事件
|
||||
export function pageEvent(data: any) {
|
||||
return request({
|
||||
url: '/cs-harmonic-boot/event/pageEvent',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 暂态事件波形分析
|
||||
export function analyseWave(data: any) {
|
||||
return request({
|
||||
url: '/cs-harmonic-boot/event/analyseWave',
|
||||
method: 'get',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
// 暂态监测点下拉框接口
|
||||
export function getSimpleLine() {
|
||||
return request({
|
||||
url: '/cs-device-boot/csline/getSimpleLine',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getLineExport(data: any) {
|
||||
return request({
|
||||
url: '/cs-harmonic-boot/eventReport/getLineExport',
|
||||
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
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function readJsonBlob(blob) {
|
||||
try {
|
||||
// 1. Blob.text() 读取二进制 → 直接转为 字符串(自动处理编码)
|
||||
const jsonStr = await blob.text()
|
||||
// 2. JSON.parse 解析字符串 → 得到可用的 JS 对象/数组
|
||||
const jsonData = JSON.parse(jsonStr)
|
||||
// 3. 拿到数据,后续随便用
|
||||
return {
|
||||
code: true,
|
||||
data: jsonData
|
||||
}
|
||||
} catch (err) {
|
||||
return {
|
||||
code: false,
|
||||
data: {}
|
||||
}
|
||||
// console.error('解析Blob的JSON数据失败:', err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,15 @@ import createAxios from '@/utils/request'
|
||||
// 获取参数指标
|
||||
export function getIndex() {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/reportChooseTree',
|
||||
// url: '/harmonic-boot/customReport/reportChooseTree',
|
||||
url: '/cs-harmonic-boot/customReport/reportChooseTree',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
//、查询数据激活报表模板
|
||||
export function updateTemplateActive(data) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/updateTemplateActive',
|
||||
url: '/cs-harmonic-boot/customReport/updateTemplateActive',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
@@ -19,7 +20,8 @@ export function updateTemplateActive(data) {
|
||||
//获取报表模板 //部门树查询
|
||||
export function getTemplateList(data:any) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/getTemplateList',
|
||||
// url: '/harmonic-boot/customReport/getTemplateList',
|
||||
url: '/cs-harmonic-boot/customReport/getTemplateList',
|
||||
// url:'/api3/harmonic-boot/customReport/getTemplateList',
|
||||
method: 'post',
|
||||
data
|
||||
@@ -28,7 +30,7 @@ export function getTemplateList(data:any) {
|
||||
//删除报表模板
|
||||
export function delTemplate(data:any) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/delTemplate',
|
||||
url: '/cs-harmonic-boot/customReport/delTemplate',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
@@ -37,7 +39,7 @@ export function delTemplate(data:any) {
|
||||
//修改获取数据
|
||||
export function getCustomReportTemplateById(params) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/getCustomReportTemplateById',
|
||||
url: '/cs-harmonic-boot/customReport/getCustomReportTemplateById',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
@@ -46,7 +48,7 @@ export function getCustomReportTemplateById(params) {
|
||||
//修改获取数据
|
||||
export function viewCustomReportTemplateById(params) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/viewCustomReportTemplateById',
|
||||
url: '/cs-harmonic-boot/customReport/viewCustomReportTemplateById',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
@@ -54,16 +56,17 @@ export function viewCustomReportTemplateById(params) {
|
||||
//修改模板
|
||||
export function dateTemplateup(data) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/updateTemplate',
|
||||
url: '/cs-harmonic-boot/customReport/updateTemplate',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//新增报表模板
|
||||
export function addTemplate(data) {
|
||||
export function addTemplate(data:any) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/addTemplate',
|
||||
// url: '/harmonic-boot/customReport/addTemplate',
|
||||
url: '/cs-harmonic-boot/customReport/addTemplate',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
@@ -71,7 +74,7 @@ export function addTemplate(data) {
|
||||
//模板对应指标替换
|
||||
export function getCustomReport(data: any) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/getCustomReport',
|
||||
url: '/cs-harmonic-boot/customReport/getCustomReport',
|
||||
method: 'POST',
|
||||
data
|
||||
})
|
||||
@@ -79,7 +82,7 @@ export function getCustomReport(data: any) {
|
||||
//绑定模板
|
||||
export function updateBindTemplate(data) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/updateBindTemplate',
|
||||
url: '/cs-harmonic-boot/customReport/updateBindTemplate',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
@@ -87,7 +90,7 @@ export function updateBindTemplate(data) {
|
||||
//根据模板ID查询数据
|
||||
export function getDataByTempId(params) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/getDataByTempId',
|
||||
url: '/cs-harmonic-boot/customReport/getDataByTempId',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
@@ -95,11 +98,19 @@ export function getDataByTempId(params) {
|
||||
//根据部门查询模板
|
||||
export function getTemplateByDept(params) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/getTemplateByDept',
|
||||
url: '/cs-harmonic-boot/customReport/getTemplateByDept',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
// 获取模版
|
||||
export function querySysExcel(params) {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/sysExcel/querySysExcel',
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
//资源管理 查询数据
|
||||
export function queryData(data) {
|
||||
return createAxios({
|
||||
@@ -144,7 +155,7 @@ export function updateFile(data) {
|
||||
//合格率报告
|
||||
export function pageTable(data) {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/qualifiedReport/pageTable',
|
||||
url: '/cs-harmonic-boot/qualifiedReport/pageTable',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
@@ -152,14 +163,56 @@ export function pageTable(data) {
|
||||
//合格率报告
|
||||
export function targetLimitChooseTree() {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/targetLimitChooseTree',
|
||||
// url: '/harmonic-boot/customReport/targetLimitChooseTree',
|
||||
url: '/cs-harmonic-boot/customReport/targetLimitChooseTree',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
//监测点指标
|
||||
export function terminalChooseTree() {
|
||||
return createAxios({
|
||||
url: '/harmonic-boot/customReport/terminalChooseTree',
|
||||
// url: '/harmonic-boot/customReport/terminalChooseTree',
|
||||
url: '/cs-harmonic-boot/customReport/terminalChooseTree',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
//新增模版
|
||||
export function addSysExcel(data:any) {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/sysExcel/addSysExcel',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
//修改模版
|
||||
export function updateSysExcel(data:any) {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/sysExcel/updateSysExcel',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
//删除模版
|
||||
export function deleteSysExcel(params:any) {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/sysExcel/deleteSysExcel',
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
//查詢綁定
|
||||
export function queryList(params:any) {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/sysExcelRelation/queryList',
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
//綁定
|
||||
export function bandRelation(data:any) {
|
||||
return createAxios({
|
||||
url: '/cs-harmonic-boot/sysExcelRelation/bandRelation',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
@@ -116,3 +116,11 @@ export const start = (params: any) => {
|
||||
params
|
||||
})
|
||||
}
|
||||
// 查询监测对象类型
|
||||
export const getDicDataByTypeCode = (params: any) => {
|
||||
return request({
|
||||
url: '/system-boot/dictData/getDicDataByTypeCode',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
@@ -54,6 +54,14 @@ export const activatePage = (params: any) => {
|
||||
params
|
||||
})
|
||||
}
|
||||
// 全局的驾驶舱页面
|
||||
export const scopePage = (params: any) => {
|
||||
return createAxios({
|
||||
url: '/system-boot/dashboard/scopePage',
|
||||
method: 'post',
|
||||
params
|
||||
})
|
||||
}
|
||||
// 查询激活的驾驶舱页面
|
||||
export const queryActivatePage = () => {
|
||||
return createAxios({
|
||||
|
||||
@@ -88,8 +88,9 @@ export const updateStatistical = (data: any) => {
|
||||
// 单位绑定
|
||||
export function codeDicTree(data: any) {
|
||||
return createAxios({
|
||||
url: '/system-boot/dictTree/codeDicTree',
|
||||
method: 'get',
|
||||
// url: '/system-boot/dictTree/codeDicTree',
|
||||
url: '/system-boot/dictTree/queryByCodeList',
|
||||
method: 'post',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
|
||||
@@ -8,14 +8,26 @@ export function getFunctionsByRoleIndex(data) {
|
||||
})
|
||||
}
|
||||
|
||||
export function updateRoleMenu(data:any) {
|
||||
export function updateRoleMenu(data: any) {
|
||||
return createAxios({
|
||||
url: '/user-boot/function/assignFunctionByRoleIndexes',
|
||||
method: 'post',
|
||||
data: data
|
||||
// params: roleIndex,functionIndexList
|
||||
// data:{
|
||||
// roleIndex,functionIndexList
|
||||
// }
|
||||
})
|
||||
}
|
||||
// 新增角色与系统关系
|
||||
export function systemAdd(data: any) {
|
||||
return createAxios({
|
||||
url: '/user-boot/sysRoleSystem/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
// 根据角色id获取系统信息
|
||||
export function getSystemByRoleId(params: any) {
|
||||
return createAxios({
|
||||
url: '/user-boot/sysRoleSystem/getSystemByRoleId',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
BIN
src/assets/img/jss.png
Normal file
BIN
src/assets/img/jss.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 213 KiB |
@@ -1,7 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--F47曲线 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||
<TableHeader
|
||||
ref="TableHeaderRef"
|
||||
:showReset="false"
|
||||
:timeKeyList="prop.timeKey"
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
v-if="fullscreen"
|
||||
></TableHeader>
|
||||
<el-descriptions class="mt2" direction="vertical" :column="4" border>
|
||||
<el-descriptions-item align="center" label="名称">{{ data.name }}</el-descriptions-item>
|
||||
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
|
||||
@@ -9,6 +16,7 @@
|
||||
<el-descriptions-item align="center" label="不可容忍">{{ data.bkrr }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<my-echart
|
||||
v-loading="tableStore.table.loading"
|
||||
ref="chartRef"
|
||||
class="tall"
|
||||
:options="echartList"
|
||||
@@ -18,10 +26,9 @@
|
||||
}"
|
||||
@chart-click="handleChartClick"
|
||||
/>
|
||||
<el-dialog v-model="isWaveCharts" draggable title="瞬时/RMS波形" append-to-body width="70%">
|
||||
<el-dialog v-model="isWaveCharts" v-if="isWaveCharts" draggable :title="dialogTitle" append-to-body width="70%">
|
||||
<waveFormAnalysis
|
||||
v-loading="loading"
|
||||
v-if="isWaveCharts"
|
||||
ref="waveFormAnalysisRef"
|
||||
@handleHideCharts="isWaveCharts = false"
|
||||
:wp="wp"
|
||||
@@ -33,28 +40,27 @@
|
||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||
import { analyseWave } from '@/api/common'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number]},
|
||||
h: { type: [String, Number]},
|
||||
width: { type: [String, Number]},
|
||||
height: { type: [String, Number]},
|
||||
timeKey: { type: [String, Number]},
|
||||
timeValue: { type: Object }
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const route = useRoute()
|
||||
const timeCacheStore = useTimeCacheStore()
|
||||
|
||||
const dialogTitle = ref('波形分析')
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
|
||||
@@ -77,7 +83,7 @@ const fullscreen = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const echartList = ref({})
|
||||
const echartList = ref()
|
||||
|
||||
const chartRef = ref()
|
||||
// 波形
|
||||
@@ -104,16 +110,14 @@ const tableStore: any = new TableStore({
|
||||
showPage: false,
|
||||
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
beforeSearchFun: () => {
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
const gongData = gongfunction(tableStore.table.data)
|
||||
data.gs = tableStore.table.data.length
|
||||
data.krr = gongData.pointI.length
|
||||
data.bkrr = gongData.pointIun.length
|
||||
// console.log(gongData,'789000')
|
||||
data.krr = gongData.pointF.length
|
||||
data.bkrr = gongData.pointFun.length
|
||||
echartList.value = {
|
||||
title: {
|
||||
text: `F47曲线`
|
||||
@@ -165,11 +169,16 @@ const tableStore: any = new TableStore({
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
max: function (value: any) {
|
||||
return value.max + 20
|
||||
// max: function (value: any) {
|
||||
// return value.max + 20
|
||||
// },
|
||||
max: function (value) {
|
||||
// 先取原始最大值+20,再向上取整到最近的10的倍数,确保刻度够用且规整
|
||||
return Math.ceil((value.max + 20) / 10) * 10
|
||||
},
|
||||
splitNumber: 10,
|
||||
minInterval: 0.1,
|
||||
// splitNumber: 10,
|
||||
// interval: 10,
|
||||
// minInterval: 10,
|
||||
name: '%'
|
||||
}
|
||||
],
|
||||
@@ -206,15 +215,7 @@ const tableStore: any = new TableStore({
|
||||
// [0.4, 50, '2023-01-01 11:00:00']
|
||||
// ],
|
||||
legendSymbol: 'circle',
|
||||
emphasis: {
|
||||
focus: 'series',
|
||||
itemStyle: {
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2,
|
||||
shadowBlur: 10,
|
||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||
}
|
||||
},
|
||||
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'item',
|
||||
@@ -229,7 +230,7 @@ const tableStore: any = new TableStore({
|
||||
{
|
||||
name: '不可容忍事件',
|
||||
type: 'scatter',
|
||||
symbol: 'rect',
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
data: gongData.pointFun,
|
||||
legendSymbol: 'rect'
|
||||
@@ -244,6 +245,25 @@ const tableRef = ref()
|
||||
provide('tableRef', tableRef)
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
function gongfunction(arr: any) {
|
||||
let standI = 0
|
||||
let unstandI = 0
|
||||
@@ -263,8 +283,9 @@ function gongfunction(arr: any) {
|
||||
let yy = arr[i].eventValue
|
||||
let time = arr[i].time
|
||||
let eventId = arr[i].eventId
|
||||
let lineName = arr[i].lineName
|
||||
// let index =arr[i].eventDetailIndex;
|
||||
point = [xx, yy, time, eventId]
|
||||
point = [xx, yy, time, eventId, lineName]
|
||||
|
||||
if (xx <= 0.003) {
|
||||
let line = 0
|
||||
@@ -413,38 +434,51 @@ onMounted(() => {
|
||||
const handleChartClick = (params: any) => {
|
||||
if (params.seriesName === '可容忍事件') {
|
||||
// 处理可容忍事件点击
|
||||
ElMessage.info(`点击了可容忍事件: 持续时间${params.value[0]}s, 幅值${params.value[1].toFixed(2)}%`)
|
||||
dialogTitle.value = '可容忍事件波形分析'
|
||||
handleTolerableEventClick(params)
|
||||
} else if (params.seriesName === '不可容忍事件') {
|
||||
dialogTitle.value = '不可容忍事件波形分析'
|
||||
// 处理不可容忍事件点击
|
||||
ElMessage.info(`点击了不可容忍事件: 持续时间${params.value[0]}s, 幅值${params.value[1].toFixed(2)}%`)
|
||||
handleIntolerableEventClick(params)
|
||||
// ElMessage.info(`点击了不可容忍事件: 持续时间${params.value[0]}s, 幅值${params.value[1].toFixed(2)}%`)
|
||||
handleTolerableEventClick(params)
|
||||
}
|
||||
}
|
||||
|
||||
// 可容忍事件点击处理函数
|
||||
const handleTolerableEventClick = async (row: any) => {
|
||||
console.log('可容忍事件详情:', row)
|
||||
isWaveCharts.value = true
|
||||
loading.value = true
|
||||
isWaveCharts.value = true
|
||||
await analyseWave(row.id)
|
||||
nextTick(() => {
|
||||
if (waveFormAnalysisRef.value) {
|
||||
//waveFormAnalysisRef.value.setHeight(false, 360)
|
||||
// waveFormAnalysisRef.value.setHeight(999, 130, 1.6666666)
|
||||
}
|
||||
})
|
||||
const messageInstance = ElMessage.info(`正在加载,请稍等...`)
|
||||
await analyseWave(row.value[3]) //eventId
|
||||
.then(res => {
|
||||
row.loading1 = false
|
||||
if (res != undefined) {
|
||||
boxoList.value = row
|
||||
boxoList.value.featureAmplitude = row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
||||
boxoList.value.systemType = 'WX'
|
||||
boxoList.value = {
|
||||
persistTime: row.value[0], //持续时间
|
||||
featureAmplitude: (row.value[1] / 100).toFixed(2), //残余电压
|
||||
startTime: row.value[2], //时间
|
||||
lineName: row.value[4] //监测点名称
|
||||
}
|
||||
boxoList.value.systemType = 'YPT'
|
||||
wp.value = res.data
|
||||
}
|
||||
|
||||
isWaveCharts.value = true
|
||||
loading.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
messageInstance.close()
|
||||
row.loading1 = false
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
nextTick(() => {
|
||||
waveFormAnalysisRef.value && waveFormAnalysisRef.value.setHeight(999, 130, 1.6666666)
|
||||
waveFormAnalysisRef.value && waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
|
||||
})
|
||||
}
|
||||
|
||||
308
src/components/cockpit/crossingTime/index.vue
Normal file
308
src/components/cockpit/crossingTime/index.vue
Normal file
@@ -0,0 +1,308 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--暂态越限时间分布 -->
|
||||
<TableHeader
|
||||
ref="TableHeaderRef"
|
||||
:timeKeyList="prop.timeKey"
|
||||
:showReset="false"
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
v-if="fullscreen"
|
||||
></TableHeader>
|
||||
<my-echart
|
||||
class="tall"
|
||||
:options="echartList1"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||
}"
|
||||
/>
|
||||
<!-- <my-echart
|
||||
class="mt10"
|
||||
:options="echartList1"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||
}"
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, reactive, watch } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
|
||||
if (datePickerValue && datePickerValue.timeValue) {
|
||||
// 更新时间参数
|
||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
}
|
||||
}
|
||||
|
||||
// 计算是否全屏展示
|
||||
const fullscreen = computed(() => {
|
||||
const w = Number(prop.w)
|
||||
const h = Number(prop.h)
|
||||
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||
// 执行相应逻辑
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
const config = useConfig()
|
||||
|
||||
const echartList = ref({})
|
||||
|
||||
const echartList1 = ref({})
|
||||
|
||||
const processDataForChart = (rawData: any[]) => {
|
||||
// 将后端返回的扁平数据转换为 ECharts 需要的三维坐标格式 [x, y, z]
|
||||
const chartData = rawData.map(item => [item.x, item.y, item.z])
|
||||
|
||||
return chartData
|
||||
}
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/cs-harmonic-boot/csevent/getEventCoords',
|
||||
method: 'POST',
|
||||
showPage: false,
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
const processedData = processDataForChart(tableStore.table.data.innerList || [])
|
||||
const trendList = tableStore.table.data.trendList || []
|
||||
const xlist = tableStore.table.data.xlist || []
|
||||
|
||||
// 处理趋势图数据
|
||||
const seriesData = trendList.map((item: any) => {
|
||||
// 根据接口返回的name字段确定系列名称和颜色
|
||||
let name = ''
|
||||
let color = ''
|
||||
|
||||
switch (item.name) {
|
||||
case 'Evt_Sys_DipStr':
|
||||
name = '电压暂降'
|
||||
color = '#FFBF00'
|
||||
break
|
||||
case 'Evt_Sys_IntrStr':
|
||||
name = '电压中断'
|
||||
color = '#FF9100'
|
||||
break
|
||||
case 'Evt_Sys_SwlStr':
|
||||
name = '电压暂升'
|
||||
color = config.layout.elementUiPrimary[0]
|
||||
break
|
||||
default:
|
||||
name = item.name
|
||||
color = '#000000'
|
||||
}
|
||||
|
||||
return {
|
||||
name: name,
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
color: color,
|
||||
data: item.trendList?.map((value: number, index: number) => [xlist[index], value]) || []
|
||||
}
|
||||
})
|
||||
|
||||
// 获取x轴和y轴的标签值
|
||||
const xLabels = [
|
||||
'0-10%',
|
||||
'10%-20%',
|
||||
'20%-30%',
|
||||
'30%-40%',
|
||||
'40%-50%',
|
||||
'50%-60%',
|
||||
'60%-70%',
|
||||
'70%-80%',
|
||||
'80%-90%',
|
||||
'90%-100%'
|
||||
]
|
||||
const yLabels = ['0-0.01s', '0.01s-0.1s', '0.1s-1s', '1s-10s', '10s']
|
||||
|
||||
echartList.value = {
|
||||
options: {
|
||||
xAxis: null,
|
||||
yAxis: null,
|
||||
dataZoom: null,
|
||||
backgroundColor: '#fff',
|
||||
tooltip: {
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0,
|
||||
formatter: function (params: any) {
|
||||
var tips = ''
|
||||
tips += '持续时间: ' + yLabels[params.value[1]] + '</br>'
|
||||
tips += '特征幅值: ' + xLabels[params.value[0]] + '</br>'
|
||||
tips += '事件次数: ' + params.value[2] + '</br>'
|
||||
return tips
|
||||
}
|
||||
},
|
||||
title: {
|
||||
text: '暂态事件概率分布',
|
||||
x: 'center'
|
||||
},
|
||||
visualMap: {
|
||||
max: 500,
|
||||
show: false,
|
||||
inRange: {
|
||||
color: ['#313695', '#00BB00', '#ff8000', '#a50026']
|
||||
}
|
||||
},
|
||||
xAxis3D: {
|
||||
type: 'category',
|
||||
name: '特征幅值',
|
||||
data: xLabels,
|
||||
nameGap: 40
|
||||
},
|
||||
yAxis3D: {
|
||||
type: 'category',
|
||||
name: '持续时间',
|
||||
data: yLabels,
|
||||
nameGap: 40,
|
||||
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
zAxis3D: {
|
||||
type: 'value',
|
||||
minInterval: 10,
|
||||
name: '暂态事件次数',
|
||||
nameGap: 30
|
||||
},
|
||||
grid3D: {
|
||||
viewControl: {
|
||||
projection: 'perspective',
|
||||
distance: 260
|
||||
},
|
||||
boxWidth: 200,
|
||||
boxDepth: 80,
|
||||
light: {
|
||||
main: {
|
||||
intensity: 1.2
|
||||
},
|
||||
ambient: {
|
||||
intensity: 0.3
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'bar3D',
|
||||
data: processedData,
|
||||
shading: 'realistic',
|
||||
label: {
|
||||
show: false,
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
borderWidth: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
echartList1.value = {
|
||||
title: {
|
||||
text: '暂态越限时间概率分布'
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: xlist,
|
||||
axisLabel: {
|
||||
formatter: '{value}'
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
name: '次'
|
||||
},
|
||||
grid: {
|
||||
left: '10px',
|
||||
right: '20px'
|
||||
},
|
||||
series: seriesData
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const tableRef = ref()
|
||||
provide('tableRef', tableRef)
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
tableStore.index()
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -1,35 +1,42 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--暂降方向统计 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||
<my-echart class="tall" :options="echartList" :style="{ width: prop.width, height: `calc(${prop.height} )` }" />
|
||||
<TableHeader
|
||||
ref="TableHeaderRef"
|
||||
:showReset="false"
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
:timeKeyList="prop.timeKey"
|
||||
v-if="fullscreen"
|
||||
></TableHeader>
|
||||
<my-echart
|
||||
v-loading="tableStore.table.loading"
|
||||
class="tall"
|
||||
:options="echartList"
|
||||
:style="{ width: prop.width, height: `calc(${prop.height} )` }"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const route = useRoute()
|
||||
const timeCacheStore = useTimeCacheStore()
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
@@ -53,85 +60,99 @@ const fullscreen = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const data = [
|
||||
{
|
||||
name: '来自电网',
|
||||
value: 4
|
||||
},
|
||||
{
|
||||
name: '来自负荷',
|
||||
value: 41
|
||||
}
|
||||
]
|
||||
const echartList = ref({
|
||||
title: {},
|
||||
const echartList = ref({})
|
||||
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
top: 'center',
|
||||
right: '5%',
|
||||
formatter: function (e: any) {
|
||||
return e + ' ' + data.filter(item => item.name == e)[0].value + '次'
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
show: false
|
||||
},
|
||||
yAxis: {
|
||||
show: false
|
||||
},
|
||||
grid: {
|
||||
left: '10px',
|
||||
right: '20px'
|
||||
},
|
||||
// const data = [
|
||||
// {
|
||||
// name: '来自电网',
|
||||
// value: 4
|
||||
// },
|
||||
// {
|
||||
// name: '来自负荷',
|
||||
// value: 41
|
||||
// }
|
||||
// ]
|
||||
|
||||
options: {
|
||||
dataZoom: null,
|
||||
title: [
|
||||
{
|
||||
text: '暂降方向统计',
|
||||
left: 'center'
|
||||
},
|
||||
{
|
||||
text: data[0].value + data[1].value + '次',
|
||||
left: 'center',
|
||||
top: 'center'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
center: 'center',
|
||||
radius: ['55%', '75%'],
|
||||
label: {
|
||||
show: false,
|
||||
position: 'outside',
|
||||
textStyle: {
|
||||
//数值样式
|
||||
}
|
||||
},
|
||||
name: '事件统计',
|
||||
data: data
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
const OverLimitDetailsRef = ref()
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/user-boot/dept/deptTree',
|
||||
url: '/cs-harmonic-boot/csevent/getEventDirectionData',
|
||||
method: 'POST',
|
||||
|
||||
showPage: false,
|
||||
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {}
|
||||
loadCallback: () => {
|
||||
if (!tableStore.table.data || !Array.isArray(tableStore.table.data)) {
|
||||
return []
|
||||
}
|
||||
const chartData = ref(
|
||||
tableStore.table.data.map((item: any) => ({
|
||||
name: item.source === 'load' ? '来自负荷' : '来自电网',
|
||||
value: item.times
|
||||
}))
|
||||
)
|
||||
|
||||
const total = chartData.value.reduce((sum: any, item: any) => sum + item.value, 0)
|
||||
|
||||
echartList.value = {
|
||||
title: {},
|
||||
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
top: '50',
|
||||
right: '10',
|
||||
formatter: function (name: string) {
|
||||
const item = chartData.value.find((i: any) => i.name === name)
|
||||
return item ? `${name} ${item.value}次` : name
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
show: false
|
||||
},
|
||||
yAxis: {
|
||||
show: false
|
||||
},
|
||||
grid: {
|
||||
left: '10px',
|
||||
right: '20px'
|
||||
},
|
||||
|
||||
options: {
|
||||
dataZoom: null,
|
||||
title: [
|
||||
{
|
||||
text: '暂降方向统计',
|
||||
left: 'center'
|
||||
},
|
||||
{
|
||||
text: total + '次',
|
||||
left: 'center',
|
||||
top: 'center'
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
center: 'center',
|
||||
radius: ['55%', '75%'],
|
||||
label: {
|
||||
show: false,
|
||||
position: 'outside',
|
||||
textStyle: {
|
||||
//数值样式
|
||||
}
|
||||
},
|
||||
name: '事件统计',
|
||||
data: chartData.value
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const tableRef = ref()
|
||||
@@ -139,10 +160,28 @@ provide('tableRef', tableRef)
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
// 点击行
|
||||
const cellClickEvent = ({ row, column }: any) => {
|
||||
if (column.field != 'name') {
|
||||
console.log(row)
|
||||
OverLimitDetailsRef.value.open(row)
|
||||
}
|
||||
}
|
||||
@@ -159,12 +198,7 @@ watch(
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
|
||||
@@ -17,7 +17,7 @@ import { yMethod } from '@/utils/echartMethod'
|
||||
const prop = defineProps({
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object }
|
||||
})
|
||||
|
||||
@@ -47,6 +47,7 @@ const init = () => {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: (params: any) => {
|
||||
console.log('🚀 ~ init ~ params:', params)
|
||||
if (!params || params.length === 0) return ''
|
||||
|
||||
// 使用第一个项目的轴标签作为时间标题
|
||||
@@ -100,28 +101,33 @@ const initData = async (row: any) => {
|
||||
}
|
||||
|
||||
// 处理每条相位数据
|
||||
const seriesData = res.data.map((item: any) => {
|
||||
const values = xAxisData.map((time: string, index: number) => {
|
||||
// 将传入的日期与时间拼接成完整的时间字符串
|
||||
const fullTime = `${row.time} ${time}`
|
||||
const value = parseFloat(item.value.split(',')[index]) || 0
|
||||
return [fullTime, value]
|
||||
const seriesData = res.data
|
||||
.filter(item => item.valueType == 'max')
|
||||
.sort((a, b) => {
|
||||
return a.phasic.localeCompare(b.phasic)
|
||||
})
|
||||
.map((item: any) => {
|
||||
const values = xAxisData.map((time: string, index: number) => {
|
||||
// 将传入的日期与时间拼接成完整的时间字符串
|
||||
const fullTime = `${row.time} ${time}`
|
||||
const value = parseFloat(item.value.split(',')[index]) || 0
|
||||
return [fullTime, value]
|
||||
})
|
||||
|
||||
return {
|
||||
name: `${item.phasic}相`,
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
smooth: true,
|
||||
data: values,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
// 根据相位设置对应颜色
|
||||
color: phaseColors[item.phasic] || config.layout.elementUiPrimary[0]
|
||||
return {
|
||||
name: `${item.phasic}相`,
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
smooth: true,
|
||||
data: values,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
// 根据相位设置对应颜色
|
||||
color: phaseColors[item.phasic] || config.layout.elementUiPrimary[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
echartList.value.yAxis.max = max
|
||||
echartList.value.yAxis.min = min
|
||||
// 更新图表配置
|
||||
@@ -135,7 +141,7 @@ onMounted(() => {})
|
||||
const open = async (row: any) => {
|
||||
dialogVisible.value = true
|
||||
dialogTitle.value = row.name + '日趋势图'
|
||||
dialogText.value = `监测点名称:${row.lineName}_越限时间:${row.time}_指标名称:${row.name}`
|
||||
dialogText.value = `监测点名称:${row.lineName} 越限时间:${row.time} 指标名称:${row.name}`
|
||||
nextTick(() => {
|
||||
initData(row)
|
||||
})
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--指标越限程度 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||
<TableHeader
|
||||
ref="TableHeaderRef"
|
||||
:showReset="false"
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
:timeKeyList="prop.timeKey"
|
||||
v-if="fullscreen"
|
||||
></TableHeader>
|
||||
<my-echart
|
||||
class="tall"
|
||||
:options="echartList"
|
||||
@@ -25,18 +32,20 @@ import TableHeader from '@/components/table/header/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||
import DailyTrendChart from '@/components/cockpit/exceedanceLevel/components/dailyTrendChart.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const dialogTrendChart = ref(false)
|
||||
@@ -66,7 +75,7 @@ const echartList = ref()
|
||||
|
||||
const dailyTrendChartRef = ref()
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/harmonic-boot/limitRateDetailD/limitExtentData',
|
||||
url: '/cs-harmonic-boot/limitRateDetailD/limitExtentData',
|
||||
method: 'POST',
|
||||
|
||||
showPage: false,
|
||||
@@ -89,7 +98,7 @@ const tableStore: any = new TableStore({
|
||||
{
|
||||
title: '越限最大值',
|
||||
field: 'maxValue',
|
||||
minWidth: '60',
|
||||
minWidth: '70',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
const extentValue =
|
||||
@@ -107,51 +116,34 @@ const tableStore: any = new TableStore({
|
||||
{
|
||||
title: '越限程度(%)',
|
||||
field: 'extent',
|
||||
minWidth: '60',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
// 保留两个小数
|
||||
const extentValue =
|
||||
row.extent !== null && row.extent !== undefined && row.extent !== ''
|
||||
? Math.floor(row.extent * 100) / 100
|
||||
: '/'
|
||||
return `<span>${extentValue}</span>`
|
||||
minWidth: '70',
|
||||
formatter: (row: any) => {
|
||||
return Math.floor(row.cellValue * 100) / 100
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '越限时间',
|
||||
field: 'time',
|
||||
minWidth: '60',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
if (row.time !== null && row.time !== undefined && row.time !== '') {
|
||||
return `<span>${row.time}</span>`
|
||||
} else {
|
||||
return `<span>/</span>`
|
||||
}
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '越限最高监测点',
|
||||
field: 'lineName',
|
||||
minWidth: '90',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
if (row.lineName !== null && row.lineName !== undefined && row.lineName !== '') {
|
||||
return `<span>${row.lineName}</span>`
|
||||
} else {
|
||||
return `<span>/</span>`
|
||||
}
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
// 定义 x 轴标签顺序
|
||||
const xAxisLabels = ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||
const xAxisLabels = ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||
|
||||
// 根据指标名称顺序提取对应的 extent 数据
|
||||
const chartData = xAxisLabels.map(label => {
|
||||
@@ -200,6 +192,7 @@ provide('tableStore', tableStore)
|
||||
// 点击行
|
||||
const cellClickEvent = ({ row, column }: any) => {
|
||||
dialogTrendChart.value = true
|
||||
|
||||
if (column.field == 'maxValue' && row.lineId) {
|
||||
nextTick(() => {
|
||||
dailyTrendChartRef.value.open(row)
|
||||
@@ -207,6 +200,25 @@ const cellClickEvent = ({ row, column }: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
@@ -219,12 +231,7 @@ watch(
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,38 +1,25 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--治理效果报表 -->
|
||||
<TableHeader :showReset="false" datePicker @selectChange="selectChange" v-if="fullscreen">
|
||||
<TableHeader :showReset="false" :timeKeyList="prop.timeKey" ref="TableHeaderRef" datePicker @selectChange="selectChange" v-if="fullscreen">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="报表模板">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.tempId"
|
||||
placeholder="请选择报表模板"
|
||||
clearable
|
||||
>
|
||||
<el-option v-for="item in templateList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
<el-form-item label="模板策略">
|
||||
<el-select filterable v-model="tableStore.table.params.tempId" placeholder="请选择模板策略" clearable>
|
||||
<el-option v-for="item in templateList" :key="item.id" :label="item.excelName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="监测对象">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.sensitiveUserId"
|
||||
placeholder="请选择监测对象"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in idList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
<el-select filterable v-model="tableStore.table.params.sensitiveUserId" placeholder="请选择监测对象" clearable>
|
||||
<el-option v-for="item in idList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-slot:operation>
|
||||
<el-button @click="downloadExcel" class="" type="primary" icon="el-icon-Download">导出excel</el-button>
|
||||
<el-button @click="downloadExcel" class="" type="primary" icon="el-icon-Download">导出</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<div style="display: flex;">
|
||||
<div
|
||||
<div style="display: flex">
|
||||
<div
|
||||
id="luckysheet"
|
||||
:style="{
|
||||
width: `calc(${prop.width} )`,
|
||||
@@ -43,44 +30,25 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, reactive, watch, h, computed } from 'vue'
|
||||
import { ref, onMounted, provide, reactive, watch, h, computed, nextTick } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import { exportExcel } from '@/views/govern/reportForms/export.js'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import Json from './index.json'
|
||||
import JsonAfter from './index.json'
|
||||
import { getTemplateList } from '@/api/harmonic-boot/luckyexcel'
|
||||
import { querySysExcel } from '@/api/harmonic-boot/luckyexcel'
|
||||
import { getListByIds } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
import { ElMessage } from 'element-plus'
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/user-boot/role/selectRoleDetail?id=0',
|
||||
method: 'POST',
|
||||
|
||||
showPage: false,
|
||||
exportName: '主要监测点列表',
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
},
|
||||
loadCallback: () => {}
|
||||
})
|
||||
|
||||
const tableRef = ref()
|
||||
provide('tableRef', tableRef)
|
||||
tableStore.table.params.power = '1'
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
// 报表模板列表
|
||||
const templateList = ref()
|
||||
@@ -93,19 +61,24 @@ const initListByIds = () => {
|
||||
getListByIds({}).then((res: any) => {
|
||||
if (res.data.length > 0) {
|
||||
idList.value = res.data
|
||||
|
||||
if (!tableStore.table.params.sensitiveUserId && idList.value?.length > 0) {
|
||||
tableStore.table.params.sensitiveUserId = idList.value[0].id
|
||||
}
|
||||
templateListData()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const templateListData = () => {
|
||||
getTemplateList({}).then(res => {
|
||||
templateList.value = res.data
|
||||
querySysExcel({}).then(res => {
|
||||
templateList.value = res.data.filter(item => item.excelType == 4)
|
||||
if (!tableStore.table.params.tempId && templateList.value?.length > 0) {
|
||||
tableStore.table.params.tempId = res.data[0].id
|
||||
tableStore.table.params.tempId = templateList.value[0].id
|
||||
}
|
||||
nextTick(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
})
|
||||
}
|
||||
// 下载表格
|
||||
@@ -115,19 +88,6 @@ const downloadExcel = () => {
|
||||
|
||||
onMounted(() => {
|
||||
initListByIds()
|
||||
templateListData()
|
||||
luckysheet.create({
|
||||
container: 'luckysheet',
|
||||
title: '', // 表 头名
|
||||
lang: 'zh', // 中文
|
||||
showtoolbar: false, // 是否显示工具栏
|
||||
showinfobar: false, // 是否显示顶部信息栏
|
||||
showsheetbar: true, // 是否显示底部sheet按钮
|
||||
allowEdit: false, // 禁止所有编辑操作(必填)
|
||||
data: Json
|
||||
})
|
||||
|
||||
tableStore.index()
|
||||
})
|
||||
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
@@ -149,6 +109,65 @@ const fullscreen = computed(() => {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/cs-harmonic-boot/customReport/getSensitiveUserReport',
|
||||
method: 'POST',
|
||||
showPage: false,
|
||||
exportName: '治理效果报表',
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
setTime()
|
||||
// if (!tableStore.table.params.sensitiveUserId && idList.value?.length > 0) {
|
||||
// tableStore.table.params.sensitiveUserId = idList.value[0].id
|
||||
// }
|
||||
// if (!tableStore.table.params.tempId && templateList.value?.length > 0) {
|
||||
// tableStore.table.params.tempId = templateList.value[0].id
|
||||
// }
|
||||
// if( !tableStore.table.params.tempId){
|
||||
// return ElMessage.warning('请选择模板')
|
||||
// }
|
||||
},
|
||||
loadCallback: () => {
|
||||
luckysheet.create({
|
||||
container: 'luckysheet',
|
||||
title: '', // 表 头名
|
||||
lang: 'zh', // 中文
|
||||
showtoolbar: false, // 是否显示工具栏
|
||||
showinfobar: false, // 是否显示顶部信息栏
|
||||
showsheetbar: true, // 是否显示底部sheet按钮
|
||||
allowEdit: false, // 禁止所有编辑操作(必填)
|
||||
data: tableStore.table.data
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const tableRef = ref()
|
||||
provide('tableRef', tableRef)
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
tableStore.table.params.startTime = time[0]
|
||||
tableStore.table.params.endTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
@@ -158,12 +177,7 @@ watch(
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--治理效果报表 -->
|
||||
<TableHeader :showReset="false" datePicker @selectChange="selectChange" v-if="fullscreen">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="监测对象">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.power"
|
||||
placeholder="请选择监测对象"
|
||||
clearable
|
||||
style="width: 130px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in powerList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template v-slot:operation>
|
||||
<el-button @click="downloadExcel" class="" type="primary" icon="el-icon-Download">导出excel</el-button>
|
||||
</template>
|
||||
</TableHeader>
|
||||
|
||||
<!-- 左右布局展示治理前后报表 -->
|
||||
<div class="report-container">
|
||||
<!-- 治理前报表 -->
|
||||
<div class="report-panel before">
|
||||
<div class="panel-header">治理前报表</div>
|
||||
<div
|
||||
id="luckysheet-before"
|
||||
:style="{
|
||||
width: '100%',
|
||||
height: `calc(${prop.height} - ${fullscreen ? '114px' : '57px'} + ${fullscreen ? 0 : 56}px)`
|
||||
}"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<!-- 治理后报表 -->
|
||||
<div class="report-panel after">
|
||||
<div class="panel-header">治理后报表</div>
|
||||
<div
|
||||
id="luckysheet-after"
|
||||
:style="{
|
||||
width: '100%',
|
||||
height: `calc(${prop.height} - ${fullscreen ? '114px' : '57px'} + ${fullscreen ? 0 : 56}px)`
|
||||
}"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, watch, computed } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import { exportExcel } from '@/views/govern/reportForms/export.js'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import Json from './index.json'
|
||||
import JsonAfter from './index1.json'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
})
|
||||
|
||||
const powerList: any = ref([
|
||||
{
|
||||
label: '1#变压器',
|
||||
value: '1'
|
||||
},
|
||||
{
|
||||
label: '2#变压器',
|
||||
value: '2'
|
||||
}
|
||||
])
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/user-boot/role/selectRoleDetail?id=0',
|
||||
method: 'POST',
|
||||
showPage: false,
|
||||
exportName: '治理效果报表',
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
},
|
||||
loadCallback: () => {}
|
||||
})
|
||||
|
||||
const tableRef = ref()
|
||||
provide('tableRef', tableRef)
|
||||
tableStore.table.params.power = '1'
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
// 下载表格
|
||||
const downloadExcel = () => {
|
||||
// 可以选择导出治理前、治理后或两个报表
|
||||
const beforeSheets = luckysheetBefore.getAllSheets()
|
||||
const afterSheets = luckysheetAfter.getAllSheets()
|
||||
exportExcel([...beforeSheets, ...afterSheets], '治理效果对比报表')
|
||||
}
|
||||
|
||||
// 治理前和治理后的Luckysheet实例
|
||||
let luckysheetBefore: any
|
||||
let luckysheetAfter: any
|
||||
|
||||
onMounted(() => {
|
||||
// 创建治理前报表
|
||||
luckysheetBefore = luckysheet.create({
|
||||
container: 'luckysheet-before',
|
||||
title: '治理前',
|
||||
lang: 'zh',
|
||||
showtoolbar: false,
|
||||
showinfobar: false,
|
||||
showsheetbar: true,
|
||||
allowEdit: false,
|
||||
data: Json
|
||||
})
|
||||
|
||||
// 创建治理后报表
|
||||
luckysheetAfter = luckysheet.create({
|
||||
container: 'luckysheet-after',
|
||||
title: '治理后',
|
||||
lang: 'zh',
|
||||
showtoolbar: false,
|
||||
showinfobar: false,
|
||||
showsheetbar: true,
|
||||
allowEdit: false,
|
||||
data: JsonAfter // 使用治理后的数据
|
||||
})
|
||||
|
||||
tableStore.index()
|
||||
})
|
||||
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
if (datePickerValue && datePickerValue.timeValue) {
|
||||
// 更新时间参数
|
||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
|
||||
// 可以在这里更新报表数据
|
||||
updateReportData()
|
||||
}
|
||||
}
|
||||
|
||||
// 更新报表数据的方法
|
||||
const updateReportData = () => {
|
||||
// 这里可以根据时间参数更新治理前后的报表数据
|
||||
// 示例:重新加载数据或更新现有数据
|
||||
console.log('更新报表数据:', {
|
||||
beginTime: tableStore.table.params.searchBeginTime,
|
||||
endTime: tableStore.table.params.searchEndTime
|
||||
})
|
||||
}
|
||||
|
||||
// 计算是否全屏展示
|
||||
const fullscreen = computed(() => {
|
||||
const w = Number(prop.w)
|
||||
const h = Number(prop.h)
|
||||
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
tableStore.index()
|
||||
updateReportData()
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
updateReportData()
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.report-container {
|
||||
display: flex;
|
||||
height: calc(100% - 57px);
|
||||
|
||||
.report-panel {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 1px solid var(--el-border-color);
|
||||
|
||||
&.before {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
&.after {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
padding: 10px 15px;
|
||||
background-color: var(--el-color-primary-light-9);
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid var(--el-border-color);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
// 确保Luckysheet容器占满剩余空间
|
||||
:deep(#luckysheet-before),
|
||||
:deep(#luckysheet-after) {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-select) {
|
||||
min-width: 80px;
|
||||
}
|
||||
</style>
|
||||
@@ -16,6 +16,7 @@
|
||||
v-model="searchForm.index"
|
||||
placeholder="请选择统计指标"
|
||||
@change="onIndexChange($event)"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in indexOptions"
|
||||
@@ -33,14 +34,15 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="统计类型">
|
||||
<el-select
|
||||
style="min-width: 120px !important"
|
||||
style="min-width: 90px !important"
|
||||
placeholder="请选择"
|
||||
v-model="searchForm.valueType"
|
||||
filterable
|
||||
>
|
||||
<el-option value="max" label="最大值"></el-option>
|
||||
<el-option value="min" label="最小值"></el-option>
|
||||
<el-option value="avg" label="平均值"></el-option>
|
||||
<el-option value="cp95" label="cp95"></el-option>
|
||||
<el-option value="cp95" label="CP95"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
@@ -59,11 +61,12 @@
|
||||
placeholder="请选择谐波次数"
|
||||
style="width: 100px"
|
||||
class="mr20"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="vv in item.countOptions"
|
||||
:key="vv"
|
||||
:label="vv"
|
||||
:label="item.name.includes('间谐波') ? vv - 0.5 : vv"
|
||||
:value="vv"
|
||||
></el-option>
|
||||
</el-select>
|
||||
@@ -79,11 +82,7 @@
|
||||
</TableHeader>
|
||||
</div>
|
||||
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
||||
<MyEchart
|
||||
ref="historyChart"
|
||||
:options="echartsData"
|
||||
v-if="showEchart"
|
||||
/>
|
||||
<MyEchart ref="historyChart" :options="echartsData" v-if="showEchart" />
|
||||
<el-empty :style="pageHeight" v-else description="暂无数据" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
@@ -157,28 +156,40 @@ const countOptions: any = ref([])
|
||||
const legendDictList: any = ref([])
|
||||
|
||||
const initCode = (field: string, title: string) => {
|
||||
queryByCode('steady_state_limit_trend').then(res => {
|
||||
queryByCode('gridSide_exceedTheLimit').then(res => {
|
||||
queryCsDictTree(res.data.id).then(item => {
|
||||
//排序
|
||||
indexOptions.value = item.data.sort((a: any, b: any) => {
|
||||
return a.sort - b.sort
|
||||
})
|
||||
const titleMap: Record<string, number> = {
|
||||
flickerOvertime: 0,
|
||||
uaberranceOvertime: 3,
|
||||
ubalanceOvertime: 4,
|
||||
freqDevOvertime: 5
|
||||
}
|
||||
let codeKey = field.includes('flickerOvertime')
|
||||
? '闪变'
|
||||
: field.includes('uharm')
|
||||
? '谐波电压'
|
||||
: field.includes('iharm')
|
||||
? '谐波电流'
|
||||
: field.includes('voltageDevOvertime')
|
||||
? '电压偏差'
|
||||
: field.includes('ubalanceOvertime')
|
||||
? '不平衡'
|
||||
: ''
|
||||
|
||||
let defaultIndex = 0 // 默认值
|
||||
// const titleMap: Record<string, number> = {
|
||||
// flickerOvertime: 0,
|
||||
// uaberranceOvertime: 3,
|
||||
// ubalanceOvertime: 4,
|
||||
// freqDevOvertime: 5
|
||||
// }
|
||||
|
||||
if (field in titleMap) {
|
||||
defaultIndex = titleMap[field]
|
||||
} else if (field.includes('uharm')) {
|
||||
defaultIndex = 1
|
||||
} else if (field.includes('iharm')) {
|
||||
defaultIndex = 2
|
||||
}
|
||||
// let defaultIndex = 0 // 默认值
|
||||
let defaultIndex = indexOptions.value.findIndex((item: any) => item.name.includes(codeKey)) || 0
|
||||
// if (field in titleMap) {
|
||||
// defaultIndex = titleMap[field]
|
||||
// } else if (field.includes('uharm')) {
|
||||
// defaultIndex = indexOptions.value.findIndex((item: any) => item.code === 'uharm')
|
||||
// } else if (field.includes('iharm')) {
|
||||
// defaultIndex = indexOptions.value.findIndex((item: any) => item.code === 'iharm')
|
||||
// }
|
||||
|
||||
searchForm.value.index[0] = indexOptions.value[defaultIndex].id
|
||||
})
|
||||
@@ -202,7 +213,7 @@ const initCode = (field: string, title: string) => {
|
||||
if (kk.harmStart && kk.harmEnd) {
|
||||
range(0, 0, 0)
|
||||
|
||||
if (kk.showName == '间谐波电压含有率') {
|
||||
if (kk.showName.includes('间谐波电压')) {
|
||||
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1).map(
|
||||
(item: any) => {
|
||||
return item - 0.5
|
||||
@@ -284,14 +295,15 @@ const init = async () => {
|
||||
let lists: any = []
|
||||
let frequencys: any = null
|
||||
countData.value.map((item: any, index: any) => {
|
||||
if (item.name.includes('谐波含有率')) {
|
||||
if (item.name.includes('谐波')) {
|
||||
frequencys = item.count
|
||||
} else {
|
||||
frequencys = ''
|
||||
}
|
||||
|
||||
lists[index] = {
|
||||
statisticalId: item.index,
|
||||
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
||||
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
||||
}
|
||||
})
|
||||
let obj = {
|
||||
@@ -597,12 +609,12 @@ const formatCountOptions = () => {
|
||||
})
|
||||
|
||||
countData.value.map((item: any, key: any) => {
|
||||
if (item.name == '谐波电流有效值') {
|
||||
item.name = '谐波电流次数'
|
||||
} else if (item.name == '谐波电压含有率') {
|
||||
item.name = '谐波电压次数'
|
||||
} else if (item.name == '间谐波电压含有率') {
|
||||
if (item.name.includes('间谐波电压')) {
|
||||
item.name = '间谐波电压次数'
|
||||
} else if (item.name.includes('谐波电流')) {
|
||||
item.name = '谐波电流次数'
|
||||
} else if (item.name.includes('谐波电压')) {
|
||||
item.name = '谐波电压次数'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
v-model="tableStore.table.params.lineId"
|
||||
placeholder="请选择监测点"
|
||||
style="width: 150px"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.lineId"
|
||||
:label="item.name"
|
||||
:label="item.lineName"
|
||||
:value="item.lineId"
|
||||
/>
|
||||
</el-select>
|
||||
@@ -48,7 +49,7 @@ const loop50 = (key: string) => {
|
||||
list.push({
|
||||
title: i + '次',
|
||||
field: key + i + 'Overtime',
|
||||
width: '80',
|
||||
width: '60',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||
@@ -58,7 +59,7 @@ const loop50 = (key: string) => {
|
||||
return list
|
||||
}
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/harmonic-boot/totalLimitStatistics/details',
|
||||
url: '/cs-harmonic-boot/totalLimitStatistics/details',
|
||||
method: 'POST',
|
||||
publicHeight: 30,
|
||||
showPage: false,
|
||||
@@ -84,9 +85,9 @@ const tableStore: any = new TableStore({
|
||||
width: '150'
|
||||
},
|
||||
{
|
||||
title: '闪变越限(%)',
|
||||
title: '长时闪变越限(%)',
|
||||
field: 'flickerOvertime',
|
||||
width: '80',
|
||||
width: '90',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||
@@ -100,16 +101,7 @@ const tableStore: any = new TableStore({
|
||||
title: '谐波电流越限(%)',
|
||||
children: loop50('iharm')
|
||||
},
|
||||
{
|
||||
title: '三相不平衡度越限(%)',
|
||||
field: 'ubalanceOvertime',
|
||||
width: '100',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
title: '电压偏差越限(%)',
|
||||
field: 'voltageDevOvertime',
|
||||
width: '100',
|
||||
@@ -119,14 +111,24 @@ const tableStore: any = new TableStore({
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '频率偏差越限(%)',
|
||||
field: 'freqDevOvertime',
|
||||
title: '三相不平衡度越限(%)',
|
||||
field: 'ubalanceOvertime',
|
||||
width: '100',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// {
|
||||
// title: '频率偏差越限(%)',
|
||||
// field: 'freqDevOvertime',
|
||||
// width: '100',
|
||||
// render: 'customTemplate',
|
||||
// customTemplate: (row: any) => {
|
||||
// return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||
// }
|
||||
// }
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
},
|
||||
@@ -138,16 +140,20 @@ const tableStore: any = new TableStore({
|
||||
provide('tableStore', tableStore)
|
||||
tableStore.table.params.sortBy = ''
|
||||
tableStore.table.params.orderBy = ''
|
||||
const open = async (row: any,searchBeginTime:any,searchEndTime:any) => {
|
||||
const open = async (row: any,searchBeginTime:any,searchEndTime:any,interval:any,list:any) => {
|
||||
dialogVisible.value = true
|
||||
initCSlineList()
|
||||
options.value = list
|
||||
// initCSlineList()
|
||||
tableStore.table.params.lineId = row.lineId
|
||||
|
||||
nextTick(() => {
|
||||
tableHeaderRef.value.setTimeInterval([searchBeginTime, searchEndTime])
|
||||
tableHeaderRef.value.setInterval(interval)
|
||||
setTimeout(() => {
|
||||
tableHeaderRef.value.setTimeInterval([searchBeginTime, searchEndTime])
|
||||
tableStore.table.params.searchBeginTime =searchBeginTime
|
||||
tableStore.table.params.searchEndTime = searchEndTime
|
||||
tableStore.index()
|
||||
},100)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--电网侧指标越限统计 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||
<TableHeader
|
||||
:showReset="false"
|
||||
ref="TableHeaderRef"
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
:timeKeyList="prop.timeKey"
|
||||
v-if="fullscreen"
|
||||
></TableHeader>
|
||||
<my-echart
|
||||
class="tall"
|
||||
:options="echartList"
|
||||
@@ -27,23 +34,25 @@ import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import OverLimitDetails from '@/components/cockpit/gridSideStatistics/components/overLimitDetails.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||
import { gridSideLimitStatisticsData } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const echartList = ref({})
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
|
||||
@@ -79,7 +88,7 @@ const initEcharts = () => {
|
||||
|
||||
xAxis: {
|
||||
// name: '(区域)',
|
||||
data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||
data: ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||
},
|
||||
|
||||
yAxis: {
|
||||
@@ -117,7 +126,7 @@ const initEcharts = () => {
|
||||
|
||||
const OverLimitDetailsRef = ref()
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/harmonic-boot/gridSideLimitStatistics/list',
|
||||
url: '/cs-harmonic-boot/gridSideLimitStatistics/list',
|
||||
method: 'POST',
|
||||
|
||||
showPage: false,
|
||||
@@ -140,7 +149,7 @@ const tableStore: any = new TableStore({
|
||||
title: '越限占比(%)',
|
||||
children: [
|
||||
{
|
||||
title: '闪变',
|
||||
title: '长时闪变',
|
||||
field: 'flicker',
|
||||
minWidth: '70',
|
||||
render: 'customTemplate',
|
||||
@@ -188,8 +197,8 @@ const tableStore: any = new TableStore({
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
tableStore.table.params.interval = TableHeaderRef.value?.datePickerRef?.interval || 3
|
||||
},
|
||||
loadCallback: () => {
|
||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||
@@ -204,18 +213,37 @@ provide('tableStore', tableStore)
|
||||
|
||||
// 点击行
|
||||
const cellClickEvent = ({ row, column }: any) => {
|
||||
if (column.field != 'name') {
|
||||
OverLimitDetailsRef.value.open(
|
||||
row,
|
||||
tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
||||
tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
)
|
||||
}
|
||||
OverLimitDetailsRef.value.open(
|
||||
row,
|
||||
tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
||||
tableStore.table.params.searchEndTime || prop.timeValue?.[1],
|
||||
tableStore.table.params.interval || prop.interval,
|
||||
tableStore.table.data
|
||||
)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
@@ -226,12 +254,7 @@ watch(
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
|
||||
480
src/components/cockpit/indicatorCrossingTime/index.vue
Normal file
480
src/components/cockpit/indicatorCrossingTime/index.vue
Normal file
@@ -0,0 +1,480 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--指标越限时间分布
|
||||
-->
|
||||
<TableHeader
|
||||
:showReset="false"
|
||||
:timeKeyList="prop.timeKey"
|
||||
ref="TableHeaderRef"
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
v-if="fullscreen"
|
||||
>
|
||||
<template v-slot:select>
|
||||
<el-form-item label="监测点">
|
||||
<el-select size="small" filterable v-model="tableStore.table.params.lineId">
|
||||
<el-option
|
||||
v-for="item in lineList"
|
||||
:key="item.lineId"
|
||||
:label="item.name"
|
||||
:value="item.lineId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<div v-loading="tableStore.table.loading">
|
||||
<my-echart
|
||||
class="tall"
|
||||
v-if="lineShow"
|
||||
:options="echartList1"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||
}"
|
||||
/>
|
||||
<el-empty
|
||||
v-else
|
||||
description="暂无监测点"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||
}"
|
||||
/>
|
||||
<!-- <my-echart
|
||||
class="mt10"
|
||||
:options="echartList1"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||
}"
|
||||
/> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { limitProbabilityData, cslineList } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
// const options = ref(JSON.parse(window.localStorage.getItem('lineIdList') || '[]'))
|
||||
|
||||
const lineList = ref()
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
const lineShow = ref(true)
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
|
||||
if (datePickerValue && datePickerValue.timeValue) {
|
||||
// 更新时间参数
|
||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
}
|
||||
}
|
||||
|
||||
// 计算是否全屏展示
|
||||
const fullscreen = computed(() => {
|
||||
const w = Number(prop.w)
|
||||
const h = Number(prop.h)
|
||||
if (!isNaN(w) && !isNaN(h) && w === 12 && h === 6) {
|
||||
// 执行相应逻辑
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
const echartList = ref()
|
||||
|
||||
const echartList1 = ref()
|
||||
|
||||
const probabilityData = ref()
|
||||
|
||||
const initLineList = async () => {
|
||||
cslineList({}).then(res => {
|
||||
if (res.data.length == 0) {
|
||||
lineShow.value = false
|
||||
return (tableStore.table.loading = false)
|
||||
}
|
||||
lineShow.value = true
|
||||
lineList.value = res.data
|
||||
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||
tableStore.index()
|
||||
})
|
||||
}
|
||||
|
||||
// 越限程度概率分布
|
||||
const initProbabilityData = () => {
|
||||
// 只有当 lineList 已加载且有数据时才设置默认 lineId
|
||||
if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) {
|
||||
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||
}
|
||||
const params = {
|
||||
searchBeginTime: tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
||||
searchEndTime: tableStore.table.params.searchEndTime || prop.timeValue?.[1],
|
||||
lineId: tableStore.table.params.lineId
|
||||
}
|
||||
limitProbabilityData(params).then((res: any) => {
|
||||
probabilityData.value = res.data
|
||||
|
||||
// 处理接口返回的数据,转换为图表所需格式
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
// 定义指标类型顺序
|
||||
const indicatorOrder = ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相电压不平衡度', '频率偏差']
|
||||
// 按照指定顺序排序数据
|
||||
const sortedData = [...res.data].sort((a, b) => {
|
||||
return indicatorOrder.indexOf(a.indexName) - indicatorOrder.indexOf(b.indexName)
|
||||
})
|
||||
|
||||
// 构造 series 数据
|
||||
const seriesData: any = []
|
||||
let maxValue: any = 0 // 用于存储数据中的最大值
|
||||
// 遍历每个越限程度区间(0-20%, 20-40%, 40-60%, 60-80%, 80-100%)
|
||||
for (let xIndex = 0; xIndex < 5; xIndex++) {
|
||||
// 遍历每个指标类型
|
||||
sortedData.forEach((item, yIndex) => {
|
||||
// 从 extentGrades 中获取对应区间的值
|
||||
const extentGrade = item.extentGrades[xIndex]
|
||||
const value = extentGrade ? (Object.values(extentGrade)[0] as number) : 0
|
||||
seriesData.push([xIndex, yIndex, value])
|
||||
|
||||
// 更新最大值
|
||||
if (value > maxValue) {
|
||||
maxValue = value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 计算 z 轴最大值(最大值加 5)
|
||||
const zAxisMax = Math.ceil(maxValue) + 5
|
||||
// 构造 yAxis 数据(指标类型名称)
|
||||
const yAxisData = sortedData.map(item => item.indexName)
|
||||
|
||||
echartList.value = {
|
||||
title: {
|
||||
text: '指标越限概率分布'
|
||||
},
|
||||
options: {
|
||||
backgroundColor: '#fff',
|
||||
tooltip: {
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0,
|
||||
formatter: function (params: any) {
|
||||
var yIndex = params.value[1] //获取y轴索引
|
||||
var tips = ''
|
||||
tips += '指标类型: ' + yAxisData[yIndex] + '</br>'
|
||||
tips += '越限程度: ' + params.seriesName + '</br>'
|
||||
tips += '越限次数: ' + params.value[2] + '</br>'
|
||||
return tips
|
||||
}
|
||||
},
|
||||
|
||||
// 移除或隐藏 visualMap 组件
|
||||
visualMap: {
|
||||
show: false, // 设置为 false 隐藏右侧颜色条
|
||||
min: 0,
|
||||
// max: 100,
|
||||
max: zAxisMax, // 使用计算出的最大值加5
|
||||
inRange: {
|
||||
color: ['#313695', '#00BB00', '#ff8000', '#d73027', '#a50026']
|
||||
}
|
||||
},
|
||||
// 添加 legend 配置并设置为不显示
|
||||
legend: {
|
||||
show: false // 隐藏图例
|
||||
},
|
||||
xAxis3D: {
|
||||
type: 'category',
|
||||
name: '越限程度',
|
||||
nameLocation: 'middle',
|
||||
nameGap: 50,
|
||||
data: ['0-20%', '20-40%', '40-60%', '60-80%', '80-100%']
|
||||
},
|
||||
yAxis3D: {
|
||||
type: 'category',
|
||||
name: '指标类型',
|
||||
nameLocation: 'middle',
|
||||
nameGap: 50,
|
||||
data: yAxisData,
|
||||
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
},
|
||||
zAxis3D: {
|
||||
type: 'value',
|
||||
name: '越限次数',
|
||||
nameLocation: 'middle',
|
||||
nameGap: 30,
|
||||
minInterval: 10
|
||||
|
||||
// max: 100
|
||||
},
|
||||
grid3D: {
|
||||
viewControl: {
|
||||
projection: 'perspective',
|
||||
distance: 260,
|
||||
rotateSensitivity: 10,
|
||||
zoomSensitivity: 2
|
||||
},
|
||||
boxWidth: 150,
|
||||
boxDepth: 100,
|
||||
boxHeight: 100,
|
||||
light: {
|
||||
main: {
|
||||
intensity: 1.2
|
||||
},
|
||||
ambient: {
|
||||
intensity: 0.4
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'bar3D',
|
||||
name: '0-20%',
|
||||
data: seriesData.filter((item: any) => item[0] === 0),
|
||||
shading: 'realistic',
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
itemStyle: {
|
||||
opacity: 0.9
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
color: '#000'
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#ff8000'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'bar3D',
|
||||
name: '20-40%',
|
||||
data: seriesData.filter((item: any) => item[0] === 1),
|
||||
shading: 'realistic',
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
itemStyle: {
|
||||
opacity: 0.9
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
color: '#000'
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#ff8000'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'bar3D',
|
||||
name: '40-60%',
|
||||
data: seriesData.filter((item: any) => item[0] === 2),
|
||||
shading: 'realistic',
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
itemStyle: {
|
||||
opacity: 0.9
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
color: '#000'
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#ff8000'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'bar3D',
|
||||
name: '60-80%',
|
||||
data: seriesData.filter((item: any) => item[0] === 3),
|
||||
shading: 'realistic',
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
itemStyle: {
|
||||
opacity: 0.9
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
color: '#000'
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#ff8000'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'bar3D',
|
||||
name: '80-100%',
|
||||
data: seriesData.filter((item: any) => item[0] === 4),
|
||||
shading: 'realistic',
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
itemStyle: {
|
||||
opacity: 0.9
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
color: '#000'
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#ff8000'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/cs-harmonic-boot/limitRateDetailD/limitTimeProbabilityData',
|
||||
method: 'POST',
|
||||
showPage: false,
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
setTime()
|
||||
// 只有当 lineList 已加载且有数据时才设置默认 lineId
|
||||
if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) {
|
||||
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||
}
|
||||
},
|
||||
loadCallback: () => {
|
||||
// 处理返回的数据,将其转换为图表所需格式
|
||||
const indexNames: any = [...new Set(tableStore.table.data.map((item: any) => item.indexName))]
|
||||
const timePeriods = [...new Set(tableStore.table.data.map((item: any) => item.timePeriod))]
|
||||
|
||||
// 构建系列数据
|
||||
const seriesData = indexNames.map((indexName: string) => {
|
||||
const dataIndex = tableStore.table.data.filter((item: any) => item.indexName === indexName)
|
||||
return {
|
||||
name: indexName,
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
data: dataIndex.map((item: any) => [item.timePeriod, item.times])
|
||||
}
|
||||
})
|
||||
|
||||
echartList1.value = {
|
||||
title: {
|
||||
text: '指标越限时间概率分布'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: indexNames
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
name: '时间段',
|
||||
data: timePeriods
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
// name: '次数'
|
||||
},
|
||||
series: seriesData
|
||||
}
|
||||
initProbabilityData()
|
||||
}
|
||||
})
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
onMounted(() => {
|
||||
initLineList()
|
||||
})
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
tableStore.index()
|
||||
}
|
||||
)
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
const addMenu = () => {}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -1,7 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--指标越限明细 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||
<TableHeader
|
||||
:showReset="false"
|
||||
ref="TableHeaderRef"
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
v-if="fullscreen"
|
||||
:timeKeyList="prop.timeKey"
|
||||
></TableHeader>
|
||||
<el-calendar
|
||||
v-model="value"
|
||||
:style="{
|
||||
@@ -25,7 +32,7 @@
|
||||
<template #content>
|
||||
<span v-html="getTextForDate(data.day)"></span>
|
||||
</template>
|
||||
<div class="details" v-html="getTextForDate(data.day)"></div>
|
||||
<div class="details" v-html="fullscreen ? getTextForDate(data.day) : '有越限'"></div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
@@ -37,20 +44,24 @@ import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { dayjs } from 'element-plus'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const list = ref()
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
dayjs.en.weekStart = 1 //设置日历的周起始日为星期一
|
||||
const value = ref(new Date())
|
||||
|
||||
@@ -82,46 +93,15 @@ const getTextForDate = (date: string) => {
|
||||
}
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
// url: '/user-boot/role/selectRoleDetail?id=0',
|
||||
url: '/harmonic-boot/limitRateDetailD/limitCalendarData',
|
||||
url: '/cs-harmonic-boot/limitRateDetailD/limitCalendarData',
|
||||
method: 'POST',
|
||||
showPage: false,
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
value.value = tableStore.table.params.searchBeginTime
|
||||
// 将后端返回的数据整合到 list 中
|
||||
// tableStore.table.data = [
|
||||
// {
|
||||
// "time": "2025-11-13",
|
||||
// "items": [
|
||||
// "闪变越限",
|
||||
// "谐波电流越限"
|
||||
// ],
|
||||
// "status": 1
|
||||
// },
|
||||
// {
|
||||
// "time": "2025-11-14",
|
||||
// "items": [
|
||||
// "频率偏差越限",
|
||||
// "三相电压不平衡越限",
|
||||
// "谐波电压越限",
|
||||
// "谐波电流越限",
|
||||
// "频率偏差越限",
|
||||
// "三相电压不平衡越限",
|
||||
// "谐波电压越限",
|
||||
// "谐波电流越限",
|
||||
// "频率偏差越限",
|
||||
// "三相电压不平衡越限",
|
||||
// "谐波电压越限",
|
||||
// "谐波电流越限"
|
||||
// ],
|
||||
// "status": 2
|
||||
// }
|
||||
// ]
|
||||
if (tableStore.table.data && tableStore.table.data.length > 0) {
|
||||
list.value = tableStore.table.data.map((item: any) => {
|
||||
// 将 items 数组转换为带换行的文本
|
||||
@@ -162,30 +142,39 @@ const setBackground = (value: string) => {
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
nextTick(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
})
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
const addMenu = () => {}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-calendar) {
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--指标越限概率分布 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen">
|
||||
<TableHeader
|
||||
:showReset="false"
|
||||
:timeKeyList="prop.timeKey"
|
||||
ref="TableHeaderRef"
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
v-if="fullscreen"
|
||||
>
|
||||
<template v-slot:select>
|
||||
<el-form-item label="监测点">
|
||||
<el-select size="small" v-model="tableStore.table.params.lineId">
|
||||
<el-select size="small" filterable v-model="tableStore.table.params.lineId">
|
||||
<el-option
|
||||
v-for="item in lineList"
|
||||
:key="item.lineId"
|
||||
@@ -17,21 +24,30 @@
|
||||
</TableHeader>
|
||||
<div v-loading="tableStore.table.loading">
|
||||
<my-echart
|
||||
v-if="lineShow"
|
||||
class="tall"
|
||||
:options="echartList"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||
}"
|
||||
/>
|
||||
<my-echart
|
||||
<el-empty
|
||||
v-else
|
||||
description="暂无监测点"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||
}"
|
||||
/>
|
||||
<!-- <my-echart
|
||||
class="mt10"
|
||||
:options="echartList1"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||
}"
|
||||
/>
|
||||
/> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -41,22 +57,26 @@ import TableStore from '@/utils/tableStore'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { limitProbabilityData, cslineList } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const lineShow = ref(true)
|
||||
// const options = ref(JSON.parse(window.localStorage.getItem('lineIdList') || '[]'))
|
||||
|
||||
const lineList = ref()
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
|
||||
@@ -87,6 +107,11 @@ const probabilityData = ref()
|
||||
|
||||
const initLineList = async () => {
|
||||
cslineList({}).then(res => {
|
||||
if (res.data.length == 0) {
|
||||
lineShow.value = false
|
||||
return (tableStore.table.loading = false)
|
||||
}
|
||||
lineShow.value = true
|
||||
lineList.value = res.data
|
||||
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||
tableStore.index()
|
||||
@@ -110,7 +135,7 @@ const initProbabilityData = () => {
|
||||
// 处理接口返回的数据,转换为图表所需格式
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
// 定义指标类型顺序
|
||||
const indicatorOrder = ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相电压不平衡度', '频率偏差']
|
||||
const indicatorOrder = ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相电压不平衡度', '频率偏差']
|
||||
// 按照指定顺序排序数据
|
||||
const sortedData = [...res.data].sort((a, b) => {
|
||||
return indicatorOrder.indexOf(a.indexName) - indicatorOrder.indexOf(b.indexName)
|
||||
@@ -141,6 +166,9 @@ const initProbabilityData = () => {
|
||||
const yAxisData = sortedData.map(item => item.indexName)
|
||||
|
||||
echartList.value = {
|
||||
title: {
|
||||
text: '指标越限概率分布'
|
||||
},
|
||||
options: {
|
||||
backgroundColor: '#fff',
|
||||
tooltip: {
|
||||
@@ -161,14 +189,7 @@ const initProbabilityData = () => {
|
||||
return tips
|
||||
}
|
||||
},
|
||||
title: {
|
||||
text: '指标越限概率分布',
|
||||
x: 'center',
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'normal'
|
||||
}
|
||||
},
|
||||
|
||||
// 移除或隐藏 visualMap 组件
|
||||
visualMap: {
|
||||
show: false, // 设置为 false 隐藏右侧颜色条
|
||||
@@ -187,43 +208,18 @@ const initProbabilityData = () => {
|
||||
type: 'category',
|
||||
name: '越限程度',
|
||||
nameLocation: 'middle',
|
||||
nameGap: 30,
|
||||
data: ['0-20%', '20-40%', '40-60%', '60-80%', '80-100%'],
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#111'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#111',
|
||||
margin: 15
|
||||
},
|
||||
nameTextStyle: {
|
||||
color: '#111'
|
||||
}
|
||||
nameGap: 50,
|
||||
data: ['0-20%', '20-40%', '40-60%', '60-80%', '80-100%']
|
||||
},
|
||||
yAxis3D: {
|
||||
type: 'category',
|
||||
name: '指标类型',
|
||||
nameLocation: 'middle',
|
||||
nameGap: 30,
|
||||
nameGap: 50,
|
||||
data: yAxisData,
|
||||
nameTextStyle: {
|
||||
color: '#111'
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#111'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#111',
|
||||
margin: 15
|
||||
},
|
||||
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: ['#111'],
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
@@ -234,25 +230,14 @@ const initProbabilityData = () => {
|
||||
name: '越限次数',
|
||||
nameLocation: 'middle',
|
||||
nameGap: 30,
|
||||
nameTextStyle: {
|
||||
color: '#111'
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#111'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#111'
|
||||
},
|
||||
min: 0,
|
||||
max: zAxisMax // 使用计算出的最大值加5
|
||||
minInterval: 10
|
||||
|
||||
// max: 100
|
||||
},
|
||||
grid3D: {
|
||||
viewControl: {
|
||||
projection: 'perspective',
|
||||
distance: 250,
|
||||
distance: 260,
|
||||
rotateSensitivity: 10,
|
||||
zoomSensitivity: 2
|
||||
},
|
||||
@@ -397,13 +382,12 @@ const initProbabilityData = () => {
|
||||
}
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/harmonic-boot/limitRateDetailD/limitTimeProbabilityData',
|
||||
url: '/cs-harmonic-boot/limitRateDetailD/limitTimeProbabilityData',
|
||||
method: 'POST',
|
||||
showPage: false,
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
// 只有当 lineList 已加载且有数据时才设置默认 lineId
|
||||
if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) {
|
||||
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||
@@ -420,13 +404,14 @@ const tableStore: any = new TableStore({
|
||||
return {
|
||||
name: indexName,
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
data: dataIndex.map((item: any) => [item.timePeriod, item.times])
|
||||
}
|
||||
})
|
||||
|
||||
echartList1.value = {
|
||||
title: {
|
||||
text: '越限时间概率分布'
|
||||
text: '指标越限时间概率分布'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
@@ -454,6 +439,25 @@ provide('tableStore', tableStore)
|
||||
onMounted(() => {
|
||||
initLineList()
|
||||
})
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
@@ -463,12 +467,7 @@ watch(
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
v-model="searchForm.index"
|
||||
placeholder="请选择统计指标"
|
||||
@change="onIndexChange($event)"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in indexOptions"
|
||||
@@ -36,6 +37,7 @@
|
||||
style="min-width: 120px !important"
|
||||
placeholder="请选择"
|
||||
v-model="searchForm.valueType"
|
||||
filterable
|
||||
>
|
||||
<el-option value="max" label="最大值"></el-option>
|
||||
<el-option value="min" label="最小值"></el-option>
|
||||
@@ -59,11 +61,12 @@
|
||||
placeholder="请选择谐波次数"
|
||||
style="width: 100px"
|
||||
class="mr20"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="vv in item.countOptions"
|
||||
:key="vv"
|
||||
:label="vv"
|
||||
:label="item.name.includes('间谐波') ? vv - 0.5 : vv"
|
||||
:value="vv"
|
||||
></el-option>
|
||||
</el-select>
|
||||
@@ -78,12 +81,8 @@
|
||||
</template>
|
||||
</TableHeader>
|
||||
</div>
|
||||
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
||||
<MyEchart
|
||||
ref="historyChart"
|
||||
:options="echartsData"
|
||||
v-if="showEchart"
|
||||
/>
|
||||
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
||||
<MyEchart ref="historyChart" :options="echartsData" v-if="showEchart" />
|
||||
<el-empty :style="pageHeight" v-else description="暂无数据" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
@@ -157,28 +156,40 @@ const countOptions: any = ref([])
|
||||
const legendDictList: any = ref([])
|
||||
|
||||
const initCode = (field: string, title: string) => {
|
||||
queryByCode('steady_state_limit_trend').then(res => {
|
||||
queryByCode('gridSide_exceedTheLimit').then(res => {
|
||||
queryCsDictTree(res.data.id).then(item => {
|
||||
//排序
|
||||
indexOptions.value = item.data.sort((a: any, b: any) => {
|
||||
return a.sort - b.sort
|
||||
})
|
||||
const titleMap: Record<string, number> = {
|
||||
flickerOvertime: 0,
|
||||
uaberranceOvertime: 3,
|
||||
ubalanceOvertime: 4,
|
||||
freqDevOvertime: 5
|
||||
}
|
||||
// const titleMap: Record<string, number> = {
|
||||
// flickerOvertime: 0,
|
||||
// uaberranceOvertime: 3,
|
||||
// ubalanceOvertime: 4,
|
||||
// freqDevOvertime: 5
|
||||
// }
|
||||
|
||||
let defaultIndex = 0 // 默认值
|
||||
// let defaultIndex = 0 // 默认值
|
||||
|
||||
if (field in titleMap) {
|
||||
defaultIndex = titleMap[field]
|
||||
} else if (field.includes('uharm')) {
|
||||
defaultIndex = 1
|
||||
} else if (field.includes('iharm')) {
|
||||
defaultIndex = 2
|
||||
}
|
||||
// if (field in titleMap) {
|
||||
// defaultIndex = titleMap[field]
|
||||
// } else if (field.includes('uharm')) {
|
||||
// defaultIndex = 1
|
||||
// } else if (field.includes('iharm')) {
|
||||
// defaultIndex = 2
|
||||
// }
|
||||
let codeKey = field.includes('flickerOvertime')
|
||||
? '闪变'
|
||||
: field.includes('uharm')
|
||||
? '谐波电压'
|
||||
: field.includes('iharm')
|
||||
? '谐波电流'
|
||||
: field.includes('voltageDevOvertime')
|
||||
? '电压偏差'
|
||||
: field.includes('ubalanceOvertime')
|
||||
? '不平衡'
|
||||
: ''
|
||||
let defaultIndex = indexOptions.value.findIndex((item: any) => item.name.includes(codeKey)) || 0
|
||||
|
||||
searchForm.value.index[0] = indexOptions.value[defaultIndex].id
|
||||
})
|
||||
@@ -291,7 +302,7 @@ const init = async () => {
|
||||
}
|
||||
lists[index] = {
|
||||
statisticalId: item.index,
|
||||
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
||||
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
||||
}
|
||||
})
|
||||
let obj = {
|
||||
@@ -576,7 +587,6 @@ const setTimeControl = () => {
|
||||
}
|
||||
|
||||
const selectChange = (flag: boolean, height: any) => {
|
||||
|
||||
pageHeight.value = mainHeight(height * 1.6, 1.6)
|
||||
}
|
||||
//导出
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
v-model="tableStore.table.params.lineId"
|
||||
placeholder="请选择监测点"
|
||||
style="width: 150px"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.lineId"
|
||||
:label="item.name"
|
||||
:label="item.lineName"
|
||||
:value="item.lineId"
|
||||
/>
|
||||
</el-select>
|
||||
@@ -23,11 +24,7 @@
|
||||
<Table ref="tableRef" @cell-click="cellClickEvent" isGroup :height="height"></Table>
|
||||
</el-dialog>
|
||||
<!-- 谐波电流、谐波电压占有率 -->
|
||||
<HarmonicRatio
|
||||
ref="harmonicRatioRef"
|
||||
@close="onHarmonicRatioClose"
|
||||
v-if="dialogFlag"
|
||||
/>
|
||||
<HarmonicRatio ref="harmonicRatioRef" @close="onHarmonicRatioClose" v-if="dialogFlag" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
@@ -53,7 +50,7 @@ const loop50 = (key: string) => {
|
||||
list.push({
|
||||
title: i + '次',
|
||||
field: key + i + 'Overtime',
|
||||
width: '80',
|
||||
width: '60',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||
@@ -63,7 +60,7 @@ const loop50 = (key: string) => {
|
||||
return list
|
||||
}
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/harmonic-boot/mainLine/statLimitRateDetails',
|
||||
url: '/cs-harmonic-boot/mainLine/statLimitRateDetails',
|
||||
method: 'POST',
|
||||
publicHeight: 30,
|
||||
showPage: false,
|
||||
@@ -89,9 +86,9 @@ const tableStore: any = new TableStore({
|
||||
width: '150'
|
||||
},
|
||||
{
|
||||
title: '闪变越限(分钟)',
|
||||
title: '越限(分钟)',
|
||||
field: 'flickerOvertime',
|
||||
width: '80',
|
||||
width: '90',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||
@@ -104,6 +101,14 @@ const tableStore: any = new TableStore({
|
||||
{
|
||||
title: '谐波电流越限(分钟)',
|
||||
children: loop50('iharm')
|
||||
}, {
|
||||
title: '电压偏差越限(分钟)',
|
||||
field: 'uaberranceOvertime',
|
||||
width: '100',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '三相不平衡度越限(分钟)',
|
||||
@@ -114,24 +119,16 @@ const tableStore: any = new TableStore({
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '电压偏差越限(分钟)',
|
||||
field: 'uaberranceOvertime',
|
||||
width: '100',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '频率偏差越限(分钟)',
|
||||
field: 'freqDevOvertime',
|
||||
width: '100',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||
}
|
||||
}
|
||||
|
||||
// {
|
||||
// title: '频率偏差越限(分钟)',
|
||||
// field: 'freqDevOvertime',
|
||||
// width: '100',
|
||||
// render: 'customTemplate',
|
||||
// customTemplate: (row: any) => {
|
||||
// return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||
// }
|
||||
// }
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
},
|
||||
@@ -143,9 +140,10 @@ const tableStore: any = new TableStore({
|
||||
provide('tableStore', tableStore)
|
||||
tableStore.table.params.sortBy = ''
|
||||
tableStore.table.params.orderBy = ''
|
||||
const open = async (row: any,searchBeginTime:any,searchEndTime:any) => {
|
||||
const open = async (row: any,searchBeginTime:any,searchEndTime:any,data:any=[]) => {
|
||||
dialogVisible.value = true
|
||||
initCSlineList()
|
||||
// initCSlineList()
|
||||
options.value = data
|
||||
tableStore.table.params.lineId = row.lineId
|
||||
|
||||
nextTick(() => {
|
||||
@@ -179,8 +177,8 @@ const onHarmonicRatioClose = () => {
|
||||
}
|
||||
|
||||
const initCSlineList = async () => {
|
||||
const res = await cslineList({})
|
||||
options.value = res.data
|
||||
// const res = await cslineList({})
|
||||
// options.value = res.data
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--主要监测点列表 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" v-if="fullscreen" datePicker ref="tableHeaderRef">
|
||||
<TableHeader
|
||||
:showReset="false"
|
||||
:timeKeyList="prop.timeKey"
|
||||
@selectChange="selectChange"
|
||||
v-if="fullscreen"
|
||||
|
||||
ref="TableHeaderRef"
|
||||
>
|
||||
<template v-slot:select>
|
||||
<el-form-item label="关键词">
|
||||
<el-input v-model="tableStore.table.params.keywords" clearable placeholder="请输关键字" />
|
||||
<el-form-item label="关键字筛选">
|
||||
<el-input v-model="tableStore.table.params.keywords" clearable placeholder="请输入监测点名称" />
|
||||
</el-form-item>
|
||||
</template>
|
||||
</TableHeader>
|
||||
@@ -26,15 +33,15 @@ import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||
import OverLimitDetails from '@/components/cockpit/indicatorFittingChart/components/overLimitDetails.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||
import { log } from 'console'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
const OverLimitDetailsRef = ref()
|
||||
const headerHeight = ref(57)
|
||||
@@ -42,7 +49,7 @@ const headerHeight = ref(57)
|
||||
const route = useRoute()
|
||||
const timeCacheStore = useTimeCacheStore()
|
||||
|
||||
const tableHeaderRef = ref()
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
// 计算是否全屏展示
|
||||
const fullscreen = computed(() => {
|
||||
@@ -59,15 +66,15 @@ const fullscreen = computed(() => {
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
|
||||
if (datePickerValue && datePickerValue.timeValue) {
|
||||
// 更新时间参数
|
||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
}
|
||||
// if (datePickerValue && datePickerValue.timeValue) {
|
||||
// // 更新时间参数
|
||||
// tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
// tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
// }
|
||||
}
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/harmonic-boot/mainLine/list',
|
||||
url: '/cs-harmonic-boot/mainLine/list',
|
||||
method: 'POST',
|
||||
showPage: fullscreen.value ? true : false,
|
||||
exportName: '主要监测点列表',
|
||||
@@ -93,19 +100,24 @@ const tableStore: any = new TableStore({
|
||||
{
|
||||
title: '监测对象类型',
|
||||
field: 'objType',
|
||||
minWidth: '90'
|
||||
minWidth: '90',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '是否治理',
|
||||
field: 'govern',
|
||||
minWidth: '70'
|
||||
minWidth: '80',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
|
||||
{ title: '主要存在的电能质量问题', field: 'problems', minWidth: '150', showOverflow: true }
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||
@@ -120,33 +132,45 @@ provide('tableStore', tableStore)
|
||||
// 点击行
|
||||
const cellClickEvent = ({ row, column }: any) => {
|
||||
if (column.field == 'lineName') {
|
||||
|
||||
let time = getTimeOfTheMonth('3');
|
||||
OverLimitDetailsRef.value.open(
|
||||
row,
|
||||
tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
||||
tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
time[0],
|
||||
time[1],
|
||||
tableStore.table.data
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const setTime = () => {
|
||||
// const time = getTime(
|
||||
// (TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
// prop.timeKey,
|
||||
// fullscreen.value
|
||||
// ? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
// : prop.timeValue
|
||||
// )
|
||||
|
||||
// if (Array.isArray(time)) {
|
||||
// tableStore.table.params.searchBeginTime = time[0]
|
||||
// tableStore.table.params.searchEndTime = time[1]
|
||||
// // TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
// // TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
// } else {
|
||||
// console.warn('获取时间失败,time 不是一个有效数组')
|
||||
// }
|
||||
}
|
||||
|
||||
// 在组件挂载时设置缓存值到 DatePicker
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
tableStore.index()
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
|
||||
@@ -69,7 +69,7 @@ const tableStore: any = new TableStore({
|
||||
width: '150'
|
||||
},
|
||||
{
|
||||
title: '闪变越限(分钟)',
|
||||
title: '长时闪变越限(分钟)',
|
||||
field: 'flicker',
|
||||
width: '80'
|
||||
},
|
||||
@@ -99,26 +99,7 @@ const tableStore: any = new TableStore({
|
||||
],
|
||||
beforeSearchFun: () => {},
|
||||
loadCallback: () => {
|
||||
tableStore.table.data = [
|
||||
{
|
||||
time: '2024-01-01 00:00:00',
|
||||
name: '35kV进线',
|
||||
flicker: '0',
|
||||
|
||||
},
|
||||
{
|
||||
time: '2024-01-01 00:00:00',
|
||||
name: '35kV进线',
|
||||
flicker: '0',
|
||||
|
||||
},
|
||||
{
|
||||
time: '2024-01-01 00:00:00',
|
||||
name: '35kV进线',
|
||||
flicker: '0',
|
||||
|
||||
},
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ const tableStore: any = new TableStore({
|
||||
width: '150'
|
||||
},
|
||||
{
|
||||
title: '闪变越限(分钟)',
|
||||
title: '长时闪变越限(分钟)',
|
||||
field: 'flicker',
|
||||
width: '80',
|
||||
render: 'customTemplate',
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--指标拟合图 -->
|
||||
<TableHeader datePicker @selectChange="selectChange" v-if="fullscreen">
|
||||
<TableHeader
|
||||
datePicker
|
||||
@selectChange="selectChange"
|
||||
v-if="fullscreen"
|
||||
ref="TableHeaderRef"
|
||||
:timeKeyList="prop.timeKey"
|
||||
>
|
||||
<template v-slot:select>
|
||||
<el-form-item label="监测点">
|
||||
<el-select v-model="tableStore.table.params.lineId" placeholder="请选择监测点" clearable>
|
||||
<el-select filterable v-model="tableStore.table.params.lineId" placeholder="请选择监测点" clearable>
|
||||
<el-option
|
||||
v-for="item in lineList"
|
||||
:key="item.lineId"
|
||||
@@ -14,7 +20,12 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户功率">
|
||||
<el-select v-model="tableStore.table.params.power" placeholder="请选择用户功率" clearable>
|
||||
<el-select
|
||||
filterable
|
||||
v-model="tableStore.table.params.power"
|
||||
placeholder="请选择用户功率"
|
||||
clearable
|
||||
>
|
||||
<el-option v-for="item in powerList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -23,6 +34,7 @@
|
||||
style="min-width: 120px !important"
|
||||
placeholder="请选择"
|
||||
v-model="tableStore.table.params.valueType"
|
||||
filterable
|
||||
>
|
||||
<el-option value="max" label="最大值"></el-option>
|
||||
<el-option value="min" label="最小值"></el-option>
|
||||
@@ -31,7 +43,12 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="电能质量指标">
|
||||
<el-select v-model="tableStore.table.params.indicator" placeholder="请选择电能质量指标" clearable>
|
||||
<el-select
|
||||
filterable
|
||||
v-model="tableStore.table.params.indicator"
|
||||
placeholder="请选择电能质量指标"
|
||||
clearable
|
||||
>
|
||||
<el-option v-for="item in indicatorList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -42,6 +59,7 @@
|
||||
v-model="tableStore.table.params.harmonicCount"
|
||||
placeholder="请选择谐波次数"
|
||||
style="min-width: 80px !important"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="num in harmonicCountOptions"
|
||||
@@ -57,12 +75,20 @@
|
||||
<div v-loading="tableStore.table.loading">
|
||||
<my-echart
|
||||
class="tall"
|
||||
v-if="lineShow"
|
||||
:options="echartList"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px )`
|
||||
}"
|
||||
v-if="showEchart"
|
||||
/>
|
||||
<el-empty
|
||||
v-else
|
||||
description="暂无监测点"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -76,28 +102,28 @@ import { useConfig } from '@/stores/config'
|
||||
import { cslineList, fittingData } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
const config = useConfig()
|
||||
|
||||
const lineList: any = ref()
|
||||
|
||||
const powerList: any = ref()
|
||||
|
||||
const countData: any = ref([])
|
||||
|
||||
const showEchart = ref(true)
|
||||
|
||||
const chartsList = ref<any>([])
|
||||
|
||||
const lineShow = ref(true)
|
||||
// 计算是否全屏展示
|
||||
const fullscreen = computed(() => {
|
||||
const w = Number(prop.w)
|
||||
@@ -124,8 +150,14 @@ const indicatorList = ref()
|
||||
|
||||
const initLineList = async () => {
|
||||
cslineList({}).then(res => {
|
||||
if (res.data.length == 0) {
|
||||
lineShow.value = false
|
||||
return (tableStore.table.loading = false)
|
||||
}
|
||||
lineShow.value = true
|
||||
lineList.value = res.data
|
||||
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||
initCode()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -134,7 +166,6 @@ const echartList = ref()
|
||||
const headerHeight = ref(57)
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
|
||||
if (datePickerValue && datePickerValue.timeValue) {
|
||||
// 更新时间参数
|
||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
@@ -152,6 +183,30 @@ const setEchart = () => {
|
||||
title: {
|
||||
text: `${indicatorName}与${powerName}负荷曲线拟合图`
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function (params: any) {
|
||||
let result = params[0].axisValueLabel
|
||||
params.forEach((item: any) => {
|
||||
if (item.seriesName === indicatorName) {
|
||||
// 对于电能质量指标,格式化Y轴值显示
|
||||
let valueText = ''
|
||||
if (item.value[1] == 0) {
|
||||
valueText = '不越限'
|
||||
} else if (item.value[1] == 1) {
|
||||
valueText = '越限'
|
||||
} else {
|
||||
valueText = item.value[1]
|
||||
}
|
||||
result += `<br/>${item.marker}${item.seriesName}: ${valueText}`
|
||||
} else {
|
||||
// 对于功率数据,正常显示数值
|
||||
result += `<br/>${item.marker}${item.seriesName}: ${item.value[1]} ${item.value[2]}`
|
||||
}
|
||||
})
|
||||
return result
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time',
|
||||
axisLabel: {
|
||||
@@ -162,7 +217,25 @@ const setEchart = () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: [{}, {}],
|
||||
yAxis: [
|
||||
{},
|
||||
indicatorName
|
||||
? {
|
||||
min: 0,
|
||||
max: 1,
|
||||
axisLabel: {
|
||||
formatter: function (value: number) {
|
||||
if (value === 0) {
|
||||
return '不越限'
|
||||
} else if (value === 1) {
|
||||
return '越限'
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
: {}
|
||||
],
|
||||
grid: {
|
||||
left: '10px',
|
||||
right: '20px'
|
||||
@@ -189,6 +262,7 @@ const setEchart = () => {
|
||||
{
|
||||
name: indicatorName, // 动态设置指标名称
|
||||
type: 'line',
|
||||
step: 'end',
|
||||
showSymbol: false,
|
||||
// smooth: true,
|
||||
data: [],
|
||||
@@ -198,12 +272,6 @@ const setEchart = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否有数据
|
||||
if (!chartsList.value || chartsList.value.length === 0) {
|
||||
showEchart.value = false // 没有数据时隐藏图表
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// 用户功率数据和电能质量数据
|
||||
let powerData: any[] = []
|
||||
@@ -224,7 +292,8 @@ const setEchart = () => {
|
||||
item.time,
|
||||
item.statisticalData !== null && item.statisticalData !== undefined
|
||||
? parseFloat(item.statisticalData.toFixed(2))
|
||||
: null
|
||||
: null,
|
||||
item.unit
|
||||
]
|
||||
})
|
||||
|
||||
@@ -234,7 +303,8 @@ const setEchart = () => {
|
||||
item.time,
|
||||
item.statisticalData !== null && item.statisticalData !== undefined
|
||||
? parseFloat(item.statisticalData.toFixed(2))
|
||||
: null
|
||||
: null,
|
||||
item.unit
|
||||
]
|
||||
})
|
||||
|
||||
@@ -242,20 +312,11 @@ const setEchart = () => {
|
||||
const hasPowerData = processedPowerData.length > 0 && processedPowerData.some(item => item[1] !== null)
|
||||
const hasQualityData = processedQualityData.length > 0 && processedQualityData.some(item => item[1] !== null)
|
||||
|
||||
if (!hasPowerData && !hasQualityData) {
|
||||
showEchart.value = false
|
||||
return
|
||||
}
|
||||
|
||||
// 更新图表配置
|
||||
echartList.value.options.series[0].data = processedPowerData
|
||||
echartList.value.options.series[1].data = processedQualityData
|
||||
|
||||
// 确保图表显示
|
||||
showEchart.value = true
|
||||
} catch (error) {
|
||||
console.error('处理图表数据时出错:', error)
|
||||
showEchart.value = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,6 +334,7 @@ const initCode = () => {
|
||||
tableStore.table.params.power = powerList.value[0].id
|
||||
tableStore.table.params.indicator = indicatorList.value[0].id
|
||||
nextTick(() => {
|
||||
// setTime()
|
||||
tableStore.index()
|
||||
})
|
||||
})
|
||||
@@ -286,10 +348,7 @@ const tableStore: any = new TableStore({
|
||||
exportName: '主要监测点列表',
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
// 设置时间参数
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
|
||||
setTime()
|
||||
// 只有当 lineList 已加载且有数据时才设置默认 lineId
|
||||
if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) {
|
||||
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||
@@ -330,11 +389,9 @@ const tableStore: any = new TableStore({
|
||||
loadCallback: () => {
|
||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||
// 数据加载完成后的处理
|
||||
if (tableStore.table.data && tableStore.table.data.length > 0) {
|
||||
if (tableStore.table.data) {
|
||||
chartsList.value = JSON.parse(JSON.stringify(tableStore.table.data))
|
||||
setEchart()
|
||||
} else if (tableStore.table.data) {
|
||||
showEchart.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -392,33 +449,44 @@ watch(
|
||||
}
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
initLineList().then(() => {
|
||||
initCode()
|
||||
})
|
||||
onMounted(async () => {
|
||||
await initLineList()
|
||||
})
|
||||
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
tableStore.index()
|
||||
}
|
||||
)
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
const addMenu = () => {}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// :deep(.el-select) {
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
v-model="tableStore.table.params.lineId"
|
||||
placeholder="请选择监测点"
|
||||
style="width: 150px"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.lineId"
|
||||
:label="item.name"
|
||||
:label="item.lineName"
|
||||
:value="item.lineId"
|
||||
/>
|
||||
</el-select>
|
||||
@@ -33,7 +34,7 @@ import TableHeader from '@/components/table/header/index.vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import HarmonicRatio from '@/components/cockpit/gridSideStatistics/components/harmonicRatio.vue'
|
||||
import { cslineList } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
import { cslineList ,governLineList} from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
|
||||
const dialogVisible: any = ref(false)
|
||||
const harmonicRatioRef: any = ref(null)
|
||||
@@ -48,7 +49,7 @@ const loop50 = (key: string) => {
|
||||
list.push({
|
||||
title: i + '次',
|
||||
field: key + i + 'Overtime',
|
||||
width: '80',
|
||||
width: '60',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||
@@ -58,7 +59,7 @@ const loop50 = (key: string) => {
|
||||
return list
|
||||
}
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/harmonic-boot/totalLimitStatistics/details',
|
||||
url: '/cs-harmonic-boot/totalLimitStatistics/details',
|
||||
method: 'POST',
|
||||
publicHeight: 30,
|
||||
showPage: false,
|
||||
@@ -84,9 +85,9 @@ const tableStore: any = new TableStore({
|
||||
width: '150'
|
||||
},
|
||||
{
|
||||
title: '闪变越限(%)',
|
||||
title: '长时闪变越限(%)',
|
||||
field: 'flickerOvertime',
|
||||
width: '80',
|
||||
width: '90',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||
@@ -100,16 +101,7 @@ const tableStore: any = new TableStore({
|
||||
title: '谐波电流越限(%)',
|
||||
children: loop50('iharm')
|
||||
},
|
||||
{
|
||||
title: '三相不平衡度越限(%)',
|
||||
field: 'ubalanceOvertime',
|
||||
width: '100',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
title: '电压偏差越限(%)',
|
||||
field: 'voltageDevOvertime',
|
||||
width: '100',
|
||||
@@ -119,14 +111,24 @@ const tableStore: any = new TableStore({
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '频率偏差越限(%)',
|
||||
field: 'freqDevOvertime',
|
||||
title: '三相不平衡度越限(%)',
|
||||
field: 'ubalanceOvertime',
|
||||
width: '100',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// {
|
||||
// title: '频率偏差越限(%)',
|
||||
// field: 'freqDevOvertime',
|
||||
// width: '100',
|
||||
// render: 'customTemplate',
|
||||
// customTemplate: (row: any) => {
|
||||
// return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||
// }
|
||||
// }
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
},
|
||||
@@ -138,8 +140,10 @@ const tableStore: any = new TableStore({
|
||||
provide('tableStore', tableStore)
|
||||
tableStore.table.params.sortBy = ''
|
||||
tableStore.table.params.orderBy = ''
|
||||
const time:any=ref([])
|
||||
const open = async (row: any,searchBeginTime:any,searchEndTime:any) => {
|
||||
dialogVisible.value = true
|
||||
time.value=[searchBeginTime,searchEndTime]
|
||||
initCSlineList()
|
||||
tableStore.table.params.lineId = row.lineId
|
||||
|
||||
@@ -174,8 +178,19 @@ const onHarmonicRatioClose = () => {
|
||||
}
|
||||
|
||||
const initCSlineList = async () => {
|
||||
const res = await cslineList({})
|
||||
options.value = res.data
|
||||
// const res = await cslineList({})
|
||||
const res = await governLineList({
|
||||
endTime:time.value[1],
|
||||
keywords:"",
|
||||
pageNum:1,
|
||||
pageSize:10000,
|
||||
searchBeginTime:time.value[0],
|
||||
searchEndTime:time.value[1],
|
||||
startTime:time.value[0],
|
||||
timeFlag:1
|
||||
})
|
||||
options.value = res.data.records
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 监测点列表 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||
<TableHeader
|
||||
ref="TableHeaderRef"
|
||||
:showReset="false"
|
||||
@selectChange="selectChange"
|
||||
|
||||
v-if="fullscreen"
|
||||
:timeKeyList="prop.timeKey"
|
||||
></TableHeader>
|
||||
<Table
|
||||
ref="tableRef"
|
||||
@cell-click="cellClickEvent"
|
||||
@@ -11,27 +18,35 @@
|
||||
<OverLimitDetails ref="OverLimitDetailsRef" />
|
||||
|
||||
<!-- 上传对话框 -->
|
||||
<el-dialog v-model="uploadDialogVisible" title="上传报告" width="500px" @closed="handleDialogClosed">
|
||||
<el-dialog
|
||||
v-model="uploadDialogVisible"
|
||||
title="上传报告"
|
||||
append-to-body
|
||||
width="500px"
|
||||
@closed="handleDialogClosed"
|
||||
>
|
||||
<el-upload
|
||||
ref="uploadRef"
|
||||
class="upload-demo"
|
||||
:auto-upload="true"
|
||||
action=""
|
||||
accept=".doc,.docx,.PDF"
|
||||
:on-change="handleChange"
|
||||
:before-upload="beforeUpload"
|
||||
:http-request="handleUpload"
|
||||
:limit="1"
|
||||
:auto-upload="false"
|
||||
:on-exceed="handleExceed"
|
||||
:on-remove="handleRemove"
|
||||
:file-list="fileList"
|
||||
>
|
||||
<el-button type="primary">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div class="el-upload__tip">只能上传Word或PDF文件,且不超过10MB</div>
|
||||
<div class="el-upload__tip">请上传Word或PDF文件</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="uploadDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="uploadDialogVisible = false">确定</el-button>
|
||||
<el-button type="primary" @click="handleUpload">确定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
@@ -46,18 +61,22 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import OverLimitDetails from '@/components/cockpit/monitoringPointList/components/overLimitDetails.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { uploadReport, getReportUrl } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
// 上传相关
|
||||
const uploadDialogVisible = ref(false)
|
||||
const currentUploadRow = ref<any>(null)
|
||||
@@ -67,11 +86,11 @@ const fileList = ref([])
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
|
||||
if (datePickerValue && datePickerValue.timeValue) {
|
||||
// 更新时间参数
|
||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
}
|
||||
// if (datePickerValue && datePickerValue.timeValue) {
|
||||
// // 更新时间参数
|
||||
// tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
// tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
// }
|
||||
}
|
||||
|
||||
// 计算是否全屏展示
|
||||
@@ -101,51 +120,87 @@ const tableStore: any = new TableStore({
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '治理对象',
|
||||
field: 'sensitiveUser',
|
||||
minWidth: '80'
|
||||
},
|
||||
|
||||
{
|
||||
title: '电压等级',
|
||||
field: 'volGrade',
|
||||
minWidth: '70'
|
||||
},
|
||||
{
|
||||
title: '是否治理',
|
||||
field: 'govern',
|
||||
minWidth: '70'
|
||||
},
|
||||
|
||||
// {
|
||||
// title: '治理前报告',
|
||||
// field: 'reportFileName',
|
||||
// minWidth: '80',
|
||||
// render: 'customTemplate',
|
||||
// customTemplate: (row: any) => {
|
||||
// return `<span style='cursor: pointer;text-decoration: underline;'>${row.reportFileName}</span>`
|
||||
// }
|
||||
// },
|
||||
{
|
||||
title: '监测点名称',
|
||||
field: 'lineName',
|
||||
minWidth: '70',
|
||||
minWidth: '120',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.lineName}</span>`
|
||||
}
|
||||
},
|
||||
{ title: '监测类型', field: 'position', minWidth: '60' },
|
||||
{
|
||||
title: '监测类型',
|
||||
field: 'position',
|
||||
minWidth: '80',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
// {
|
||||
// title: '监测点状态',
|
||||
// field: 'runStatus',
|
||||
// minWidth: '90',
|
||||
// render: 'customTemplate',
|
||||
// customTemplate: (row: any) => {
|
||||
// return `<span style='color: ${row.runStatus === '中断' ? '#FF0000' : ''}'>${row.runStatus==null?'/':row.runStatus}</span>`
|
||||
// }
|
||||
// },
|
||||
{
|
||||
title: '监测点状态',
|
||||
field: 'runStatus',
|
||||
minWidth: '60',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='color: ${row.runStatus === '中断' ? '#FF0000' : ''}'>${row.runStatus}</span>`
|
||||
render: 'tag',
|
||||
|
||||
width: 100,
|
||||
custom: {
|
||||
停运: 'danger',
|
||||
退运: 'danger',
|
||||
运行: 'success',
|
||||
在线: 'success',
|
||||
中断: 'warning',
|
||||
离线: 'danger',
|
||||
检修: 'warning',
|
||||
调试: 'warning',
|
||||
null: 'info'
|
||||
},
|
||||
replaceValue: {
|
||||
运行: '运行',
|
||||
在线: '在线',
|
||||
退运: '退运',
|
||||
停运: '停运',
|
||||
中断: '中断',
|
||||
检修: '检修',
|
||||
离线: '离线',
|
||||
调试: '调试',
|
||||
null: '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '治理对象',
|
||||
field: 'sensitiveUser',
|
||||
minWidth: '90',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: '电压等级',
|
||||
field: 'volGrade',
|
||||
minWidth: '80',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue==0?'/': row.cellValue+'kV' || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '是否治理',
|
||||
field: 'govern',
|
||||
minWidth: '80',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
title: '最新数据时间',
|
||||
field: 'latestTime',
|
||||
@@ -159,10 +214,30 @@ const tableStore: any = new TableStore({
|
||||
}
|
||||
}
|
||||
},
|
||||
// {
|
||||
// title: '报告',
|
||||
// field: 'reportFilePath',
|
||||
// minWidth: '120',
|
||||
// render: 'customTemplate',
|
||||
// customTemplate: (row: any) => {
|
||||
// return row.reportFilePath == null
|
||||
// ? '/'
|
||||
// : `<span style='cursor: pointer;text-decoration: underline;'>${row.reportFilePath
|
||||
// .split('/')
|
||||
// .pop()}</span>`
|
||||
// }
|
||||
// },
|
||||
{
|
||||
title: '操作',
|
||||
minWidth: 120,
|
||||
// fixed: 'right',
|
||||
title: '报告',
|
||||
field: 'reportFilePath',
|
||||
minWidth: '120',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue == null ? '/' : row.cellValue.split('/').pop()
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作', fixed: 'right',
|
||||
width: 150,
|
||||
render: 'buttons',
|
||||
buttons: [
|
||||
{
|
||||
@@ -186,7 +261,7 @@ const tableStore: any = new TableStore({
|
||||
icon: 'el-icon-EditPen',
|
||||
render: 'basicButton',
|
||||
click: row => {
|
||||
downloadTheReport(row.lineId)
|
||||
downloadTheReport(row.lineId, row.reportFilePath)
|
||||
},
|
||||
disabled: row => {
|
||||
return row.reportFilePath == null || row.reportFilePath.length == 0
|
||||
@@ -209,8 +284,7 @@ const tableStore: any = new TableStore({
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||
@@ -222,6 +296,25 @@ provide('tableRef', tableRef)
|
||||
tableStore.table.params.keywords = ''
|
||||
provide('tableStore', tableStore)
|
||||
|
||||
const setTime = () => {
|
||||
// const time = getTime(
|
||||
// (TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
// prop.timeKey,
|
||||
// fullscreen.value
|
||||
// ? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
// : prop.timeValue
|
||||
// )
|
||||
|
||||
// if (Array.isArray(time)) {
|
||||
// tableStore.table.params.searchBeginTime = time[0]
|
||||
// tableStore.table.params.searchEndTime = time[1]
|
||||
// TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
// TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
// } else {
|
||||
// console.warn('获取时间失败,time 不是一个有效数组')
|
||||
// }
|
||||
}
|
||||
|
||||
// 点击行
|
||||
const cellClickEvent = ({ row, column }: any) => {
|
||||
if (column.field == 'lineName') {
|
||||
@@ -234,16 +327,43 @@ const cellClickEvent = ({ row, column }: any) => {
|
||||
}
|
||||
|
||||
// 下载报告
|
||||
const downloadTheReport = (lineId: string) => {
|
||||
const downloadTheReport = (lineId: string, name: string) => {
|
||||
getReportUrl({ lineId: lineId }).then((res: any) => {
|
||||
const link = document.createElement('a')
|
||||
link.href = res.data
|
||||
link.download = '治理报告'
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
forceDownloadPdf(res.data, name.split('/').pop() || '')
|
||||
})
|
||||
}
|
||||
const forceDownloadPdf = async (pdfUrl, fileName = '文件.pdf') => {
|
||||
try {
|
||||
// 1. 请求 PDF 并转为 Blob(关键:绕开浏览器直接解析)
|
||||
const response = await fetch(pdfUrl, {
|
||||
method: 'GET'
|
||||
// 若需要鉴权,添加请求头(如 token)
|
||||
})
|
||||
|
||||
// 校验响应是否成功
|
||||
if (!response.ok) throw new Error(`请求失败:${response.status}`)
|
||||
|
||||
// 2. 将响应转为 Blob(指定类型为 PDF,确保兼容性)
|
||||
const blob = await response.blob()
|
||||
const pdfBlob = new Blob([blob], { type: 'application/pdf' })
|
||||
|
||||
// 3. 创建临时 URL 并触发下载
|
||||
const blobUrl = URL.createObjectURL(pdfBlob)
|
||||
const a = document.createElement('a')
|
||||
a.href = blobUrl
|
||||
a.download = fileName // 此时 Blob URL 是同源的,download 必生效
|
||||
a.style.display = 'none'
|
||||
document.body.appendChild(a)
|
||||
a.click() // 触发下载
|
||||
|
||||
// 4. 清理资源(避免内存泄漏)
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(blobUrl)
|
||||
} catch (error) {
|
||||
console.error('PDF 下载失败:', error)
|
||||
// ElMessage.error('文件下载失败,请检查网络或文件地址') // 适配 Element Plus
|
||||
}
|
||||
}
|
||||
|
||||
// 上传报告
|
||||
const uploadReportRow = (row: any) => {
|
||||
@@ -260,14 +380,18 @@ const handleDialogClosed = () => {
|
||||
}
|
||||
|
||||
// 处理文件超出限制
|
||||
const handleExceed = (files: any, fileList: any) => {
|
||||
const handleExceed = (files: any) => {
|
||||
ElMessage.warning('只能上传一个文件,请先删除已选择的文件')
|
||||
}
|
||||
const handleRemove = (files: any) => {
|
||||
fileList.value = []
|
||||
}
|
||||
|
||||
// 文件变更处理函数
|
||||
const handleChange = (file: any, fileList: any) => {
|
||||
const handleChange = (file: any) => {
|
||||
// 在这里直接处理文件上传逻辑
|
||||
beforeUpload(file.raw) // 注意使用 file.raw 获取原始文件对象
|
||||
// beforeUpload(file.raw) // 注意使用 file.raw 获取原始文件对象
|
||||
fileList.value = [file] // 只保留最新选择的文件
|
||||
}
|
||||
|
||||
// 处理上传前检查
|
||||
@@ -284,11 +408,7 @@ const beforeUpload = (file: any) => {
|
||||
const isLt10M = file.size / 1024 / 1024 < 10
|
||||
|
||||
if (!isValidType) {
|
||||
ElMessage.error('上传文件只能是 Word 文档(.doc/.docx) 或 PDF 文件(.pdf)!')
|
||||
return false
|
||||
}
|
||||
if (!isLt10M) {
|
||||
ElMessage.error('上传文件大小不能超过 10MB!')
|
||||
ElMessage.error('请上传(.doc/.docx/.pdf)格式文件!')
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -296,10 +416,11 @@ const beforeUpload = (file: any) => {
|
||||
return true
|
||||
}
|
||||
|
||||
const handleUpload = async (options: any) => {
|
||||
const { file } = options
|
||||
const handleUpload = async () => {
|
||||
// return
|
||||
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
formData.append('file', fileList.value[0]?.raw)
|
||||
formData.append('lineId', currentUploadRow.value?.lineId || currentUploadRow.value?.id || '')
|
||||
|
||||
try {
|
||||
@@ -326,12 +447,7 @@ watch(
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
v-model="searchForm.index"
|
||||
placeholder="请选择统计指标"
|
||||
@change="onIndexChange($event)"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in indexOptions"
|
||||
@@ -36,6 +37,7 @@
|
||||
style="min-width: 120px !important"
|
||||
placeholder="请选择"
|
||||
v-model="searchForm.valueType"
|
||||
filterable
|
||||
>
|
||||
<el-option value="max" label="最大值"></el-option>
|
||||
<el-option value="min" label="最小值"></el-option>
|
||||
@@ -59,11 +61,12 @@
|
||||
placeholder="请选择谐波次数"
|
||||
style="width: 100px"
|
||||
class="mr20"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="vv in item.countOptions"
|
||||
:key="vv"
|
||||
:label="vv"
|
||||
:label="item.name.includes('间谐波') ? vv - 0.5 : vv"
|
||||
:value="vv"
|
||||
></el-option>
|
||||
</el-select>
|
||||
@@ -79,11 +82,7 @@
|
||||
</TableHeader>
|
||||
</div>
|
||||
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
||||
<MyEchart
|
||||
ref="historyChart"
|
||||
:options="echartsData"
|
||||
v-if="showEchart"
|
||||
/>
|
||||
<MyEchart ref="historyChart" :options="echartsData" v-if="showEchart" />
|
||||
<el-empty :style="pageHeight" v-else description="暂无数据" />
|
||||
</div>
|
||||
</el-dialog>
|
||||
@@ -157,28 +156,40 @@ const countOptions: any = ref([])
|
||||
const legendDictList: any = ref([])
|
||||
|
||||
const initCode = (field: string, title: string) => {
|
||||
queryByCode('steady_state_limit_trend').then(res => {
|
||||
queryByCode('gridSide_exceedTheLimit').then(res => {
|
||||
queryCsDictTree(res.data.id).then(item => {
|
||||
//排序
|
||||
indexOptions.value = item.data.sort((a: any, b: any) => {
|
||||
return a.sort - b.sort
|
||||
})
|
||||
const titleMap: Record<string, number> = {
|
||||
flickerOvertime: 0,
|
||||
uaberranceOvertime: 3,
|
||||
ubalanceOvertime: 4,
|
||||
freqDevOvertime: 5
|
||||
}
|
||||
// const titleMap: Record<string, number> = {
|
||||
// flickerOvertime: 0,
|
||||
// uaberranceOvertime: 3,
|
||||
// ubalanceOvertime: 4,
|
||||
// freqDevOvertime: 5
|
||||
// }
|
||||
|
||||
let defaultIndex = 0 // 默认值
|
||||
// let defaultIndex = 0 // 默认值
|
||||
|
||||
if (field in titleMap) {
|
||||
defaultIndex = titleMap[field]
|
||||
} else if (field.includes('uharm')) {
|
||||
defaultIndex = 1
|
||||
} else if (field.includes('iharm')) {
|
||||
defaultIndex = 2
|
||||
}
|
||||
// if (field in titleMap) {
|
||||
// defaultIndex = titleMap[field]
|
||||
// } else if (field.includes('uharm')) {
|
||||
// defaultIndex = 1
|
||||
// } else if (field.includes('iharm')) {
|
||||
// defaultIndex = 2
|
||||
// }
|
||||
let codeKey = field.includes('flickerOvertime')
|
||||
? '闪变'
|
||||
: field.includes('uharm')
|
||||
? '谐波电压'
|
||||
: field.includes('iharm')
|
||||
? '谐波电流'
|
||||
: field.includes('voltageDevOvertime')
|
||||
? '电压偏差'
|
||||
: field.includes('ubalanceOvertime')
|
||||
? '不平衡'
|
||||
: ''
|
||||
let defaultIndex = indexOptions.value.findIndex((item: any) => item.name.includes(codeKey)) || 0
|
||||
|
||||
searchForm.value.index[0] = indexOptions.value[defaultIndex].id
|
||||
})
|
||||
@@ -202,7 +213,7 @@ const initCode = (field: string, title: string) => {
|
||||
if (kk.harmStart && kk.harmEnd) {
|
||||
range(0, 0, 0)
|
||||
|
||||
if (kk.showName == '间谐波电压含有率') {
|
||||
if (kk.showName.includes('间谐波电压')) {
|
||||
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1).map(
|
||||
(item: any) => {
|
||||
return item - 0.5
|
||||
@@ -291,7 +302,7 @@ const init = async () => {
|
||||
}
|
||||
lists[index] = {
|
||||
statisticalId: item.index,
|
||||
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
||||
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
||||
}
|
||||
})
|
||||
let obj = {
|
||||
@@ -597,12 +608,12 @@ const formatCountOptions = () => {
|
||||
})
|
||||
|
||||
countData.value.map((item: any, key: any) => {
|
||||
if (item.name == '谐波电流有效值') {
|
||||
item.name = '谐波电流次数'
|
||||
} else if (item.name == '谐波电压含有率') {
|
||||
item.name = '谐波电压次数'
|
||||
} else if (item.name == '间谐波电压含有率') {
|
||||
if (item.name.includes('间谐波电压')) {
|
||||
item.name = '间谐波电压次数'
|
||||
} else if (item.name.includes('谐波电流')) {
|
||||
item.name = '谐波电流次数'
|
||||
} else if (item.name.includes('谐波电压')) {
|
||||
item.name = '谐波电压次数'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
v-model="tableStore.table.params.lineId"
|
||||
placeholder="请选择监测点"
|
||||
style="width: 150px"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.lineId"
|
||||
:label="item.name"
|
||||
:label="item.lineName"
|
||||
:value="item.lineId"
|
||||
/>
|
||||
</el-select>
|
||||
@@ -48,7 +49,7 @@ const loop50 = (key: string) => {
|
||||
list.push({
|
||||
title: i + '次',
|
||||
field: key + i + 'Overtime',
|
||||
width: '80',
|
||||
width: '60',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||
@@ -58,7 +59,7 @@ const loop50 = (key: string) => {
|
||||
return list
|
||||
}
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/harmonic-boot/totalLimitStatistics/details',
|
||||
url: '/cs-harmonic-boot/totalLimitStatistics/details',
|
||||
method: 'POST',
|
||||
publicHeight: 30,
|
||||
showPage: false,
|
||||
@@ -84,9 +85,9 @@ const tableStore: any = new TableStore({
|
||||
width: '150'
|
||||
},
|
||||
{
|
||||
title: '闪变越限(%)',
|
||||
title: '长时闪变越限(%)',
|
||||
field: 'flickerOvertime',
|
||||
width: '80',
|
||||
width: '90',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||
@@ -100,16 +101,7 @@ const tableStore: any = new TableStore({
|
||||
title: '谐波电流越限(%)',
|
||||
children: loop50('iharm')
|
||||
},
|
||||
{
|
||||
title: '三相不平衡度越限(%)',
|
||||
field: 'ubalanceOvertime',
|
||||
width: '100',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
title: '电压偏差越限(%)',
|
||||
field: 'voltageDevOvertime',
|
||||
width: '100',
|
||||
@@ -119,14 +111,24 @@ const tableStore: any = new TableStore({
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '频率偏差越限(%)',
|
||||
field: 'freqDevOvertime',
|
||||
title: '三相不平衡度越限(%)',
|
||||
field: 'ubalanceOvertime',
|
||||
width: '100',
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// {
|
||||
// title: '频率偏差越限(%)',
|
||||
// field: 'freqDevOvertime',
|
||||
// width: '100',
|
||||
// render: 'customTemplate',
|
||||
// customTemplate: (row: any) => {
|
||||
// return `<span style='cursor: pointer;text-decoration: underline;'>${row.freqDevOvertime}</span>`
|
||||
// }
|
||||
// }
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
},
|
||||
@@ -138,9 +140,10 @@ const tableStore: any = new TableStore({
|
||||
provide('tableStore', tableStore)
|
||||
tableStore.table.params.sortBy = ''
|
||||
tableStore.table.params.orderBy = ''
|
||||
const open = async (row: any,searchBeginTime:any,searchEndTime:any) => {
|
||||
const open = async (row: any,searchBeginTime:any,searchEndTime:any,data: any) => {
|
||||
dialogVisible.value = true
|
||||
initCSlineList()
|
||||
// initCSlineList()
|
||||
options.value = data
|
||||
tableStore.table.params.lineId = row.lineId
|
||||
|
||||
nextTick(() => {
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--总体指标越限统计 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||
<TableHeader
|
||||
:showReset="false"
|
||||
ref="TableHeaderRef"
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
v-if="fullscreen" :timeKeyList="prop.timeKey"
|
||||
></TableHeader>
|
||||
<my-echart
|
||||
class="tall"
|
||||
:options="echartList"
|
||||
@@ -30,20 +36,21 @@ import OverLimitDetails from '@/components/cockpit/overLimitStatistics/component
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||
import { totalLimitStatisticsData } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const route = useRoute()
|
||||
const timeCacheStore = useTimeCacheStore()
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
const echartList = ref({})
|
||||
|
||||
@@ -82,7 +89,7 @@ const initEcharts = () => {
|
||||
|
||||
xAxis: {
|
||||
// name: '(区域)',
|
||||
data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||
data: ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||
},
|
||||
|
||||
yAxis: {
|
||||
@@ -120,7 +127,7 @@ const initEcharts = () => {
|
||||
|
||||
const OverLimitDetailsRef = ref()
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/harmonic-boot/totalLimitStatistics/list',
|
||||
url: '/cs-harmonic-boot/totalLimitStatistics/list',
|
||||
method: 'POST',
|
||||
|
||||
showPage: false,
|
||||
@@ -143,7 +150,7 @@ const tableStore: any = new TableStore({
|
||||
title: '越限占比(%)',
|
||||
children: [
|
||||
{
|
||||
title: '闪变',
|
||||
title: '长时闪变',
|
||||
field: 'flicker',
|
||||
minWidth: '70',
|
||||
render: 'customTemplate',
|
||||
@@ -191,8 +198,7 @@ const tableStore: any = new TableStore({
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||
@@ -211,7 +217,8 @@ const cellClickEvent = ({ row, column }: any) => {
|
||||
OverLimitDetailsRef.value.open(
|
||||
row,
|
||||
tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
||||
tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
tableStore.table.params.searchEndTime || prop.timeValue?.[1],
|
||||
tableStore.table.data
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -219,6 +226,26 @@ const cellClickEvent = ({ row, column }: any) => {
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
@@ -229,12 +256,7 @@ watch(
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--敏感负荷列表 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height} - ${headerHeight}px + ${fullscreen ? -58 : 56}px )`" isGroup></Table>
|
||||
<TableHeader
|
||||
ref="TableHeaderRef"
|
||||
:showReset="false"
|
||||
@selectChange="selectChange"
|
||||
|
||||
v-if="fullscreen"
|
||||
:timeKeyList="prop.timeKey"
|
||||
></TableHeader>
|
||||
<Table
|
||||
ref="tableRef"
|
||||
@cell-click="cellClickEvent"
|
||||
:height="`calc(${prop.height} - ${headerHeight}px + ${fullscreen ? -58 : 56}px )`"
|
||||
isGroup
|
||||
></Table>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
@@ -10,33 +22,34 @@ import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number]},
|
||||
h: { type: [String, Number]},
|
||||
width: { type: [String, Number]},
|
||||
height: { type: [String, Number]},
|
||||
timeKey: { type: [String, Number]},
|
||||
timeValue: { type: Object }
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const dictData = useDictData()
|
||||
const sensitiveUserType = dictData.getBasicData('Sensitive_User_Type')
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
const dictData = useDictData()
|
||||
const sensitiveUserType = dictData.getBasicData('Interference_Source')
|
||||
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
|
||||
if (datePickerValue && datePickerValue.timeValue) {
|
||||
// 更新时间参数
|
||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
}
|
||||
// if (datePickerValue && datePickerValue.timeValue) {
|
||||
// // 更新时间参数
|
||||
// tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
// tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
// }
|
||||
}
|
||||
|
||||
// 计算是否全屏展示
|
||||
@@ -51,7 +64,6 @@ const fullscreen = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const OverLimitDetailsRef = ref()
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/cs-harmonic-boot/pqSensitiveUser/getList',
|
||||
@@ -76,28 +88,32 @@ const tableStore: any = new TableStore({
|
||||
title: '敏感负荷类型',
|
||||
field: 'loadType',
|
||||
minWidth: '70',
|
||||
formatter: row => {
|
||||
formatter: row => {
|
||||
return sensitiveUserType.filter(item => item.id == row.cellValue)[0]?.name
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '是否监测',
|
||||
field: 'isMonitor',
|
||||
minWidth: '80'
|
||||
minWidth: '80',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '是否治理',
|
||||
field: 'isGovern',
|
||||
minWidth: '80'
|
||||
minWidth: '80',
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue || '/'
|
||||
}
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
},
|
||||
|
||||
loadCallback: () => {
|
||||
}
|
||||
loadCallback: () => {}
|
||||
})
|
||||
|
||||
const tableRef = ref()
|
||||
@@ -113,6 +129,25 @@ const cellClickEvent = ({ row, column }: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
const setTime = () => {
|
||||
// const time = getTime(
|
||||
// (TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
// prop.timeKey,
|
||||
// fullscreen.value
|
||||
// ? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
// : prop.timeValue
|
||||
// )
|
||||
|
||||
// if (Array.isArray(time)) {
|
||||
// tableStore.table.params.searchBeginTime = time[0]
|
||||
// tableStore.table.params.searchEndTime = time[1]
|
||||
// TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
// TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
// } else {
|
||||
// console.warn('获取时间失败,time 不是一个有效数组')
|
||||
// }
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
tableStore.index()
|
||||
@@ -127,17 +162,11 @@ watch(
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 暂态事件列表 -->
|
||||
<el-dialog draggable title="暂态事件列表" v-model="dialogVisible" append-to-body width="70%">
|
||||
<!-- <TableHeader datePicker showExport :showReset="false">
|
||||
<!-- 暂态事件详情 -->
|
||||
<el-dialog draggable title="暂态事件详情 " v-model="dialogVisible" append-to-body width="70%">
|
||||
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef" @selectChange="selectChange">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="监测点名称">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.searchValue"
|
||||
placeholder="请选择监测点名称"
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-form-item label="监测点">
|
||||
<el-select v-model="tableStore.table.params.lineId" placeholder="请选择监测点名称">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
@@ -19,8 +15,25 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</TableHeader> -->
|
||||
<Table ref="tableRef" isGroup :height="height"></Table>
|
||||
</TableHeader>
|
||||
<Table ref="tableRef" isGroup :height="heightRef"></Table>
|
||||
</el-dialog>
|
||||
<!-- 查看波形 -->
|
||||
<el-dialog
|
||||
v-model="isWaveCharts"
|
||||
draggable
|
||||
title="波形分析"
|
||||
append-to-body
|
||||
v-if="isWaveCharts"
|
||||
width="70%"
|
||||
@close="handleHideCharts"
|
||||
>
|
||||
<waveFormAnalysis
|
||||
v-loading="loading"
|
||||
ref="waveFormAnalysisRef"
|
||||
@handleHideCharts="handleHideCharts"
|
||||
:wp="wp"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
@@ -30,21 +43,36 @@ import Table from '@/components/table/index.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
|
||||
import { analyseWave } from '@/api/common'
|
||||
import { getSimpleLine } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
|
||||
const dialogVisible: any = ref(false)
|
||||
const harmonicRatioRef: any = ref(null)
|
||||
const options = [
|
||||
{
|
||||
value: '35kV进线',
|
||||
label: '35kV进线'
|
||||
}
|
||||
]
|
||||
const height = mainHeight(0, 2).height as any
|
||||
const waveFormAnalysisRef: any = ref(null)
|
||||
// 波形
|
||||
const isWaveCharts = ref(false)
|
||||
const loading = ref(false)
|
||||
const wp = ref({})
|
||||
const boxoList: any = ref({})
|
||||
|
||||
const tableHeaderRef = ref()
|
||||
|
||||
const options = ref()
|
||||
const heightRef = ref(mainHeight(168, 2.1).height)
|
||||
const selectChange = (flag: boolean, h: any) => {
|
||||
heightRef.value = mainHeight(h, 2.1).height
|
||||
}
|
||||
|
||||
const getSimpleLineList = async () => {
|
||||
const res = await getSimpleLine()
|
||||
options.value = res.data
|
||||
}
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/user-boot/role/selectRoleDetail?id=0',
|
||||
url: '/cs-harmonic-boot/event/pageEvent',
|
||||
method: 'POST',
|
||||
publicHeight: 30,
|
||||
showPage: false,
|
||||
exportName: '主要监测点列表',
|
||||
showPage: true,
|
||||
exportName: '暂态事件详情',
|
||||
column: [
|
||||
{
|
||||
field: 'index',
|
||||
@@ -56,76 +84,142 @@ const tableStore: any = new TableStore({
|
||||
},
|
||||
{
|
||||
title: '暂态时间',
|
||||
field: 'time',
|
||||
field: 'startTime',
|
||||
minWidth: '180'
|
||||
},
|
||||
{
|
||||
title: '测点名称',
|
||||
field: 'name',
|
||||
width: '150'
|
||||
field: 'lineName',
|
||||
minWidth: '150'
|
||||
},
|
||||
{
|
||||
title: '暂态类型',
|
||||
field: 'flicker',
|
||||
width: '100',
|
||||
field: 'tag',
|
||||
minWidth: '100'
|
||||
},
|
||||
{
|
||||
title: '特征幅值(%)',
|
||||
field: 'flicker',
|
||||
width: '100'
|
||||
field: 'amplitude',
|
||||
minWidth: '100'
|
||||
},
|
||||
{
|
||||
title: '暂降深度(%)',
|
||||
field: 'flicker',
|
||||
width: '100'
|
||||
field: 'depth',
|
||||
minWidth: '100',
|
||||
formatter: (row: any) => {
|
||||
// 当暂态类型不是电压暂升时,计算暂降深度 = 100 - 特征幅值
|
||||
if (row.row.tag !== '电压暂升') {
|
||||
const amplitude = parseFloat(row.row.amplitude)
|
||||
if (!isNaN(amplitude)) {
|
||||
return 100 - amplitude
|
||||
}
|
||||
return '-'
|
||||
} else {
|
||||
// 电压暂升时不显示暂降深度
|
||||
return '/'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '持续时间(S)',
|
||||
field: 'flicker',
|
||||
width: '100'
|
||||
field: 'persistTime',
|
||||
minWidth: '100'
|
||||
},
|
||||
{
|
||||
{
|
||||
title: '严重度',
|
||||
field: 'flicker',
|
||||
width: '80'
|
||||
field: 'severity',
|
||||
minWidth: '80'
|
||||
},
|
||||
{
|
||||
title: '波形',
|
||||
minWidth: '100',
|
||||
render: 'buttons',
|
||||
buttons: [
|
||||
{
|
||||
name: 'edit',
|
||||
text: '波形分析',
|
||||
type: 'primary',
|
||||
icon: 'el-icon-DataLine',
|
||||
render: 'basicButton',
|
||||
disabled: row => {
|
||||
return !row.wavePath
|
||||
},
|
||||
|
||||
click: async row => {
|
||||
row.loading1 = true
|
||||
loading.value = true
|
||||
isWaveCharts.value = true
|
||||
dialogVisible.value = false
|
||||
// 在打开弹窗时立即设置高度
|
||||
nextTick(() => {
|
||||
if (waveFormAnalysisRef.value) {
|
||||
// waveFormAnalysisRef.value.setHeight(false, 360)
|
||||
waveFormAnalysisRef.value.setHeight(999, 130, 1.6666666)
|
||||
}
|
||||
})
|
||||
await analyseWave(row.id)
|
||||
.then(res => {
|
||||
row.loading1 = false
|
||||
if (res != undefined) {
|
||||
boxoList.value = row
|
||||
// boxoList.value = {
|
||||
// ...row,
|
||||
// duration: row.persistTime // 将 persistTime 值赋给 duration
|
||||
// }
|
||||
boxoList.value.featureAmplitude = (row.amplitude - 0) / 100
|
||||
// row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
||||
boxoList.value.systemType = 'YPT'
|
||||
wp.value = res.data
|
||||
}
|
||||
loading.value = false
|
||||
})
|
||||
.catch(() => {
|
||||
row.loading1 = false
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
nextTick(() => {
|
||||
waveFormAnalysisRef.value &&
|
||||
waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'edit',
|
||||
text: '暂无波形',
|
||||
type: 'info',
|
||||
icon: 'el-icon-DataLine',
|
||||
render: 'basicButton',
|
||||
disabled: row => {
|
||||
return !!row.wavePath
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {},
|
||||
loadCallback: () => {
|
||||
tableStore.table.data = [
|
||||
{
|
||||
time: '2024-01-01 00:00:00',
|
||||
name: '35kV进线',
|
||||
flicker: '0'
|
||||
},
|
||||
{
|
||||
time: '2024-01-01 00:00:00',
|
||||
name: '35kV进线',
|
||||
flicker: '0'
|
||||
},
|
||||
{
|
||||
time: '2024-01-01 00:00:00',
|
||||
name: '35kV进线',
|
||||
flicker: '0'
|
||||
}
|
||||
]
|
||||
}
|
||||
loadCallback: () => {}
|
||||
})
|
||||
|
||||
tableStore.table.params.searchValue = ''
|
||||
provide('tableStore', tableStore)
|
||||
const open = async (row: any) => {
|
||||
const open = async (time: any) => {
|
||||
dialogVisible.value = true
|
||||
tableStore.index()
|
||||
getSimpleLineList()
|
||||
tableStore.table.params.lineId = ''
|
||||
nextTick(() => {
|
||||
tableHeaderRef.value.setInterval(5)
|
||||
tableHeaderRef.value.setTimeInterval([time, time])
|
||||
tableStore.table.params.searchBeginTime = time
|
||||
tableStore.table.params.searchEndTime = time
|
||||
tableStore.index()
|
||||
})
|
||||
}
|
||||
|
||||
// 点击行
|
||||
const cellClickEvent = ({ row, column }: any) => {
|
||||
if (column.field != 'name') {
|
||||
harmonicRatioRef.value.openDialog(row)
|
||||
}
|
||||
const handleHideCharts = () => {
|
||||
isWaveCharts.value = false
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
v-if="fullscreen"
|
||||
:timeKeyList="prop.timeKey"
|
||||
></TableHeader>
|
||||
<el-calendar
|
||||
v-model="value"
|
||||
@@ -14,9 +15,16 @@
|
||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px )`,
|
||||
overflow: 'auto'
|
||||
}"
|
||||
v-loading="tableStore.table.loading"
|
||||
>
|
||||
<template #date-cell="{ data }">
|
||||
<div style="height: 100%; padding: 8px" :style="{ background: setBackground(data.day) }">
|
||||
<div
|
||||
style="padding: 8px"
|
||||
:style="{
|
||||
background: setBackground(data.day),
|
||||
height: `calc((${prop.height} - 100px - ${headerHeight}px + ${fullscreen ? 0 : 56}px) / 5 )`
|
||||
}"
|
||||
>
|
||||
<p :class="data.isSelected ? 'is-selected' : ''">
|
||||
{{ data.day.split('-').slice(2).join('-') }}
|
||||
</p>
|
||||
@@ -31,12 +39,19 @@
|
||||
</template>
|
||||
<div
|
||||
style="text-decoration: underline"
|
||||
:style="{ height: `calc(${prop.height} / 5 - 40px)`, overflow: 'auto' }"
|
||||
class="details"
|
||||
v-for="item in list?.filter((item:any) => item.name == data.day)"
|
||||
@click="descentClick(item)"
|
||||
>
|
||||
<div @click="descentClick">电压暂降:{{ item.eventDown || 0 }}</div>
|
||||
<div>电压中断:{{ item.eventOff || 0 }}</div>
|
||||
<div>电压暂升:{{ item.eventUp || 0 }}</div>
|
||||
<!-- <div>电压暂降:{{ item.eventDown || 0 }}</div>
|
||||
<div>电压中断:{{ item.eventOff || 0 }}</div>
|
||||
<div>电压暂升:{{ item.eventUp || 0 }}</div> -->
|
||||
<template v-if="fullscreen">
|
||||
<div>电压暂降:{{ item.eventDown || 0 }}</div>
|
||||
<div>电压中断:{{ item.eventOff || 0 }}</div>
|
||||
<div>电压暂升:{{ item.eventUp || 0 }}</div>
|
||||
</template>
|
||||
<template v-else>暂态事件</template>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
@@ -49,20 +64,19 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, provide, reactive, watch, nextTick } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||
import { dayjs } from 'element-plus'
|
||||
import TransientList from './components/transientList.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const headerHeight = ref(57)
|
||||
@@ -79,11 +93,11 @@ const hasEventData = (day: string) => {
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
|
||||
// if (datePickerValue && datePickerValue.timeValue) {
|
||||
// // 更新时间参数
|
||||
// tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
// tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
// }
|
||||
if (datePickerValue && datePickerValue.timeValue) {
|
||||
// 更新时间参数
|
||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||
}
|
||||
}
|
||||
|
||||
// 计算是否全屏展示
|
||||
@@ -113,13 +127,11 @@ const tableStore: any = new TableStore({
|
||||
column: [],
|
||||
|
||||
beforeSearchFun: () => {
|
||||
if (prop.timeValue && Array.isArray(prop.timeValue)) {
|
||||
tableStore.table.params.searchBeginTime = prop.timeValue[0]
|
||||
tableStore.table.params.searchEndTime = prop.timeValue[1]
|
||||
}
|
||||
setTime()
|
||||
},
|
||||
|
||||
loadCallback: () => {
|
||||
value.value = tableStore.table.params.searchBeginTime
|
||||
list.value = tableStore.table.data
|
||||
}
|
||||
})
|
||||
@@ -141,61 +153,65 @@ provide('tableStore', tableStore)
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
if (TableHeaderRef.value && typeof TableHeaderRef.value.setDatePicker === 'function') {
|
||||
TableHeaderRef.value.setDatePicker([{ label: '月份', value: 3 }])
|
||||
}
|
||||
if (fullscreen.value) {
|
||||
TableHeaderRef.value.setInterval(3)
|
||||
}
|
||||
tableStore.index()
|
||||
})
|
||||
})
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
tableStore.index()
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
// (newVal, oldVal) => {
|
||||
// // 当外部时间值变化时,更新表格的时间参数
|
||||
// if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
// tableStore.table.params.searchBeginTime = newVal[0]
|
||||
// tableStore.table.params.searchEndTime = newVal[1]
|
||||
// tableStore.index()
|
||||
// }
|
||||
// },
|
||||
val => {
|
||||
(newVal, oldVal) => {
|
||||
tableStore.index()
|
||||
},
|
||||
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
// 电压暂降点击事件
|
||||
const descentClick = () => {
|
||||
transientListRef.value.open()
|
||||
const descentClick = (item: any) => {
|
||||
transientListRef.value.open(item.name)
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-calendar) {
|
||||
.el-calendar__header {
|
||||
.el-calendar__button-group {
|
||||
display: none;
|
||||
}
|
||||
.el-calendar__body {
|
||||
padding: 0px !important;
|
||||
height: 100%;
|
||||
height: calc(100% - 46px);
|
||||
.el-calendar-table {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.el-calendar-day {
|
||||
// height: calc(912px / 5 );
|
||||
height: 100%;
|
||||
padding: 0px;
|
||||
overflow: hidden;
|
||||
.details {
|
||||
height: calc(100% - 20px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
.el-calendar-table__row {
|
||||
.next {
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--暂态事件概率分布 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||
<TableHeader
|
||||
ref="TableHeaderRef"
|
||||
:timeKeyList="prop.timeKey"
|
||||
:showReset="false"
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
v-if="fullscreen"
|
||||
></TableHeader>
|
||||
<my-echart
|
||||
class="tall"
|
||||
:options="echartList"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||
}"
|
||||
/>
|
||||
<my-echart
|
||||
<!-- <my-echart
|
||||
class="mt10"
|
||||
:options="echartList1"
|
||||
:style="{
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||
}"
|
||||
/>
|
||||
/> -->
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
@@ -26,16 +33,20 @@ import TableStore from '@/utils/tableStore'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
@@ -66,135 +77,6 @@ const echartList = ref({})
|
||||
|
||||
const echartList1 = ref({})
|
||||
|
||||
// const echartList1 = ref({
|
||||
// title: {
|
||||
// text: '越限时间概率分布'
|
||||
// },
|
||||
|
||||
// xAxis: {
|
||||
// // name: '时间',
|
||||
// // data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||
// type: 'time',
|
||||
// axisLabel: {
|
||||
// formatter: {
|
||||
// day: '{MM}-{dd}',
|
||||
// month: '{MM}',
|
||||
// year: '{yyyy}'
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
|
||||
// yAxis: {
|
||||
// name: '次' // 给X轴加单位
|
||||
// },
|
||||
// grid: {
|
||||
// left: '10px',
|
||||
// right: '20px'
|
||||
// },
|
||||
// options: {
|
||||
// series: [
|
||||
// {
|
||||
// type: 'line',
|
||||
// showSymbol: false,
|
||||
// // smooth: true,
|
||||
// name: '电压中断',
|
||||
// color: '#FF9100',
|
||||
// data: [
|
||||
// ['2025-10-16 07:00:00', 10],
|
||||
// ['2025-10-16 07:15:00', 10],
|
||||
// ['2025-10-16 07:30:00', 10],
|
||||
// ['2025-10-16 07:45:00', 10],
|
||||
// ['2025-10-16 08:00:00', 30],
|
||||
// ['2025-10-16 08:15:00', 50],
|
||||
// ['2025-10-16 08:30:00', 60],
|
||||
// ['2025-10-16 08:45:00', 70],
|
||||
// ['2025-10-16 09:00:00', 100],
|
||||
// ['2025-10-16 09:15:00', 120],
|
||||
// ['2025-10-16 09:30:00', 130],
|
||||
// ['2025-10-16 09:45:00', 140],
|
||||
// ['2025-10-16 10:00:00', 160],
|
||||
// ['2025-10-16 10:15:00', 160],
|
||||
// ['2025-10-16 10:30:00', 130],
|
||||
// ['2025-10-16 10:45:00', 120],
|
||||
// ['2025-10-16 11:00:00', 140],
|
||||
// ['2025-10-16 11:15:00', 80],
|
||||
// ['2025-10-16 11:30:00', 70],
|
||||
// ['2025-10-16 11:45:00', 90],
|
||||
// ['2025-10-16 12:00:00', 60],
|
||||
// ['2025-10-16 12:15:00', 60],
|
||||
// ['2025-10-16 12:30:00', 60],
|
||||
// ['2025-10-16 12:45:00', 60]
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// type: 'line',
|
||||
// showSymbol: false,
|
||||
// // smooth: true,
|
||||
// color: '#FFBF00',
|
||||
// name: '电压暂降',
|
||||
// data: [
|
||||
// ['2025-10-16 07:00:00', 1],
|
||||
// ['2025-10-16 07:15:00', 1],
|
||||
// ['2025-10-16 07:30:00', 1],
|
||||
// ['2025-10-16 07:45:00', 1],
|
||||
// ['2025-10-16 08:00:00', 3],
|
||||
// ['2025-10-16 08:15:00', 5],
|
||||
// ['2025-10-16 08:30:00', 6],
|
||||
// ['2025-10-16 08:45:00', 7],
|
||||
// ['2025-10-16 09:00:00', 10],
|
||||
// ['2025-10-16 09:15:00', 12],
|
||||
// ['2025-10-16 09:30:00', 13],
|
||||
// ['2025-10-16 09:45:00', 14],
|
||||
// ['2025-10-16 10:00:00', 16],
|
||||
// ['2025-10-16 10:15:00', 16],
|
||||
// ['2025-10-16 10:30:00', 13],
|
||||
// ['2025-10-16 10:45:00', 12],
|
||||
// ['2025-10-16 11:00:00', 14],
|
||||
// ['2025-10-16 11:15:00', 8],
|
||||
// ['2025-10-16 11:30:00', 7],
|
||||
// ['2025-10-16 11:45:00', 9],
|
||||
// ['2025-10-16 12:00:00', 6],
|
||||
// ['2025-10-16 12:15:00', 6],
|
||||
// ['2025-10-16 12:30:00', 6],
|
||||
// ['2025-10-16 12:45:00', 6]
|
||||
// ]
|
||||
// },
|
||||
// {
|
||||
// type: 'line',
|
||||
// showSymbol: false,
|
||||
// // smooth: true,
|
||||
// name: '电压暂升',
|
||||
// color: config.layout.elementUiPrimary[0],
|
||||
// data: [
|
||||
// ['2025-10-16 07:00:00', 19],
|
||||
// ['2025-10-16 07:15:00', 19],
|
||||
// ['2025-10-16 07:30:00', 19],
|
||||
// ['2025-10-16 07:45:00', 19],
|
||||
// ['2025-10-16 08:00:00', 39],
|
||||
// ['2025-10-16 08:15:00', 59],
|
||||
// ['2025-10-16 08:30:00', 69],
|
||||
// ['2025-10-16 08:45:00', 79],
|
||||
// ['2025-10-16 09:00:00', 109],
|
||||
// ['2025-10-16 09:15:00', 129],
|
||||
// ['2025-10-16 09:30:00', 139],
|
||||
// ['2025-10-16 09:45:00', 149],
|
||||
// ['2025-10-16 10:00:00', 169],
|
||||
// ['2025-10-16 10:15:00', 169],
|
||||
// ['2025-10-16 10:30:00', 139],
|
||||
// ['2025-10-16 10:45:00', 129],
|
||||
// ['2025-10-16 11:00:00', 149],
|
||||
// ['2025-10-16 11:15:00', 89],
|
||||
// ['2025-10-16 11:30:00', 79],
|
||||
// ['2025-10-16 11:45:00', 99],
|
||||
// ['2025-10-16 12:00:00', 69],
|
||||
// ['2025-10-16 12:15:00', 69],
|
||||
// ['2025-10-16 12:30:00', 69],
|
||||
// ['2025-10-16 12:45:00', 69]
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// })
|
||||
const processDataForChart = (rawData: any[]) => {
|
||||
// 将后端返回的扁平数据转换为 ECharts 需要的三维坐标格式 [x, y, z]
|
||||
const chartData = rawData.map(item => [item.x, item.y, item.z])
|
||||
@@ -208,8 +90,7 @@ const tableStore: any = new TableStore({
|
||||
showPage: false,
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
const processedData = processDataForChart(tableStore.table.data.innerList || [])
|
||||
@@ -217,29 +98,37 @@ const tableStore: any = new TableStore({
|
||||
const xlist = tableStore.table.data.xlist || []
|
||||
|
||||
// 处理趋势图数据
|
||||
const seriesData = [
|
||||
{
|
||||
name: '电压中断',
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
color: '#FF9100',
|
||||
data: trendList[0]?.map((value: number, index: number) => [xlist[index], value]) || []
|
||||
},
|
||||
{
|
||||
name: '电压暂降',
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
color: '#FFBF00',
|
||||
data: trendList[1]?.map((value: number, index: number) => [xlist[index], value]) || []
|
||||
},
|
||||
{
|
||||
name: '电压暂升',
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
color: config.layout.elementUiPrimary[0],
|
||||
data: trendList[2]?.map((value: number, index: number) => [xlist[index], value]) || []
|
||||
const seriesData = trendList.map((item: any) => {
|
||||
// 根据接口返回的name字段确定系列名称和颜色
|
||||
let name = ''
|
||||
let color = ''
|
||||
|
||||
switch (item.name) {
|
||||
case 'Evt_Sys_DipStr':
|
||||
name = '电压暂降'
|
||||
color = '#FFBF00'
|
||||
break
|
||||
case 'Evt_Sys_IntrStr':
|
||||
name = '电压中断'
|
||||
color = '#FF9100'
|
||||
break
|
||||
case 'Evt_Sys_SwlStr':
|
||||
name = '电压暂升'
|
||||
color = config.layout.elementUiPrimary[0]
|
||||
break
|
||||
default:
|
||||
name = item.name
|
||||
color = '#000000'
|
||||
}
|
||||
]
|
||||
|
||||
return {
|
||||
name: name,
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
color: color,
|
||||
data: item.trendList?.map((value: number, index: number) => [xlist[index], value]) || []
|
||||
}
|
||||
})
|
||||
|
||||
// 获取x轴和y轴的标签值
|
||||
const xLabels = [
|
||||
@@ -272,9 +161,7 @@ const tableStore: any = new TableStore({
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0,
|
||||
formatter: function (params: any) {
|
||||
console.log(params, '99000')
|
||||
var tips = ''
|
||||
|
||||
tips += '持续时间: ' + yLabels[params.value[1]] + '</br>'
|
||||
tips += '特征幅值: ' + xLabels[params.value[0]] + '</br>'
|
||||
tips += '事件次数: ' + params.value[2] + '</br>'
|
||||
@@ -296,34 +183,16 @@ const tableStore: any = new TableStore({
|
||||
type: 'category',
|
||||
name: '特征幅值',
|
||||
data: xLabels,
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#111'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#111'
|
||||
}
|
||||
nameGap: 40
|
||||
},
|
||||
yAxis3D: {
|
||||
type: 'category',
|
||||
name: '持续时间',
|
||||
data: yLabels,
|
||||
nameTextStyle: {
|
||||
color: '#111'
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#111'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#111'
|
||||
},
|
||||
nameGap: 40,
|
||||
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: ['#111'],
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
@@ -331,25 +200,28 @@ const tableStore: any = new TableStore({
|
||||
},
|
||||
zAxis3D: {
|
||||
type: 'value',
|
||||
splitNumber: 10,
|
||||
minInterval: 10,
|
||||
name: '暂态事件次数'
|
||||
name: '暂态事件次数',
|
||||
nameGap: 30
|
||||
},
|
||||
grid3D: {
|
||||
viewControl: {
|
||||
projection: 'perspective',
|
||||
distance: 250
|
||||
},
|
||||
boxWidth: 200,
|
||||
boxDepth: 80,
|
||||
light: {
|
||||
main: {
|
||||
intensity: 1.2
|
||||
projection: 'perspective',
|
||||
distance: 260,
|
||||
rotateSensitivity: 10,
|
||||
zoomSensitivity: 2
|
||||
},
|
||||
ambient: {
|
||||
intensity: 0.3
|
||||
boxWidth: 150,
|
||||
boxDepth: 100,
|
||||
boxHeight: 100,
|
||||
light: {
|
||||
main: {
|
||||
intensity: 1.2
|
||||
},
|
||||
ambient: {
|
||||
intensity: 0.4
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
@@ -362,20 +234,6 @@ const tableStore: any = new TableStore({
|
||||
fontSize: 16,
|
||||
borderWidth: 1
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
opacity: 1
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
textStyle: {
|
||||
fontSize: 20,
|
||||
color: '#900'
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#900'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -413,26 +271,41 @@ provide('tableStore', tableStore)
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
})
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => prop.timeKey,
|
||||
val => {
|
||||
tableStore.index()
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
const addMenu = () => {}
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
@@ -2,33 +2,36 @@
|
||||
<div>
|
||||
<!-- 暂态事件详情 -->
|
||||
<el-dialog draggable title="暂态事件详情 " v-model="dialogVisible" append-to-body width="70%">
|
||||
<TableHeader datePicker showExport :showReset="false">
|
||||
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef" @selectChange="selectChange">
|
||||
<template v-slot:select>
|
||||
<el-form-item label="监测点名称">
|
||||
<el-select
|
||||
v-model="tableStore.table.params.searchValue"
|
||||
placeholder="请选择监测点名称"
|
||||
style="width: 240px"
|
||||
>
|
||||
<el-form-item label="监测点">
|
||||
<el-select filterable v-model="tableStore.table.params.lineId" placeholder="请选择监测点名称">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:key="item.lineId"
|
||||
:label="item.name"
|
||||
:value="item.lineId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</TableHeader>
|
||||
<Table ref="tableRef" @cell-click="cellClickEvent" isGroup :height="height"></Table>
|
||||
<Table ref="tableRef" isGroup :height="heightRef"></Table>
|
||||
</el-dialog>
|
||||
<!-- 查看波形 -->
|
||||
<el-dialog v-model="isWaveCharts" draggable title="瞬时/RMS波形" append-to-body width="70%">
|
||||
<el-dialog
|
||||
v-model="isWaveCharts"
|
||||
draggable
|
||||
title="波形分析"
|
||||
append-to-body
|
||||
width="70%"
|
||||
@close="handleHideCharts"
|
||||
>
|
||||
<waveFormAnalysis
|
||||
v-loading="loading"
|
||||
v-if="isWaveCharts"
|
||||
ref="waveFormAnalysisRef"
|
||||
@handleHideCharts="isWaveCharts = false"
|
||||
@handleHideCharts="handleHideCharts"
|
||||
:wp="wp"
|
||||
/>
|
||||
</el-dialog>
|
||||
@@ -42,6 +45,8 @@ import TableStore from '@/utils/tableStore'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
|
||||
import { analyseWave } from '@/api/common'
|
||||
import { getSimpleLine } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
|
||||
const dialogVisible: any = ref(false)
|
||||
const waveFormAnalysisRef: any = ref(null)
|
||||
// 波形
|
||||
@@ -50,18 +55,23 @@ const loading = ref(false)
|
||||
const wp = ref({})
|
||||
const boxoList: any = ref({})
|
||||
|
||||
const options = [
|
||||
{
|
||||
value: '35kV进线',
|
||||
label: '35kV进线'
|
||||
}
|
||||
]
|
||||
const height = mainHeight(0, 2).height as any
|
||||
const tableHeaderRef = ref()
|
||||
|
||||
const options = ref()
|
||||
const heightRef = ref(mainHeight(168, 2.2).height)
|
||||
const selectChange = (flag: boolean, h: any) => {
|
||||
heightRef.value = mainHeight(h, 2.2).height
|
||||
}
|
||||
|
||||
const getSimpleLineList = async () => {
|
||||
const res = await getSimpleLine()
|
||||
options.value = res.data
|
||||
}
|
||||
|
||||
const tableStore: any = new TableStore({
|
||||
url: '/user-boot/role/selectRoleDetail?id=0',
|
||||
url: '/cs-harmonic-boot/event/pageEvent',
|
||||
method: 'POST',
|
||||
publicHeight: 30,
|
||||
showPage: false,
|
||||
showPage: true,
|
||||
exportName: '主要监测点列表',
|
||||
column: [
|
||||
{
|
||||
@@ -74,65 +84,92 @@ const tableStore: any = new TableStore({
|
||||
},
|
||||
{
|
||||
title: '暂态时间',
|
||||
field: 'time'
|
||||
field: 'startTime',
|
||||
minWidth: '180'
|
||||
},
|
||||
{
|
||||
title: '测点名称',
|
||||
field: 'name',
|
||||
width: '150'
|
||||
field: 'lineName',
|
||||
minWidth: '150'
|
||||
},
|
||||
{
|
||||
title: '暂态类型',
|
||||
field: 'flicker',
|
||||
width: '100'
|
||||
field: 'tag',
|
||||
minWidth: '100'
|
||||
},
|
||||
{
|
||||
title: '特征幅值(%)',
|
||||
field: 'flicker',
|
||||
width: '100'
|
||||
field: 'amplitude',
|
||||
minWidth: '100'
|
||||
},
|
||||
{
|
||||
title: '暂降深度(%)',
|
||||
field: 'flicker',
|
||||
width: '100'
|
||||
field: 'depth',
|
||||
minWidth: '100',
|
||||
formatter: (row: any) => {
|
||||
// 当暂态类型不是电压暂升时,计算暂降深度 = 100 - 特征幅值
|
||||
if (row.row.tag !== '电压暂升') {
|
||||
const amplitude = parseFloat(row.row.amplitude)
|
||||
if (!isNaN(amplitude)) {
|
||||
return 100 - amplitude
|
||||
}
|
||||
return '-'
|
||||
} else {
|
||||
// 电压暂升时不显示暂降深度
|
||||
return '/'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '持续时间(S)',
|
||||
field: 'flicker',
|
||||
width: '100'
|
||||
field: 'persistTime',
|
||||
minWidth: '100'
|
||||
},
|
||||
{
|
||||
title: '严重度',
|
||||
field: 'flicker',
|
||||
width: '80'
|
||||
field: 'severity',
|
||||
minWidth: '80'
|
||||
},
|
||||
{
|
||||
title: '波形',
|
||||
width: '100',
|
||||
width: '90',
|
||||
render: 'buttons',
|
||||
buttons: [
|
||||
{
|
||||
name: 'check',
|
||||
title: '查看波形',
|
||||
name: 'edit',
|
||||
text: '波形分析',
|
||||
type: 'primary',
|
||||
icon: 'el-icon-EditPen',
|
||||
icon: 'el-icon-DataLine',
|
||||
render: 'basicButton',
|
||||
loading: 'loading1',
|
||||
// disabled: row => {
|
||||
// return !row.wavePath
|
||||
// },
|
||||
disabled: row => {
|
||||
return !row.wavePath
|
||||
},
|
||||
|
||||
click: async row => {
|
||||
row.loading1 = true
|
||||
loading.value = true
|
||||
isWaveCharts.value = true
|
||||
dialogVisible.value = false
|
||||
// 在打开弹窗时立即设置高度
|
||||
nextTick(() => {
|
||||
if (waveFormAnalysisRef.value) {
|
||||
// waveFormAnalysisRef.value.setHeight(false, 360)
|
||||
waveFormAnalysisRef.value.setHeight(999, 130, 1.6666666)
|
||||
}
|
||||
})
|
||||
await analyseWave(row.id)
|
||||
.then(res => {
|
||||
row.loading1 = false
|
||||
if (res != undefined) {
|
||||
boxoList.value = row
|
||||
boxoList.value.featureAmplitude =
|
||||
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
||||
boxoList.value.systemType = 'WX'
|
||||
// boxoList.value = {
|
||||
// ...row,
|
||||
// duration: row.persistTime // 将 persistTime 值赋给 duration
|
||||
// }
|
||||
// boxoList.value.featureAmplitude =
|
||||
// row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
||||
boxoList.value.featureAmplitude = (row.amplitude - 0) / 100
|
||||
boxoList.value.systemType = 'YPT'
|
||||
wp.value = res.data
|
||||
}
|
||||
loading.value = false
|
||||
@@ -147,44 +184,40 @@ const tableStore: any = new TableStore({
|
||||
waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'edit',
|
||||
text: '暂无波形',
|
||||
type: 'info',
|
||||
icon: 'el-icon-DataLine',
|
||||
render: 'basicButton',
|
||||
disabled: row => {
|
||||
return !!row.wavePath
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {},
|
||||
loadCallback: () => {
|
||||
tableStore.table.data = [
|
||||
{
|
||||
time: '2024-01-01 00:00:00',
|
||||
name: '35kV进线',
|
||||
flicker: '0'
|
||||
},
|
||||
{
|
||||
time: '2024-01-01 00:00:00',
|
||||
name: '35kV进线',
|
||||
flicker: '0'
|
||||
},
|
||||
{
|
||||
time: '2024-01-01 00:00:00',
|
||||
name: '35kV进线',
|
||||
flicker: '0'
|
||||
}
|
||||
]
|
||||
}
|
||||
loadCallback: () => {}
|
||||
})
|
||||
|
||||
tableStore.table.params.searchValue = ''
|
||||
provide('tableStore', tableStore)
|
||||
const open = async (row: any) => {
|
||||
const open = async (row: any, searchBeginTime: any, searchEndTime: any) => {
|
||||
dialogVisible.value = true
|
||||
tableStore.index()
|
||||
getSimpleLineList()
|
||||
tableStore.table.params.lineId = row.id
|
||||
nextTick(() => {
|
||||
tableHeaderRef.value.setTimeInterval([searchBeginTime, searchEndTime])
|
||||
tableStore.table.params.searchBeginTime = searchBeginTime
|
||||
tableStore.table.params.searchEndTime = searchEndTime
|
||||
tableStore.index()
|
||||
})
|
||||
}
|
||||
|
||||
// 点击行
|
||||
const cellClickEvent = ({ row, column }: any) => {
|
||||
if (column.field != 'name') {
|
||||
isWaveCharts.value = true
|
||||
}
|
||||
const handleHideCharts = () => {
|
||||
isWaveCharts.value = false
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--暂态事件统计 -->
|
||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
||||
<TableHeader
|
||||
ref="TableHeaderRef"
|
||||
:showReset="false"
|
||||
@selectChange="selectChange"
|
||||
datePicker
|
||||
v-if="fullscreen" :timeKeyList="prop.timeKey"
|
||||
></TableHeader>
|
||||
<my-echart
|
||||
class="tall"
|
||||
:options="echartList"
|
||||
@@ -24,25 +30,27 @@ import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import TransientStatisticsDetail from '@/components/cockpit/transientStatistics/components/transientStatisticsDetail.vue'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||
import { netEventEcharts } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const TableHeaderRef = ref()
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
|
||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||
headerHeight.value = height
|
||||
|
||||
@@ -76,7 +84,7 @@ const eventEcharts = () => {
|
||||
searchEndTime: tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
}).then(res => {
|
||||
// 整理接口数据为图表所需格式
|
||||
const rawData = res.data || {};
|
||||
const rawData = res.data || {}
|
||||
data.value = [
|
||||
{
|
||||
name: '电压中断',
|
||||
@@ -90,7 +98,7 @@ const eventEcharts = () => {
|
||||
name: '电压暂升',
|
||||
value: rawData.eventUp || 0
|
||||
}
|
||||
];
|
||||
]
|
||||
|
||||
echartList.value = {
|
||||
title: {},
|
||||
@@ -99,8 +107,8 @@ const eventEcharts = () => {
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
top: 'center',
|
||||
right: '5%',
|
||||
top: '50',
|
||||
right: '10',
|
||||
formatter: function (e: any) {
|
||||
return e + ' ' + data.value.filter((item: any) => item.name == e)[0].value + '次'
|
||||
}
|
||||
@@ -124,7 +132,7 @@ const eventEcharts = () => {
|
||||
left: 'center'
|
||||
},
|
||||
{
|
||||
text: (rawData.eventOff + rawData.eventDown + rawData.eventUp) + '次',
|
||||
text: rawData.eventOff + rawData.eventDown + rawData.eventUp + '次',
|
||||
left: 'center',
|
||||
top: 'center'
|
||||
}
|
||||
@@ -174,6 +182,7 @@ const tableStore: any = new TableStore({
|
||||
title: '电压中断(次)',
|
||||
field: 'eventOff',
|
||||
minWidth: '70',
|
||||
sortable: true,
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.eventOff}</span>`
|
||||
@@ -183,6 +192,7 @@ const tableStore: any = new TableStore({
|
||||
title: '电压暂降(次)',
|
||||
field: 'eventDown',
|
||||
minWidth: '80',
|
||||
sortable: true,
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.eventDown}</span>`
|
||||
@@ -192,6 +202,7 @@ const tableStore: any = new TableStore({
|
||||
title: '电压暂升(次)',
|
||||
field: 'eventUp',
|
||||
minWidth: '80',
|
||||
sortable: true,
|
||||
render: 'customTemplate',
|
||||
customTemplate: (row: any) => {
|
||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.eventUp}</span>`
|
||||
@@ -199,8 +210,7 @@ const tableStore: any = new TableStore({
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
},
|
||||
loadCallback: () => {
|
||||
eventEcharts()
|
||||
@@ -215,7 +225,30 @@ provide('tableStore', tableStore)
|
||||
// 点击行
|
||||
const cellClickEvent = ({ row, column }: any) => {
|
||||
if (column.field != 'name') {
|
||||
transientStatisticsDetailRef.value.open(row)
|
||||
transientStatisticsDetailRef.value.open(
|
||||
row,
|
||||
tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
||||
tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,12 +266,7 @@ watch(
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
<template>
|
||||
<div>
|
||||
<!--趋势对比 -->
|
||||
<TableHeader datePicker :showReset="false" @selectChange="selectChange" v-if="fullscreen">
|
||||
<TableHeader
|
||||
datePicker
|
||||
ref="TableHeaderRef"
|
||||
:timeKeyList="prop.timeKey"
|
||||
:showReset="false"
|
||||
@selectChange="selectChange"
|
||||
v-if="fullscreen"
|
||||
>
|
||||
<template v-slot:select>
|
||||
<el-form-item label="监测对象">
|
||||
<el-select v-model="tableStore.table.params.sensitiveUserId" placeholder="请选择监测对象" clearable>
|
||||
<el-select
|
||||
filterable
|
||||
v-model="tableStore.table.params.sensitiveUserId"
|
||||
placeholder="请选择监测对象"
|
||||
clearable
|
||||
>
|
||||
<el-option v-for="item in idList" :key="item.id" :label="item.name" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -68,8 +80,8 @@
|
||||
width: prop.width,
|
||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||
}"
|
||||
v-if="showEchart"
|
||||
/>
|
||||
<!-- <el-empty description="暂无数据" /> -->
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
@@ -78,26 +90,24 @@ import TableStore from '@/utils/tableStore'
|
||||
import TableHeader from '@/components/table/header/index.vue'
|
||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||
import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree'
|
||||
import { getListByIds } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||
|
||||
import { getTime } from '@/utils/formatTime'
|
||||
import { yMethod, exportCSV } from '@/utils/echartMethod'
|
||||
import { max } from 'lodash'
|
||||
const prop = defineProps({
|
||||
w: { type: [String, Number] },
|
||||
h: { type: [String, Number] },
|
||||
width: { type: [String, Number] },
|
||||
height: { type: [String, Number] },
|
||||
timeKey: { type: [String, Number] },
|
||||
timeValue: { type: Object }
|
||||
timeKey: { type: Array as () => string[] },
|
||||
timeValue: { type: Object },
|
||||
interval: { type: Number }
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
const timeCacheStore = useTimeCacheStore()
|
||||
const TableHeaderRef = ref()
|
||||
const config = useConfig()
|
||||
|
||||
const lineIdList = ref(JSON.parse(window.localStorage.getItem('lineIdList') || '[]'))
|
||||
|
||||
// 计算是否全屏展示
|
||||
const fullscreen = computed(() => {
|
||||
const w = Number(prop.w)
|
||||
@@ -116,19 +126,19 @@ const indicatorList = ref()
|
||||
|
||||
const echartList = ref()
|
||||
|
||||
const showEchart = ref(true)
|
||||
|
||||
const headerHeight = ref(57)
|
||||
|
||||
// 监测对象
|
||||
const idList = ref()
|
||||
const idList = ref([])
|
||||
|
||||
// 监测对象
|
||||
const initListByIds = () => {
|
||||
getListByIds({}).then((res: any) => {
|
||||
if (res.data.length > 0) {
|
||||
if (res.data?.length > 0) {
|
||||
idList.value = res.data
|
||||
initCode()
|
||||
} else {
|
||||
tableStore.index()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -173,7 +183,7 @@ const setEchart = () => {
|
||||
if (!beforeGroupedByPhase[phase]) {
|
||||
beforeGroupedByPhase[phase] = []
|
||||
}
|
||||
beforeGroupedByPhase[phase].push([item.time, item.statisticalData])
|
||||
beforeGroupedByPhase[phase].push([item.time, item.statisticalData, item.unit, 'solid'])
|
||||
})
|
||||
|
||||
// 处理治理后数据
|
||||
@@ -182,7 +192,7 @@ const setEchart = () => {
|
||||
if (!afterGroupedByPhase[phase]) {
|
||||
afterGroupedByPhase[phase] = []
|
||||
}
|
||||
afterGroupedByPhase[phase].push([item.time, item.statisticalData])
|
||||
afterGroupedByPhase[phase].push([item.time, item.statisticalData, item.unit, 'dotted'])
|
||||
})
|
||||
|
||||
// 构建系列数据
|
||||
@@ -209,13 +219,7 @@ const setEchart = () => {
|
||||
data: beforeGroupedByPhase[phase],
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: function (params: any) {
|
||||
if (params.value[1] == 0 || params.value[1] == 3.14159) {
|
||||
return '#ccc'
|
||||
} else {
|
||||
return color
|
||||
}
|
||||
}
|
||||
color: color
|
||||
}
|
||||
},
|
||||
lineStyle: {
|
||||
@@ -240,13 +244,7 @@ const setEchart = () => {
|
||||
data: afterGroupedByPhase[phase],
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: function (params: any) {
|
||||
if (params.value[1] == 0 || params.value[1] == 3.14159) {
|
||||
return '#ccc'
|
||||
} else {
|
||||
return color
|
||||
}
|
||||
}
|
||||
color: color
|
||||
}
|
||||
},
|
||||
lineStyle: {
|
||||
@@ -265,6 +263,11 @@ const setEchart = () => {
|
||||
titleText = afterData[0].anotherName
|
||||
}
|
||||
|
||||
// statisticalData
|
||||
// chartsListBefore.value.map((item: any) => item.statisticalData)
|
||||
// chartsListAfter.value = tableStore.table.data.after
|
||||
|
||||
|
||||
// 构建图例数据
|
||||
const legendData = series.map((item: any, index: number) => {
|
||||
let color = config.layout.elementUiPrimary[0]
|
||||
@@ -294,11 +297,45 @@ const setEchart = () => {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
let [min, max] = yMethod(
|
||||
[...chartsListBefore.value.map((item: any) => item.statisticalData),
|
||||
...chartsListAfter.value.map((item: any) => item.statisticalData)]
|
||||
)
|
||||
echartList.value = {
|
||||
title: {
|
||||
text: titleText
|
||||
},
|
||||
tooltip: {
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
color: '#fff',
|
||||
fontSize: 16
|
||||
}
|
||||
},
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontStyle: 'normal',
|
||||
opacity: 0.35,
|
||||
fontSize: 14
|
||||
},
|
||||
backgroundColor: 'rgba(0,0,0,0.55)',
|
||||
borderWidth: 0,
|
||||
formatter(params: any) {
|
||||
const xname = params[0].value[0]
|
||||
let str = `${xname}<br>`
|
||||
params.forEach((el: any, index: any) => {
|
||||
let marker = ''
|
||||
|
||||
marker = `<span style="display:inline-block;border: 2px ${el.color} ${el.value[3]};margin-right:5px;width:40px;height:0px;background-color:#ffffff00;"></span>`
|
||||
|
||||
str += `${marker}${el.seriesName.split('(')[0]}:${
|
||||
el.value[1] != null ? el.value[1] + ' ' + (el.value[2] == null ? '' : el.value[2]) : '-'
|
||||
}<br>`
|
||||
})
|
||||
return str
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: legendData,
|
||||
icon: 'rect',
|
||||
@@ -322,7 +359,9 @@ const setEchart = () => {
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
name: beforeData.length > 0 ? beforeData[0].unit : afterData.length > 0 ? afterData[0].unit : ''
|
||||
name: beforeData.length > 0 ? beforeData[0].unit : afterData.length > 0 ? afterData[0].unit : '',
|
||||
max: max,
|
||||
min: min,
|
||||
},
|
||||
grid: {
|
||||
left: '10px',
|
||||
@@ -339,8 +378,7 @@ const tableStore: any = new TableStore({
|
||||
exportName: '趋势对比',
|
||||
column: [],
|
||||
beforeSearchFun: () => {
|
||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
||||
setTime()
|
||||
if (!tableStore.table.params.sensitiveUserId && idList.value?.length > 0) {
|
||||
tableStore.table.params.sensitiveUserId = idList.value[0].id
|
||||
}
|
||||
@@ -371,14 +409,12 @@ const tableStore: any = new TableStore({
|
||||
chartsListBefore.value = tableStore.table.data.before
|
||||
chartsListAfter.value = tableStore.table.data.after
|
||||
setEchart()
|
||||
} else if (tableStore.table.data) {
|
||||
showEchart.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
tableStore.table.params.indicator = '1'
|
||||
tableStore.table.params.exceedingTheLimit = '1'
|
||||
tableStore.table.params.indicator = ''
|
||||
tableStore.table.params.exceedingTheLimit = ''
|
||||
tableStore.table.params.dataLevel = 'Primary'
|
||||
tableStore.table.params.valueType = 'avg'
|
||||
provide('tableStore', tableStore)
|
||||
@@ -387,6 +423,25 @@ onMounted(() => {
|
||||
initListByIds()
|
||||
})
|
||||
|
||||
const setTime = () => {
|
||||
const time = getTime(
|
||||
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||
prop.timeKey,
|
||||
fullscreen.value
|
||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
||||
: prop.timeValue
|
||||
)
|
||||
|
||||
if (Array.isArray(time)) {
|
||||
tableStore.table.params.searchBeginTime = time[0]
|
||||
tableStore.table.params.searchEndTime = time[1]
|
||||
TableHeaderRef.value?.setInterval(time[2] - 0)
|
||||
TableHeaderRef.value?.setTimeInterval([time[0], time[1]])
|
||||
} else {
|
||||
console.warn('获取时间失败,time 不是一个有效数组')
|
||||
}
|
||||
}
|
||||
|
||||
// 判断是否应该显示谐波次数选择框
|
||||
const shouldShowHarmonicCount = () => {
|
||||
if (!tableStore.table.params.indicator || !indicatorList.value) return false
|
||||
@@ -395,7 +450,7 @@ const shouldShowHarmonicCount = () => {
|
||||
|
||||
return (
|
||||
currentIndicator &&
|
||||
(currentIndicator.name.includes('电压谐波含有率') || currentIndicator.name.includes('电流谐波含有率'))
|
||||
(currentIndicator.name.includes('幅值') || currentIndicator.name.includes('含有率'))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -404,9 +459,9 @@ const getHarmonicTypeName = () => {
|
||||
const currentIndicator = indicatorList.value.find((item: any) => item.id === tableStore.table.params.indicator)
|
||||
|
||||
if (currentIndicator) {
|
||||
if (currentIndicator.name.includes('电压谐波含有率')) {
|
||||
if (currentIndicator.name.includes('电压')) {
|
||||
return '电压'
|
||||
} else if (currentIndicator.name.includes('电流谐波含有率')) {
|
||||
} else if (currentIndicator.name.includes('电流')) {
|
||||
return '电流'
|
||||
}
|
||||
}
|
||||
@@ -422,12 +477,7 @@ watch(
|
||||
watch(
|
||||
() => prop.timeValue,
|
||||
(newVal, oldVal) => {
|
||||
// 当外部时间值变化时,更新表格的时间参数
|
||||
if (newVal && (!oldVal || newVal[0] !== oldVal[0] || newVal[1] !== oldVal[1])) {
|
||||
tableStore.table.params.searchBeginTime = newVal[0]
|
||||
tableStore.table.params.searchEndTime = newVal[1]
|
||||
tableStore.index()
|
||||
}
|
||||
tableStore.index()
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
@@ -449,8 +499,6 @@ watch(
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const addMenu = () => {}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
// :deep(.el-select) {
|
||||
|
||||
@@ -1,311 +1,320 @@
|
||||
// 辅助函数
|
||||
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;
|
||||
};
|
||||
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;
|
||||
};
|
||||
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;
|
||||
};
|
||||
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;
|
||||
};
|
||||
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 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 = [];
|
||||
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;
|
||||
if (titleList[iphasicValue * step + 1]?.substring(0, 1) !== 'U') {
|
||||
xishu = ct
|
||||
unit = '电流'
|
||||
}
|
||||
|
||||
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];
|
||||
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
|
||||
}
|
||||
|
||||
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 };
|
||||
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
|
||||
}
|
||||
|
||||
return {
|
||||
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]
|
||||
}
|
||||
|
||||
instantF,
|
||||
instantS,
|
||||
RMSF,
|
||||
RMSS,
|
||||
RMSFMinDetail,
|
||||
RMSSMinDetail,
|
||||
shunshiF,
|
||||
shunshiS,
|
||||
RMSFWave,
|
||||
RMSSWave,
|
||||
title,
|
||||
unit,
|
||||
};
|
||||
};
|
||||
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 } = JSON.parse(e.data);
|
||||
const { wp, isOpen, value, boxoList } = JSON.parse(e.data)
|
||||
|
||||
try {
|
||||
const iphasicValue = wp.iphasic || 1;
|
||||
try {
|
||||
const iphasicValue = wp.iphasic || 1
|
||||
|
||||
const picCounts = (wp.waveTitle.length - 1) / iphasicValue;
|
||||
const waveDatas = [];
|
||||
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);
|
||||
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({
|
||||
titles: titles,
|
||||
success: true,
|
||||
waveDatas,
|
||||
time: wp.time,
|
||||
type: wp.waveType,
|
||||
severity: wp.yzd,
|
||||
iphasic: iphasicValue
|
||||
})
|
||||
} catch (error) {
|
||||
self.postMessage({
|
||||
success: false,
|
||||
error: error.message
|
||||
})
|
||||
}
|
||||
// 处理标题
|
||||
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.equipmentName +
|
||||
" 发生时刻:" +
|
||||
boxoList.startTime +
|
||||
" 残余电压:" +
|
||||
boxoList.evtParamVVaDepth +
|
||||
" 持续时间:" +
|
||||
boxoList.evtParamTm +
|
||||
"s";
|
||||
} else {
|
||||
titles =
|
||||
"变电站名称:" +
|
||||
boxoList.subName +
|
||||
" 监测点名称:" +
|
||||
boxoList.lineName +
|
||||
" 发生时刻:" +
|
||||
boxoList.startTime +
|
||||
" 残余电压:" +
|
||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||
"% 持续时间:" +
|
||||
boxoList.duration +
|
||||
"s";
|
||||
}
|
||||
// 发送处理结果回主线程
|
||||
self.postMessage({
|
||||
titles: titles,
|
||||
success: true,
|
||||
waveDatas,
|
||||
time: wp.time,
|
||||
type: wp.waveType,
|
||||
severity: wp.yzd,
|
||||
iphasic: iphasicValue,
|
||||
});
|
||||
} catch (error) {
|
||||
self.postMessage({
|
||||
success: false,
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
<template>
|
||||
|
||||
<div v-loading="loading" :element-loading-background="'rgba(122, 122, 122, 0.8)'"
|
||||
style="position: relative;height: 100%;">
|
||||
|
||||
<div id="boxr" style="background: #343849c7">
|
||||
<div id="rmsp" :style="`height:${vh};overflow: hidden;`">
|
||||
<div class="bx" id="rms"></div>
|
||||
<div v-loading="loading" style="position: relative; height: 100%">
|
||||
<div id="boxr">
|
||||
<div id="rmsp" :style="`height:${vh};overflow: hidden;min-height: 200px;`">
|
||||
<div class="bx" id="rms" style="min-height: 200px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -16,6 +13,7 @@ import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
|
||||
import html2canvas from 'html2canvas'
|
||||
import $ from 'jquery'
|
||||
import * as echarts from 'echarts'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import url from '@/assets/img/point.png'
|
||||
import url2 from '@/assets/img/dw.png'
|
||||
const worker = ref<Worker | null>(null)
|
||||
@@ -66,7 +64,7 @@ interface WaveData {
|
||||
interface Props {
|
||||
value?: number
|
||||
flag?: string | number | boolean
|
||||
parentHeight?: string | number | boolean
|
||||
parentHeight?: any
|
||||
DColor?: boolean
|
||||
boxoList?: any
|
||||
wp?: any
|
||||
@@ -78,7 +76,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
parentHeight: 0,
|
||||
DColor: false,
|
||||
boxoList: () => ({}),
|
||||
wp: () => ({}),
|
||||
wp: () => ({})
|
||||
})
|
||||
|
||||
const loading = ref(true)
|
||||
@@ -110,34 +108,41 @@ const myChartess4 = ref<echarts.ECharts | null>(null)
|
||||
const myChartess5 = ref<echarts.ECharts | null>(null)
|
||||
|
||||
const vh = computed(() => {
|
||||
if (props.flag == 1) {
|
||||
return '690px'
|
||||
if (props.parentHeight == 999) {
|
||||
return `calc((60vh - 150px) / 2 )`
|
||||
} else if (props.parentHeight != 0) {
|
||||
return '310px'
|
||||
return mainHeight(props.parentHeight, 2).height
|
||||
}
|
||||
|
||||
if (props.flag == 1) {
|
||||
return mainHeight(200).height
|
||||
} else {
|
||||
return '350px'
|
||||
return mainHeight(200, 2).height
|
||||
}
|
||||
})
|
||||
|
||||
const vw = computed(() => '100%')
|
||||
|
||||
watch(() => props.value, (newVal) => {
|
||||
if (newVal == 2) {
|
||||
initWaves()
|
||||
} else {
|
||||
$('#wave1').remove()
|
||||
initWaves()
|
||||
watch(
|
||||
() => props.value,
|
||||
newVal => {
|
||||
if (newVal == 2) {
|
||||
initWaves()
|
||||
} else {
|
||||
$('#wave1').remove()
|
||||
initWaves()
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
const zoomValue = document.body.style.getPropertyValue('zoom');
|
||||
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1);
|
||||
const zoomValue = document.body.style.getPropertyValue('zoom')
|
||||
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1)
|
||||
window.addEventListener('resize', handleResize)
|
||||
|
||||
// 初始化 Web Worker
|
||||
worker.value = new Worker(new URL('./rmsWorker.js', import.meta.url));
|
||||
worker.value.onmessage = (e) => {
|
||||
worker.value = new Worker(new URL('./rmsWorker.js', import.meta.url))
|
||||
worker.value.onmessage = e => {
|
||||
if (e.data.success) {
|
||||
const data = e.data
|
||||
titles.value = data.titles
|
||||
@@ -171,15 +176,15 @@ onBeforeUnmount(() => {
|
||||
})
|
||||
|
||||
const handleResize = () => {
|
||||
const zoomValue = document.body.style.getPropertyValue('zoom');
|
||||
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1);
|
||||
const zoomValue = document.body.style.getPropertyValue('zoom')
|
||||
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1)
|
||||
}
|
||||
|
||||
const download = () => {
|
||||
const boxr = document.getElementById('boxr')
|
||||
if (boxr) {
|
||||
html2canvas(boxr, {
|
||||
scale: 2,
|
||||
scale: 2
|
||||
}).then(function (canvas) {
|
||||
const creatIMg = document.createElement('a')
|
||||
creatIMg.download = 'rms波形.png'
|
||||
@@ -195,13 +200,14 @@ const query = () => {
|
||||
if (props.wp) {
|
||||
// 使用 Worker 处理数据
|
||||
if (worker.value) {
|
||||
|
||||
worker.value.postMessage(JSON.stringify({
|
||||
wp: props.wp,
|
||||
isOpen: isOpen.value,
|
||||
value: props.value,
|
||||
boxoList: props.boxoList
|
||||
}))
|
||||
worker.value.postMessage(
|
||||
JSON.stringify({
|
||||
wp: props.wp,
|
||||
isOpen: isOpen.value,
|
||||
value: props.value,
|
||||
boxoList: props.boxoList
|
||||
})
|
||||
)
|
||||
}
|
||||
} else {
|
||||
initWave(null, null, null, null, null)
|
||||
@@ -240,7 +246,6 @@ const waveData = (
|
||||
|
||||
const initWaves = () => {
|
||||
if (props.wp) {
|
||||
|
||||
iphasic.value = props.wp.iphasic || 1
|
||||
const picCounts = (props.wp.waveTitle.length - 1) / iphasic.value
|
||||
waveDatas.value = []
|
||||
@@ -266,15 +271,29 @@ const initWaves = () => {
|
||||
}
|
||||
|
||||
const fliteWaveData = (wp: any, step: number): WaveData => {
|
||||
|
||||
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
|
||||
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: number[][] = []
|
||||
const shunshiFB: number[][] = []
|
||||
@@ -289,7 +308,6 @@ const fliteWaveData = (wp: any, step: number): WaveData => {
|
||||
const rmsSB: number[][] = []
|
||||
const rmsSC: number[][] = []
|
||||
|
||||
|
||||
if (titleList[iphasic.value * step + 1]?.substring(0, 1) !== 'U') {
|
||||
xishu = ct
|
||||
unit = '电流'
|
||||
@@ -309,8 +327,6 @@ const fliteWaveData = (wp: any, step: number): WaveData => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (rmsData[0][iphasic.value * step + 1] !== undefined) {
|
||||
rfmax = rmsData[0][iphasic.value * step + 1] * xishu
|
||||
rfmin = rmsData[0][iphasic.value * step + 1] * xishu
|
||||
@@ -322,8 +338,6 @@ const fliteWaveData = (wp: any, step: number): WaveData => {
|
||||
rmsvSecondX = rmsData[0][0]
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (let rms = 0; rms < rmsData.length; rms++) {
|
||||
if (rmsData[rms][iphasic.value * step + 1] === undefined) {
|
||||
break
|
||||
@@ -388,12 +402,14 @@ const fliteWaveData = (wp: any, step: number): WaveData => {
|
||||
const rmsFirstA3 = rmsData[rms][iphasic.value * step + 1] * xishu
|
||||
const rmsFirstB3 = rmsData[rms][iphasic.value * step + 2] * xishu
|
||||
const rmsFirstC3 = rmsData[rms][iphasic.value * step + 3] * xishu
|
||||
rmsFA.push([rmsData[rms][0], rmsFirstA3]);
|
||||
rmsFA.push([rmsData[rms][0], rmsFirstA3])
|
||||
|
||||
rmsFB.push([rmsData[rms][0], rmsFirstB3]);
|
||||
rmsFC.push([rmsData[rms][0], rmsFirstC3]);
|
||||
rmsFB.push([rmsData[rms][0], rmsFirstB3])
|
||||
rmsFC.push([rmsData[rms][0], rmsFirstC3])
|
||||
rfmax = getMax(rfmax, rmsFirstA3, rmsFirstB3, rmsFirstC3)
|
||||
rfmin = isOpen.value ? getMinOpen(rfmin, rmsFirstA3, rmsFirstC3) : getMin(rfmin, rmsFirstA3, rmsFirstB3, rmsFirstC3)
|
||||
rfmin = isOpen.value
|
||||
? getMinOpen(rfmin, rmsFirstA3, rmsFirstC3)
|
||||
: getMin(rfmin, rmsFirstA3, rmsFirstB3, rmsFirstC3)
|
||||
if (rfmin < rmsvFirstY) {
|
||||
rmsvFirstY = rfmin
|
||||
if (rfmin === rmsFirstA3) {
|
||||
@@ -413,7 +429,9 @@ const fliteWaveData = (wp: any, step: number): WaveData => {
|
||||
rmsSB.push([rmsData[rms][0], rmsSecondB3])
|
||||
rmsSC.push([rmsData[rms][0], rmsSecondC3])
|
||||
rsmax = getMax(rsmax, rmsSecondA3, rmsSecondB3, rmsSecondC3)
|
||||
rsmin = isOpen.value ? getMinOpen(rsmin, rmsSecondA3, rmsSecondC3) : getMin(rsmin, rmsSecondA3, rmsSecondB3, rmsSecondC3)
|
||||
rsmin = isOpen.value
|
||||
? getMinOpen(rsmin, rmsSecondA3, rmsSecondC3)
|
||||
: getMin(rsmin, rmsSecondA3, rmsSecondB3, rmsSecondC3)
|
||||
if (rsmin < rmsvSecondY) {
|
||||
rmsvSecondY = rsmin
|
||||
if (rsmin === rmsSecondA3) {
|
||||
@@ -429,7 +447,6 @@ const fliteWaveData = (wp: any, step: number): WaveData => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const instantF = { max: ifmax, min: ifmin }
|
||||
const instantS = { max: ismax, min: ismin }
|
||||
const RMSF = { max: rfmax, min: rfmin }
|
||||
@@ -442,11 +459,29 @@ const fliteWaveData = (wp: any, step: number): WaveData => {
|
||||
const RMSSWave = { rmsSA, rmsSB, rmsSC }
|
||||
const title = { aTitle, bTitle, cTitle, unit }
|
||||
|
||||
return waveData(instantF, instantS, RMSF, RMSS, RMSFMinDetail, RMSSMinDetail, shunshiF, shunshiS, RMSFWave, RMSSWave, title, unit)
|
||||
return waveData(
|
||||
instantF,
|
||||
instantS,
|
||||
RMSF,
|
||||
RMSS,
|
||||
RMSFMinDetail,
|
||||
RMSSMinDetail,
|
||||
shunshiF,
|
||||
shunshiS,
|
||||
RMSFWave,
|
||||
RMSSWave,
|
||||
title,
|
||||
unit
|
||||
)
|
||||
}
|
||||
|
||||
const initWave = (waveDatas: WaveData[] | null, time: string | null, type: string | null, severity: string | null, isOpen: boolean | null) => {
|
||||
|
||||
const initWave = (
|
||||
waveDatas: WaveData[] | null,
|
||||
time: string | null,
|
||||
type: string | null,
|
||||
severity: string | null,
|
||||
isOpen: boolean | null
|
||||
) => {
|
||||
$('div.bx').remove()
|
||||
|
||||
let picHeight = vh.value
|
||||
@@ -456,9 +491,15 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
let rmscm: number[][] = []
|
||||
let titleText = ''
|
||||
let unit = ''
|
||||
let a: string | null = null, b: string | null = null, c: string | null = null
|
||||
let radata: number[][] = [], rbdata: number[][] = [], rcdata: number[][] = []
|
||||
let rmsvX: any = 0, rmsvY: any = 0, zhou = ''
|
||||
let a: string | null = null,
|
||||
b: string | null = null,
|
||||
c: string | null = null
|
||||
let radata: number[][] = [],
|
||||
rbdata: number[][] = [],
|
||||
rcdata: number[][] = []
|
||||
let rmsvX: any = 0,
|
||||
rmsvY: any = 0,
|
||||
zhou = ''
|
||||
|
||||
if (!waveDatas) {
|
||||
titleText = '该事件暂无波形图'
|
||||
@@ -543,10 +584,7 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
]
|
||||
unit = 'kV'
|
||||
} else {
|
||||
fz.value = [
|
||||
props.wp.listRmsMinData[0][0],
|
||||
props.wp.listRmsMinData[0][1]
|
||||
]
|
||||
fz.value = [props.wp.listRmsMinData[0][0], props.wp.listRmsMinData[0][1]]
|
||||
unit = 'V'
|
||||
}
|
||||
} else {
|
||||
@@ -555,18 +593,40 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
|
||||
for (let step = waveDatas.length - 1; step > 0 && step < waveDatas.length; step--) {
|
||||
const rmsId = 'rms' + step
|
||||
const newDivRms = $(`<div style="height:${vh.value};overflow: hidden;"><div class='bx' id='${rmsId}'></div></div>`)
|
||||
const newDivRms = $(
|
||||
`<div style="height:${vh.value};overflow: hidden;min-height: 200px;"><div class='bx' id='${rmsId}'></div></div>`
|
||||
)
|
||||
newDivRms.insertAfter($('#rmsp'))
|
||||
$(`#${rmsId}`).css('height', picHeight).css('width', vw.value)
|
||||
$(`#${rmsId}`).css('height', picHeight).css('width', vw.value).css('min-height', '200px')
|
||||
}
|
||||
} else {
|
||||
titleText = `变电站名称:${subName.value} 监测点名称:${lineName.value} 发生时刻:${time} 残余电压:${(Number(eventValue.value) * 1).toFixed(0)}% 持续时间:${persistTime.value}s`
|
||||
titleText = `变电站名称:${subName.value} 监测点名称:${lineName.value} 发生时刻:${time} 暂降(骤升)幅值:${(
|
||||
Number(eventValue.value) * 1
|
||||
).toFixed(0)}% 持续时间:${persistTime.value}s`
|
||||
}
|
||||
const rms = document.getElementById('rmsp')
|
||||
|
||||
if (!rms) return
|
||||
const myChartes = echarts.init(rms)
|
||||
const echartsColor = { WordColor: "#fff", thread: "#fff", FigureColor: ["#07CCCA ", "#00BFF5", "#FFBF00", "#77DA63", "#D5FF6B", "#Ff6600", "#FF9100", "#5B6E96", "#66FFCC", "#B3B3B3", "#FF00FF", "#CC00FF", "#FF9999"] }
|
||||
const echartsColor = {
|
||||
WordColor: '#000',
|
||||
thread: '#000',
|
||||
FigureColor: [
|
||||
'#07CCCA ',
|
||||
'#00BFF5',
|
||||
'#FFBF00',
|
||||
'#77DA63',
|
||||
'#D5FF6B',
|
||||
'#Ff6600',
|
||||
'#FF9100',
|
||||
'#5B6E96',
|
||||
'#66FFCC',
|
||||
'#B3B3B3',
|
||||
'#FF00FF',
|
||||
'#CC00FF',
|
||||
'#FF9999'
|
||||
]
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
rms.style.width = '100%'
|
||||
@@ -582,7 +642,12 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
let tips = '时刻:' + params[0].data[0] + '</br/>'
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
if (params[i].seriesName != '暂降触发点') {
|
||||
tips += params[i].marker + params[i].seriesName + ':' + (params[i].value[1] - 0).toFixed(2) + '<br/>'
|
||||
tips +=
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
':' +
|
||||
(params[i].value[1] - 0).toFixed(2) +
|
||||
'<br/>'
|
||||
}
|
||||
}
|
||||
return tips
|
||||
@@ -604,8 +669,8 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
align: 'left'
|
||||
},
|
||||
textStyle: {
|
||||
fontSize: '0.8rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '16px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
@@ -615,8 +680,8 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
enabled: true,
|
||||
itemDistance: 5,
|
||||
textStyle: {
|
||||
fontSize: '0.7rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
rich: { a: { verticalAlign: 'middle' } },
|
||||
padding: [0, 0, 0, 0]
|
||||
}
|
||||
@@ -641,13 +706,13 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
title: {
|
||||
text: 'ms',
|
||||
textStyle: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
},
|
||||
enabled: true,
|
||||
align: 'high'
|
||||
},
|
||||
nameTextStyle: { fontSize: '0.6rem' },
|
||||
nameTextStyle: { fontSize: '12px' },
|
||||
labels: {
|
||||
formatter: function () {
|
||||
return this.value
|
||||
@@ -657,13 +722,13 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
axisTick: { alignWithLabel: true },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: props.DColor ? '#fff' : echartsColor.thread
|
||||
color: props.DColor ? '#000' : echartsColor.thread
|
||||
},
|
||||
onZero: false
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
formatter: function (value: number) {
|
||||
if (valA.value != (value - 0).toFixed(0)) {
|
||||
valA.value = Number((value - 0).toFixed(0))
|
||||
@@ -684,31 +749,31 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
y: -10
|
||||
},
|
||||
max: rmscm[0]?.[1] * 1.06 || 0,
|
||||
min: rmscu[0]?.[1] - (rmscu[0]?.[1] * 0.04) || 0,
|
||||
min: rmscu[0]?.[1] - rmscu[0]?.[1] * 0.2 || 0,
|
||||
boundaryGap: [0, '100%'],
|
||||
showLastLabel: true,
|
||||
opposite: false,
|
||||
nameTextStyle: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: props.DColor ? '#fff' : echartsColor.thread
|
||||
color: props.DColor ? '#000' : echartsColor.thread
|
||||
},
|
||||
onZero: false
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
formatter: function (value: number) {
|
||||
return (value - 0).toFixed(2)
|
||||
return Math.floor(value * 1000) / 1000
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: [props.DColor ? '#fff' : echartsColor.thread],
|
||||
color: [props.DColor ? '#000' : echartsColor.thread],
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
@@ -718,7 +783,7 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
left: '1%',
|
||||
right: '45px',
|
||||
bottom: '40px',
|
||||
top: '70px',
|
||||
top: '60px',
|
||||
containLabel: true
|
||||
},
|
||||
dataZoom: [
|
||||
@@ -772,7 +837,7 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
data: rmscu
|
||||
},
|
||||
{
|
||||
name: '最小残余电压',
|
||||
name: '最小暂降(骤升)幅值',
|
||||
type: 'scatter',
|
||||
symbol: 'image://' + url2,
|
||||
itemStyle: { width: 45, height: 45 },
|
||||
@@ -780,7 +845,7 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
show: true,
|
||||
position: [5, -20],
|
||||
color: '#000',
|
||||
fontSize: '14px',
|
||||
fontSize: '12px',
|
||||
fontWeight: 'bold',
|
||||
borderType: 'solid',
|
||||
borderWidth: 0.5,
|
||||
@@ -792,7 +857,6 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
myChartes.setOption(option)
|
||||
myChartess.value = myChartes
|
||||
|
||||
@@ -809,12 +873,25 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
}
|
||||
}
|
||||
|
||||
const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show: boolean, myChartes1: echarts.ECharts, rmscm: number[][], rmscu: number[][], title: string) => {
|
||||
const drawPics = (
|
||||
waveDataTemp: WaveData,
|
||||
picHeight: string,
|
||||
step: number,
|
||||
show: boolean,
|
||||
myChartes1: echarts.ECharts,
|
||||
rmscm: number[][],
|
||||
rmscu: number[][],
|
||||
title: string
|
||||
) => {
|
||||
step = step + 1
|
||||
const rmsId = 'rms' + step
|
||||
let a = '', b = '', c = ''
|
||||
let a = '',
|
||||
b = '',
|
||||
c = ''
|
||||
let unit = ''
|
||||
let radata: number[][] = [], rbdata: number[][] = [], rcdata: number[][] = []
|
||||
let radata: number[][] = [],
|
||||
rbdata: number[][] = [],
|
||||
rcdata: number[][] = []
|
||||
|
||||
switch (iphasic.value) {
|
||||
case 1:
|
||||
@@ -877,7 +954,25 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
if (!rmsIds) return
|
||||
|
||||
const myChartes = echarts.init(rmsIds)
|
||||
const echartsColor = { WordColor: "#fff", thread: "#fff", FigureColor: ["#07CCCA ", "#00BFF5", "#FFBF00", "#77DA63", "#D5FF6B", "#Ff6600", "#FF9100", "#5B6E96", "#66FFCC", "#B3B3B3", "#FF00FF", "#CC00FF", "#FF9999"] }
|
||||
const echartsColor = {
|
||||
WordColor: '#000',
|
||||
thread: '#000',
|
||||
FigureColor: [
|
||||
'#07CCCA ',
|
||||
'#00BFF5',
|
||||
'#FFBF00',
|
||||
'#77DA63',
|
||||
'#D5FF6B',
|
||||
'#Ff6600',
|
||||
'#FF9100',
|
||||
'#5B6E96',
|
||||
'#66FFCC',
|
||||
'#B3B3B3',
|
||||
'#FF00FF',
|
||||
'#CC00FF',
|
||||
'#FF9999'
|
||||
]
|
||||
}
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
@@ -888,7 +983,12 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
let tips = '时刻:' + params[0].data[0] + '</br/>'
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
if (params[i].seriesName != '暂降触发点') {
|
||||
tips += params[i].marker + params[i].seriesName + ':' + (params[i].value[1] - 0).toFixed(2) + '<br/>'
|
||||
tips +=
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
':' +
|
||||
(params[i].value[1] - 0).toFixed(2) +
|
||||
'<br/>'
|
||||
}
|
||||
}
|
||||
return tips
|
||||
@@ -904,10 +1004,10 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
},
|
||||
title: {
|
||||
left: 'center',
|
||||
text: '',//titlename || title,
|
||||
text: '', //titlename || title,
|
||||
textStyle: {
|
||||
fontSize: '0.8rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '16px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
@@ -917,8 +1017,8 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
enabled: true,
|
||||
itemDistance: 5,
|
||||
textStyle: {
|
||||
fontSize: '0.7rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
rich: { a: { verticalAlign: 'middle' } },
|
||||
padding: [0, 0, 0, 0]
|
||||
}
|
||||
@@ -932,8 +1032,8 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
title: {
|
||||
text: 'ms',
|
||||
textStyle: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
},
|
||||
enabled: true,
|
||||
align: 'high'
|
||||
@@ -943,18 +1043,18 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
return this.value
|
||||
}
|
||||
},
|
||||
nameTextStyle: { fontSize: '0.6rem' },
|
||||
nameTextStyle: { fontSize: '12px' },
|
||||
splitLine: { show: false },
|
||||
axisTick: { alignWithLabel: true },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: props.DColor ? '#fff' : echartsColor.thread
|
||||
color: props.DColor ? '#000' : echartsColor.thread
|
||||
},
|
||||
onZero: false
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
formatter: function (value: number) {
|
||||
if (valB.value != (value - 0).toFixed(0)) {
|
||||
valB.value = Number((value - 0).toFixed(0))
|
||||
@@ -978,26 +1078,27 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
showLastLabel: true,
|
||||
opposite: false,
|
||||
nameTextStyle: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: props.DColor ? '#fff' : echartsColor.thread
|
||||
color: props.DColor ? '#000' : echartsColor.thread
|
||||
},
|
||||
onZero: false
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
formatter: function (value: number) {
|
||||
return (value - 0).toFixed(2)
|
||||
// return (value - 0).toFixed(2)
|
||||
return Math.floor(value * 1000) / 1000
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: [props.DColor ? '#fff' : echartsColor.thread],
|
||||
color: [props.DColor ? '#000' : echartsColor.thread],
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
@@ -1007,7 +1108,7 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
left: '1%',
|
||||
right: '45px',
|
||||
bottom: '40px',
|
||||
top: '70px',
|
||||
top: '60px',
|
||||
containLabel: true
|
||||
},
|
||||
dataZoom: [
|
||||
@@ -1059,11 +1160,21 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
myChartes.setOption(option)
|
||||
|
||||
switch (step) {
|
||||
case 1: myChartess1.value = myChartes; break
|
||||
case 2: myChartess2.value = myChartes; break
|
||||
case 3: myChartess3.value = myChartes; break
|
||||
case 4: myChartess4.value = myChartes; break
|
||||
case 5: myChartess5.value = myChartes; break
|
||||
case 1:
|
||||
myChartess1.value = myChartes
|
||||
break
|
||||
case 2:
|
||||
myChartess2.value = myChartes
|
||||
break
|
||||
case 3:
|
||||
myChartess3.value = myChartes
|
||||
break
|
||||
case 4:
|
||||
myChartess4.value = myChartes
|
||||
break
|
||||
case 5:
|
||||
myChartess5.value = myChartes
|
||||
break
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
@@ -1076,7 +1187,14 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
|
||||
const backbxlb = () => {
|
||||
waveDatas.value = []
|
||||
const charts = [myChartess.value, myChartess1.value, myChartess2.value, myChartess3.value, myChartess4.value, myChartess5.value]
|
||||
const charts = [
|
||||
myChartess.value,
|
||||
myChartess1.value,
|
||||
myChartess2.value,
|
||||
myChartess3.value,
|
||||
myChartess4.value,
|
||||
myChartess5.value
|
||||
]
|
||||
|
||||
charts.forEach(chart => {
|
||||
if (chart) {
|
||||
@@ -1092,13 +1210,11 @@ const backbxlb = () => {
|
||||
myChartess5.value = null
|
||||
|
||||
// echarts.disconnect(charts.filter(Boolean) as echarts.ECharts[])
|
||||
charts
|
||||
.filter(Boolean)
|
||||
.forEach(chart => {
|
||||
if (chart && typeof chart.dispose === 'function') {
|
||||
chart.dispose();
|
||||
}
|
||||
});
|
||||
charts.filter(Boolean).forEach(chart => {
|
||||
if (chart && typeof chart.dispose === 'function') {
|
||||
chart.dispose()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getMax = (temp: number, tempA: number, tempB: number, tempC: number): number => {
|
||||
|
||||
@@ -1,179 +1,205 @@
|
||||
// waveData.worker.js
|
||||
self.addEventListener('message', function(e) {
|
||||
const { wp, value, iphasic, isOpen, boxoList } = JSON.parse(e.data);
|
||||
self.addEventListener('message', function (e) {
|
||||
const { wp, value, iphasic, isOpen, boxoList } = JSON.parse(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 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 = [];
|
||||
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 = '电流';
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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];
|
||||
}
|
||||
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;
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 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 }
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
return { instantF, instantS, shunshiF, shunshiS, title, unit }
|
||||
}
|
||||
|
||||
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 };
|
||||
// 处理标题
|
||||
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'
|
||||
}
|
||||
|
||||
return { instantF, instantS, shunshiF, shunshiS, title, unit };
|
||||
};
|
||||
const iphasicValue = wp.iphasic || 1
|
||||
const picCounts = (wp.waveTitle.length - 1) / iphasicValue
|
||||
const waveDatas = []
|
||||
|
||||
// 处理标题
|
||||
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.equipmentName +
|
||||
' 发生时刻:' +
|
||||
boxoList.startTime +
|
||||
' 残余电压:' +
|
||||
boxoList.evtParamVVaDepth +
|
||||
' 持续时间:' +
|
||||
boxoList.evtParamTm +
|
||||
's';
|
||||
} else {
|
||||
titles = '变电站名称:' +
|
||||
boxoList.subName +
|
||||
' 监测点名称:' +
|
||||
boxoList.lineName +
|
||||
' 发生时刻:' +
|
||||
boxoList.startTime +
|
||||
' 残余电压:' +
|
||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||
'% 持续时间:' +
|
||||
boxoList.duration +
|
||||
's';
|
||||
}
|
||||
for (let i = 0; i < picCounts; i++) {
|
||||
const data = fliteWaveData(wp, i)
|
||||
waveDatas.push(data)
|
||||
}
|
||||
|
||||
const iphasicValue = wp.iphasic || 1;
|
||||
const picCounts = (wp.waveTitle.length - 1) / iphasicValue;
|
||||
const waveDatas = [];
|
||||
const time = wp.time
|
||||
const type = wp.waveType
|
||||
let severity = wp.yzd
|
||||
|
||||
for (let i = 0; i < picCounts; i++) {
|
||||
const data = fliteWaveData(wp, i);
|
||||
waveDatas.push(data);
|
||||
}
|
||||
if (severity < 0) {
|
||||
severity = '/'
|
||||
type = '/'
|
||||
}
|
||||
|
||||
const time = wp.time;
|
||||
const type = wp.waveType;
|
||||
let severity = wp.yzd;
|
||||
|
||||
if (severity < 0) {
|
||||
severity = '/';
|
||||
type = '/';
|
||||
}
|
||||
|
||||
// 将处理结果发送回主线程
|
||||
self.postMessage({
|
||||
waveDatas,
|
||||
time,
|
||||
type,
|
||||
severity,
|
||||
titles,
|
||||
iphasic: iphasicValue
|
||||
});
|
||||
});
|
||||
// 将处理结果发送回主线程
|
||||
self.postMessage({
|
||||
waveDatas,
|
||||
time,
|
||||
type,
|
||||
severity,
|
||||
titles,
|
||||
iphasic: iphasicValue
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
<template>
|
||||
<div v-loading="loading" :element-loading-background="'rgba(122, 122, 122, 0.8)'" class="boxbx"
|
||||
style="position: relative;height: 100%;">
|
||||
<div id="boxsj" style="background: #343849c7">
|
||||
<div id="shushi" :style="`height:${vh};overflow: hidden;`">
|
||||
<div class="bx" id="wave"></div>
|
||||
<div v-loading="loading" class="boxbx" style="position: relative; height: 100%">
|
||||
<div id="boxsj">
|
||||
<div id="shushi" :style="`height:${vh};overflow: hidden;min-height: 200px;`">
|
||||
<div class="bx" id="wave" style="min-height: 200px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -14,9 +13,10 @@ import { ref, computed, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
|
||||
import html2canvas from 'html2canvas'
|
||||
import $ from 'jquery'
|
||||
import * as echarts from 'echarts'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import url from '@/assets/img/point.png'
|
||||
// 创建Worker
|
||||
let waveDataWorker: Worker | null = null;
|
||||
let waveDataWorker: Worker | null = null
|
||||
interface WaveData {
|
||||
instantF: { max: number; min: number }
|
||||
instantS: { max: number; min: number }
|
||||
@@ -42,7 +42,7 @@ interface WaveData {
|
||||
interface Props {
|
||||
value?: number
|
||||
flag?: string | number | boolean
|
||||
parentHeight?: string | number | boolean
|
||||
parentHeight?: any
|
||||
DColor?: boolean
|
||||
boxoList?: any
|
||||
wp?: any
|
||||
@@ -87,29 +87,44 @@ const myChartess4 = ref<echarts.ECharts | null>(null)
|
||||
const myChartess5 = ref<echarts.ECharts | null>(null)
|
||||
|
||||
const vh = computed(() => {
|
||||
if (props.flag == 1) {
|
||||
return '690px'
|
||||
if (props.parentHeight == 999) {
|
||||
return `calc((60vh - 150px) / 2 )`
|
||||
} else if (props.parentHeight != 0) {
|
||||
return '310px'
|
||||
} else {
|
||||
return '350px'
|
||||
return mainHeight(props.parentHeight, 2).height
|
||||
}
|
||||
|
||||
if (props.flag == 1) {
|
||||
return mainHeight(200).height
|
||||
} else {
|
||||
return mainHeight(200, 2).height
|
||||
}
|
||||
|
||||
// if (props.flag == 1) {
|
||||
// return '690px'
|
||||
// } else if (props.parentHeight != 0) {
|
||||
// return '310px'
|
||||
// } else {
|
||||
// return '350px'
|
||||
// }
|
||||
})
|
||||
|
||||
const vw = computed(() => '100%')
|
||||
|
||||
watch(() => props.value, (newVal) => {
|
||||
if (newVal == 2) {
|
||||
initWaves()
|
||||
} else {
|
||||
$('#wave1').remove()
|
||||
initWaves()
|
||||
watch(
|
||||
() => props.value,
|
||||
newVal => {
|
||||
if (newVal == 2) {
|
||||
initWaves()
|
||||
} else {
|
||||
$('#wave1').remove()
|
||||
initWaves()
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
const zoomValue = document.body.style.getPropertyValue('zoom');
|
||||
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1);
|
||||
const zoomValue = document.body.style.getPropertyValue('zoom')
|
||||
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1)
|
||||
|
||||
window.addEventListener('resize', handleResize)
|
||||
nextTick(() => {
|
||||
@@ -120,27 +135,27 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
console.log('组件卸载');
|
||||
console.log('组件卸载')
|
||||
|
||||
if (waveDataWorker) {
|
||||
waveDataWorker.terminate();
|
||||
waveDataWorker = null;
|
||||
waveDataWorker.terminate()
|
||||
waveDataWorker = null
|
||||
}
|
||||
|
||||
backbxlb();
|
||||
window.removeEventListener('resize', handleResize);
|
||||
backbxlb()
|
||||
window.removeEventListener('resize', handleResize)
|
||||
})
|
||||
|
||||
const handleResize = () => {
|
||||
const zoomValue = document.body.style.getPropertyValue('zoom');
|
||||
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1);
|
||||
const zoomValue = document.body.style.getPropertyValue('zoom')
|
||||
zoom.value = 1 / (zoomValue ? parseFloat(zoomValue) : 1)
|
||||
}
|
||||
|
||||
const download = () => {
|
||||
const boxsj = document.getElementById('boxsj')
|
||||
if (boxsj) {
|
||||
html2canvas(boxsj, {
|
||||
scale: 2,
|
||||
scale: 2
|
||||
}).then(function (canvas) {
|
||||
const creatIMg = document.createElement('a')
|
||||
creatIMg.download = '瞬间波形.png'
|
||||
@@ -170,49 +185,56 @@ const waveData = (instantF: any, instantS: any, shunshiF: any, shunshiS: any, ti
|
||||
// 在组件中修改initWaves函数
|
||||
const initWaves = () => {
|
||||
if (props.wp) {
|
||||
loading.value = true;
|
||||
loading.value = true
|
||||
iphasic.value = props.wp.iphasic || 1
|
||||
// 使用Web Worker处理数据
|
||||
if (!waveDataWorker) {
|
||||
waveDataWorker = new Worker(new URL('./shuWorker.js', import.meta.url));
|
||||
waveDataWorker = new Worker(new URL('./shuWorker.js', import.meta.url))
|
||||
|
||||
waveDataWorker.onmessage = function (e) {
|
||||
const data = e.data;
|
||||
const data = e.data
|
||||
|
||||
titles.value = data.titles;
|
||||
iphasic.value = data.iphasic;
|
||||
time.value = data.time;
|
||||
type.value = data.type;
|
||||
severity.value = data.severity;
|
||||
titles.value = data.titles
|
||||
iphasic.value = data.iphasic
|
||||
time.value = data.time
|
||||
type.value = data.type
|
||||
severity.value = data.severity
|
||||
|
||||
initWave(data.waveDatas, data.time, data.type, data.severity, isOpen.value);
|
||||
initWave(data.waveDatas, data.time, data.type, data.severity, isOpen.value)
|
||||
|
||||
loading.value = false;
|
||||
};
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
waveDataWorker.onerror = function (error) {
|
||||
console.error('Worker error:', error);
|
||||
loading.value = false;
|
||||
console.error('Worker error:', error)
|
||||
loading.value = false
|
||||
// 备用方案:在主线程处理数据
|
||||
// processDataInMainThread();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 发送数据到Worker
|
||||
waveDataWorker.postMessage(JSON.stringify({
|
||||
wp: props.wp,
|
||||
value: props.value,
|
||||
iphasic: iphasic.value,
|
||||
isOpen: isOpen.value,
|
||||
boxoList: props.boxoList
|
||||
}));
|
||||
waveDataWorker.postMessage(
|
||||
JSON.stringify({
|
||||
wp: props.wp,
|
||||
value: props.value,
|
||||
iphasic: iphasic.value,
|
||||
isOpen: isOpen.value,
|
||||
boxoList: props.boxoList
|
||||
})
|
||||
)
|
||||
} else {
|
||||
initWave(null, null, null, null, null);
|
||||
initWave(null, null, null, null, null)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const initWave = (waveDatas: WaveData[] | null, time: string | null, type: string | null, severity: string | null, isOpen: boolean | null) => {
|
||||
const initWave = (
|
||||
waveDatas: WaveData[] | null,
|
||||
time: string | null,
|
||||
type: string | null,
|
||||
severity: string | null,
|
||||
isOpen: boolean | null
|
||||
) => {
|
||||
$('div.bx1').remove()
|
||||
|
||||
let picHeight = vh.value
|
||||
@@ -221,9 +243,14 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
let cu: number[][] = []
|
||||
let titleText = ''
|
||||
let unit = ''
|
||||
let max: any = 0, min: any = 0
|
||||
let a: string | null = null, b: string | null = null, c: string | null = null
|
||||
let adata: number[][] = [], bdata: number[][] = [], cdata: number[][] = []
|
||||
let max: any = 0,
|
||||
min: any = 0
|
||||
let a: string | null = null,
|
||||
b: string | null = null,
|
||||
c: string | null = null
|
||||
let adata: number[][] = [],
|
||||
bdata: number[][] = [],
|
||||
cdata: number[][] = []
|
||||
const colors: string[] = []
|
||||
|
||||
if (!waveDatas) {
|
||||
@@ -249,7 +276,7 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
min = waveDatas[0].instantS.min
|
||||
adata = waveDatas[0].shunshiS.shunshiSA
|
||||
}
|
||||
colors.push('#DAA520', '#fff', '#fff')
|
||||
colors.push('#DAA520', '#000', '#000')
|
||||
break
|
||||
case 2:
|
||||
a = waveDatas[0].title.aTitle
|
||||
@@ -267,7 +294,7 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
adata = waveDatas[0].shunshiS.shunshiSA
|
||||
bdata = waveDatas[0].shunshiS.shunshiSB
|
||||
}
|
||||
colors.push('#DAA520', '#2E8B57', '#fff')
|
||||
colors.push('#DAA520', '#2E8B57', '#000')
|
||||
break
|
||||
case 3:
|
||||
a = waveDatas[0].title.aTitle
|
||||
@@ -300,21 +327,41 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
|
||||
for (let step = waveDatas.length - 1; step > 0 && step < waveDatas.length; step--) {
|
||||
const waveId = 'wave' + step
|
||||
const newDivShunshi = $(`<div style="height:${vh.value};overflow: hidden;">
|
||||
const newDivShunshi = $(`<div style="height:${vh.value};overflow: hidden;min-height: 200px;">
|
||||
<div class='bx1' id='${waveId}'></div>
|
||||
</div>`)
|
||||
newDivShunshi.insertAfter($('#shushi'))
|
||||
$(`#${waveId}`).css('height', picHeight).css('width', vw.value)
|
||||
$(`#${waveId}`).css('height', picHeight).css('width', vw.value).css('min-height', '200px')
|
||||
}
|
||||
} else {
|
||||
titleText = `变电站名称:${subName.value} 监测点名称:${lineName.value} 发生时刻:${time} 残余电压:${(Number(eventValue.value) * 1).toFixed(0)}% 持续时间:${persistTime.value}s`
|
||||
titleText = `变电站名称:${subName.value} 监测点名称:${lineName.value} 发生时刻:${time} 暂降(骤升)幅值:${(
|
||||
Number(eventValue.value) * 1
|
||||
).toFixed(0)}% 持续时间:${persistTime.value}s`
|
||||
}
|
||||
|
||||
const wave = document.getElementById('wave')
|
||||
if (!wave) return
|
||||
|
||||
const myChartes = echarts.init(wave)
|
||||
const echartsColor = { WordColor: "#fff", thread: "#fff", FigureColor: ["#07CCCA ", "#00BFF5", "#FFBF00", "#77DA63", "#D5FF6B", "#Ff6600", "#FF9100", "#5B6E96", "#66FFCC", "#B3B3B3", "#FF00FF", "#CC00FF", "#FF9999"] }
|
||||
const echartsColor = {
|
||||
WordColor: '#000',
|
||||
thread: '#000',
|
||||
FigureColor: [
|
||||
'#07CCCA ',
|
||||
'#00BFF5',
|
||||
'#FFBF00',
|
||||
'#77DA63',
|
||||
'#D5FF6B',
|
||||
'#Ff6600',
|
||||
'#FF9100',
|
||||
'#5B6E96',
|
||||
'#66FFCC',
|
||||
'#B3B3B3',
|
||||
'#FF00FF',
|
||||
'#CC00FF',
|
||||
'#FF9999'
|
||||
]
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
wave.style.width = '100%'
|
||||
@@ -335,7 +382,12 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
let tips = '时刻:' + params[0].data[0] + '</br/>'
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
if (params[i].seriesName != '暂降触发点') {
|
||||
tips += params[i].marker + params[i].seriesName + ':' + (params[i].value[1] - 0).toFixed(2) + '<br/>'
|
||||
tips +=
|
||||
params[i].marker +
|
||||
params[i].seriesName +
|
||||
':' +
|
||||
(params[i].value[1] - 0).toFixed(2) +
|
||||
'<br/>'
|
||||
}
|
||||
}
|
||||
return tips
|
||||
@@ -353,8 +405,8 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
left: 'center',
|
||||
text: titleText,
|
||||
textStyle: {
|
||||
fontSize: '0.8rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '16px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
@@ -364,8 +416,8 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
enabled: true,
|
||||
itemDistance: 5,
|
||||
textStyle: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: 12,
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
rich: { a: { verticalAlign: 'middle' } },
|
||||
padding: [0, 0, 0, 0]
|
||||
}
|
||||
@@ -390,24 +442,24 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
title: {
|
||||
text: 'ms',
|
||||
textStyle: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
},
|
||||
enabled: true,
|
||||
align: 'high'
|
||||
},
|
||||
splitLine: { show: false },
|
||||
nameTextStyle: { fontSize: '0.6rem' },
|
||||
nameTextStyle: { fontSize: '12px' },
|
||||
axisTick: { alignWithLabel: true },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: props.DColor ? '#fff' : echartsColor.thread
|
||||
color: props.DColor ? '#000' : echartsColor.thread
|
||||
},
|
||||
onZero: false
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
formatter: function (value: number) {
|
||||
if (valA.value != (value - 0).toFixed(0)) {
|
||||
valA.value = Number((value - 0).toFixed(0))
|
||||
@@ -433,26 +485,27 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
min: min.toFixed(2) > 0 ? min.toFixed(2) - min.toFixed(2) * 0.1 : min.toFixed(2) * 1.1,
|
||||
opposite: false,
|
||||
nameTextStyle: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: props.DColor ? '#fff' : echartsColor.thread
|
||||
color: props.DColor ? '#000' : echartsColor.thread
|
||||
},
|
||||
onZero: false
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
formatter: function (value: number) {
|
||||
return (value - 0).toFixed(2)
|
||||
// return (value - 0).toFixed(2)
|
||||
return Math.floor(value * 1000) / 1000
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: [props.DColor ? '#fff' : echartsColor.thread],
|
||||
color: [props.DColor ? '#000' : echartsColor.thread],
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
@@ -460,9 +513,9 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
},
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '2.8%',
|
||||
right: '45px',
|
||||
bottom: '40px',
|
||||
top: '70px',
|
||||
top: '60px',
|
||||
containLabel: true
|
||||
},
|
||||
dataZoom: [
|
||||
@@ -537,23 +590,36 @@ const initWave = (waveDatas: WaveData[] | null, time: string | null, type: strin
|
||||
}
|
||||
}
|
||||
|
||||
const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show: boolean, myChartes1: echarts.ECharts, title: string) => {
|
||||
const drawPics = (
|
||||
waveDataTemp: WaveData,
|
||||
picHeight: any,
|
||||
step: number,
|
||||
show: boolean,
|
||||
myChartes1: echarts.ECharts,
|
||||
title: string
|
||||
) => {
|
||||
step = step + 1
|
||||
const waveId = 'wave' + step
|
||||
let a: string | null = null, b: string | null = null, c: string | null = null
|
||||
let max: any = 0, min: any = 0, unit = ''
|
||||
let adata: number[][] = [], bdata: number[][] = [], cdata: number[][] = []
|
||||
let a: string | null = null,
|
||||
b: string | null = null,
|
||||
c: string | null = null
|
||||
let max: any = 0,
|
||||
min: any = 0,
|
||||
unit = ''
|
||||
let adata: number[][] = [],
|
||||
bdata: number[][] = [],
|
||||
cdata: number[][] = []
|
||||
const colors: string[] = []
|
||||
|
||||
switch (iphasic.value) {
|
||||
case 1:
|
||||
a = waveDataTemp.title.aTitle
|
||||
colors.push('#DAA520', '#fff', '#fff')
|
||||
colors.push('#DAA520', '#000', '#000')
|
||||
break
|
||||
case 2:
|
||||
a = waveDataTemp.title.aTitle
|
||||
b = waveDataTemp.title.bTitle
|
||||
colors.push('#DAA520', '#2E8B57', '#fff')
|
||||
colors.push('#DAA520', '#2E8B57', '#000')
|
||||
break
|
||||
case 3:
|
||||
a = waveDataTemp.title.aTitle
|
||||
@@ -612,7 +678,25 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
if (!waveIds) return
|
||||
|
||||
const myChartes = echarts.init(waveIds)
|
||||
const echartsColor = { WordColor: "#fff", thread: "#fff", FigureColor: ["#07CCCA ", "#00BFF5", "#FFBF00", "#77DA63", "#D5FF6B", "#Ff6600", "#FF9100", "#5B6E96", "#66FFCC", "#B3B3B3", "#FF00FF", "#CC00FF", "#FF9999"] }
|
||||
const echartsColor = {
|
||||
WordColor: '#000',
|
||||
thread: '#000',
|
||||
FigureColor: [
|
||||
'#07CCCA ',
|
||||
'#00BFF5',
|
||||
'#FFBF00',
|
||||
'#77DA63',
|
||||
'#D5FF6B',
|
||||
'#Ff6600',
|
||||
'#FF9100',
|
||||
'#5B6E96',
|
||||
'#66FFCC',
|
||||
'#B3B3B3',
|
||||
'#FF00FF',
|
||||
'#CC00FF',
|
||||
'#FF9999'
|
||||
]
|
||||
}
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
@@ -638,10 +722,10 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
},
|
||||
title: {
|
||||
left: 'center',
|
||||
text: '',//titlename || title,
|
||||
text: '', //titlename || title,
|
||||
textStyle: {
|
||||
fontSize: '0.8rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '16px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
@@ -651,8 +735,8 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
enabled: true,
|
||||
itemDistance: 5,
|
||||
textStyle: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: 12,
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
rich: { a: { verticalAlign: 'middle' } },
|
||||
padding: [0, 0, 0, 0]
|
||||
}
|
||||
@@ -666,8 +750,8 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
title: {
|
||||
text: 'ms',
|
||||
textStyle: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
},
|
||||
enabled: true,
|
||||
align: 'high'
|
||||
@@ -676,14 +760,14 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
axisTick: { alignWithLabel: true },
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: props.DColor ? '#fff' : echartsColor.thread
|
||||
color: props.DColor ? '#000' : echartsColor.thread
|
||||
},
|
||||
onZero: false
|
||||
},
|
||||
nameTextStyle: { fontSize: '0.6rem' },
|
||||
nameTextStyle: { fontSize: '12px' },
|
||||
axisLabel: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
formatter: function (value: number) {
|
||||
if (valB.value != (value - 0).toFixed(0)) {
|
||||
valB.value = Number((value - 0).toFixed(0))
|
||||
@@ -709,26 +793,27 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
min: min.toFixed(2) > 0 ? min.toFixed(2) - min.toFixed(2) * 0.1 : min.toFixed(2) * 1.1,
|
||||
opposite: false,
|
||||
nameTextStyle: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: props.DColor ? '#fff' : echartsColor.thread
|
||||
color: props.DColor ? '#000' : echartsColor.thread
|
||||
},
|
||||
onZero: false
|
||||
},
|
||||
axisLabel: {
|
||||
fontSize: '0.6rem',
|
||||
color: props.DColor ? '#fff' : echartsColor.WordColor,
|
||||
fontSize: '12px',
|
||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||
formatter: function (value: number) {
|
||||
return (value - 0).toFixed(2)
|
||||
// return (value - 0).toFixed(2)
|
||||
return Math.floor(value * 1000) / 1000
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: [props.DColor ? '#fff' : echartsColor.thread],
|
||||
color: [props.DColor ? '#000' : echartsColor.thread],
|
||||
type: 'dashed',
|
||||
opacity: 0.5
|
||||
}
|
||||
@@ -736,9 +821,9 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
},
|
||||
grid: {
|
||||
left: '1%',
|
||||
right: '2.8%',
|
||||
right: '45px',
|
||||
bottom: '40px',
|
||||
top: '70px',
|
||||
top: '60px',
|
||||
containLabel: true
|
||||
},
|
||||
dataZoom: [
|
||||
@@ -793,11 +878,21 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
myChartes.setOption(option)
|
||||
|
||||
switch (step) {
|
||||
case 1: myChartess1.value = myChartes; break
|
||||
case 2: myChartess2.value = myChartes; break
|
||||
case 3: myChartess3.value = myChartes; break
|
||||
case 4: myChartess4.value = myChartes; break
|
||||
case 5: myChartess5.value = myChartes; break
|
||||
case 1:
|
||||
myChartess1.value = myChartes
|
||||
break
|
||||
case 2:
|
||||
myChartess2.value = myChartes
|
||||
break
|
||||
case 3:
|
||||
myChartess3.value = myChartes
|
||||
break
|
||||
case 4:
|
||||
myChartess4.value = myChartes
|
||||
break
|
||||
case 5:
|
||||
myChartess5.value = myChartes
|
||||
break
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
@@ -810,7 +905,14 @@ const drawPics = (waveDataTemp: WaveData, picHeight: string, step: number, show:
|
||||
|
||||
const backbxlb = () => {
|
||||
waveDatas.value = []
|
||||
const charts = [myChartess.value, myChartess1.value, myChartess2.value, myChartess3.value, myChartess4.value, myChartess5.value]
|
||||
const charts = [
|
||||
myChartess.value,
|
||||
myChartess1.value,
|
||||
myChartess2.value,
|
||||
myChartess3.value,
|
||||
myChartess4.value,
|
||||
myChartess5.value
|
||||
]
|
||||
|
||||
charts.forEach(chart => {
|
||||
if (chart) {
|
||||
@@ -826,13 +928,11 @@ const backbxlb = () => {
|
||||
myChartess5.value = null
|
||||
|
||||
// echarts.disconnect(charts.filter(Boolean) as echarts.ECharts[])
|
||||
charts
|
||||
.filter(Boolean)
|
||||
.forEach(chart => {
|
||||
if (chart && typeof chart.dispose === 'function') {
|
||||
chart.dispose();
|
||||
}
|
||||
});
|
||||
charts.filter(Boolean).forEach(chart => {
|
||||
if (chart && typeof chart.dispose === 'function') {
|
||||
chart.dispose()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getMax = (temp: number, tempA: number, tempB: number, tempC: number): number => {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
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-option v-for="item in filteredTimeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
<el-date-picker
|
||||
v-model.trim="timeValue"
|
||||
@@ -20,6 +20,7 @@
|
||||
value-format="YYYY-MM-DD"
|
||||
:shortcuts="shortcuts"
|
||||
/>
|
||||
|
||||
<el-button :disabled="backDisabled" type="primary" :icon="DArrowLeft" @click="preClick"></el-button>
|
||||
<el-button type="primary" :icon="VideoPause" @click="nowTime">当前</el-button>
|
||||
<el-button :disabled="preDisabled" type="primary" :icon="DArrowRight" @click="next"></el-button>
|
||||
@@ -35,13 +36,15 @@ interface Props {
|
||||
theCurrentTime?: boolean
|
||||
initialInterval?: number
|
||||
initialTimeValue?: any
|
||||
timeKeyList?: string[] //日期下拉
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
nextFlag: false,
|
||||
theCurrentTime: true,
|
||||
initialInterval: 3,
|
||||
initialTimeValue: undefined
|
||||
initialTimeValue: undefined,
|
||||
timeKeyList: () => []
|
||||
})
|
||||
|
||||
const emit = defineEmits(['change'])
|
||||
@@ -89,6 +92,16 @@ const shortcuts = [
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
// 计算过滤后的 timeOptions
|
||||
const filteredTimeOptions = computed(() => {
|
||||
if (!props.timeKeyList || props.timeKeyList.length === 0) {
|
||||
return timeOptions.value
|
||||
}
|
||||
|
||||
return timeOptions.value.filter((option: any) => props.timeKeyList.includes(option.value.toString()))
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
// 使用传入的初始值
|
||||
if (props.initialInterval !== undefined) {
|
||||
@@ -113,9 +126,13 @@ const checkInitialButtonStatus = () => {
|
||||
const endTime = timeValue.value[1]
|
||||
const currentDate = window.XEUtils.toDateString(new Date(), 'yyyy-MM-dd')
|
||||
|
||||
// 如果结束时间小于当前日期,则不禁用"下一个"按钮
|
||||
if (new Date(endTime + ' 00:00:00').getTime() < new Date(currentDate + ' 00:00:00').getTime()) {
|
||||
preDisabled.value = false
|
||||
// 只有当 props.nextFlag 为 false 时才应用限制
|
||||
if (!props.nextFlag) {
|
||||
// 如果结束时间早于当前日期,则按钮可用(preDisabled = false)
|
||||
// 如果结束时间晚于或等于当前日期,则按钮禁用(preDisabled = true)
|
||||
const endDateTime = new Date(endTime).getTime()
|
||||
const currentDateTime = new Date(currentDate).getTime()
|
||||
preDisabled.value = endDateTime >= currentDateTime
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,30 +181,15 @@ const timeChange = (e: number) => {
|
||||
timeFlag.value = 1
|
||||
}
|
||||
|
||||
// 检查按钮状态
|
||||
checkButtonStatus()
|
||||
nextTick(() => {
|
||||
// 检查按钮状态
|
||||
checkInitialButtonStatus()
|
||||
})
|
||||
|
||||
// 触发 change 事件
|
||||
emitChange()
|
||||
}
|
||||
|
||||
// 添加按钮状态检查方法
|
||||
const checkButtonStatus = () => {
|
||||
if (timeValue.value && timeValue.value.length >= 2) {
|
||||
const endTime = timeValue.value[1]
|
||||
const currentDate = window.XEUtils.toDateString(new Date(), 'yyyy-MM-dd')
|
||||
|
||||
// 如果结束时间大于等于当前日期,且 nextFlag 为 false,则禁用"下一个"按钮
|
||||
if (!props.nextFlag) {
|
||||
if (new Date(endTime + ' 00:00:00').getTime() >= new Date(currentDate + ' 00:00:00').getTime()) {
|
||||
preDisabled.value = true
|
||||
} else {
|
||||
preDisabled.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 当前
|
||||
const nowTime = () => {
|
||||
// console.log(interval.value, '000000000')
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
<el-image
|
||||
:hide-on-click-modal="true"
|
||||
:preview-teleported="true"
|
||||
:preview-src-list="[fieldValue]"
|
||||
:src="fieldValue.length > 100 ? fieldValue : getUrl(fieldValue)"
|
||||
:preview-src-list="[imgList[fieldValue]]"
|
||||
:src="fieldValue.length > 100 ? fieldValue : getUrl(fieldValue) ? imgList[fieldValue] : ''"
|
||||
></el-image>
|
||||
</div>
|
||||
|
||||
@@ -226,10 +226,12 @@ const handlerCommand = (item: OptButton) => {
|
||||
break
|
||||
}
|
||||
}
|
||||
const imgList: any = ref({})
|
||||
const getUrl = (url: string) => {
|
||||
getFileUrl({ filePath: url }).then(res => {
|
||||
return res.data
|
||||
imgList.value[url] = res.data
|
||||
})
|
||||
return true
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div ref="tableHeader" class="cn-table-header">
|
||||
<div class="table-header ba-scroll-style" :key="num">
|
||||
<el-form
|
||||
style="flex: 1; height: 34px; margin-right: 20px; display: flex; flex-wrap: wrap"
|
||||
style="flex: 1; height: 34px; margin-right: 0px; display: flex; flex-wrap: wrap"
|
||||
ref="headerForm"
|
||||
@submit.prevent=""
|
||||
@keyup.enter="onComSearch"
|
||||
@@ -15,6 +15,7 @@
|
||||
:nextFlag="nextFlag"
|
||||
:theCurrentTime="theCurrentTime"
|
||||
@change="handleDatePickerChange"
|
||||
:timeKeyList="props.timeKeyList"
|
||||
></DatePicker>
|
||||
</el-form-item>
|
||||
|
||||
@@ -28,12 +29,27 @@
|
||||
<Icon size="14" name="el-icon-ArrowUp" style="color: #fff" v-if="showSelect" />
|
||||
<Icon size="14" name="el-icon-ArrowDown" style="color: #fff" v-else />
|
||||
</el-button>
|
||||
<el-button @click="onComSearch" v-if="showSearch" type="primary" :icon="Search">查询</el-button>
|
||||
<el-button @click="onResetForm" v-if="showSearch && showReset" :icon="RefreshLeft">重置</el-button>
|
||||
<el-button
|
||||
@click="onComSearch"
|
||||
v-if="showSearch"
|
||||
:loading="tableStore.table.loading"
|
||||
type="primary"
|
||||
:icon="Search"
|
||||
>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button
|
||||
@click="onResetForm"
|
||||
v-if="showSearch && showReset"
|
||||
:loading="tableStore.table.loading"
|
||||
:icon="RefreshLeft"
|
||||
>
|
||||
重置
|
||||
</el-button>
|
||||
<el-button
|
||||
@click="onExport"
|
||||
v-if="showExport"
|
||||
:loading="tableStore.table.loading"
|
||||
:loading="tableStore.table.exportLoading"
|
||||
type="primary"
|
||||
icon="el-icon-Download"
|
||||
>
|
||||
@@ -88,6 +104,8 @@ interface Props {
|
||||
theCurrentTime?: boolean //控制时间前3天展示上个月时间
|
||||
showReset?: boolean //是否显示重置
|
||||
showExport?: boolean //导出控制
|
||||
timeCacheFlag?: boolean //是否取缓存时间
|
||||
timeKeyList?: string[] //日期下拉列表
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@@ -97,7 +115,9 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
nextFlag: false,
|
||||
theCurrentTime: true,
|
||||
showReset: true,
|
||||
showExport: false
|
||||
showExport: false,
|
||||
timeCacheFlag: true,
|
||||
timeKeyList: () => ['1', '2', '3', '4', '5'] // 修改为箭头函数返回空数组
|
||||
})
|
||||
|
||||
// 处理 DatePicker 值变化事件
|
||||
@@ -134,7 +154,7 @@ onMounted(() => {
|
||||
if (props.datePicker && datePickerRef.value) {
|
||||
// 从缓存中获取值并设置
|
||||
const cached = timeCacheStore.getCache(route.path)
|
||||
if (cached) {
|
||||
if (props.timeCacheFlag && cached) {
|
||||
if (cached.interval !== undefined) {
|
||||
datePickerRef.value.setInterval(cached.interval)
|
||||
}
|
||||
|
||||
189
src/components/tree/allocation.vue
Normal file
189
src/components/tree/allocation.vue
Normal file
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<div :style="{ width: menuCollapse ? '40px' : props.width }" style="transition: all 0.3s; overflow: hidden">
|
||||
<div class="mt10 mr10" style="display: flex; justify-content: end">
|
||||
<el-button type="primary" icon="el-icon-Select" @click="save" :loading="loading">保存</el-button>
|
||||
</div>
|
||||
<Icon
|
||||
v-show="menuCollapse"
|
||||
@click="onMenuCollapse"
|
||||
:name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||
:class="menuCollapse ? 'unfold' : ''"
|
||||
size="18"
|
||||
class="fold ml10 mt20 menu-collapse"
|
||||
style="cursor: pointer"
|
||||
/>
|
||||
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1 }">
|
||||
<div style="display: flex; align-items: center" class="mb10">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="filterText" placeholder="请输入内容" clearable>
|
||||
<template #prefix>
|
||||
<Icon name="el-icon-Search" style="font-size: 16px" />
|
||||
</template>
|
||||
</el-input>
|
||||
<el-tooltip placement="bottom" :hide-after="0" v-if="props.showPush">
|
||||
<template #content>
|
||||
<span>台账推送</span>
|
||||
</template>
|
||||
|
||||
<Icon
|
||||
name="el-icon-Promotion"
|
||||
size="20"
|
||||
class="fold ml10 menu-collapse"
|
||||
style="cursor: pointer"
|
||||
:style="{ color: config.getColorVal('elementUiPrimary') }"
|
||||
@click="onAdd"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<!-- <Icon @click='onMenuCollapse' :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'" v-else
|
||||
:class="menuCollapse ? 'unfold' : ''" size='18' class='fold ml10 menu-collapse'
|
||||
style='cursor: pointer' v-if='props.canExpand' /> -->
|
||||
</div>
|
||||
|
||||
<el-tree
|
||||
:style="{ height: 'calc(100vh - 267px)' }"
|
||||
style="overflow: auto"
|
||||
ref="treeRef"
|
||||
:props="defaultProps"
|
||||
highlight-current
|
||||
:default-expand-all="false"
|
||||
@check-change="checkTreeNodeChange"
|
||||
:filter-node-method="filterNode"
|
||||
node-key="id"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<Icon
|
||||
:name="data.icon"
|
||||
style="font-size: 16px"
|
||||
:style="{ color: data.color }"
|
||||
v-if="data.icon"
|
||||
/>
|
||||
<span style="margin-left: 4px">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import useCurrentInstance from '@/utils/useCurrentInstance'
|
||||
import { ElTree } from 'element-plus'
|
||||
import { emit } from 'process'
|
||||
import { ref, watch } from 'vue'
|
||||
import { t } from 'vxe-table'
|
||||
import { useConfig } from '@/stores/config'
|
||||
|
||||
defineOptions({
|
||||
name: 'govern/tree'
|
||||
})
|
||||
|
||||
interface Props {
|
||||
width?: string
|
||||
canExpand?: boolean
|
||||
showPush?: boolean
|
||||
}
|
||||
const loading = ref(false)
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
width: '280px',
|
||||
canExpand: true,
|
||||
showPush: false
|
||||
})
|
||||
const config = useConfig()
|
||||
const { proxy } = useCurrentInstance()
|
||||
const menuCollapse = ref(false)
|
||||
const filterText = ref('')
|
||||
const defaultProps = {
|
||||
label: 'name',
|
||||
value: 'id'
|
||||
}
|
||||
const emit = defineEmits(['checkTreeNodeChange', 'onAdd', 'checkChange'])
|
||||
watch(filterText, val => {
|
||||
treeRef.value!.filter(val)
|
||||
})
|
||||
const onMenuCollapse = () => {
|
||||
menuCollapse.value = !menuCollapse.value
|
||||
proxy.eventBus.emit('cnTreeCollapse', menuCollapse)
|
||||
}
|
||||
const save = () => {
|
||||
loading.value = true
|
||||
emit('checkChange')
|
||||
}
|
||||
const filterNode = (value: string, data: any, node: any) => {
|
||||
console.log(value, data, node, 'filterNode')
|
||||
if (!value) return true
|
||||
// return data.name.includes(value)
|
||||
if (data.name) {
|
||||
return chooseNode(value, data, node)
|
||||
}
|
||||
}
|
||||
|
||||
// 过滤父节点 / 子节点 (如果输入的参数是父节点且能匹配,则返回该节点以及其下的所有子节点;如果参数是子节点,则返回该节点的父节点。name是中文字符,enName是英文字符.
|
||||
const chooseNode = (value: string, data: any, node: any) => {
|
||||
if (data.name.indexOf(value) !== -1) {
|
||||
return true
|
||||
}
|
||||
const level = node.level
|
||||
// 如果传入的节点本身就是一级节点就不用校验了
|
||||
if (level === 1) {
|
||||
return false
|
||||
}
|
||||
// 先取当前节点的父节点
|
||||
let parentData = node.parent
|
||||
// 遍历当前节点的父节点
|
||||
let index = 0
|
||||
while (index < level - 1) {
|
||||
// 如果匹配到直接返回,此处name值是中文字符,enName是英文字符。判断匹配中英文过滤
|
||||
if (parentData.data.name.indexOf(value) !== -1) {
|
||||
return true
|
||||
}
|
||||
// 否则的话再往上一层做匹配
|
||||
parentData = parentData.parent
|
||||
index++
|
||||
}
|
||||
// 没匹配到返回false
|
||||
return false
|
||||
}
|
||||
const checkTreeNodeChange = () => {
|
||||
// console.log(treeRef.value?.getCheckedNodes(), "ikkkkkiisiiisis");
|
||||
emit('checkTreeNodeChange', treeRef.value?.getCheckedNodes())
|
||||
}
|
||||
|
||||
const onAdd = () => {
|
||||
emit('onAdd')
|
||||
}
|
||||
|
||||
const treeRef = ref<InstanceType<typeof ElTree>>()
|
||||
defineExpose({ treeRef, loading })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cn-tree {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
:deep(.el-tree) {
|
||||
border: 1px solid var(--el-border-color);
|
||||
}
|
||||
|
||||
:deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content) {
|
||||
background-color: var(--el-color-primary-light-7);
|
||||
}
|
||||
|
||||
.menu-collapse {
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
|
||||
}
|
||||
</style>
|
||||
@@ -14,7 +14,7 @@
|
||||
:class="menuCollapse ? 'unfold' : ''" size='18' class='fold ml10 menu-collapse'
|
||||
style='cursor: pointer' v-if='props.canExpand' /> -->
|
||||
</div>
|
||||
<el-tree :style="{ height: 'calc(100vh - 110px)' }"
|
||||
<el-tree :style="{ height: 'calc(100vh - 230px)' }"
|
||||
style=' overflow: auto;' ref='treeRef' :props='defaultProps' highlight-current :default-expand-all="false"
|
||||
@check-change="checkTreeNodeChange" :filter-node-method='filterNode' node-key='id' v-bind='$attrs'>
|
||||
<template #default='{ node, data }'>
|
||||
@@ -32,7 +32,6 @@
|
||||
<script lang='ts' setup>
|
||||
import useCurrentInstance from '@/utils/useCurrentInstance'
|
||||
import { ElTree } from 'element-plus'
|
||||
import { emit } from 'process';
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
defineOptions({
|
||||
|
||||
@@ -1,27 +1,48 @@
|
||||
<!-- 设备管理使用折叠面板渲染多个tree -->
|
||||
<template>
|
||||
<div :style="{ width: menuCollapse ? '40px' : props.width }" style="display: flex; overflow: hidden">
|
||||
<Icon v-show="menuCollapse" @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 mt20 menu-collapse"
|
||||
style="cursor: pointer" />
|
||||
<Icon
|
||||
v-show="menuCollapse"
|
||||
@click="onMenuCollapse"
|
||||
:name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||
:class="menuCollapse ? 'unfold' : ''"
|
||||
size="18"
|
||||
class="fold ml10 mt20 menu-collapse"
|
||||
style="cursor: pointer"
|
||||
/>
|
||||
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1 }">
|
||||
<div style="display: flex; align-items: center" class="mb10">
|
||||
<!-- <el-form-item> -->
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="filterText" autocomplete="off"
|
||||
placeholder="请输入内容" clearable>
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
v-model.trim="filterText"
|
||||
autocomplete="off"
|
||||
placeholder="请输入内容"
|
||||
clearable
|
||||
>
|
||||
<template #prefix>
|
||||
<Icon name="el-icon-Search" style="font-size: 16px" />
|
||||
</template>
|
||||
</el-input>
|
||||
<!-- </el-form-item> -->
|
||||
<Icon @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 menu-collapse"
|
||||
style="cursor: pointer" v-if="props.canExpand" />
|
||||
<Icon
|
||||
@click="onMenuCollapse"
|
||||
:name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||
:class="menuCollapse ? 'unfold' : ''"
|
||||
size="18"
|
||||
class="fold ml10 menu-collapse"
|
||||
style="cursor: pointer"
|
||||
v-if="props.canExpand"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<el-collapse :accordion="true" v-model.trim="activeName" style="flex: 1; height: 100%"
|
||||
@change="changeDevice">
|
||||
|
||||
<el-collapse
|
||||
:accordion="true"
|
||||
v-model.trim="activeName"
|
||||
style="flex: 1; height: 100%"
|
||||
@change="changeDevice"
|
||||
>
|
||||
<el-collapse-item title="治理设备" name="0" v-if="zlDeviceData.length != 0">
|
||||
<el-select v-model.trim="process" clearable placeholder="请选择状态" class="mb10">
|
||||
<el-option label="功能调试" value="2"></el-option>
|
||||
@@ -29,13 +50,30 @@
|
||||
<el-option label="正式投运" value="4"></el-option>
|
||||
</el-select>
|
||||
<el-tree
|
||||
:style="{ height: bxsDeviceData.length != 0 ? 'calc(100vh - 340px)' : 'calc(100vh - 278px)' }"
|
||||
ref="treeRef1" :props="defaultProps" highlight-current :filter-node-method="filterNode"
|
||||
node-key="id" :default-expand-all="false" v-bind="$attrs" :data="zlDevList" style="overflow: auto">
|
||||
:style="{
|
||||
height:
|
||||
bxsDeviceData.length != 0
|
||||
? `calc(100vh - 380px - ${props.height}px)`
|
||||
: 'calc(100vh - 278px)'
|
||||
}"
|
||||
ref="treeRef1"
|
||||
:props="defaultProps"
|
||||
highlight-current
|
||||
:filter-node-method="filterNode"
|
||||
node-key="id"
|
||||
:default-expand-all="false"
|
||||
v-bind="$attrs"
|
||||
:data="zlDevList"
|
||||
style="overflow: auto"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
||||
v-if="data.icon" />
|
||||
<Icon
|
||||
:name="data.icon"
|
||||
style="font-size: 16px"
|
||||
:style="{ color: data.color }"
|
||||
v-if="data.icon"
|
||||
/>
|
||||
<span style="margin-left: 4px">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
@@ -43,29 +81,61 @@
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="便携式设备" name="1" v-if="bxsDeviceData.length != 0">
|
||||
<el-tree
|
||||
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 280px)' : 'calc(100vh - 238px)' }"
|
||||
ref="treeRef2" :props="defaultProps" highlight-current :default-expand-all="false"
|
||||
:filter-node-method="filterNode" node-key="id" :data="bxsDeviceData" v-bind="$attrs"
|
||||
style="overflow: auto">
|
||||
:style="{
|
||||
height:
|
||||
zlDeviceData.length != 0
|
||||
? `calc(100vh - 340px - ${props.height}px)`
|
||||
: 'calc(100vh - 238px)'
|
||||
}"
|
||||
ref="treeRef2"
|
||||
:props="defaultProps"
|
||||
highlight-current
|
||||
:default-expand-all="false"
|
||||
:filter-node-method="filterNode"
|
||||
node-key="id"
|
||||
:data="bxsDeviceData"
|
||||
v-bind="$attrs"
|
||||
style="overflow: auto"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
||||
v-if="data.icon" />
|
||||
<Icon
|
||||
:name="data.icon"
|
||||
style="font-size: 16px"
|
||||
:style="{ color: data.color }"
|
||||
v-if="data.icon"
|
||||
/>
|
||||
<span style="margin-left: 4px">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="在线设备" name="2" v-if="frontDeviceData.length != 0">
|
||||
<el-collapse-item title="监测设备" name="2" v-if="frontDeviceData.length != 0">
|
||||
<el-tree
|
||||
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 280px)' : 'calc(100vh - 238px)' }"
|
||||
ref="treeRef3" :props="defaultProps" highlight-current :default-expand-all="false"
|
||||
:filter-node-method="filterNode" node-key="id" :data="frontDeviceData" v-bind="$attrs"
|
||||
style="overflow: auto">
|
||||
:style="{
|
||||
height:
|
||||
zlDeviceData.length != 0
|
||||
? `calc(100vh - 340px - ${props.height}px)`
|
||||
: 'calc(100vh - 238px)'
|
||||
}"
|
||||
ref="treeRef3"
|
||||
:props="defaultProps"
|
||||
highlight-current
|
||||
:default-expand-all="false"
|
||||
:filter-node-method="filterNode"
|
||||
node-key="id"
|
||||
:data="frontDeviceData"
|
||||
v-bind="$attrs"
|
||||
style="overflow: auto"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
||||
v-if="data.icon" />
|
||||
<Icon
|
||||
:name="data.icon"
|
||||
style="font-size: 16px"
|
||||
:style="{ color: data.color }"
|
||||
v-if="data.icon"
|
||||
/>
|
||||
<span style="margin-left: 4px">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
@@ -90,13 +160,15 @@ interface Props {
|
||||
canExpand?: boolean
|
||||
type?: string
|
||||
data?: any
|
||||
height?: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
width: '280px',
|
||||
canExpand: true,
|
||||
type: '',
|
||||
data: []
|
||||
data: [],
|
||||
height: 0
|
||||
})
|
||||
const { proxy } = useCurrentInstance()
|
||||
const menuCollapse = ref(false)
|
||||
@@ -130,13 +202,12 @@ watch(
|
||||
item.children.map((vv: any) => {
|
||||
bxsDeviceData.value.push(vv)
|
||||
})
|
||||
}else if (item.name == '在线设备') {
|
||||
} else if (item.name == '监测设备') {
|
||||
frontDeviceData.value = []
|
||||
|
||||
item.children.map((vv: any) => {
|
||||
frontDeviceData.value.push(vv)
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -157,8 +228,9 @@ watch(filterText, val => {
|
||||
}
|
||||
})
|
||||
watch(process, val => {
|
||||
if (val == '') {
|
||||
if (val == '' || val == undefined) {
|
||||
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
||||
console.log('🚀 ~ zlDevList.value:', zlDeviceData.value)
|
||||
} else {
|
||||
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
|
||||
}
|
||||
@@ -176,7 +248,7 @@ function filterProcess(nodes: any) {
|
||||
const children = node.children ? filterProcess(node.children) : []
|
||||
|
||||
// 如果当前节点的process=4,或者有子节点满足条件,则保留当前节点
|
||||
if ( node.process == process.value || children.length > 0) {
|
||||
if (node.process == process.value || children.length > 0) {
|
||||
return {
|
||||
...node,
|
||||
children: children
|
||||
@@ -228,7 +300,6 @@ const chooseNode = (value: string, data: any, node: any) => {
|
||||
}
|
||||
|
||||
const changeDevice = (val: any) => {
|
||||
console.log('changeDevice', val)
|
||||
let arr1: any = []
|
||||
|
||||
//zlDeviceData
|
||||
@@ -259,22 +330,30 @@ const changeDevice = (val: any) => {
|
||||
arr2.map((item: any) => {
|
||||
item.checked = false
|
||||
})
|
||||
treeRef1.value && treeRef1.value.setCurrentKey(arr1[0]?.id)
|
||||
|
||||
emit('changeDeviceType', activeName.value, arr1[0])
|
||||
setTimeout(() => {
|
||||
treeRef1.value?.setCurrentKey(arr1[0]?.id)
|
||||
}, 100)
|
||||
}
|
||||
if (val == '1') {
|
||||
arr1.map((item: any) => {
|
||||
item.checked = false
|
||||
})
|
||||
treeRef2.value && treeRef2.value.setCurrentKey(arr2[0]?.id)
|
||||
emit('changeDeviceType', activeName.value, arr2[0])
|
||||
setTimeout(() => {
|
||||
treeRef2.value?.setCurrentKey(arr2[0]?.id)
|
||||
}, 100)
|
||||
}
|
||||
if (val == '2') {
|
||||
arr3.map((item: any) => {
|
||||
item.checked = false
|
||||
})
|
||||
treeRef3.value && treeRef3.value.setCurrentKey(arr3[0]?.id)
|
||||
|
||||
emit('changeDeviceType', activeName.value, arr3[0])
|
||||
setTimeout(() => {
|
||||
treeRef3.value?.setCurrentKey(arr3[0]?.id)
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
//治理
|
||||
@@ -283,7 +362,7 @@ const treeRef1 = ref<InstanceType<typeof ElTree>>()
|
||||
const treeRef2 = ref<InstanceType<typeof ElTree>>()
|
||||
//前置
|
||||
const treeRef3 = ref<InstanceType<typeof ElTree>>()
|
||||
defineExpose({ treeRef1, treeRef2 })
|
||||
defineExpose({ treeRef1, treeRef2, treeRef3 })
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
if (zlDeviceData.value.length != 0) {
|
||||
@@ -293,6 +372,9 @@ onMounted(() => {
|
||||
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length != 0) {
|
||||
activeName.value = '1'
|
||||
}
|
||||
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length === 0) {
|
||||
activeName.value = '2'
|
||||
}
|
||||
if (!zlDeviceData.value && !bxsDeviceData.value) {
|
||||
activeName.value = ''
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Tree ref="treRef" :width="width" :data="tree" default-expand-all @changePointType="changePointType" @onAdd="onAdd"/>
|
||||
<Tree ref="treRef" :width="width" :showPush="props.showPush" :data="tree" default-expand-all @changePointType="changePointType" @onAdd="onAdd"/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -7,14 +7,16 @@ import { ref, nextTick, onMounted, defineProps } from 'vue'
|
||||
import Tree from '../index.vue'
|
||||
import { getLineTree,getCldTree } from '@/api/cs-device-boot/csLedger'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import { getTemplateByDept } from '@/api/harmonic-boot/luckyexcel'
|
||||
import { querySysExcel } from '@/api/harmonic-boot/luckyexcel'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
|
||||
interface Props {
|
||||
template?: boolean
|
||||
showPush?: boolean
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
template: false
|
||||
template: false,
|
||||
showPush: false
|
||||
})
|
||||
defineOptions({
|
||||
name: 'govern/deviceTree'
|
||||
@@ -37,8 +39,8 @@ const info = (selectedNodeId?: string) => {
|
||||
let rootData = null;
|
||||
if (Array.isArray(res.data)) {
|
||||
// 旧的数据结构 - 数组
|
||||
rootData = res.data.find((item: any) => item.name == '在线设备');
|
||||
} else if (res.data && res.data.name == '在线设备') {
|
||||
rootData = res.data.find((item: any) => item.name == '监测设备');
|
||||
} else if (res.data && res.data.name == '监测设备') {
|
||||
// 新的数据结构 - 单个对象
|
||||
rootData = res.data;
|
||||
}
|
||||
@@ -95,13 +97,16 @@ const info = (selectedNodeId?: string) => {
|
||||
tree.value = []
|
||||
}
|
||||
nextTick(() => {
|
||||
|
||||
if (arr1.length) {
|
||||
// 安全检查 treRef 和 treeRef1 是否存在
|
||||
if (treRef.value && treRef.value.treeRef1 && treRef.value.treeRef1.setCurrentKey) {
|
||||
// 安全检查 treRef 和 treeRef 是否存在
|
||||
console.log("🚀 ~ info ~ treRef.value && treRef.value.treeRef && treRef.value.treeRef.setCurrentKey:", treRef.value && treRef.value.treeRef1 && treRef.value.treeRef1.setCurrentKey)
|
||||
|
||||
if (treRef.value && treRef.value.treeRef && treRef.value.treeRef.setCurrentKey) {
|
||||
// 如果传入了要选中的节点ID,则选中该节点,否则选中第一个节点
|
||||
console.log('selectedNodeId:', selectedNodeId);
|
||||
if (selectedNodeId) {
|
||||
treRef.value.treeRef1.setCurrentKey(selectedNodeId);
|
||||
treRef.value.treeRef.setCurrentKey(selectedNodeId);
|
||||
// 查找对应的节点数据并触发事件
|
||||
let selectedNode = null;
|
||||
const findNode = (nodes: any[]) => {
|
||||
@@ -127,7 +132,7 @@ const info = (selectedNodeId?: string) => {
|
||||
}
|
||||
} else {
|
||||
// 初始化选中第一个节点
|
||||
treRef.value.treeRef1.setCurrentKey(arr1[0].id);
|
||||
treRef.value.treeRef.setCurrentKey(arr1[0].id);
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr1[0]
|
||||
@@ -153,7 +158,7 @@ const onAdd = () => {
|
||||
emit('onAdd')
|
||||
}
|
||||
if (props.template) {
|
||||
getTemplateByDept({ id: dictData.state.area[0].id })
|
||||
querySysExcel({ id: dictData.state.area[0]?.id })
|
||||
.then((res: any) => {
|
||||
emit('Policy', res.data)
|
||||
info()
|
||||
|
||||
106
src/components/tree/govern/cloudDeviceEntryTreeZL.vue
Normal file
106
src/components/tree/govern/cloudDeviceEntryTreeZL.vue
Normal file
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<Tree
|
||||
ref="treRef"
|
||||
:width="width"
|
||||
:showPush="props.showPush"
|
||||
:data="tree"
|
||||
default-expand-all
|
||||
@changePointType="changePointType"
|
||||
@onAdd="onAdd"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, nextTick, onMounted, defineProps } from 'vue'
|
||||
import Tree from '../index.vue'
|
||||
import { getLineTree, objTree } from '@/api/cs-device-boot/csLedger'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import { querySysExcel } from '@/api/harmonic-boot/luckyexcel'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
|
||||
interface Props {
|
||||
template?: boolean
|
||||
showPush?: boolean
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
template: false,
|
||||
showPush: false
|
||||
})
|
||||
defineOptions({
|
||||
name: 'govern/deviceTree'
|
||||
})
|
||||
|
||||
const emit = defineEmits(['init', 'checkChange', 'pointTypeChange', 'Policy', 'onAdd'])
|
||||
const config = useConfig()
|
||||
const tree = ref()
|
||||
const dictData = useDictData()
|
||||
const treRef = ref()
|
||||
const width = ref('')
|
||||
|
||||
const info = (selectedNodeId?: string) => {
|
||||
tree.value = []
|
||||
let arr1: any[] = []
|
||||
objTree().then(res => {
|
||||
try {
|
||||
res.data.map((item: any) => {
|
||||
item.icon = 'el-icon-HomeFilled'
|
||||
item.level = 1
|
||||
item.color = config.getColorVal('elementUiPrimary')
|
||||
item.children.forEach((item: any) => {
|
||||
item.icon = 'el-icon-List'
|
||||
item.level = 2
|
||||
item.color = config.getColorVal('elementUiPrimary')
|
||||
item.children.forEach((item2: any) => {
|
||||
arr1.push(item2)
|
||||
item2.icon = 'el-icon-Platform'
|
||||
item2.level = 3
|
||||
item2.color = config.getColorVal('elementUiPrimary')
|
||||
})
|
||||
})
|
||||
})
|
||||
tree.value = res.data
|
||||
nextTick(() => {
|
||||
if (arr1.length) {
|
||||
//初始化选中
|
||||
treRef.value.treeRef.setCurrentKey(arr1[0].id)
|
||||
// 注册父组件事件
|
||||
emit('init', arr1[0])
|
||||
return
|
||||
} else {
|
||||
emit('init')
|
||||
return
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error in processing getCldTree response:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const changePointType = (val: any, obj: any) => {
|
||||
emit('pointTypeChange', val, obj)
|
||||
}
|
||||
|
||||
const onAdd = () => {
|
||||
emit('onAdd')
|
||||
}
|
||||
if (props.template) {
|
||||
querySysExcel({ id: dictData.state.area[0]?.id })
|
||||
.then((res: any) => {
|
||||
emit('Policy', res.data)
|
||||
info()
|
||||
})
|
||||
.catch(err => {
|
||||
info()
|
||||
})
|
||||
} else {
|
||||
info()
|
||||
}
|
||||
|
||||
// 暴露 info 方法给父组件调用
|
||||
defineExpose({
|
||||
info
|
||||
})
|
||||
|
||||
onMounted(() => {})
|
||||
</script>
|
||||
179
src/components/tree/govern/csLedgerLineTree.vue
Normal file
179
src/components/tree/govern/csLedgerLineTree.vue
Normal file
@@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<Tree ref="treRef" :width="width" :showPush="props.showPush" :data="tree" default-expand-all @changePointType="changePointType" @onAdd="onAdd"/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, nextTick, onMounted, defineProps } from 'vue'
|
||||
import Tree from '../index.vue'
|
||||
import { getLineTree,lineTree } from '@/api/cs-device-boot/csLedger'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import { querySysExcel } from '@/api/harmonic-boot/luckyexcel'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
|
||||
interface Props {
|
||||
template?: boolean
|
||||
showPush?: boolean
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
template: false,
|
||||
showPush: false
|
||||
})
|
||||
defineOptions({
|
||||
name: 'govern/deviceTree'
|
||||
})
|
||||
|
||||
const emit = defineEmits(['init', 'checkChange', 'pointTypeChange', 'Policy','onAdd'])
|
||||
const config = useConfig()
|
||||
const tree = ref()
|
||||
const dictData = useDictData()
|
||||
const treRef = ref()
|
||||
const width = ref('')
|
||||
|
||||
|
||||
const info = (selectedNodeId?: string) => {
|
||||
tree.value = []
|
||||
let arr1: any[] = []
|
||||
lineTree().then(res => {
|
||||
try {
|
||||
// 检查响应数据结构
|
||||
let rootData = null;
|
||||
if (Array.isArray(res.data)) {
|
||||
// 旧的数据结构 - 数组
|
||||
rootData = res.data.find((item: any) => item.name == '监测设备');
|
||||
} else if (res.data && res.data.name == '监测设备') {
|
||||
// 新的数据结构 - 单个对象
|
||||
rootData = res.data;
|
||||
}
|
||||
|
||||
// 治理设备
|
||||
if (rootData) {
|
||||
rootData.icon = 'el-icon-Menu'
|
||||
rootData.level = 0
|
||||
rootData.color = config.getColorVal('elementUiPrimary')
|
||||
// 确保根节点的 children 是数组
|
||||
if (!Array.isArray(rootData.children)) {
|
||||
rootData.children = []
|
||||
}
|
||||
rootData.children.forEach((item: any) => {
|
||||
item.icon = 'el-icon-HomeFilled'
|
||||
item.level = 1
|
||||
item.color = config.getColorVal('elementUiPrimary')
|
||||
// 确保 children 是数组
|
||||
if (!Array.isArray(item.children)) {
|
||||
item.children = []
|
||||
}
|
||||
item.children.forEach((item2: any) => {
|
||||
item2.icon = 'el-icon-List'
|
||||
item2.level = 2
|
||||
item2.color = config.getColorVal('elementUiPrimary')
|
||||
|
||||
// 确保 children 是数组
|
||||
if (!Array.isArray(item2.children)) {
|
||||
item2.children = []
|
||||
}
|
||||
item2.children.forEach((item3: any) => {
|
||||
item3.icon = 'el-icon-Platform'
|
||||
item3.level = 3
|
||||
item3.color =
|
||||
item3.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
|
||||
|
||||
// 确保 children 是数组
|
||||
if (!Array.isArray(item3.children)) {
|
||||
item3.children = []
|
||||
}
|
||||
|
||||
item3.children.forEach((item4: any) => {
|
||||
item4.icon = 'el-icon-Platform'
|
||||
item4.level = 4
|
||||
item4.color =
|
||||
item4.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
|
||||
arr1.push(item4)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
tree.value = [rootData] // 确保 tree.value 是数组
|
||||
} else {
|
||||
tree.value = []
|
||||
}
|
||||
nextTick(() => {
|
||||
|
||||
if (arr1.length) {
|
||||
// 安全检查 treRef 和 treeRef 是否存在
|
||||
console.log("🚀 ~ info ~ treRef.value && treRef.value.treeRef && treRef.value.treeRef.setCurrentKey:", treRef.value && treRef.value.treeRef1 && treRef.value.treeRef1.setCurrentKey)
|
||||
|
||||
if (treRef.value && treRef.value.treeRef && treRef.value.treeRef.setCurrentKey) {
|
||||
// 如果传入了要选中的节点ID,则选中该节点,否则选中第一个节点
|
||||
console.log('selectedNodeId:', selectedNodeId);
|
||||
if (selectedNodeId) {
|
||||
treRef.value.treeRef.setCurrentKey(selectedNodeId);
|
||||
// 查找对应的节点数据并触发事件
|
||||
let selectedNode = null;
|
||||
const findNode = (nodes: any[]) => {
|
||||
for (const node of nodes) {
|
||||
if (node.id === selectedNodeId) {
|
||||
selectedNode = node;
|
||||
return true;
|
||||
}
|
||||
if (node.children && findNode(node.children)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
findNode(tree.value);
|
||||
|
||||
if (selectedNode) {
|
||||
emit('init', {
|
||||
level: selectedNode.level,
|
||||
...selectedNode
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 初始化选中第一个节点
|
||||
treRef.value.treeRef.setCurrentKey(arr1[0].id);
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr1[0]
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error in processing getCldTree response:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
const changePointType = (val: any, obj: any) => {
|
||||
emit('pointTypeChange', val, obj)
|
||||
}
|
||||
|
||||
const onAdd = () => {
|
||||
emit('onAdd')
|
||||
}
|
||||
if (props.template) {
|
||||
querySysExcel({ id: dictData.state.area[0]?.id })
|
||||
.then((res: any) => {
|
||||
emit('Policy', res.data)
|
||||
info()
|
||||
})
|
||||
.catch(err => {
|
||||
info()
|
||||
})
|
||||
} else {
|
||||
info()
|
||||
}
|
||||
|
||||
// 暴露 info 方法给父组件调用
|
||||
defineExpose({
|
||||
info
|
||||
})
|
||||
|
||||
onMounted(() => {})
|
||||
</script>
|
||||
@@ -5,15 +5,17 @@
|
||||
:default-checked-keys="defaultCheckedKeys"
|
||||
:show-checkbox="props.showCheckbox"
|
||||
:data="tree"
|
||||
:height="props.height"
|
||||
@changeDeviceType="changeDeviceType"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, nextTick, defineEmits } from 'vue'
|
||||
import { ref, nextTick } from 'vue'
|
||||
import Tree from '../device.vue'
|
||||
import { getDeviceTree } from '@/api/cs-device-boot/csLedger'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import { throttle } from 'lodash'
|
||||
defineOptions({
|
||||
name: 'govern/deviceTree'
|
||||
})
|
||||
@@ -21,10 +23,12 @@ const props = withDefaults(
|
||||
defineProps<{
|
||||
showCheckbox?: boolean
|
||||
defaultCheckedKeys?: any
|
||||
height?: number
|
||||
}>(),
|
||||
{
|
||||
showCheckbox: false,
|
||||
defaultCheckedKeys: []
|
||||
defaultCheckedKeys: [],
|
||||
height: 0
|
||||
}
|
||||
)
|
||||
const emit = defineEmits(['init', 'checkChange', 'deviceTypeChange'])
|
||||
@@ -32,7 +36,6 @@ const config = useConfig()
|
||||
const tree = ref()
|
||||
const treRef = ref()
|
||||
const changeDeviceType = (val: any, obj: any) => {
|
||||
console.log("🚀 ~ changeDeviceType ~ val:", val,obj)
|
||||
emit('deviceTypeChange', val, obj)
|
||||
}
|
||||
getDeviceTree().then(res => {
|
||||
@@ -49,8 +52,9 @@ getDeviceTree().then(res => {
|
||||
item2.icon = 'el-icon-List'
|
||||
item2.color = config.getColorVal('elementUiPrimary')
|
||||
item2.children.forEach((item3: any) => {
|
||||
item3.pName = '治理设备'
|
||||
item3.icon = 'el-icon-Platform'
|
||||
item3.level = 2
|
||||
item3.level = 2
|
||||
item3.color = config.getColorVal('elementUiPrimary')
|
||||
if (item3.comFlag === 1) {
|
||||
item3.color = '#e26257 !important'
|
||||
@@ -65,14 +69,15 @@ getDeviceTree().then(res => {
|
||||
item.color = config.getColorVal('elementUiPrimary')
|
||||
item.color = '#e26257 !important'
|
||||
item.color = item.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
|
||||
|
||||
// item.disabled =true
|
||||
item.pName = '便携式设备'
|
||||
if (item.type == 'device') {
|
||||
arr2.push(item)
|
||||
}
|
||||
item.children.forEach((item2: any) => {
|
||||
item2.icon = 'el-icon-Platform'
|
||||
item2.color = item2.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
|
||||
|
||||
item2.pName = '便携式设备'
|
||||
// item2.children.forEach((item3: any) => {
|
||||
// item3.icon = 'el-icon-Platform'
|
||||
// item3.color = config.getColorVal('elementUiPrimary')
|
||||
@@ -83,14 +88,15 @@ getDeviceTree().then(res => {
|
||||
// })
|
||||
})
|
||||
})
|
||||
}else if (item.name == '在线设备') {
|
||||
item.children.forEach((item: any) => {
|
||||
} else if (item.name == '监测设备') {
|
||||
item.children.forEach((item: any) => {
|
||||
item.icon = 'el-icon-HomeFilled'
|
||||
item.color = config.getColorVal('elementUiPrimary')
|
||||
item.children.forEach((item2: any) => {
|
||||
item2.icon = 'el-icon-List'
|
||||
item2.color = config.getColorVal('elementUiPrimary')
|
||||
item2.children.forEach((item3: any) => {
|
||||
item3.pName = '监测设备'
|
||||
item3.icon = 'el-icon-Platform'
|
||||
item3.color = config.getColorVal('elementUiPrimary')
|
||||
if (item3.comFlag === 1) {
|
||||
@@ -102,45 +108,59 @@ getDeviceTree().then(res => {
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log("🚀 ~ file: deviceTree.vue ~ line 18 ~ getDeviceTree ~ tree:", arr,arr2,arr3)
|
||||
tree.value = res.data
|
||||
|
||||
nextTick(() => {
|
||||
if (arr.length) {
|
||||
treRef.value.treeRef1.setCurrentKey(arr[0].id)
|
||||
// 注册父组件事件
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr[0]
|
||||
})
|
||||
return
|
||||
}
|
||||
if (arr2.length) {
|
||||
treRef.value.treeRef2.setCurrentKey(arr2[0].id)
|
||||
// 注册父组件事件
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr2[0]
|
||||
})
|
||||
return
|
||||
}
|
||||
console.log("🚀 ~ file: deviceTree.vue ~ line 33 ~ getDeviceTree ~ tree:", arr3.length)
|
||||
if (arr3.length) {
|
||||
console.log("🚀 ~ file: deviceTree.vue ~ line 33 ~ getDeviceTree ~ tree:", arr3)
|
||||
treRef.value.treeRef3.setCurrentKey(arr3[0].id)
|
||||
// 注册父组件事件
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr3[0]
|
||||
})
|
||||
return
|
||||
}
|
||||
else {
|
||||
emit('init')
|
||||
return
|
||||
}
|
||||
setTimeout(() => {
|
||||
if (arr.length > 0) {
|
||||
treRef.value.treeRef1.setCurrentKey(arr[0].id)
|
||||
// 注册父组件事件
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr[0]
|
||||
})
|
||||
return
|
||||
} else if (arr2.length > 0) {
|
||||
treRef.value.treeRef2.setCurrentKey(arr2[0].id)
|
||||
// 注册父组件事件
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr2[0]
|
||||
})
|
||||
return
|
||||
} else if (arr3.length > 0) {
|
||||
console.log('🚀 ~ arr3:', arr3)
|
||||
|
||||
treRef.value.treeRef3.setCurrentKey(arr3[0].id)
|
||||
// 注册父组件事件
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr3[0]
|
||||
})
|
||||
return
|
||||
} else {
|
||||
emit('init')
|
||||
return
|
||||
}
|
||||
}, 500)
|
||||
})
|
||||
})
|
||||
|
||||
throttle(
|
||||
(data: any, checked: any, indeterminate: any) => {
|
||||
emit('checkChange', {
|
||||
data,
|
||||
checked,
|
||||
indeterminate
|
||||
})
|
||||
},
|
||||
300,
|
||||
{
|
||||
leading: true, // 首次触发立即执行(可选,默认 true)
|
||||
trailing: false // 节流结束后是否执行最后一次(可选,默认 true,根据需求调整)
|
||||
}
|
||||
)
|
||||
|
||||
const handleCheckChange = (data: any, checked: any, indeterminate: any) => {
|
||||
emit('checkChange', {
|
||||
data,
|
||||
@@ -148,4 +168,7 @@ const handleCheckChange = (data: any, checked: any, indeterminate: any) => {
|
||||
indeterminate
|
||||
})
|
||||
}
|
||||
defineExpose({
|
||||
treRef
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { ref, nextTick, onMounted, defineProps } from 'vue'
|
||||
import Tree from '../point.vue'
|
||||
import { getLineTree } from '@/api/cs-device-boot/csLedger'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import { getTemplateByDept } from '@/api/harmonic-boot/luckyexcel'
|
||||
import { querySysExcel } from '@/api/harmonic-boot/luckyexcel'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
// const props = defineProps(['template'])
|
||||
interface Props {
|
||||
@@ -71,7 +71,7 @@ const info = () => {
|
||||
arr2.push(item2)
|
||||
})
|
||||
})
|
||||
} else if (item.name == '在线设备') {
|
||||
} else if (item.name == '监测设备') {
|
||||
item.children.forEach((item: any) => {
|
||||
item.icon = 'el-icon-HomeFilled'
|
||||
item.level = 1
|
||||
@@ -99,38 +99,38 @@ const info = () => {
|
||||
})
|
||||
tree.value = res.data
|
||||
nextTick(() => {
|
||||
if (arr1.length) {
|
||||
//初始化选中
|
||||
treRef.value.treeRef1.setCurrentKey(arr1[0].id)
|
||||
// 注册父组件事件
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr1[0]
|
||||
})
|
||||
return
|
||||
}
|
||||
if (arr2.length) {
|
||||
//初始化选中
|
||||
treRef.value.treeRef2.setCurrentKey(arr2[0].id)
|
||||
// 注册父组件事件
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr2[0]
|
||||
})
|
||||
return
|
||||
}
|
||||
if(arr3.length){
|
||||
treRef.value.treeRef3.setCurrentKey(arr3[0].id)
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr3[0]
|
||||
})
|
||||
return
|
||||
}
|
||||
else {
|
||||
emit('init')
|
||||
return
|
||||
}
|
||||
setTimeout(() => {
|
||||
if (arr1.length > 0) {
|
||||
//初始化选中
|
||||
treRef.value?.treeRef1.setCurrentKey(arr1[0].id)
|
||||
// 注册父组件事件
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr1[0]
|
||||
})
|
||||
return
|
||||
} else if (arr2.length > 0) {
|
||||
//初始化选中
|
||||
treRef.value?.treeRef2.setCurrentKey(arr2[0].id)
|
||||
// 注册父组件事件
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr2[0]
|
||||
})
|
||||
return
|
||||
} else if (arr3.length > 0) {
|
||||
|
||||
treRef.value?.treeRef3?.setCurrentKey(arr3[0].id)
|
||||
emit('init', {
|
||||
level: 2,
|
||||
...arr3[0]
|
||||
})
|
||||
return
|
||||
} else {
|
||||
emit('init')
|
||||
return
|
||||
}
|
||||
}, 500)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -138,7 +138,7 @@ const changePointType = (val: any, obj: any) => {
|
||||
emit('pointTypeChange', val, obj)
|
||||
}
|
||||
if (props.template) {
|
||||
getTemplateByDept({ id: dictData.state.area[0].id })
|
||||
querySysExcel({ id: dictData.state.area[0]?.id })
|
||||
.then((res: any) => {
|
||||
emit('Policy', res.data)
|
||||
info()
|
||||
|
||||
@@ -1,26 +1,44 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="transition: all 0.3s; overflow: hidden; height: 100%">
|
||||
|
||||
<div class="cn-tree">
|
||||
<div style="display: flex; align-items: center" class="mb10">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="filterText" placeholder="请输入内容" clearable>
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
v-model.trim="filterText"
|
||||
placeholder="请输入内容"
|
||||
clearable
|
||||
>
|
||||
<template #prefix>
|
||||
<Icon name="el-icon-Search" style="font-size: 16px" />
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<el-tree style="flex: 1; overflow: auto" :props="defaultProps" highlight-current
|
||||
:filter-node-method="filterNode" node-key="id" v-bind="$attrs" default-expand-all :data="tree"
|
||||
ref="treRef" @node-click="clickNode" :expand-on-click-node="false">
|
||||
<el-tree
|
||||
style="flex: 1; overflow: auto"
|
||||
:props="defaultProps"
|
||||
highlight-current
|
||||
:filter-node-method="filterNode"
|
||||
node-key="id"
|
||||
v-bind="$attrs"
|
||||
default-expand-all
|
||||
:data="tree"
|
||||
ref="treRef"
|
||||
@node-click="clickNode"
|
||||
:expand-on-click-node="false"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<div class="left">
|
||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
||||
v-if="data.icon" />
|
||||
<span>{{ node.label }}</span>
|
||||
<div class="left" style="display: flex; align-items: center">
|
||||
<Icon
|
||||
:name="data.icon"
|
||||
style="font-size: 16px"
|
||||
:style="{ color: data.color }"
|
||||
v-if="data.icon"
|
||||
/>
|
||||
<span style="margin-left: 5px;">{{ node.label }}</span>
|
||||
</div>
|
||||
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
@@ -35,7 +53,7 @@ import { getSchemeTree, getTestRecordInfo } from '@/api/cs-device-boot/planData'
|
||||
import { useConfig } from '@/stores/config'
|
||||
import useCurrentInstance from '@/utils/useCurrentInstance'
|
||||
import { ElTree } from 'element-plus'
|
||||
import { getTemplateByDept } from '@/api/harmonic-boot/luckyexcel'
|
||||
import { querySysExcel } from '@/api/harmonic-boot/luckyexcel'
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
defineOptions({
|
||||
name: 'govern/schemeTree'
|
||||
@@ -43,12 +61,10 @@ defineOptions({
|
||||
|
||||
interface Props {
|
||||
template?: boolean
|
||||
|
||||
}
|
||||
const dictData = useDictData()
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
template: false,
|
||||
|
||||
template: false
|
||||
})
|
||||
const filterText = ref('')
|
||||
watch(filterText, val => {
|
||||
@@ -94,7 +110,6 @@ const defaultProps = {
|
||||
value: 'id'
|
||||
}
|
||||
|
||||
|
||||
const emit = defineEmits(['init', 'checkChange', 'nodeChange', 'editNode', 'getChart', 'Policy'])
|
||||
const config = useConfig()
|
||||
const tree = ref()
|
||||
@@ -141,18 +156,18 @@ const clickNode = (e: anyObj) => {
|
||||
emit('nodeChange', e)
|
||||
}
|
||||
|
||||
|
||||
if (props.template) {
|
||||
getTemplateByDept({ id: dictData.state.area[0].id }).then((res: any) => {
|
||||
emit('Policy', res.data)
|
||||
getTreeList()
|
||||
}).catch(err => {
|
||||
getTreeList()
|
||||
})
|
||||
querySysExcel({ id: dictData.state.area[0]?.id })
|
||||
.then((res: any) => {
|
||||
emit('Policy', res.data)
|
||||
getTreeList()
|
||||
})
|
||||
.catch(err => {
|
||||
getTreeList()
|
||||
})
|
||||
} else {
|
||||
getTreeList()
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.cn-tree {
|
||||
|
||||
@@ -33,7 +33,7 @@ const info = () => {
|
||||
getLineTree().then(res => {
|
||||
//治理设备
|
||||
res.data.map((item: any) => {
|
||||
if (item.name == '在线设备') {
|
||||
if (item.name == '监测设备') {
|
||||
item.children.forEach((item: any) => {
|
||||
item.icon = 'el-icon-HomeFilled'
|
||||
item.level = 1
|
||||
@@ -59,7 +59,7 @@ const info = () => {
|
||||
})
|
||||
}
|
||||
})
|
||||
tree.value = res.data.filter(item => item.name == '在线设备')
|
||||
tree.value = res.data.filter(item => item.name == '监测设备')
|
||||
nextTick(() => {
|
||||
if (arr3.length) {
|
||||
//初始化选中
|
||||
@@ -87,7 +87,7 @@ const handleCheckedNodesChange = (nodes: any[]) => {
|
||||
|
||||
|
||||
if (props.template) {
|
||||
getTemplateByDept({ id: dictData.state.area[0].id })
|
||||
getTemplateByDept({ id: dictData.state.area[0]?.id })
|
||||
.then((res: any) => {
|
||||
emit('Policy', res.data)
|
||||
info()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<Icon name='el-icon-Search' style='font-size: 16px' />
|
||||
</template>
|
||||
</el-input>
|
||||
<el-tooltip placement="bottom" :hide-after="0">
|
||||
<el-tooltip placement="bottom" :hide-after="0" v-if="props.showPush">
|
||||
<template #content>
|
||||
<span>台账推送</span>
|
||||
</template>
|
||||
@@ -23,12 +23,12 @@
|
||||
:style="{ color: config.getColorVal('elementUiPrimary') }"
|
||||
@click="onAdd" />
|
||||
</el-tooltip>
|
||||
<!-- <Icon @click='onMenuCollapse' :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||
<!-- <Icon @click='onMenuCollapse' :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'" v-else
|
||||
:class="menuCollapse ? 'unfold' : ''" size='18' class='fold ml10 menu-collapse'
|
||||
style='cursor: pointer' v-if='props.canExpand' /> -->
|
||||
</div>
|
||||
|
||||
<el-tree :style="{ height: 'calc(100vh - 200px)' }"
|
||||
<el-tree :style="{ height: 'calc(100vh - 190px)' }"
|
||||
style=' overflow: auto;' ref='treeRef' :props='defaultProps' highlight-current :default-expand-all="false"
|
||||
@check-change="checkTreeNodeChange" :filter-node-method='filterNode' node-key='id' v-bind='$attrs'>
|
||||
<template #default='{ node, data }'>
|
||||
@@ -58,11 +58,13 @@ defineOptions({
|
||||
interface Props {
|
||||
width?: string
|
||||
canExpand?: boolean
|
||||
showPush?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
width: '280px',
|
||||
canExpand: true
|
||||
canExpand: true,
|
||||
showPush: false
|
||||
})
|
||||
const config = useConfig()
|
||||
const { proxy } = useCurrentInstance()
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
<!-- 设备监控使用折叠面板渲染多个tree -->
|
||||
<template>
|
||||
<div :style="{ width: menuCollapse ? '40px' : props.width }" style="display: flex; overflow: hidden">
|
||||
<Icon v-show="menuCollapse" @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 mt20 menu-collapse" style="cursor: pointer"
|
||||
v-if="route.path != '/admin/govern/reportCore/statistics/index'" />
|
||||
<Icon
|
||||
v-show="menuCollapse"
|
||||
@click="onMenuCollapse"
|
||||
:name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||
:class="menuCollapse ? 'unfold' : ''"
|
||||
size="18"
|
||||
class="fold ml10 mt20 menu-collapse"
|
||||
style="cursor: pointer"
|
||||
v-if="route.path != '/admin/govern/reportCore/statistics/index'"
|
||||
/>
|
||||
<div class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1, display: menuCollapse ? 'none' : '' }">
|
||||
<div style="display: flex; align-items: center" class="mb10">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="filterText" placeholder="请输入内容" clearable>
|
||||
@@ -11,13 +18,23 @@
|
||||
<Icon name="el-icon-Search" style="font-size: 16px" />
|
||||
</template>
|
||||
</el-input>
|
||||
<Icon @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 menu-collapse"
|
||||
<Icon
|
||||
@click="onMenuCollapse"
|
||||
:name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||
:class="menuCollapse ? 'unfold' : ''"
|
||||
size="18"
|
||||
class="fold ml10 menu-collapse"
|
||||
style="cursor: pointer"
|
||||
v-if="props.canExpand && route.path != '/admin/govern/reportCore/statistics/index'" />
|
||||
v-if="props.canExpand && route.path != '/admin/govern/reportCore/statistics/index'"
|
||||
/>
|
||||
</div>
|
||||
<el-collapse :accordion="true" v-model.trim="activeName" style="flex: 1; height: 100%"
|
||||
@change="changeDevice">
|
||||
|
||||
<el-collapse
|
||||
:accordion="true"
|
||||
v-model.trim="activeName"
|
||||
style="flex: 1; height: 100%"
|
||||
@change="changeDevice"
|
||||
>
|
||||
<el-collapse-item title="治理设备" name="0" v-if="zlDeviceData.length != 0">
|
||||
<el-select v-model.trim="process" clearable placeholder="请选择状态" class="mb10">
|
||||
<el-option label="功能调试" value="2"></el-option>
|
||||
@@ -26,14 +43,25 @@
|
||||
</el-select>
|
||||
|
||||
<el-tree
|
||||
:style="{ height: bxsDeviceData.length != 0 ? 'calc(100vh - 340px)' : 'calc(100vh - 278px)' }"
|
||||
ref="treeRef1" :props="defaultProps" highlight-current :filter-node-method="filterNode"
|
||||
node-key="id" v-bind="$attrs" :data="zlDevList" style="overflow: auto"
|
||||
:default-expand-all="false">
|
||||
:style="{ height: bxsDeviceData.length != 0 ? 'calc(100vh - 380px)' : 'calc(100vh - 278px)' }"
|
||||
ref="treeRef1"
|
||||
:props="defaultProps"
|
||||
highlight-current
|
||||
:filter-node-method="filterNode"
|
||||
node-key="id"
|
||||
v-bind="$attrs"
|
||||
:data="zlDevList"
|
||||
style="overflow: auto"
|
||||
:default-expand-all="false"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
||||
v-if="data.icon" />
|
||||
<Icon
|
||||
:name="data.icon"
|
||||
style="font-size: 16px"
|
||||
:style="{ color: data.color }"
|
||||
v-if="data.icon"
|
||||
/>
|
||||
<span style="margin-left: 4px">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
@@ -41,29 +69,51 @@
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="便携式设备" name="1" v-if="bxsDeviceData.length != 0">
|
||||
<el-tree
|
||||
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 330px)' : 'calc(100vh - 238px)' }"
|
||||
ref="treeRef2" :props="defaultProps" highlight-current :default-expand-all="false"
|
||||
:filter-node-method="filterNode" node-key="id" :data="bxsDeviceData" v-bind="$attrs"
|
||||
style="overflow: auto" >
|
||||
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 340px)' : 'calc(100vh - 238px)' }"
|
||||
ref="treeRef2"
|
||||
:props="defaultProps"
|
||||
highlight-current
|
||||
:default-expand-all="false"
|
||||
:filter-node-method="filterNode"
|
||||
node-key="id"
|
||||
:data="bxsDeviceData"
|
||||
v-bind="$attrs"
|
||||
style="overflow: auto"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
||||
v-if="data.icon" />
|
||||
<Icon
|
||||
:name="data.icon"
|
||||
style="font-size: 16px"
|
||||
:style="{ color: data.color }"
|
||||
v-if="data.icon"
|
||||
/>
|
||||
<span style="margin-left: 4px">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="在线设备" name="2" v-if="yqfDeviceData.length != 0">
|
||||
<el-collapse-item title="监测设备" name="2" v-if="yqfDeviceData.length != 0">
|
||||
<el-tree
|
||||
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 330px)' : 'calc(100vh - 238px)' }"
|
||||
ref="treeRef3" :props="defaultProps" highlight-current :default-expand-all="false"
|
||||
:filter-node-method="filterNode" node-key="id" :data="yqfDeviceData" v-bind="$attrs"
|
||||
style="overflow: auto">
|
||||
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 340px)' : 'calc(100vh - 238px)' }"
|
||||
ref="treeRef3"
|
||||
:props="defaultProps"
|
||||
highlight-current
|
||||
:default-expand-all="false"
|
||||
:filter-node-method="filterNode"
|
||||
node-key="id"
|
||||
:data="yqfDeviceData"
|
||||
v-bind="$attrs"
|
||||
style="overflow: auto"
|
||||
>
|
||||
<template #default="{ node, data }">
|
||||
<span class="custom-tree-node">
|
||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
||||
v-if="data.icon" />
|
||||
<Icon
|
||||
:name="data.icon"
|
||||
style="font-size: 16px"
|
||||
:style="{ color: data.color }"
|
||||
v-if="data.icon"
|
||||
/>
|
||||
<span style="margin-left: 4px">{{ node.label }}</span>
|
||||
</span>
|
||||
</template>
|
||||
@@ -112,33 +162,31 @@ const zlDeviceData = ref<any>([])
|
||||
const zlDevList = ref<any>([])
|
||||
//便携式设备数据
|
||||
const bxsDeviceData = ref<any>([])
|
||||
//在线设备数据
|
||||
//监测设备数据
|
||||
const yqfDeviceData = ref<any>([])
|
||||
watch(
|
||||
() => props.data,
|
||||
(val, oldVal) => {
|
||||
if (val && val.length != 0) {
|
||||
|
||||
val.map((item: any) => {
|
||||
if (item.name == '治理设备') {
|
||||
zlDeviceData.value = []
|
||||
item.children.map((vv: any) => {
|
||||
zlDeviceData.value.push(vv)
|
||||
})
|
||||
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
||||
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
||||
} else if (item.name == '便携式设备') {
|
||||
bxsDeviceData.value = []
|
||||
item.children.map((vv: any) => {
|
||||
bxsDeviceData.value.push(vv)
|
||||
})
|
||||
}else if (item.name == '在线设备') {
|
||||
} else if (item.name == '监测设备') {
|
||||
yqfDeviceData.value = []
|
||||
item.children.map((vv: any) => {
|
||||
yqfDeviceData.value.push(vv)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -157,12 +205,10 @@ watch(filterText, val => {
|
||||
}
|
||||
})
|
||||
watch(process, val => {
|
||||
|
||||
if (val == '') {
|
||||
if (val == '' || val == undefined) {
|
||||
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
||||
} else {
|
||||
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
|
||||
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
@@ -170,9 +216,8 @@ watch(process, val => {
|
||||
}, 0)
|
||||
})
|
||||
|
||||
|
||||
|
||||
const changeDevice = (val: any) => {
|
||||
console.log('🚀 ~ changeDevice ~ val:', val)
|
||||
|
||||
let arr1: any = []
|
||||
//zlDeviceData
|
||||
@@ -206,22 +251,28 @@ const changeDevice = (val: any) => {
|
||||
arr2.map((item: any) => {
|
||||
item.checked = false
|
||||
})
|
||||
treeRef1?.value && treeRef1.value.setCurrentKey(arr1[0]?.id)
|
||||
emit('changePointType', activeName.value, arr1[0])
|
||||
setTimeout(() => {
|
||||
treeRef1.value?.setCurrentKey(arr1[0]?.id)
|
||||
}, 100)
|
||||
}
|
||||
if (val == '1') {
|
||||
arr1.map((item: any) => {
|
||||
item.checked = false
|
||||
})
|
||||
treeRef2?.value && treeRef2.value.setCurrentKey(arr2[0]?.id)
|
||||
emit('changePointType', activeName.value, arr2[0])
|
||||
setTimeout(() => {
|
||||
treeRef2.value?.setCurrentKey(arr2[0]?.id)
|
||||
}, 100)
|
||||
}
|
||||
if (val == '2') {
|
||||
arr3.map((item: any) => {
|
||||
item.checked = false
|
||||
})
|
||||
treeRef3?.value && treeRef3.value.setCurrentKey(arr3[0]?.id)
|
||||
emit('changePointType', activeName.value, arr3[0])
|
||||
setTimeout(() => {
|
||||
treeRef3.value?.setCurrentKey(arr3[0]?.id)
|
||||
}, 100)
|
||||
}
|
||||
// if(activeName.value){
|
||||
// emit('changePointType', activeName.value)
|
||||
@@ -263,8 +314,7 @@ function filterProcess(nodes: any) {
|
||||
// 1. 如果有满足条件的子节点则保留
|
||||
// 2. 如果本身 process 值匹配则保留
|
||||
// 3. 如果是叶子节点也保留(监测点通常没有子节点)
|
||||
if (children.length > 0 || node.process == process.value ||
|
||||
(!node.children || node.children.length === 0)) {
|
||||
if (children.length > 0 || node.process == process.value || !node.children || node.children.length === 0) {
|
||||
return {
|
||||
...node,
|
||||
children: children
|
||||
@@ -276,7 +326,6 @@ function filterProcess(nodes: any) {
|
||||
.filter(Boolean) // 移除null节点
|
||||
}
|
||||
|
||||
|
||||
// function filterProcess(nodes: any) {
|
||||
// if (process.value == '') {
|
||||
// return nodes
|
||||
@@ -332,11 +381,9 @@ const treeRef1 = ref<InstanceType<typeof ElTree>>()
|
||||
const treeRef2 = ref<InstanceType<typeof ElTree>>()
|
||||
//在线
|
||||
const treeRef3 = ref<InstanceType<typeof ElTree>>()
|
||||
defineExpose({ treeRef1, treeRef2 })
|
||||
defineExpose({ treeRef1, treeRef2, treeRef3 })
|
||||
onMounted(() => {
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
if (zlDeviceData.value.length != 0) {
|
||||
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
|
||||
activeName.value = '0'
|
||||
@@ -344,8 +391,11 @@ onMounted(() => {
|
||||
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length != 0) {
|
||||
activeName.value = '1'
|
||||
}
|
||||
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length === 0) {
|
||||
activeName.value = '2'
|
||||
}
|
||||
if (!zlDeviceData.value && !bxsDeviceData.value) {
|
||||
activeName.value = ''
|
||||
activeName.value = '2'
|
||||
}
|
||||
nextTick(() => {
|
||||
changeDevice(activeName.value)
|
||||
|
||||
@@ -218,11 +218,12 @@ const updateNodeCheckStatus = (currentCount: number) => {
|
||||
const allNodes = treeRef.value.store._getAllNodes()
|
||||
allNodes.forEach((node: any) => {
|
||||
if (node.level === 3) { // 监测点层级
|
||||
|
||||
// 如果已达到最大数量且该节点未被选中,则禁用勾选
|
||||
if (isMaxSelected && !node.checked) {
|
||||
node.disabled = true
|
||||
if (isMaxSelected && !node.data.checked) {
|
||||
node.data.disabled = true
|
||||
} else {
|
||||
node.disabled = false
|
||||
node.data.disabled = false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div class="nav-tabs" ref="tabScrollbarRef">
|
||||
|
||||
<div
|
||||
v-for="(item, idx) in navTabs.state.tabsView"
|
||||
@click="onTab(item)"
|
||||
@@ -71,8 +72,11 @@ const onTab = (menu: RouteLocationNormalized) => {
|
||||
}
|
||||
|
||||
const onContextmenu = (menu: RouteLocationNormalized, el: MouseEvent) => {
|
||||
|
||||
// 禁用刷新
|
||||
state.contextmenuItems[0].disabled = route.path !== menu.path
|
||||
|
||||
|
||||
// 禁用关闭其他和关闭全部
|
||||
state.contextmenuItems[4].disabled = state.contextmenuItems[3].disabled =
|
||||
navTabs.state.tabsView.length == 1 ? true : false
|
||||
@@ -210,8 +214,8 @@ onMounted(() => {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
margin-right: var(--ba-main-space);
|
||||
scrollbar-width: none;
|
||||
|
||||
// scrollbar-width: none;
|
||||
// overflow-x: auto;
|
||||
&::-webkit-scrollbar {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="nav-menus" :class="configStore.layout.layoutMode">
|
||||
<div @click="savePng" class="nav-menu-item">
|
||||
<!-- <div @click="savePng" class="nav-menu-item">
|
||||
<Icon
|
||||
:color="configStore.getColorVal('headerBarTabColor')"
|
||||
class="nav-menu-icon"
|
||||
@@ -23,7 +23,7 @@
|
||||
name="fa-solid fa-expand"
|
||||
size="18"
|
||||
/>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<el-dropdown style="height: 100%" @command="handleCommand">
|
||||
<div class="admin-info" :class="state.currentNavMenu == 'adminInfo' ? 'hover' : ''">
|
||||
@@ -47,7 +47,8 @@
|
||||
name="fa fa-cogs"
|
||||
size="18"
|
||||
/>
|
||||
</div> -->"
|
||||
</div> -->
|
||||
"
|
||||
|
||||
<Config />
|
||||
<PopupPwd ref="popupPwd" />
|
||||
@@ -71,7 +72,6 @@ import PopupPwd from './popup/password.vue'
|
||||
import AdminInfo from './popup/adminInfo.vue'
|
||||
import { useNavTabs } from '@/stores/navTabs'
|
||||
|
||||
|
||||
const adminInfo = useAdminInfo()
|
||||
const navTabs = useNavTabs()
|
||||
const configStore = useConfig()
|
||||
@@ -106,7 +106,7 @@ const onFullScreen = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const handleCommand = (key: string) => {
|
||||
const handleCommand = async (key: string) => {
|
||||
// console.log(key)
|
||||
switch (key) {
|
||||
case 'adminInfo':
|
||||
@@ -116,10 +116,13 @@ const handleCommand = (key: string) => {
|
||||
popupPwd.value.open()
|
||||
break
|
||||
case 'layout':
|
||||
navTabs.closeTabs()
|
||||
window.localStorage.clear()
|
||||
adminInfo.reset()
|
||||
router.push({ name: 'login' })
|
||||
await window.location.reload()
|
||||
setTimeout(() => {
|
||||
navTabs.closeTabs()
|
||||
window.localStorage.clear()
|
||||
adminInfo.reset()
|
||||
router.push({ name: 'login' })
|
||||
}, 0)
|
||||
break
|
||||
default:
|
||||
break
|
||||
|
||||
@@ -9,7 +9,12 @@
|
||||
<el-input v-model.trim="form.newPwd" type="password" placeholder="请输入新密码" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码:" prop="confirmPwd">
|
||||
<el-input v-model.trim="form.confirmPwd" type="password" placeholder="请输入确认密码" show-password />
|
||||
<el-input
|
||||
v-model.trim="form.confirmPwd"
|
||||
type="password"
|
||||
placeholder="请输入确认密码"
|
||||
show-password
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
@@ -28,8 +33,10 @@ import { ElMessage } from 'element-plus'
|
||||
import { passwordConfirm, updatePassword } from '@/api/user-boot/user'
|
||||
import { validatePwd } from '@/utils/common'
|
||||
import { useAdminInfo } from '@/stores/adminInfo'
|
||||
|
||||
import router from '@/router'
|
||||
import { useNavTabs } from '@/stores/navTabs'
|
||||
const adminInfo = useAdminInfo()
|
||||
const navTabs = useNavTabs()
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('修改密码')
|
||||
const formRef = ref()
|
||||
@@ -96,9 +103,16 @@ const submit = () => {
|
||||
updatePassword({
|
||||
id: adminInfo.$state.userIndex,
|
||||
newPassword: form.newPwd
|
||||
}).then((res: any) => {
|
||||
}).then(async (res: any) => {
|
||||
ElMessage.success('密码修改成功')
|
||||
dialogVisible.value = false
|
||||
|
||||
setTimeout(() => {
|
||||
navTabs.closeTabs()
|
||||
window.localStorage.clear()
|
||||
adminInfo.reset()
|
||||
router.push({ name: 'login' })
|
||||
}, 0)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ router.beforeEach((to, from, next) => {
|
||||
const token = adminInfo.getToken()
|
||||
// token 不存在
|
||||
if (token === null || token === '') {
|
||||
ElMessage.error('您还没有登录,请先登录')
|
||||
// ElMessage.error('您还没有登录,请先登录')
|
||||
next('/login')
|
||||
} else {
|
||||
next()
|
||||
|
||||
@@ -4,6 +4,7 @@ import { STORE_TAB_VIEW_CONFIG } from '@/stores/constant/cacheKey'
|
||||
import type { NavTabs } from '@/stores/interface/index'
|
||||
import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'
|
||||
import { adminBaseRoutePath } from '@/router/static'
|
||||
import { set } from 'lodash'
|
||||
|
||||
export const useNavTabs = defineStore(
|
||||
'navTabs',
|
||||
@@ -20,7 +21,7 @@ export const useNavTabs = defineStore(
|
||||
// 从后台加载到的菜单路由列表
|
||||
tabsViewRoutes: [],
|
||||
// 按钮权限节点
|
||||
authNode: new Map(),
|
||||
authNode: new Map()
|
||||
})
|
||||
|
||||
function addTab(route: RouteLocationNormalized) {
|
||||
@@ -29,6 +30,7 @@ export const useNavTabs = defineStore(
|
||||
if (state.tabsView[key].path === route.path) {
|
||||
state.tabsView[key].params = route.params ? route.params : state.tabsView[key].params
|
||||
state.tabsView[key].query = route.query ? route.query : state.tabsView[key].query
|
||||
state.tabsView[key].meta = route.query ? route.meta : state.tabsView[key].meta
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -66,7 +68,7 @@ export const useNavTabs = defineStore(
|
||||
}
|
||||
|
||||
const setTabsViewRoutes = (data: RouteRecordRaw[]): void => {
|
||||
state.tabsViewRoutes = encodeRoutesURI(data)
|
||||
state.tabsViewRoutes = encodeRoutesURI(JSON.parse(JSON.stringify(data)))
|
||||
}
|
||||
|
||||
const setAuthNode = (key: string, data: string[]) => {
|
||||
@@ -81,21 +83,79 @@ export const useNavTabs = defineStore(
|
||||
state.tabFullScreen = fullScreen
|
||||
}
|
||||
|
||||
return { state, addTab, closeTab, closeTabs, setActiveRoute, setTabsViewRoutes, setAuthNode, fillAuthNode, setFullScreen }
|
||||
const refresh = () => {
|
||||
// setTimeout(() => {
|
||||
// console.log(123, state.tabsViewRoutes)
|
||||
|
||||
let list = matchAndReturnRouteData(state.tabsViewRoutes, state.tabsView)
|
||||
state.tabsView = []
|
||||
list.forEach(item => {
|
||||
addTab(item)
|
||||
})
|
||||
// }, 1000)
|
||||
}
|
||||
return {
|
||||
state,
|
||||
addTab,
|
||||
closeTab,
|
||||
closeTabs,
|
||||
setActiveRoute,
|
||||
setTabsViewRoutes,
|
||||
setAuthNode,
|
||||
fillAuthNode,
|
||||
setFullScreen,
|
||||
refresh
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
key: STORE_TAB_VIEW_CONFIG,
|
||||
paths: ['state.tabFullScreen'],
|
||||
},
|
||||
paths: ['state.tabFullScreen']
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* 核心逻辑:
|
||||
* 1. 递归遍历树形菜单,筛选出与routeList中name匹配的节点
|
||||
* 2. 将匹配到的节点格式转换为routeList的结构并返回
|
||||
*/
|
||||
function matchAndReturnRouteData(tree, routeList) {
|
||||
// 1. 构建路由name映射(name -> 完整路由对象)
|
||||
const routeMap = new Map()
|
||||
routeList.forEach(route => {
|
||||
if (route.name) {
|
||||
routeMap.set(route.name, route)
|
||||
}
|
||||
})
|
||||
|
||||
// 2. 递归遍历树形菜单,收集匹配的节点
|
||||
const matchedNodes = []
|
||||
function recursion(node) {
|
||||
// 匹配当前节点
|
||||
if (routeMap.has(node.name)) {
|
||||
// 深度克隆路由对象,避免修改原数据
|
||||
const matchedRoute = JSON.parse(JSON.stringify(routeMap.get(node.name)))
|
||||
matchedNodes.push(matchedRoute)
|
||||
}
|
||||
// 递归处理子节点
|
||||
if (node.children && node.children.length) {
|
||||
node.children.forEach(child => recursion(child))
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历所有顶级节点
|
||||
tree.forEach(node => recursion(node))
|
||||
|
||||
// 3. 返回匹配后的第二个数据格式(和routeList结构一致)
|
||||
return matchedNodes
|
||||
}
|
||||
|
||||
/**
|
||||
* 对iframe的url进行编码
|
||||
*/
|
||||
function encodeRoutesURI(data: RouteRecordRaw[]) {
|
||||
data.forEach((item) => {
|
||||
data.forEach(item => {
|
||||
if (item.meta?.menu_type == 'iframe') {
|
||||
item.path = adminBaseRoutePath + '/iframe/' + encodeURIComponent(item.path)
|
||||
}
|
||||
|
||||
58
src/styles/vxeTable.css
Normal file
58
src/styles/vxeTable.css
Normal file
@@ -0,0 +1,58 @@
|
||||
.vxe-header--row {
|
||||
background: var(--vxe-table-header-background-color);
|
||||
color: var(--vxe-table-header-font-color);
|
||||
}
|
||||
|
||||
.is--checked.vxe-checkbox,
|
||||
.is--checked.vxe-checkbox .vxe-checkbox--icon,
|
||||
.is--checked.vxe-custom--checkbox-option,
|
||||
.is--checked.vxe-custom--checkbox-option .vxe-checkbox--icon,
|
||||
.is--checked.vxe-export--panel-column-option,
|
||||
.is--checked.vxe-export--panel-column-option .vxe-checkbox--icon,
|
||||
.is--checked.vxe-table--filter-option,
|
||||
.is--checked.vxe-table--filter-option .vxe-checkbox--icon,
|
||||
.is--indeterminate.vxe-checkbox,
|
||||
.is--indeterminate.vxe-checkbox .vxe-checkbox--icon,
|
||||
.is--indeterminate.vxe-custom--checkbox-option,
|
||||
.is--indeterminate.vxe-custom--checkbox-option .vxe-checkbox--icon,
|
||||
.is--indeterminate.vxe-export--panel-column-option,
|
||||
.is--indeterminate.vxe-export--panel-column-option .vxe-checkbox--icon,
|
||||
.is--indeterminate.vxe-table--filter-option,
|
||||
.is--indeterminate.vxe-table--filter-option .vxe-checkbox--icon,
|
||||
.vxe-table--render-default .is--checked.vxe-cell--checkbox,
|
||||
.vxe-table--render-default .is--checked.vxe-cell--checkbox .vxe-checkbox--icon,
|
||||
.vxe-table--render-default .is--indeterminate.vxe-cell--checkbox,
|
||||
.vxe-table--render-default .is--indeterminate.vxe-cell--checkbox .vxe-checkbox--icon,
|
||||
.vxe-table--render-default .is--checked.vxe-cell--radio .vxe-radio--icon {
|
||||
color: var(--el-color-primary-light-3);
|
||||
}
|
||||
|
||||
.vxe-checkbox:not(.is--disabled):hover .vxe-checkbox--icon,
|
||||
.vxe-custom--checkbox-option:not(.is--disabled):hover .vxe-checkbox--icon,
|
||||
.vxe-export--panel-column-option:not(.is--disabled):hover .vxe-checkbox--icon,
|
||||
.vxe-table--filter-option:not(.is--disabled):hover .vxe-checkbox--icon,
|
||||
.vxe-table--render-default .vxe-cell--checkbox:not(.is--disabled):hover .vxe-checkbox--icon,
|
||||
.vxe-radio:not(.is--disabled):hover .vxe-radio--icon,
|
||||
.vxe-custom--radio-option:not(.is--disabled):hover .vxe-radio--icon,
|
||||
.vxe-export--panel-column-option:not(.is--disabled):hover .vxe-radio--icon,
|
||||
.vxe-table--filter-option:not(.is--disabled):hover .vxe-radio--icon,
|
||||
.vxe-table--render-default .vxe-cell--radio:not(.is--disabled):hover .vxe-radio--icon {
|
||||
color: var(--el-color-primary-light-5);
|
||||
}
|
||||
|
||||
.vxe-table--render-default .vxe-body--row.row--current,
|
||||
.vxe-table--render-default .vxe-body--row.row--current:hover {
|
||||
background-color: var(--el-color-primary-light-8);
|
||||
}
|
||||
|
||||
.vxe-table--tooltip-wrapper {
|
||||
z-index: 10000 !important;
|
||||
}
|
||||
|
||||
.is--disabled {
|
||||
background-color: var(--vxe-input-disabled-color);
|
||||
}
|
||||
|
||||
.vxe-modal--wrapper {
|
||||
z-index: 5000 !important;
|
||||
}
|
||||
1
src/styles/vxeTable.min.css
vendored
Normal file
1
src/styles/vxeTable.min.css
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.vxe-header--row{background:var(--vxe-table-header-background-color);color:var(--vxe-table-header-font-color)}.is--checked.vxe-checkbox,.is--checked.vxe-checkbox .vxe-checkbox--icon,.is--checked.vxe-custom--checkbox-option,.is--checked.vxe-custom--checkbox-option .vxe-checkbox--icon,.is--checked.vxe-export--panel-column-option,.is--checked.vxe-export--panel-column-option .vxe-checkbox--icon,.is--checked.vxe-table--filter-option,.is--checked.vxe-table--filter-option .vxe-checkbox--icon,.is--indeterminate.vxe-checkbox,.is--indeterminate.vxe-checkbox .vxe-checkbox--icon,.is--indeterminate.vxe-custom--checkbox-option,.is--indeterminate.vxe-custom--checkbox-option .vxe-checkbox--icon,.is--indeterminate.vxe-export--panel-column-option,.is--indeterminate.vxe-export--panel-column-option .vxe-checkbox--icon,.is--indeterminate.vxe-table--filter-option,.is--indeterminate.vxe-table--filter-option .vxe-checkbox--icon,.vxe-table--render-default .is--checked.vxe-cell--checkbox,.vxe-table--render-default .is--checked.vxe-cell--checkbox .vxe-checkbox--icon,.vxe-table--render-default .is--indeterminate.vxe-cell--checkbox,.vxe-table--render-default .is--indeterminate.vxe-cell--checkbox .vxe-checkbox--icon,.vxe-table--render-default .is--checked.vxe-cell--radio .vxe-radio--icon{color:var(--el-color-primary-light-3)}.vxe-checkbox:not(.is--disabled):hover .vxe-checkbox--icon,.vxe-custom--checkbox-option:not(.is--disabled):hover .vxe-checkbox--icon,.vxe-export--panel-column-option:not(.is--disabled):hover .vxe-checkbox--icon,.vxe-table--filter-option:not(.is--disabled):hover .vxe-checkbox--icon,.vxe-table--render-default .vxe-cell--checkbox:not(.is--disabled):hover .vxe-checkbox--icon,.vxe-radio:not(.is--disabled):hover .vxe-radio--icon,.vxe-custom--radio-option:not(.is--disabled):hover .vxe-radio--icon,.vxe-export--panel-column-option:not(.is--disabled):hover .vxe-radio--icon,.vxe-table--filter-option:not(.is--disabled):hover .vxe-radio--icon,.vxe-table--render-default .vxe-cell--radio:not(.is--disabled):hover .vxe-radio--icon{color:var(--el-color-primary-light-5)}.vxe-table--render-default .vxe-body--row.row--current,.vxe-table--render-default .vxe-body--row.row--current:hover{background-color:var(--el-color-primary-light-8)}.vxe-table--tooltip-wrapper{z-index:10000 !important}.is--disabled{background-color:var(--vxe-input-disabled-color)}.vxe-modal--wrapper{z-index:5000 !important}
|
||||
@@ -60,7 +60,10 @@
|
||||
.vxe-table--render-default .vxe-cell--radio:not(.is--disabled):hover .vxe-radio--icon {
|
||||
color: var(--el-color-primary-light-5);
|
||||
}
|
||||
|
||||
.vxe-table--render-default .vxe-body--row.row--current,
|
||||
.vxe-table--render-default .vxe-body--row.row--current:hover {
|
||||
background-color: var(--el-color-primary-light-8);
|
||||
}
|
||||
// .vxe-table--render-default .is--disabled.vxe-cell--checkbox .vxe-checkbox--icon{
|
||||
// color: #fff0;
|
||||
// }
|
||||
@@ -74,11 +77,11 @@
|
||||
.vxe-modal--wrapper {
|
||||
z-index: 5000 !important;
|
||||
}
|
||||
.vxe-table--body .vxe-body--row:nth-child(even) {
|
||||
background-color: #f9f9f9;
|
||||
// background-color: var(--el-color-primary-light-9);
|
||||
}
|
||||
// .vxe-table--body .vxe-body--row:nth-child(even) {
|
||||
// background-color: #f9f9f9;
|
||||
// // background-color: var(--el-color-primary-light-9);
|
||||
// }
|
||||
|
||||
.vxe-table--body .vxe-body--row:nth-child(odd) {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
// .vxe-table--body .vxe-body--row:nth-child(odd) {
|
||||
// background-color: #ffffff;
|
||||
// }
|
||||
|
||||
@@ -41,8 +41,8 @@ const form = reactive({
|
||||
id: ''
|
||||
})
|
||||
const rules = {
|
||||
name: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
|
||||
code: [{ required: true, message: '角色编码不能为空', trigger: 'blur' }]
|
||||
name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
|
||||
code: [{ required: true, message: '请输入角色编码', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
const open = (text: string, data?: anyObj) => {
|
||||
|
||||
@@ -44,7 +44,8 @@ const calculateValue = (o: number, value: number, num: number, isMin: boolean) =
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@@ -352,7 +352,9 @@ export function getTimeOfTheMonth(key: any): [string, string] {
|
||||
const dayOfWeek = now.getDay() // 0是周日
|
||||
const diff = now.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1) // 调整为周一
|
||||
const weekStart = new Date(year, month, diff)
|
||||
return [formatDate(weekStart, 'YYYY-MM-DD'), formatDate(now, 'YYYY-MM-DD')]
|
||||
const weekEnd = new Date(weekStart)
|
||||
weekEnd.setDate(weekEnd.getDate() + 6)
|
||||
return [formatDate(weekStart, 'YYYY-MM-DD'), formatDate(weekEnd, 'YYYY-MM-DD')]
|
||||
|
||||
case '5': // 日
|
||||
return [formatDate(now, 'YYYY-MM-DD'), formatDate(now, 'YYYY-MM-DD')]
|
||||
@@ -361,3 +363,23 @@ export function getTimeOfTheMonth(key: any): [string, string] {
|
||||
throw new Error('Invalid key')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当月时间
|
||||
* @param interval 组件外部时间 1 年 2 季 3 月 4 周 5 日
|
||||
* @param timeList 驾驶舱里面组件勾选时间 []
|
||||
* @param externalTime //外部传入时间
|
||||
* @param fullscreen // 全屏是否全屏
|
||||
*/
|
||||
export function getTime(interval: number | 3, timeList: any, externalTime: any) {
|
||||
// console.log('🚀 ~ getTime ~ timeList:', timeList)
|
||||
// 1、先匹配时间
|
||||
// 检查 interval 是否在 timeList 中
|
||||
if (timeList && timeList.includes(interval.toString())) {
|
||||
return [externalTime[0], externalTime[1], interval]
|
||||
} else {
|
||||
if (timeList && timeList.length > 0) {
|
||||
return [...getTimeOfTheMonth(timeList[0]), timeList[0]]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useAdminInfo } from '@/stores/adminInfo'
|
||||
|
||||
window.requests = []
|
||||
window.tokenRefreshing = false
|
||||
let loginExpireTimer:any=null
|
||||
let loginExpireTimer: any = null
|
||||
const pendingMap = new Map()
|
||||
const loadingInstance: LoadingInstance = {
|
||||
target: null,
|
||||
@@ -65,9 +65,18 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
|
||||
if (
|
||||
!(
|
||||
config.url == '/system-boot/file/upload' ||
|
||||
config.url == '/user-boot/sysRoleSystem/getSystemByRoleId' ||
|
||||
config.url == '/system-boot/file/getFileUrl' ||
|
||||
config.url == '/cs-harmonic-boot/realData/getBaseRealData' ||
|
||||
config.url == '/harmonic-boot/grid/getAssessOverview' ||
|
||||
config.url == '/harmonic-boot/gridDiagram/getGridDiagramAreaData' ||
|
||||
config.url == '/cs-device-boot/csline/list'
|
||||
config.url == '/cs-device-boot/csline/list' ||
|
||||
config.url == '/cs-harmonic-boot/pqSensitiveUser/getListByIds' ||
|
||||
config.url == '/cs-harmonic-boot/csevent/getEventCoords' ||
|
||||
config.url == '/cs-harmonic-boot/limitRateDetailD/limitTimeProbabilityData' ||
|
||||
config.url == '/cs-harmonic-boot/limitRateDetailD/limitProbabilityData' ||
|
||||
config.url == '/system-boot/dictTree/queryByCode' ||
|
||||
config.url == '/system-boot/dictTree/query'
|
||||
)
|
||||
)
|
||||
removePending(config)
|
||||
@@ -105,7 +114,7 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
|
||||
response => {
|
||||
removePending(response.config)
|
||||
options.loading && closeLoading(options) // 关闭loading
|
||||
if (
|
||||
if (
|
||||
response.data.code === 'A0000' ||
|
||||
response.data.type === 'application/json' ||
|
||||
Array.isArray(response.data) ||
|
||||
@@ -144,7 +153,7 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
|
||||
})
|
||||
}
|
||||
} else if (response.data.code == 'A0024') {
|
||||
// // 登录失效
|
||||
// // 登录失效
|
||||
// 清除上一次的定时器
|
||||
if (loginExpireTimer) {
|
||||
clearTimeout(loginExpireTimer)
|
||||
@@ -173,6 +182,7 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
|
||||
setTimeout(() => {
|
||||
ElMessage.error(response.data.message || '未知错误')
|
||||
}, 6000)
|
||||
} else if (response.config.url == '/cs-harmonic-boot/cspage/getByUserId') {
|
||||
} else {
|
||||
ElMessage.error(response.data.message || '未知错误')
|
||||
}
|
||||
|
||||
@@ -304,7 +304,7 @@ export const getMenu = () => {
|
||||
}
|
||||
handlerMenu(res.data)
|
||||
handleAdminRoute(res.data)
|
||||
if (route.params.to) {
|
||||
if (route?.params?.to) {
|
||||
const lastRoute = JSON.parse(route.params.to as string)
|
||||
if (lastRoute.path != adminBaseRoutePath) {
|
||||
let query = !isEmpty(lastRoute.query) ? lastRoute.query : {}
|
||||
|
||||
@@ -45,6 +45,7 @@ export default class TableStore {
|
||||
pageSize: 20
|
||||
},
|
||||
loading: true,
|
||||
exportLoading: false,
|
||||
column: [],
|
||||
loadCallback: null,
|
||||
resetCallback: null,
|
||||
@@ -196,6 +197,7 @@ export default class TableStore {
|
||||
[
|
||||
'export',
|
||||
() => {
|
||||
this.table.exportLoading = true
|
||||
// this.index()
|
||||
let params = { ...this.table.params, pageNum: 1, pageSize: this.table.total }
|
||||
createAxios(
|
||||
@@ -206,11 +208,16 @@ export default class TableStore {
|
||||
},
|
||||
requestPayload(this.method, params, this.paramsPOST)
|
||||
)
|
||||
).then(res => {
|
||||
this.table.allData = filtration(res.data.records || res.data)
|
||||
this.table.exportProcessingData && this.table.exportProcessingData()
|
||||
this.table.allFlag = data.showAllFlag || true
|
||||
})
|
||||
)
|
||||
.then(res => {
|
||||
this.table.allData = filtration(res.data.records || res.data)
|
||||
this.table.exportProcessingData && this.table.exportProcessingData()
|
||||
this.table.allFlag = data.showAllFlag || true
|
||||
this.table.exportLoading = false
|
||||
})
|
||||
.catch(() => {
|
||||
this.table.exportLoading = false
|
||||
})
|
||||
}
|
||||
]
|
||||
])
|
||||
|
||||
@@ -23,7 +23,7 @@ const tableStore = new TableStore({
|
||||
method: 'POST',
|
||||
url: '/user-boot/user/checkUserList',
|
||||
column: [
|
||||
// { width: '60', type: 'checkbox' },
|
||||
{ width: '60', type: 'checkbox' },
|
||||
{ title: '名称', field: 'name' },
|
||||
{ title: '登录名', field: 'loginName' },
|
||||
{ title: '角色', field: 'roleName' },
|
||||
@@ -33,7 +33,7 @@ const tableStore = new TableStore({
|
||||
{ title: '类型', field: 'casualUserName' },
|
||||
{ title: '状态', field: 'stateName' },
|
||||
{
|
||||
title: '操作',
|
||||
title: '操作', fixed: 'right',
|
||||
width: '180',
|
||||
render: 'buttons',
|
||||
buttons: [
|
||||
|
||||
@@ -2,8 +2,16 @@
|
||||
<div>
|
||||
<div class="custom-table-header">
|
||||
<div class="title">接口权限列表</div>
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue"
|
||||
style="width: 240px" placeholder="请输入菜单名称" class="ml10" clearable @input="search" />
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
v-model.trim="tableStore.table.params.searchValue"
|
||||
style="width: 240px"
|
||||
placeholder="请输入菜单名称"
|
||||
class="ml10"
|
||||
clearable
|
||||
@input="search"
|
||||
/>
|
||||
<el-button :icon="Plus" type="primary" @click="addMenu" class="ml10" :disabled="!props.id">新增</el-button>
|
||||
</div>
|
||||
<Table ref="tableRef" />
|
||||
@@ -17,7 +25,7 @@ import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import popupApi from './popupApi.vue'
|
||||
import { deleteMenu } from '@/api/user-boot/function'
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
defineOptions({
|
||||
name: 'auth/menu/api'
|
||||
})
|
||||
@@ -36,21 +44,31 @@ const apiList = ref([])
|
||||
const tableStore = new TableStore({
|
||||
showPage: false,
|
||||
url: '/user-boot/function/getButtonById',
|
||||
publicHeight: 60,
|
||||
publicHeight: 60,
|
||||
column: [
|
||||
{ title: '普通接口/接口名称', field: 'name' },
|
||||
{
|
||||
field: 'index',
|
||||
title: '序号',
|
||||
width: '80',
|
||||
formatter: (row: any) => {
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '普通接口/接口名称', field: 'name', minWidth: '180' },
|
||||
{
|
||||
title: '接口类型',
|
||||
field: 'type',
|
||||
minWidth: '140',
|
||||
formatter: row => {
|
||||
return row.cellValue == 1 ? '普通接口' : '公用接口'
|
||||
}
|
||||
},
|
||||
{ title: 'URL接口路径', field: 'path' },
|
||||
{ title: 'URL接口路径', field: 'path', minWidth: '200' },
|
||||
{
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
width: '180',
|
||||
width: '140',
|
||||
render: 'buttons',
|
||||
buttons: [
|
||||
{
|
||||
@@ -77,6 +95,8 @@ const tableStore = new TableStore({
|
||||
},
|
||||
click: row => {
|
||||
deleteMenu(row.id).then(() => {
|
||||
ElMessage.success('删除成功!')
|
||||
|
||||
tableStore.index()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import TableStore from '@/utils/tableStore'
|
||||
import Table from '@/components/table/index.vue'
|
||||
import popupMenu from './popupMenu.vue'
|
||||
import { delMenu } from '@/api/systerm'
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
defineOptions({
|
||||
name: 'auth/menu/menu'
|
||||
})
|
||||
@@ -50,7 +50,7 @@ const tableStore = new TableStore({
|
||||
render: 'icon'
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
title: '操作', fixed: 'right',
|
||||
align: 'center',
|
||||
width: '180',
|
||||
render: 'buttons',
|
||||
@@ -89,6 +89,8 @@ const tableStore = new TableStore({
|
||||
},
|
||||
click: row => {
|
||||
delMenu(row.id).then(() => {
|
||||
ElMessage.success('删除成功!')
|
||||
|
||||
emits('init')
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,12 +1,25 @@
|
||||
<template>
|
||||
<el-dialog width="700px" v-model.trim="dialogVisible" :title="title">
|
||||
<el-scrollbar>
|
||||
<el-form :mode="form" :inline="false" :model="form" label-width="120px" :rules="rules" class="form-one">
|
||||
<el-form
|
||||
:mode="form"
|
||||
:inline="false"
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
label-width="120px"
|
||||
:rules="rules"
|
||||
class="form-one"
|
||||
>
|
||||
<el-form-item prop="name" label="接口/按钮名称">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入接口名称" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="code" label="接口/按钮标识">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.code" placeholder="请输入英文接口标识" />
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
v-model.trim="form.code"
|
||||
placeholder="请输入英文接口标识"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="path" label="接口路径">
|
||||
<el-input v-model.trim="form.path" placeholder="请输入接口路径" />
|
||||
@@ -18,11 +31,17 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="sort" label="排序">
|
||||
<el-input maxlength="32" show-word-limit-number v-model.trim="form.sort" :min="0" />
|
||||
<el-input maxlength="32" show-word-limit-number v-model.number="form.sort" :min="0" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="remark" label="接口/按钮描述">
|
||||
<el-input maxlength="300" show-word-limit v-model.trim="form.remark" :rows="2" type="textarea"
|
||||
placeholder="请输入描述" />
|
||||
<el-input
|
||||
maxlength="300"
|
||||
show-word-limit
|
||||
v-model.trim="form.remark"
|
||||
:rows="2"
|
||||
type="textarea"
|
||||
placeholder="请输入描述"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
@@ -39,13 +58,14 @@
|
||||
import { ref, inject } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
import { update, add } from '@/api/user-boot/function'
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
defineOptions({
|
||||
name: 'auth/menu/popupApi'
|
||||
})
|
||||
const emits = defineEmits<{
|
||||
(e: 'init'): void
|
||||
}>()
|
||||
const formRef = ref()
|
||||
const form: any = reactive({
|
||||
id: '',
|
||||
pid: '0',
|
||||
@@ -58,7 +78,7 @@ const form: any = reactive({
|
||||
})
|
||||
const rules = {
|
||||
code: [
|
||||
{ required: true, message: '标识不能为空', trigger: 'blur' },
|
||||
{ required: true, message: '请输入标识', trigger: 'blur' },
|
||||
{
|
||||
pattern: /^[a-zA-Z_]{1}[a-zA-Z0-9_]{2,20}$/,
|
||||
message: '请输入至少3-20位英文',
|
||||
@@ -74,12 +94,14 @@ const rules = {
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('新增菜单')
|
||||
const open = (text: string, data: anyObj) => {
|
||||
formRef.value?.resetFields()
|
||||
title.value = text
|
||||
// 重置表单
|
||||
for (let key in form) {
|
||||
form[key] = ''
|
||||
}
|
||||
form.type = 1
|
||||
form.sort = 100
|
||||
form.pid = data.pid
|
||||
if (data.id) {
|
||||
for (let key in form) {
|
||||
@@ -89,15 +111,23 @@ const open = (text: string, data: anyObj) => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
const submit = async () => {
|
||||
if (form.id) {
|
||||
await update(form)
|
||||
} else {
|
||||
let obj = JSON.parse(JSON.stringify(form))
|
||||
delete obj.id
|
||||
await add(obj)
|
||||
}
|
||||
emits('init')
|
||||
dialogVisible.value = false
|
||||
formRef.value.validate(async valid => {
|
||||
if (valid) {
|
||||
if (form.id) {
|
||||
await update(form).then(() => {
|
||||
ElMessage.success('修改成功!')
|
||||
})
|
||||
} else {
|
||||
let obj = JSON.parse(JSON.stringify(form))
|
||||
delete obj.id
|
||||
await add(obj).then(() => {
|
||||
ElMessage.success('新增成功!')
|
||||
})
|
||||
}
|
||||
emits('init')
|
||||
dialogVisible.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
|
||||
@@ -1,29 +1,43 @@
|
||||
<template>
|
||||
<el-dialog class="cn-operate-dialog" width="700px" v-model.trim="dialogVisible" :title="title">
|
||||
<el-scrollbar>
|
||||
<el-form :inline="false" :model="form" label-width="auto" class="form-one">
|
||||
<el-form :inline="false" :model="form" label-width="auto" ref="formRef" class="form-one" :rules="rules">
|
||||
<el-form-item label="上级菜单">
|
||||
<el-cascader v-model.trim="form.pid" :options="tableStore.table.data" :props="cascaderProps"
|
||||
style="width: 100%" />
|
||||
<el-cascader
|
||||
v-model.trim="form.pid"
|
||||
:options="tableStore.table.data"
|
||||
:props="cascaderProps"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单名称">
|
||||
<el-form-item label="菜单名称" prop="name">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入菜单名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图标">
|
||||
<IconSelector v-model.trim="form.icon" placeholder="请选择图标" />
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单路由">
|
||||
<el-form-item label="菜单路由" prop="path">
|
||||
<el-input v-model.trim="form.path" placeholder="请输入菜单名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="组件路径">
|
||||
<el-input v-model.trim="form.routeName" placeholder="请输入组件路径,如/src/views/dashboard/index.vue" />
|
||||
<el-form-item label="组件路径" prop="routeName">
|
||||
<el-input
|
||||
v-model.trim="form.routeName"
|
||||
placeholder="请输入组件路径,如/src/views/dashboard/index.vue"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序">
|
||||
<el-input maxlength="32" show-word-limit-number v-model.trim="form.sort" :min="0" />
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input maxlength="32" show-word-limit-number v-model.number="form.sort" :min="0" />
|
||||
</el-form-item>
|
||||
<el-form-item label="菜单描述">
|
||||
<el-input maxlength="300" show-word-limit v-model.trim="form.remark" :rows="2" type="textarea"
|
||||
placeholder="请输入描述" />
|
||||
<el-input
|
||||
maxlength="300"
|
||||
show-word-limit
|
||||
v-model.trim="form.remark"
|
||||
:rows="2"
|
||||
type="textarea"
|
||||
placeholder="请输入描述"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-scrollbar>
|
||||
@@ -42,10 +56,11 @@ import { reactive } from 'vue'
|
||||
import TableStore from '@/utils/tableStore'
|
||||
import IconSelector from '@/components/baInput/components/iconSelector.vue'
|
||||
import { updateMenu, addMenu } from '@/api/systerm'
|
||||
|
||||
import { ElMessage } from 'element-plus'
|
||||
defineOptions({
|
||||
name: 'auth/menu/popupMenu'
|
||||
})
|
||||
const formRef = ref()
|
||||
const emits = defineEmits<{
|
||||
(e: 'init'): void
|
||||
}>()
|
||||
@@ -71,7 +86,15 @@ const form: any = reactive({
|
||||
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('新增菜单')
|
||||
const rules = {
|
||||
name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
|
||||
path: [{ required: true, message: '请输入菜单路由', trigger: 'blur' }],
|
||||
icon: [{ required: true, message: '请选择图标', trigger: 'blur' }],
|
||||
routeName: [{ required: true, message: '请输入组件路径', trigger: 'blur' }],
|
||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]
|
||||
}
|
||||
const open = (text: string, data: anyObj) => {
|
||||
formRef.value?.resetFields()
|
||||
title.value = text
|
||||
// 重置表单
|
||||
for (let key in form) {
|
||||
@@ -91,16 +114,27 @@ const open = (text: string, data: anyObj) => {
|
||||
dialogVisible.value = true
|
||||
}
|
||||
const submit = async () => {
|
||||
if (form.id) {
|
||||
await updateMenu(form)
|
||||
} else {
|
||||
form.code = 'menu'
|
||||
let obj = JSON.parse(JSON.stringify(form))
|
||||
delete obj.id
|
||||
await addMenu(obj)
|
||||
}
|
||||
emits('init')
|
||||
dialogVisible.value = false
|
||||
formRef.value.validate(async valid => {
|
||||
if (valid) {
|
||||
if (form.id) {
|
||||
form.pid = form.pid || '0'
|
||||
await updateMenu(form).then(() => {
|
||||
ElMessage.success('编辑成功!')
|
||||
})
|
||||
} else {
|
||||
form.code = 'menu'
|
||||
form.pid = form.pid || '0'
|
||||
let obj = JSON.parse(JSON.stringify(form))
|
||||
delete obj.id
|
||||
|
||||
await addMenu(obj).then(() => {
|
||||
ElMessage.success('新增成功!')
|
||||
})
|
||||
}
|
||||
emits('init')
|
||||
dialogVisible.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
|
||||
@@ -5,18 +5,36 @@
|
||||
<div class="title">角色列表</div>
|
||||
<el-button :icon="Plus" type="primary" @click="addRole" class="ml10">新增</el-button>
|
||||
</div>
|
||||
<Table ref="tableRef" @currentChange="currentChange" />
|
||||
<Table ref="tableRef" :row-config="{ isCurrent: true, isHover: true }" @currentChange="currentChange" />
|
||||
</div>
|
||||
<div>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="菜单">
|
||||
<Tree
|
||||
v-if="menuListId"
|
||||
ref="treeRef"
|
||||
show-checkbox
|
||||
width="350px"
|
||||
:data="menuTree"
|
||||
:checkStrictly="checkStrictly"
|
||||
@checkChange="checkChange"
|
||||
></Tree>
|
||||
<el-empty
|
||||
style="width: 350px; padding-top: 300px; box-sizing: border-box"
|
||||
description="请选择角色"
|
||||
v-else
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="系统">
|
||||
<div class="mt10 mr10" style="display: flex; justify-content: end">
|
||||
<el-button type="primary" icon="el-icon-Select" @click="saveSystem">保存</el-button>
|
||||
</div>
|
||||
<el-checkbox-group v-model="systemIds" class="md10 system">
|
||||
<el-checkbox v-for="item in systemList" :label="item.name" :value="item.id" :key="item.id" />
|
||||
</el-checkbox-group>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<Tree
|
||||
v-if="menuListId"
|
||||
ref="treeRef"
|
||||
show-checkbox
|
||||
width="350px"
|
||||
:data="menuTree"
|
||||
:checkStrictly="checkStrictly"
|
||||
@check-change="checkChange"
|
||||
></Tree>
|
||||
<el-empty style="width: 350px; padding-top: 300px; box-sizing: border-box" description="请选择角色" v-else />
|
||||
<PopupForm ref="popupRef"></PopupForm>
|
||||
</div>
|
||||
</template>
|
||||
@@ -26,23 +44,27 @@ 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 Tree from '@/components/tree/index.vue'
|
||||
import Tree from '@/components/tree/allocation.vue'
|
||||
import { functionTree } from '@/api/user-boot/function'
|
||||
import { getFunctionsByRoleIndex, updateRoleMenu } from '@/api/user-boot/roleFuction'
|
||||
import { getFunctionsByRoleIndex, updateRoleMenu, getSystemByRoleId, systemAdd } from '@/api/user-boot/roleFuction'
|
||||
import { mainHeight } from '@/utils/layout'
|
||||
import { del } from '@/api/user-boot/role'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import PopupForm from './popupForm.vue'
|
||||
import { useAdminInfo } from '@/stores/adminInfo'
|
||||
|
||||
import { useDictData } from '@/stores/dictData'
|
||||
const dictData = useDictData()
|
||||
const systemList = dictData.getBasicData('System_Type')
|
||||
const adminInfo = useAdminInfo()
|
||||
defineOptions({
|
||||
name: 'auth/role'
|
||||
})
|
||||
const systemIds = ref([])
|
||||
const height = mainHeight(20).height
|
||||
const treeRef = ref()
|
||||
const menuTree = ref<treeData[]>([])
|
||||
const popupRef = ref()
|
||||
const tableRef = ref()
|
||||
const checkStrictly = ref(true)
|
||||
const menuListId = ref('')
|
||||
const tableStore = new TableStore({
|
||||
@@ -68,7 +90,7 @@ const tableStore = new TableStore({
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
title: '操作', fixed: 'right',
|
||||
align: 'center',
|
||||
width: '180',
|
||||
render: 'buttons',
|
||||
@@ -104,7 +126,13 @@ const tableStore = new TableStore({
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
],
|
||||
loadCallback: () => {
|
||||
tableRef.value.getRef().setCurrentRow(tableStore.table.data[0])
|
||||
currentChange({
|
||||
row: tableStore.table.data[0]
|
||||
})
|
||||
}
|
||||
})
|
||||
tableStore.table.params.searchValue = ''
|
||||
|
||||
@@ -134,6 +162,12 @@ const currentChange = (data: any) => {
|
||||
menuListId.value = data.row.id
|
||||
getFunctionsByRoleIndex({ id: data.row.id }).then((res: any) => {
|
||||
treeRef.value.treeRef.setCheckedKeys(res.data.map((item: any) => item.id))
|
||||
setTimeout(() => {
|
||||
checkStrictly.value = false
|
||||
}, 100)
|
||||
})
|
||||
getSystemByRoleId({ id: data.row.id }).then((res: any) => {
|
||||
systemIds.value = res.data.systemIds || []
|
||||
})
|
||||
}
|
||||
|
||||
@@ -143,17 +177,31 @@ const checkChange = (data: any) => {
|
||||
checkStrictly.value = false
|
||||
return
|
||||
}
|
||||
if (timeout.value) {
|
||||
clearTimeout(timeout.value)
|
||||
}
|
||||
timeout.value = setTimeout(() => {
|
||||
updateRoleMenu({
|
||||
id: menuListId.value,
|
||||
idList: treeRef.value.treeRef.getCheckedNodes(false, true).map((node: any) => node.id)
|
||||
}).then(() => {
|
||||
|
||||
updateRoleMenu({
|
||||
id: menuListId.value,
|
||||
idList: treeRef.value.treeRef.getCheckedNodes(false, true).map((node: any) => node.id)
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage.success('操作成功!')
|
||||
treeRef.value.loading = false
|
||||
})
|
||||
.catch(() => {
|
||||
treeRef.value.loading = false
|
||||
})
|
||||
}
|
||||
const saveSystem = () => {
|
||||
systemAdd({
|
||||
roleId: menuListId.value,
|
||||
systemIds: systemIds.value
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage.success('操作成功!')
|
||||
treeRef.value.loading = false
|
||||
})
|
||||
.catch(() => {
|
||||
treeRef.value.loading = false
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
onMounted(() => {
|
||||
tableStore.index()
|
||||
@@ -162,3 +210,17 @@ const addRole = () => {
|
||||
popupRef.value.open('新增角色')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-tabs--border-card > .el-tabs__content) {
|
||||
padding: 0px !important;
|
||||
}
|
||||
.system {
|
||||
width: 330px;
|
||||
height: calc(100vh - 225px);
|
||||
border: 1px solid var(--el-border-color);
|
||||
padding: 5px 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
<template>
|
||||
<el-dialog class="cn-operate-dialog" width="700px" v-model.trim="dialogVisible" :title="title">
|
||||
<el-form :inline="false" :model="form" label-width="auto" class="form-one" :rules="rules">
|
||||
<el-form-item label="角色名称">
|
||||
<el-dialog class="cn-operate-dialog" width="500px" v-model.trim="dialogVisible" :title="title">
|
||||
<el-form :inline="false" ref="formRef" :model="form" label-width="auto" class="form-one" :rules="rules">
|
||||
<el-form-item label="角色名称" prop="name">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入菜单名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="角色编码">
|
||||
<el-form-item label="角色编码" prop="code">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.code" placeholder="请输入菜单名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="角色描述">
|
||||
<el-input maxlength="300" show-word-limit v-model.trim="form.remark" :rows="2" type="textarea"
|
||||
placeholder="请输入描述" />
|
||||
<el-input
|
||||
maxlength="300"
|
||||
show-word-limit
|
||||
v-model.trim="form.remark"
|
||||
:rows="2"
|
||||
type="textarea"
|
||||
placeholder="请输入描述"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@@ -40,12 +46,14 @@ const form = reactive({
|
||||
type: 0
|
||||
})
|
||||
const rules = {
|
||||
name: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
|
||||
code: [{ required: true, message: '角色编码不能为空', trigger: 'blur' }]
|
||||
name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
|
||||
code: [{ required: true, message: '请输入角色编码', trigger: 'blur' }]
|
||||
}
|
||||
const dialogVisible = ref(false)
|
||||
const title = ref('新增菜单')
|
||||
const formRef = ref()
|
||||
const open = (text: string, data?: anyObj) => {
|
||||
formRef.value?.resetFields()
|
||||
title.value = text
|
||||
dialogVisible.value = true
|
||||
if (data) {
|
||||
@@ -59,15 +67,19 @@ const open = (text: string, data?: anyObj) => {
|
||||
}
|
||||
}
|
||||
const submit = async () => {
|
||||
if (form.id) {
|
||||
await update(form)
|
||||
} else {
|
||||
form.type = adminInfo.$state.userType + 1
|
||||
await add(form)
|
||||
}
|
||||
ElMessage.success('保存成功')
|
||||
tableStore.index()
|
||||
dialogVisible.value = false
|
||||
formRef.value.validate(async valid => {
|
||||
if (valid) {
|
||||
if (form.id) {
|
||||
await update(form)
|
||||
} else {
|
||||
form.type = adminInfo.$state.userType + 1
|
||||
await add(form)
|
||||
}
|
||||
ElMessage.success('保存成功')
|
||||
tableStore.index()
|
||||
dialogVisible.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
|
||||
@@ -79,10 +79,10 @@ const tableStore = new TableStore({
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
title: '操作', fixed: 'right',
|
||||
width: '180',
|
||||
render: 'buttons',
|
||||
fixed: 'right',
|
||||
|
||||
buttons: [
|
||||
{
|
||||
name: 'edit',
|
||||
@@ -95,6 +95,7 @@ const tableStore = new TableStore({
|
||||
},
|
||||
click: row => {
|
||||
popupEditRef.value.open('编辑用户', row)
|
||||
console.log("🚀 ~ row:", row)
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<el-dialog class="cn-operate-dialog" v-model.trim="dialogVisible" :title="title">
|
||||
|
||||
<el-form :model="form" label-width="auto" class="form-two" :rules="rules">
|
||||
<el-form :model="form" ref="formRef" label-width="auto" class="form-two" :rules="rules">
|
||||
<el-form-item label="用户名" prop="name">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入昵称" />
|
||||
</el-form-item>
|
||||
@@ -9,18 +8,32 @@
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.loginName" placeholder="请输入登录名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="默认密码" prop="password" v-if="title === '新增用户'">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="form.password" placeholder="请输入密码" disabled />
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
v-model.trim="form.password"
|
||||
placeholder="请输入密码"
|
||||
disabled
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="权限类型" prop="type">
|
||||
<el-select v-model.trim="form.type" @change="changeValue" disabled placeholder="请选择权限类型">
|
||||
<el-option v-for="(item, index) in UserTypeOption" :label="item.label" :value="item.value"
|
||||
:key="index"></el-option>
|
||||
<el-option
|
||||
v-for="(item, index) in UserTypeOption"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:key="index"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户类型" prop="casualUser">
|
||||
<el-select v-model.trim="form.casualUser" placeholder="请选择权限类型">
|
||||
<el-option v-for="(item, index) in TypeOptions" :label="item.label" :value="item.value"
|
||||
:key="index"></el-option>
|
||||
<el-option
|
||||
v-for="(item, index) in TypeOptions"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:key="index"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="所属部门" prop="deptId">
|
||||
@@ -28,8 +41,12 @@
|
||||
</el-form-item> -->
|
||||
<el-form-item label="角色" prop="role">
|
||||
<el-select v-model.trim="form.role" placeholder="请选择角色" multiple collapse-tags>
|
||||
<el-option v-for="(item, index) in roleOptions" :label="item.label" :value="item.value"
|
||||
:key="index"></el-option>
|
||||
<el-option
|
||||
v-for="(item, index) in roleOptions"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:key="index"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@@ -67,8 +84,16 @@
|
||||
<el-radio-button :label="1">是</el-radio-button>
|
||||
<el-radio-button :label="0">否</el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-input maxlength="32" show-word-limit :disabled="title !== '新增用户'" v-model.trim="form.id"
|
||||
placeholder="请输入用户id" v-if="useId" style="flex: 1;" class="ml10"></el-input>
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
:disabled="title !== '新增用户'"
|
||||
v-model.trim="form.id"
|
||||
placeholder="请输入用户id"
|
||||
v-if="useId"
|
||||
style="flex: 1"
|
||||
class="ml10"
|
||||
></el-input>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@@ -113,16 +138,17 @@ const form = reactive({
|
||||
emailNotice: 0,
|
||||
type: 0
|
||||
})
|
||||
const formRef = ref()
|
||||
const rules: Partial<Record<string, Arrayable<FormItemRule>>> = {
|
||||
name: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
|
||||
role: [{ required: true, message: '角色不能为空', trigger: 'blur' }],
|
||||
password: [{ required: true, message: '用户密码不能为空', trigger: 'blur' }],
|
||||
loginName: [{ required: true, message: '登录名不能为空', trigger: 'blur' }],
|
||||
casualUser: [{ required: true, message: '用户类型不能为空', trigger: 'blur' }],
|
||||
smsNotice: [{ required: true, message: '短信通知不能为空', trigger: 'blur' }],
|
||||
emailNotice: [{ required: true, message: '邮件通知不能为空', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
||||
role: [{ required: true, message: '请输入角色', trigger: 'blur' }],
|
||||
password: [{ required: true, message: '请输入用户密码', trigger: 'blur' }],
|
||||
loginName: [{ required: true, message: '请输入登录名', trigger: 'blur' }],
|
||||
casualUser: [{ required: true, message: '请输入用户类型', trigger: 'blur' }],
|
||||
smsNotice: [{ required: true, message: '请输入短信通知', trigger: 'blur' }],
|
||||
emailNotice: [{ required: true, message: '请输入邮件通知', trigger: 'blur' }],
|
||||
email: [
|
||||
{ required: false, message: '邮箱不能为空', trigger: 'blur' },
|
||||
{ required: false, message: '请输入邮箱', trigger: 'blur' },
|
||||
{
|
||||
type: 'email',
|
||||
message: "'请输入正确的邮箱地址",
|
||||
@@ -130,16 +156,16 @@ const rules: Partial<Record<string, Arrayable<FormItemRule>>> = {
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{ required: false, message: '手机号不能为空', trigger: 'blur' },
|
||||
{ required: false, message: '请输入手机号', trigger: 'blur' },
|
||||
{
|
||||
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
||||
message: '请输入正确的手机号码',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
limitTime: [{ required: true, message: '时间段不能为空', trigger: 'blur' }],
|
||||
limitTime: [{ required: true, message: '请选择时间段', trigger: 'blur' }],
|
||||
limitIpStart: [
|
||||
{ required: true, message: '起始IP不能为空', trigger: 'blur' },
|
||||
{ required: true, message: '请输入起始IP', trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
validator: (rule: any, value: string, callback: any) => {
|
||||
@@ -157,7 +183,7 @@ const rules: Partial<Record<string, Arrayable<FormItemRule>>> = {
|
||||
}
|
||||
],
|
||||
limitIpEnd: [
|
||||
{ required: true, message: '结束IP不能为空', trigger: 'blur' },
|
||||
{ required: true, message: '请输入结束IP', trigger: 'blur' },
|
||||
{
|
||||
required: true,
|
||||
validator: (rule: any, value: string, callback: any) => {
|
||||
@@ -199,8 +225,10 @@ queryRole()
|
||||
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]
|
||||
@@ -221,25 +249,29 @@ const open = (text: string, data?: anyObj) => {
|
||||
form.limitIpStart = '0.0.0.0'
|
||||
form.limitIpEnd = '255.255.255.255'
|
||||
form.password = '123456'
|
||||
form.type = adminInfo.$state.userType + 1
|
||||
}
|
||||
form.type = adminInfo.$state.userType + 1
|
||||
}
|
||||
const submit = async () => {
|
||||
let obj = JSON.parse(JSON.stringify(form))
|
||||
obj.limitTime = obj.limitTime.join('-')
|
||||
delete obj.password
|
||||
if (form.id) {
|
||||
await edit(obj)
|
||||
ElMessage.success('修改成功')
|
||||
} else {
|
||||
form.type = adminInfo.$state.userType + 1
|
||||
await add(obj)
|
||||
ElMessage.success('新增成功')
|
||||
}
|
||||
tableStore.index()
|
||||
dialogVisible.value = false
|
||||
formRef.value.validate(async (valid: any) => {
|
||||
if (valid) {
|
||||
let obj = JSON.parse(JSON.stringify(form))
|
||||
obj.limitTime = obj.limitTime.join('-')
|
||||
delete obj.password
|
||||
if (form.id) {
|
||||
await edit(obj)
|
||||
ElMessage.success('修改成功')
|
||||
} else {
|
||||
form.type = adminInfo.$state.userType + 1
|
||||
await add(obj)
|
||||
ElMessage.success('新增成功')
|
||||
}
|
||||
tableStore.index()
|
||||
dialogVisible.value = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const changeValue = () => { }
|
||||
const changeValue = () => {}
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
@change="sourceChange"
|
||||
:options="deviceTreeOptions"
|
||||
:show-all-levels="false"
|
||||
:props="{ checkStrictly: true }"
|
||||
:props="{ checkStrictly: true, value: 'id', label: 'name' }"
|
||||
clearable
|
||||
></el-cascader>
|
||||
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
|
||||
@@ -57,17 +57,33 @@ const tabsList = ref([
|
||||
])
|
||||
const rankOptions = ref([
|
||||
{
|
||||
value: '1',
|
||||
label: '1级'
|
||||
value: '1,7',
|
||||
label: '1级(ERROR)'
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: '2级'
|
||||
value: '2,6',
|
||||
label: '2级(WARN)'
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
label: '3级'
|
||||
}
|
||||
value: '3,4,5',
|
||||
label: '3级(DEBUG,NORMAL)'
|
||||
},
|
||||
// {
|
||||
// value: '4',
|
||||
// label: 'DEBUG'
|
||||
// },
|
||||
// {
|
||||
// value: '5',
|
||||
// label: 'NORMAL'
|
||||
// },
|
||||
// {
|
||||
// value: '6',
|
||||
// label: 'WARN'
|
||||
// },
|
||||
// {
|
||||
// value: '7',
|
||||
// label: 'ERROR'
|
||||
// }
|
||||
])
|
||||
|
||||
const tableStore = new TableStore({
|
||||
@@ -83,14 +99,15 @@ const tableStore = new TableStore({
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '设备名称', field: 'equipmentName', align: 'center' },
|
||||
{ title: '工程名称', field: 'engineeringName', align: 'center' },
|
||||
{ title: '项目名称', field: 'projectName', align: 'center' },
|
||||
{ title: '设备名称', field: 'equipmentName', align: 'center', width: 120 },
|
||||
{ title: '工程名称', field: 'engineeringName', align: 'center', width: 120 },
|
||||
{ title: '项目名称', field: 'projectName', align: 'center', width: 120 },
|
||||
{ title: '发生时刻', field: 'startTime', align: 'center', width: 180, sortable: true },
|
||||
{
|
||||
title: '模块信息',
|
||||
field: 'moduleNo',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue ? row.cellValue : '/'
|
||||
}
|
||||
@@ -107,7 +124,7 @@ const tableStore = new TableStore({
|
||||
},
|
||||
{
|
||||
title: '事件描述',
|
||||
minWidth: 220,
|
||||
minWidth: 250,
|
||||
field: 'showName'
|
||||
},
|
||||
{
|
||||
@@ -116,14 +133,24 @@ const tableStore = new TableStore({
|
||||
width: 100,
|
||||
render: 'tag',
|
||||
custom: {
|
||||
// 1:Ⅰ级 2:Ⅱ级 3:Ⅲ级 4:DEBUG 5:NORMAL 6:WARN 7:ERROR
|
||||
|
||||
1: 'danger',
|
||||
2: 'warning',
|
||||
3: 'success'
|
||||
3: 'success',
|
||||
4: 'warning',
|
||||
5: 'success',
|
||||
6: 'warning',
|
||||
7: 'danger'
|
||||
},
|
||||
replaceValue: {
|
||||
1: '1级',
|
||||
2: '2级',
|
||||
3: '3级'
|
||||
3: '3级',
|
||||
4: 'DEBUG',
|
||||
5: 'NORMAL',
|
||||
6: 'WARN',
|
||||
7: 'ERROR'
|
||||
}
|
||||
}
|
||||
// {
|
||||
@@ -135,7 +162,25 @@ const tableStore = new TableStore({
|
||||
// }
|
||||
],
|
||||
beforeSearchFun: () => {},
|
||||
|
||||
exportProcessingData: () => {
|
||||
tableStore.table.allData = tableStore.table.allData.filter(item => {
|
||||
item.level =
|
||||
item.level == 1
|
||||
? '1级'
|
||||
: item.level == 2
|
||||
? '2级'
|
||||
: item.level == 3
|
||||
? '3级'
|
||||
: item.level == 4
|
||||
? 'DEBUG'
|
||||
: item.level == 5
|
||||
? 'NORMAL'
|
||||
: item.level == 6
|
||||
? 'WARN'
|
||||
: 'ERROR'
|
||||
return item
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
@@ -177,6 +222,7 @@ const sourceChange = (e: any) => {
|
||||
tableStore.table.params.deviceTypeId = e[0] || ''
|
||||
tableStore.table.params.engineeringid = e[1] || ''
|
||||
tableStore.table.params.projectId = e[2] || ''
|
||||
tableStore.table.params.deviceId = e[3] || ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,24 @@
|
||||
<template>
|
||||
<TableHeader datePicker ref="refheader" showExport>
|
||||
<template v-slot:select>
|
||||
<el-form-item label="关键词">
|
||||
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入前置服务器名称,ip" />
|
||||
<el-form-item label="关键字筛选">
|
||||
<el-input
|
||||
maxlength="32"
|
||||
show-word-limit
|
||||
v-model.trim="tableStore.table.params.searchValue"
|
||||
placeholder="请输入前置服务器名称,ip"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="级别">
|
||||
<el-select v-model.trim="tableStore.table.params.level" placeholder="请选择级别" clearable>
|
||||
<el-option
|
||||
v-for="item in rankOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
</template>
|
||||
</TableHeader>
|
||||
<!-- <div style="height: 300px;"> -->
|
||||
@@ -21,7 +35,36 @@ import { mainHeight } from '@/utils/layout'
|
||||
const props = defineProps(['deviceTree'])
|
||||
|
||||
const refheader = ref()
|
||||
|
||||
const rankOptions = ref([
|
||||
{
|
||||
value: '1,7',
|
||||
label: '1级(ERROR)'
|
||||
},
|
||||
{
|
||||
value: '2,6',
|
||||
label: '2级(WARN)'
|
||||
},
|
||||
{
|
||||
value: '3,4,5',
|
||||
label: '3级(DEBUG,NORMAL)'
|
||||
},
|
||||
// {
|
||||
// value: '4',
|
||||
// label: 'DEBUG'
|
||||
// },
|
||||
// {
|
||||
// value: '5',
|
||||
// label: 'NORMAL'
|
||||
// },
|
||||
// {
|
||||
// value: '6',
|
||||
// label: 'WARN'
|
||||
// },
|
||||
// {
|
||||
// value: '7',
|
||||
// label: 'ERROR'
|
||||
// }
|
||||
])
|
||||
const tableStore = new TableStore({
|
||||
url: '/cs-harmonic-boot/eventUser/frontWarnInfo',
|
||||
method: 'POST',
|
||||
@@ -35,33 +78,79 @@ const tableStore = new TableStore({
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '前置服务器名称', field: 'lineId', align: 'center' },
|
||||
{ title: '前置服务器ip', field: 'wavePath', align: 'center' },
|
||||
{ title: '进程号', field: 'clDid', align: 'center' },
|
||||
{ title: '发生时刻', field: 'startTime', align: 'center', minWidth: 80, sortable: true },
|
||||
{ title: '前置服务器名称', field: 'lineId', align: 'center', width: 120 },
|
||||
{ title: '前置服务器ip', field: 'wavePath', align: 'center', width: 120 },
|
||||
{ title: '进程号', field: 'clDid', align: 'center', width: 60 },
|
||||
{ title: '发生时刻', field: 'startTime', align: 'center', width: 180, sortable: true },
|
||||
|
||||
{
|
||||
title: '事件描述',
|
||||
field: 'tag',
|
||||
minWidth: 350
|
||||
},
|
||||
{
|
||||
{
|
||||
title: '告警代码',
|
||||
field: 'code',
|
||||
align: 'center',
|
||||
width: 100,
|
||||
|
||||
formatter: (row: any) => {
|
||||
return row.cellValue ? '\u200B' + row.cellValue : '/'
|
||||
return row.cellValue ? '\u200B' + row.cellValue : '/'
|
||||
},
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
title: '级别',
|
||||
field: 'level',
|
||||
width: 100,
|
||||
render: 'tag',
|
||||
custom: {
|
||||
// 1:Ⅰ级 2:Ⅱ级 3:Ⅲ级 4:DEBUG 5:NORMAL 6:WARN 7:ERROR
|
||||
|
||||
1: 'danger',
|
||||
2: 'warning',
|
||||
3: 'success',
|
||||
4: 'warning',
|
||||
5: 'success',
|
||||
6: 'warning',
|
||||
7: 'danger'
|
||||
},
|
||||
replaceValue: {
|
||||
1: '1级',
|
||||
2: '2级',
|
||||
3: '3级',
|
||||
4: 'DEBUG',
|
||||
5: 'NORMAL',
|
||||
6: 'WARN',
|
||||
7: 'ERROR'
|
||||
}
|
||||
}
|
||||
],
|
||||
beforeSearchFun: () => {}
|
||||
beforeSearchFun: () => {},
|
||||
exportProcessingData: () => {
|
||||
tableStore.table.allData = tableStore.table.allData.filter(item => {
|
||||
item.level =
|
||||
item.level == 1
|
||||
? '1级'
|
||||
: item.level == 2
|
||||
? '2级'
|
||||
: item.level == 3
|
||||
? '3级'
|
||||
: item.level == 4
|
||||
? 'DEBUG'
|
||||
: item.level == 5
|
||||
? 'NORMAL'
|
||||
: item.level == 6
|
||||
? 'WARN'
|
||||
: 'ERROR'
|
||||
return item
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
provide('tableStore', tableStore)
|
||||
tableStore.table.params.searchValue = ''
|
||||
tableStore.table.params.level = ''
|
||||
const deviceTreeOptions = ref<any>(props.deviceTree)
|
||||
deviceTreeOptions.value.map((item: any, index: any) => {
|
||||
if (item.children.length == 0) {
|
||||
@@ -75,6 +164,5 @@ onMounted(() => {
|
||||
setTimeout(() => {
|
||||
// tableStore.table.height = mainHeight(200).height as any
|
||||
}, 0)
|
||||
|
||||
</script>
|
||||
<style></style>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
@change="sourceChange"
|
||||
:options="deviceTreeOptions"
|
||||
:show-all-levels="false"
|
||||
:props="{ checkStrictly: true }"
|
||||
:props="{ checkStrictly: true, value: 'id', label: 'name' }"
|
||||
clearable
|
||||
></el-cascader>
|
||||
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
|
||||
@@ -133,6 +133,7 @@ const sourceChange = (e: any) => {
|
||||
tableStore.table.params.deviceTypeId = e[0] || ''
|
||||
tableStore.table.params.engineeringid = e[1] || ''
|
||||
tableStore.table.params.projectId = e[2] || ''
|
||||
tableStore.table.params.deviceId = e[3] || ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div ref="refheader" v-if="!isWaveCharts">
|
||||
<div ref="refheader" v-show="!isWaveCharts" style="width: 100%;">
|
||||
<TableHeader datePicker showExport>
|
||||
<template v-slot:select>
|
||||
<el-form-item label="数据来源">
|
||||
@@ -10,7 +10,7 @@
|
||||
v-model.trim="tableStore.table.params.cascader"
|
||||
:options="deviceTreeOptions"
|
||||
:show-all-levels="false"
|
||||
:props="{ checkStrictly: true }"
|
||||
:props="{ checkStrictly: true, value: 'id', label: 'name' }"
|
||||
clearable
|
||||
></el-cascader>
|
||||
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
|
||||
@@ -121,28 +121,30 @@ const tableStore = new TableStore({
|
||||
method: 'POST',
|
||||
publicHeight: 65,
|
||||
exportName: '暂态事件',
|
||||
column: [ {
|
||||
column: [
|
||||
{
|
||||
title: '序号',
|
||||
width: 80,
|
||||
formatter: (row: any) => {
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '设备名称', field: 'equipmentName', align: 'center' },
|
||||
{ title: '工程名称', field: 'engineeringName', align: 'center' },
|
||||
{ title: '项目名称', field: 'projectName', align: 'center' },
|
||||
{ title: '发生时刻', field: 'startTime', align: 'center', width: '240',sortable: true },
|
||||
{ title: '监测点名称', field: 'lineName', align: 'center' },
|
||||
{ title: '事件描述', field: 'showName', align: 'center' },
|
||||
{ title: '事件发生位置', field: 'evtParamPosition', align: 'center' },
|
||||
{ title: '相别', field: 'evtParamPhase', align: 'center' },
|
||||
{ title: '持续时间(s)', field: 'evtParamTm', align: 'center',sortable: true },
|
||||
{ title: '暂降(聚升)幅值(%)', minWidth: 100, field: 'evtParamVVaDepth', align: 'center',sortable: true },
|
||||
{ title: '设备名称', field: 'equipmentName', minWidth: 120, align: 'center' },
|
||||
{ title: '工程名称', field: 'engineeringName', minWidth: 120, align: 'center' },
|
||||
{ title: '项目名称', field: 'projectName', minWidth: 120, align: 'center' },
|
||||
{ title: '发生时刻', field: 'startTime', align: 'center', minWidth: 180, sortable: true },
|
||||
{ title: '监测点名称', field: 'lineName', minWidth: 120, align: 'center' },
|
||||
{ title: '事件描述', field: 'showName', minWidth: 120, align: 'center' },
|
||||
{ title: '事件发生位置', field: 'evtParamPosition', minWidth: 150, align: 'center' },
|
||||
{ title: '相别', field: 'evtParamPhase', minWidth: 80, align: 'center' },
|
||||
{ title: '持续时间(s)', field: 'evtParamTm', minWidth: 80, align: 'center', sortable: true },
|
||||
{ title: '暂降(聚升)幅值(%)', minWidth: 100, field: 'evtParamVVaDepth', align: 'center', sortable: true },
|
||||
|
||||
{
|
||||
title: '操作',
|
||||
title: '操作', fixed: 'right',
|
||||
align: 'center',
|
||||
width: '180',
|
||||
|
||||
render: 'buttons',
|
||||
buttons: [
|
||||
{
|
||||
@@ -164,9 +166,10 @@ const tableStore = new TableStore({
|
||||
row.loading1 = false
|
||||
if (res != undefined) {
|
||||
boxoList.value = row
|
||||
boxoList.value.persistTime = row.evtParamTm
|
||||
boxoList.value.featureAmplitude =
|
||||
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
||||
boxoList.value.systemType = 'WX'
|
||||
row.evtParamVVaDepth != '-' ? (row.evtParamVVaDepth - 0) / 100 : null
|
||||
boxoList.value.systemType = 'YPT'
|
||||
wp.value = res.data
|
||||
}
|
||||
loading.value = false
|
||||
@@ -234,24 +237,24 @@ const tableStore = new TableStore({
|
||||
icon: 'el-icon-DataLine',
|
||||
render: 'basicButton',
|
||||
disabled: row => {
|
||||
return row.showName != '未知';
|
||||
return row.showName != '未知'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'edit',
|
||||
title: '波形补召',
|
||||
type: 'primary',
|
||||
icon: 'el-icon-Check',
|
||||
render: 'basicButton',
|
||||
disabled: row => {
|
||||
return row.wavePath || row.showName === '未知';
|
||||
},
|
||||
click: row => {
|
||||
name: 'edit',
|
||||
title: '波形补召',
|
||||
type: 'primary',
|
||||
icon: 'el-icon-Check',
|
||||
render: 'basicButton',
|
||||
disabled: row => {
|
||||
return row.wavePath || row.showName === '未知'
|
||||
},
|
||||
click: row => {
|
||||
getFileByEventId(row.id).then(res => {
|
||||
ElMessage.success(res.message)
|
||||
tableStore.index()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -312,8 +315,8 @@ const sourceChange = (e: any) => {
|
||||
tableStore.table.params.deviceTypeId = e[0] || ''
|
||||
tableStore.table.params.engineeringid = e[1] || ''
|
||||
tableStore.table.params.projectId = e[2] || ''
|
||||
tableStore.table.params.deviceId = e[3] || ''
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// tableStore.table.params.engineeringid = e[1] || ''
|
||||
|
||||
@@ -7,15 +7,15 @@
|
||||
<el-tab-pane label="前置告警" name="2">
|
||||
<Front v-if="activeName == '2'" :deviceTree="deviceTree" :key="key" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="稳态越限告警" name="3">
|
||||
<!-- <el-tab-pane label="稳态越限告警" name="3">
|
||||
<Steady v-if="activeName == '3'" :deviceTree="deviceTree" :key="key" />
|
||||
</el-tab-pane>
|
||||
</el-tab-pane> -->
|
||||
<el-tab-pane label="暂态事件" name="4">
|
||||
<Transient v-if="activeName == '4'" :deviceTree="deviceTree" :key="key" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="异常事件" name="5">
|
||||
<!-- <el-tab-pane label="异常事件" name="5">
|
||||
<Abnormal v-if="activeName == '5'" :deviceTree="deviceTree" :key="key" />
|
||||
</el-tab-pane>
|
||||
</el-tab-pane> -->
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
@@ -31,24 +31,25 @@ defineOptions({
|
||||
name: 'govern/alarm/index'
|
||||
})
|
||||
const deviceTree = ref([])
|
||||
const activeName = ref('1')
|
||||
const activeName = ref('0')
|
||||
const key = ref(0)
|
||||
getDeviceTree().then(res => {
|
||||
res.data.forEach((item: any) => {
|
||||
item.value = item.id
|
||||
item.label = item.name
|
||||
item.children.forEach((child: any) => {
|
||||
child.value = child.id
|
||||
child.label = child.name
|
||||
child.children.forEach((grand: any) => {
|
||||
grand.value = grand.id
|
||||
grand.label = grand.name
|
||||
delete grand.children
|
||||
})
|
||||
})
|
||||
})
|
||||
// res.data.forEach((item: any) => {
|
||||
// item.value = item.id
|
||||
// item.label = item.name
|
||||
// item.children.forEach((child: any) => {
|
||||
// child.value = child.id
|
||||
// child.label = child.name
|
||||
// child.children.forEach((grand: any) => {
|
||||
// grand.value = grand.id
|
||||
// grand.label = grand.name
|
||||
// delete grand.children
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
deviceTree.value = res.data
|
||||
key.value += 1
|
||||
activeName.value = '1'
|
||||
})
|
||||
onMounted(() => { })
|
||||
|
||||
|
||||
@@ -158,6 +158,7 @@ const nodeClick = async (e: anyObj) => {
|
||||
getDevCapacity(formInline.devId)
|
||||
.then(res => {
|
||||
devCapacity.value = res.data
|
||||
|
||||
search()
|
||||
})
|
||||
.catch(() => {
|
||||
|
||||
@@ -136,21 +136,39 @@ const tableStore = new TableStore({
|
||||
url: '/cs-harmonic-boot/eventUser/queryEventpageWeb',
|
||||
method: 'POST',
|
||||
column: [
|
||||
{ title: '事件描述', field: 'showName' },
|
||||
{ title: '发生位置', field: 'evtParamPosition' },
|
||||
{ title: '持续时间(s)', field: 'evtParamTm', sortable: true },
|
||||
{
|
||||
field: 'index',
|
||||
title: '序号',
|
||||
width: '80',
|
||||
formatter: (row: any) => {
|
||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||
}
|
||||
},
|
||||
{ title: '事件描述', field: 'showName', minWidth: 150 },
|
||||
{ title: '发生位置', field: 'evtParamPosition', minWidth: 150 },
|
||||
{
|
||||
title: '持续时间(s)',
|
||||
field: 'evtParamTm',
|
||||
sortable: true,
|
||||
minWidth: 110,
|
||||
formatter: (row: any) => {
|
||||
return Math.floor(row.cellValue * 10000) / 100
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '暂降(聚升)幅值(%)',
|
||||
field: 'evtParamVVaDepth',
|
||||
minWidth: 150,
|
||||
formatter: (row: any) => {
|
||||
let a = row.cellValue.split('%')[0] - 0
|
||||
console.log('🚀 ~ a:', a)
|
||||
return a ? a.toFixed(2) : '/'
|
||||
}, sortable: true
|
||||
},
|
||||
sortable: true
|
||||
},
|
||||
{ title: '发生时刻', field: 'startTime', sortable: true },
|
||||
{ title: '发生时刻', field: 'startTime', sortable: true, minWidth: 180 },
|
||||
{
|
||||
title: '操作',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
width: '180',
|
||||
render: 'buttons',
|
||||
@@ -175,8 +193,11 @@ const tableStore = new TableStore({
|
||||
if (res != undefined) {
|
||||
boxoList.value = row
|
||||
boxoList.value.featureAmplitude =
|
||||
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
||||
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth.split('%')[0] / 100 : null
|
||||
boxoList.value.persistTime =
|
||||
row.evtParamTm != '-' ? Math.floor(row.evtParamTm * 10000) / 100 : null
|
||||
// boxoList.value.systemType = 'WX'
|
||||
boxoList.value.systemType = 'YPT'
|
||||
wp.value = res.data
|
||||
}
|
||||
loading.value = false
|
||||
@@ -243,12 +264,12 @@ tableStore.table.params.eventType = ''
|
||||
tableStore.table.params.location = ''
|
||||
provide('tableStore', tableStore)
|
||||
const deviceTypeChange = (val: any, obj: any) => {
|
||||
flag.value = true
|
||||
flag.value = true
|
||||
nodeClick(obj)
|
||||
}
|
||||
const nodeClick = async (e: anyObj) => {
|
||||
// console.log("🚀 ~ nodeClick ~ e:", e)
|
||||
if (e.level == 2&& flag.value) {
|
||||
if (e.level == 2 && flag.value) {
|
||||
loading.value = false
|
||||
tableStore.table.params.deviceId = e.id
|
||||
nextTick(() => {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user