Compare commits
62 Commits
8355fc6aed
...
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 |
@@ -15,6 +15,13 @@ export function getLineTree() {
|
|||||||
method: 'POST'
|
method: 'POST'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 监测点列表治理
|
||||||
|
export function objTree() {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-device-boot/csLedger/objTree',
|
||||||
|
method: 'POST'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//云设备录入树
|
//云设备录入树
|
||||||
@@ -24,4 +31,11 @@ export function getCldTree() {
|
|||||||
method: 'POST'
|
method: 'POST'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
//报表树
|
||||||
|
export function lineTree() {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-device-boot/csLedger/lineTree',
|
||||||
|
method: 'POST'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,82 @@
|
|||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
// 新增程序版本
|
// 新增程序版本
|
||||||
export const addEdData = (data) => {
|
export const addEdData = data => {
|
||||||
return request({
|
return request({
|
||||||
url: '/cs-device-boot/edData/addEdData',
|
url: '/cs-device-boot/edData/addEdData',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: {
|
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({
|
return request({
|
||||||
url: '/cs-device-boot/edData/auditEdData',
|
url: '/cs-device-boot/edData/auditEdData',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
headers: {
|
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({
|
return request({
|
||||||
url: '/cs-device-boot/engineering/auditEngineering',
|
url: '/cs-device-boot/engineering/auditEngineering',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data,
|
data: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 修改项目
|
// 修改项目
|
||||||
export const updateProject = (data:any) => {
|
export const updateProject = (data: any) => {
|
||||||
return request({
|
return request({
|
||||||
url: '/cs-device-boot/project/updateProject',
|
url: '/cs-device-boot/project/updateProject',
|
||||||
method: 'post',
|
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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,59 @@
|
|||||||
import createAxios from '@/utils/request'
|
import createAxios from '@/utils/request'
|
||||||
|
import { genFileId, ElMessage, ElNotification } from 'element-plus'
|
||||||
// 查询设备数据趋势
|
// 查询设备数据趋势
|
||||||
export function getDeviceDataTrend(data: any) {
|
export function getDeviceDataTrend(data: any) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/cs-harmonic-boot/datatrend/querydatatrend',
|
url: '/cs-harmonic-boot/datatrend/querydatatrend',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 波形下载
|
||||||
|
export function getFileZip(params: any) {
|
||||||
// 波形下载
|
return createAxios({
|
||||||
export function getFileZip(params: any) {
|
url: '/cs-harmonic-boot/event/getFileZip',
|
||||||
return createAxios({
|
method: 'get',
|
||||||
url: '/cs-harmonic-boot/event/getFileZip',
|
params,
|
||||||
method: 'get',
|
responseType: 'blob'
|
||||||
params,
|
})
|
||||||
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,50 +1,67 @@
|
|||||||
import createAxios from '@/utils/request'
|
import createAxios from '@/utils/request'
|
||||||
|
|
||||||
//新增组态项目
|
//新增组态项目
|
||||||
export function add(data: any) {
|
export function add(data: any) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/cs-harmonic-boot/csconfiguration/add',
|
url: '/cs-harmonic-boot/csconfiguration/add',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
//组态项目分页查询
|
//组态项目分页查询
|
||||||
export function coFqueryPage(data: any) {
|
export function coFqueryPage(data: any) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/cs-harmonic-boot/csconfiguration/queryPage',
|
url: '/cs-harmonic-boot/csconfiguration/queryPage',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
//修改组态项目
|
//修改组态项目
|
||||||
export function audit(data: any) {
|
export function audit(data: any) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/cs-harmonic-boot/csconfiguration/audit',
|
url: '/cs-harmonic-boot/csconfiguration/audit',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
//组态页面分页查询
|
//组态页面分页查询
|
||||||
export function queryPageData(data: any) {
|
export function queryPageData(data: any) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/cs-harmonic-boot/cspage/queryPage',
|
url: '/cs-harmonic-boot/cspage/queryPage',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
//查询工程列表
|
//查询工程列表
|
||||||
export function deviceTree(data: any) {
|
export function deviceTree(data: any) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/cs-device-boot/csLedger/deviceTree',
|
url: '/cs-device-boot/csLedger/deviceTree',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//三层设备树(项目层根节点为治理设备和便携式设备组态)
|
//三层设备树(项目层根节点为治理设备和便携式设备组态)
|
||||||
export function getztProjectTree() {
|
export function getztProjectTree() {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/cs-device-boot/csLedger/getztProjectTree',
|
url: '/cs-device-boot/csLedger/getztProjectTree',
|
||||||
method: 'post',
|
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) {
|
export function getMakeUpData(data: any) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/cs-harmonic-boot/offlineDataUpload/makeUpData?lineId='+data,
|
url: '/cs-harmonic-boot/offlineDataUpload/makeUpData?lineId=' + data,
|
||||||
method: 'POST'
|
method: 'POST'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,14 @@ export function offlineDataUploadMakeUp(data: any) {
|
|||||||
export function getListByIds() {
|
export function getListByIds() {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/cs-harmonic-boot/pqSensitiveUser/getListByIds',
|
url: '/cs-harmonic-boot/pqSensitiveUser/getListByIds',
|
||||||
method: 'POST',
|
method: 'POST'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 根据id集合获取敏感负荷用户列表
|
||||||
|
export function getList(data) {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-harmonic-boot/pqSensitiveUser/getList',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,30 @@
|
|||||||
import createAxios from '@/utils/request'
|
import createAxios from '@/utils/request'
|
||||||
|
|
||||||
// 更新问题状态
|
// 更新问题状态
|
||||||
export function auditFeedBack(data: any) {
|
export function auditFeedBack(data: any) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/cs-system-boot/feedback/auditFeedBack',
|
url: '/cs-system-boot/feedback/auditFeedBack',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
params: data
|
params: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//下载文件
|
//下载文件
|
||||||
export function downLoadFile(filePath: any) {
|
export function downLoadFile(filePath: any) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/system-boot/file/download',
|
url: '/system-boot/file/download',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
responseType: 'blob',
|
responseType: 'blob',
|
||||||
params: { filePath: filePath }
|
params: { filePath: filePath }
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取文件的一个短期url
|
||||||
|
export function getFileUrl(filePath: any) {
|
||||||
|
return createAxios({
|
||||||
|
url: '/system-boot/file/getFileUrl',
|
||||||
|
method: 'get',
|
||||||
|
// responseType: 'blob',
|
||||||
|
params: { filePath: filePath }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
import { genFileId, ElMessage, ElNotification } from 'element-plus'
|
||||||
// 主要监测点列表查询>>分页
|
// 主要监测点列表查询>>分页
|
||||||
export function mainLineList(data: any) {
|
export function mainLineList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
@@ -115,7 +115,6 @@ export function limitProbabilityData(data: any) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 电网侧指标越限统计列表
|
// 电网侧指标越限统计列表
|
||||||
export function gridSideLimitStatisticsList(data: any) {
|
export function gridSideLimitStatisticsList(data: any) {
|
||||||
return request({
|
return request({
|
||||||
@@ -152,7 +151,6 @@ export function getListByIds(data: any) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 上传治理报告
|
// 上传治理报告
|
||||||
export function uploadReport(data: any) {
|
export function uploadReport(data: any) {
|
||||||
return request({
|
return request({
|
||||||
@@ -260,5 +258,42 @@ export function getSimpleLine() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -103,6 +103,14 @@ export function getTemplateByDept(params) {
|
|||||||
params
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 获取模版
|
||||||
|
export function querySysExcel(params) {
|
||||||
|
return createAxios({
|
||||||
|
url: '/cs-harmonic-boot/sysExcel/querySysExcel',
|
||||||
|
method: 'post',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
//资源管理 查询数据
|
//资源管理 查询数据
|
||||||
export function queryData(data) {
|
export function queryData(data) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
@@ -168,3 +176,43 @@ export function terminalChooseTree() {
|
|||||||
method: 'get'
|
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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -54,6 +54,14 @@ export const activatePage = (params: any) => {
|
|||||||
params
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 全局的驾驶舱页面
|
||||||
|
export const scopePage = (params: any) => {
|
||||||
|
return createAxios({
|
||||||
|
url: '/system-boot/dashboard/scopePage',
|
||||||
|
method: 'post',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
// 查询激活的驾驶舱页面
|
// 查询激活的驾驶舱页面
|
||||||
export const queryActivatePage = () => {
|
export const queryActivatePage = () => {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
|
|||||||
@@ -1,21 +1,33 @@
|
|||||||
import createAxios from '@/utils/request'
|
import createAxios from '@/utils/request'
|
||||||
|
|
||||||
export function getFunctionsByRoleIndex(data) {
|
export function getFunctionsByRoleIndex(data) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/user-boot/roleFunction/getFunctionsByRoleIndex',
|
url: '/user-boot/roleFunction/getFunctionsByRoleIndex',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
params: data
|
params: data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateRoleMenu(data:any) {
|
export function updateRoleMenu(data: any) {
|
||||||
return createAxios({
|
return createAxios({
|
||||||
url: '/user-boot/function/assignFunctionByRoleIndexes',
|
url: '/user-boot/function/assignFunctionByRoleIndexes',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: data
|
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>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--F47曲线 -->
|
<!--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 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.name }}</el-descriptions-item>
|
||||||
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
|
<el-descriptions-item align="center" label="事件总数">{{ data.gs }}</el-descriptions-item>
|
||||||
@@ -22,7 +29,6 @@
|
|||||||
<el-dialog v-model="isWaveCharts" v-if="isWaveCharts" draggable :title="dialogTitle" append-to-body width="70%">
|
<el-dialog v-model="isWaveCharts" v-if="isWaveCharts" draggable :title="dialogTitle" append-to-body width="70%">
|
||||||
<waveFormAnalysis
|
<waveFormAnalysis
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
|
|
||||||
ref="waveFormAnalysisRef"
|
ref="waveFormAnalysisRef"
|
||||||
@handleHideCharts="isWaveCharts = false"
|
@handleHideCharts="isWaveCharts = false"
|
||||||
:wp="wp"
|
:wp="wp"
|
||||||
@@ -38,15 +44,20 @@ import waveFormAnalysis from '@/views/govern/device/control/tabs/components/wave
|
|||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import { analyseWave } from '@/api/common'
|
import { analyseWave } from '@/api/common'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { getTime } from '@/utils/formatTime'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const TableHeaderRef = ref()
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
const dialogTitle = ref('波形分析')
|
const dialogTitle = ref('波形分析')
|
||||||
@@ -100,14 +111,13 @@ const tableStore: any = new TableStore({
|
|||||||
|
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
const gongData = gongfunction(tableStore.table.data)
|
const gongData = gongfunction(tableStore.table.data)
|
||||||
data.gs = tableStore.table.data.length
|
data.gs = tableStore.table.data.length
|
||||||
data.krr = gongData.pointI.length
|
data.krr = gongData.pointF.length
|
||||||
data.bkrr = gongData.pointIun.length
|
data.bkrr = gongData.pointFun.length
|
||||||
echartList.value = {
|
echartList.value = {
|
||||||
title: {
|
title: {
|
||||||
text: `F47曲线`
|
text: `F47曲线`
|
||||||
@@ -159,11 +169,16 @@ const tableStore: any = new TableStore({
|
|||||||
yAxis: [
|
yAxis: [
|
||||||
{
|
{
|
||||||
type: 'value',
|
type: 'value',
|
||||||
max: function (value: any) {
|
// max: function (value: any) {
|
||||||
return value.max + 20
|
// return value.max + 20
|
||||||
|
// },
|
||||||
|
max: function (value) {
|
||||||
|
// 先取原始最大值+20,再向上取整到最近的10的倍数,确保刻度够用且规整
|
||||||
|
return Math.ceil((value.max + 20) / 10) * 10
|
||||||
},
|
},
|
||||||
splitNumber: 10,
|
// splitNumber: 10,
|
||||||
minInterval: 0.1,
|
// interval: 10,
|
||||||
|
// minInterval: 10,
|
||||||
name: '%'
|
name: '%'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -200,15 +215,7 @@ const tableStore: any = new TableStore({
|
|||||||
// [0.4, 50, '2023-01-01 11:00:00']
|
// [0.4, 50, '2023-01-01 11:00:00']
|
||||||
// ],
|
// ],
|
||||||
legendSymbol: 'circle',
|
legendSymbol: 'circle',
|
||||||
emphasis: {
|
|
||||||
focus: 'series',
|
|
||||||
itemStyle: {
|
|
||||||
borderColor: '#fff',
|
|
||||||
borderWidth: 2,
|
|
||||||
shadowBlur: 10,
|
|
||||||
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tooltip: {
|
tooltip: {
|
||||||
show: true,
|
show: true,
|
||||||
trigger: 'item',
|
trigger: 'item',
|
||||||
@@ -238,6 +245,25 @@ const tableRef = ref()
|
|||||||
provide('tableRef', tableRef)
|
provide('tableRef', tableRef)
|
||||||
provide('tableStore', tableStore)
|
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) {
|
function gongfunction(arr: any) {
|
||||||
let standI = 0
|
let standI = 0
|
||||||
let unstandI = 0
|
let unstandI = 0
|
||||||
@@ -424,10 +450,10 @@ const handleTolerableEventClick = async (row: any) => {
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (waveFormAnalysisRef.value) {
|
if (waveFormAnalysisRef.value) {
|
||||||
//waveFormAnalysisRef.value.setHeight(false, 360)
|
//waveFormAnalysisRef.value.setHeight(false, 360)
|
||||||
waveFormAnalysisRef.value.setHeight(999, 130, 1.6666666)
|
// waveFormAnalysisRef.value.setHeight(999, 130, 1.6666666)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const messageInstance = ElMessage.info(`正在加载,请稍等...`)
|
const messageInstance = ElMessage.info(`正在加载,请稍等...`)
|
||||||
await analyseWave(row.value[3]) //eventId
|
await analyseWave(row.value[3]) //eventId
|
||||||
.then(res => {
|
.then(res => {
|
||||||
row.loading1 = false
|
row.loading1 = false
|
||||||
@@ -452,6 +478,7 @@ const handleTolerableEventClick = async (row: any) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
waveFormAnalysisRef.value && waveFormAnalysisRef.value.setHeight(999, 130, 1.6666666)
|
||||||
waveFormAnalysisRef.value && waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
|
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>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--暂降方向统计 -->
|
<!--暂降方向统计 -->
|
||||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
<TableHeader
|
||||||
<my-echart class="tall" :options="echartList" :style="{ width: prop.width, height: `calc(${prop.height} )` }" />
|
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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
|
||||||
import MyEchart from '@/components/echarts/MyEchart.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 TableHeader from '@/components/table/header/index.vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { getTime } from '@/utils/formatTime'
|
||||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
const route = useRoute()
|
const TableHeaderRef = ref()
|
||||||
const timeCacheStore = useTimeCacheStore()
|
|
||||||
|
|
||||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
headerHeight.value = height
|
headerHeight.value = height
|
||||||
@@ -53,85 +60,99 @@ const fullscreen = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const data = [
|
const echartList = ref({})
|
||||||
{
|
|
||||||
name: '来自电网',
|
|
||||||
value: 4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '来自负荷',
|
|
||||||
value: 41
|
|
||||||
}
|
|
||||||
]
|
|
||||||
const echartList = ref({
|
|
||||||
title: {},
|
|
||||||
|
|
||||||
tooltip: {
|
// const data = [
|
||||||
trigger: 'item'
|
// {
|
||||||
},
|
// name: '来自电网',
|
||||||
legend: {
|
// value: 4
|
||||||
orient: 'vertical',
|
// },
|
||||||
top: 'center',
|
// {
|
||||||
right: '5%',
|
// name: '来自负荷',
|
||||||
formatter: function (e: any) {
|
// value: 41
|
||||||
return e + ' ' + data.filter(item => item.name == e)[0].value + '次'
|
// }
|
||||||
}
|
// ]
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
show: false
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: '10px',
|
|
||||||
right: '20px'
|
|
||||||
},
|
|
||||||
|
|
||||||
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 OverLimitDetailsRef = ref()
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/user-boot/dept/deptTree',
|
url: '/cs-harmonic-boot/csevent/getEventDirectionData',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
||||||
showPage: false,
|
showPage: false,
|
||||||
|
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
},
|
},
|
||||||
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()
|
const tableRef = ref()
|
||||||
@@ -139,10 +160,28 @@ provide('tableRef', tableRef)
|
|||||||
|
|
||||||
provide('tableStore', tableStore)
|
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) => {
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
if (column.field != 'name') {
|
if (column.field != 'name') {
|
||||||
console.log(row)
|
|
||||||
OverLimitDetailsRef.value.open(row)
|
OverLimitDetailsRef.value.open(row)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,12 +198,7 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { yMethod } from '@/utils/echartMethod'
|
|||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object }
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -47,6 +47,7 @@ const init = () => {
|
|||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis',
|
trigger: 'axis',
|
||||||
formatter: (params: any) => {
|
formatter: (params: any) => {
|
||||||
|
console.log('🚀 ~ init ~ params:', params)
|
||||||
if (!params || params.length === 0) return ''
|
if (!params || params.length === 0) return ''
|
||||||
|
|
||||||
// 使用第一个项目的轴标签作为时间标题
|
// 使用第一个项目的轴标签作为时间标题
|
||||||
@@ -100,28 +101,33 @@ const initData = async (row: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理每条相位数据
|
// 处理每条相位数据
|
||||||
const seriesData = res.data.map((item: any) => {
|
const seriesData = res.data
|
||||||
const values = xAxisData.map((time: string, index: number) => {
|
.filter(item => item.valueType == 'max')
|
||||||
// 将传入的日期与时间拼接成完整的时间字符串
|
.sort((a, b) => {
|
||||||
const fullTime = `${row.time} ${time}`
|
return a.phasic.localeCompare(b.phasic)
|
||||||
const value = parseFloat(item.value.split(',')[index]) || 0
|
|
||||||
return [fullTime, value]
|
|
||||||
})
|
})
|
||||||
|
.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 {
|
return {
|
||||||
name: `${item.phasic}相`,
|
name: `${item.phasic}相`,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
showSymbol: false,
|
showSymbol: false,
|
||||||
smooth: true,
|
smooth: true,
|
||||||
data: values,
|
data: values,
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
normal: {
|
normal: {
|
||||||
// 根据相位设置对应颜色
|
// 根据相位设置对应颜色
|
||||||
color: phaseColors[item.phasic] || config.layout.elementUiPrimary[0]
|
color: phaseColors[item.phasic] || config.layout.elementUiPrimary[0]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
echartList.value.yAxis.max = max
|
echartList.value.yAxis.max = max
|
||||||
echartList.value.yAxis.min = min
|
echartList.value.yAxis.min = min
|
||||||
// 更新图表配置
|
// 更新图表配置
|
||||||
@@ -135,7 +141,7 @@ onMounted(() => {})
|
|||||||
const open = async (row: any) => {
|
const open = async (row: any) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
dialogTitle.value = row.name + '日趋势图'
|
dialogTitle.value = row.name + '日趋势图'
|
||||||
dialogText.value = `监测点名称:${row.lineName}_越限时间:${row.time}_指标名称:${row.name}`
|
dialogText.value = `监测点名称:${row.lineName} 越限时间:${row.time} 指标名称:${row.name}`
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
initData(row)
|
initData(row)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<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
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
@@ -25,18 +32,20 @@ import TableHeader from '@/components/table/header/index.vue'
|
|||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import DailyTrendChart from '@/components/cockpit/exceedanceLevel/components/dailyTrendChart.vue'
|
import DailyTrendChart from '@/components/cockpit/exceedanceLevel/components/dailyTrendChart.vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { getTime } from '@/utils/formatTime'
|
||||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const TableHeaderRef = ref()
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
const dialogTrendChart = ref(false)
|
const dialogTrendChart = ref(false)
|
||||||
@@ -89,7 +98,7 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
title: '越限最大值',
|
title: '越限最大值',
|
||||||
field: 'maxValue',
|
field: 'maxValue',
|
||||||
minWidth: '60',
|
minWidth: '70',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
const extentValue =
|
const extentValue =
|
||||||
@@ -107,51 +116,34 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
title: '越限程度(%)',
|
title: '越限程度(%)',
|
||||||
field: 'extent',
|
field: 'extent',
|
||||||
minWidth: '60',
|
minWidth: '70',
|
||||||
render: 'customTemplate',
|
formatter: (row: any) => {
|
||||||
customTemplate: (row: any) => {
|
return Math.floor(row.cellValue * 100) / 100
|
||||||
// 保留两个小数
|
|
||||||
const extentValue =
|
|
||||||
row.extent !== null && row.extent !== undefined && row.extent !== ''
|
|
||||||
? Math.floor(row.extent * 100) / 100
|
|
||||||
: '/'
|
|
||||||
return `<span>${extentValue}</span>`
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '越限时间',
|
title: '越限时间',
|
||||||
field: 'time',
|
field: 'time',
|
||||||
minWidth: '60',
|
minWidth: '60',
|
||||||
render: 'customTemplate',
|
formatter: (row: any) => {
|
||||||
customTemplate: (row: any) => {
|
return row.cellValue || '/'
|
||||||
if (row.time !== null && row.time !== undefined && row.time !== '') {
|
|
||||||
return `<span>${row.time}</span>`
|
|
||||||
} else {
|
|
||||||
return `<span>/</span>`
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '越限最高监测点',
|
title: '越限最高监测点',
|
||||||
field: 'lineName',
|
field: 'lineName',
|
||||||
minWidth: '90',
|
minWidth: '90',
|
||||||
render: 'customTemplate',
|
formatter: (row: any) => {
|
||||||
customTemplate: (row: any) => {
|
return row.cellValue || '/'
|
||||||
if (row.lineName !== null && row.lineName !== undefined && row.lineName !== '') {
|
|
||||||
return `<span>${row.lineName}</span>`
|
|
||||||
} else {
|
|
||||||
return `<span>/</span>`
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
// 定义 x 轴标签顺序
|
// 定义 x 轴标签顺序
|
||||||
const xAxisLabels = ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
const xAxisLabels = ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||||
|
|
||||||
// 根据指标名称顺序提取对应的 extent 数据
|
// 根据指标名称顺序提取对应的 extent 数据
|
||||||
const chartData = xAxisLabels.map(label => {
|
const chartData = xAxisLabels.map(label => {
|
||||||
@@ -200,6 +192,7 @@ provide('tableStore', tableStore)
|
|||||||
// 点击行
|
// 点击行
|
||||||
const cellClickEvent = ({ row, column }: any) => {
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
dialogTrendChart.value = true
|
dialogTrendChart.value = true
|
||||||
|
|
||||||
if (column.field == 'maxValue' && row.lineId) {
|
if (column.field == 'maxValue' && row.lineId) {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
dailyTrendChartRef.value.open(row)
|
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(() => {
|
onMounted(() => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
@@ -219,12 +231,7 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<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>
|
<template v-slot:select>
|
||||||
<el-form-item label="报表模板">
|
<el-form-item label="模板策略">
|
||||||
<el-select v-model="tableStore.table.params.tempId" placeholder="请选择报表模板" clearable>
|
<el-select filterable 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-option v-for="item in templateList" :key="item.id" :label="item.excelName" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="监测对象">
|
<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-option v-for="item in idList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:operation>
|
<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>
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<div style="display: flex">
|
<div style="display: flex">
|
||||||
@@ -34,19 +34,22 @@ import { ref, onMounted, provide, reactive, watch, h, computed, nextTick } from
|
|||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import { exportExcel } from '@/views/govern/reportForms/export.js'
|
import { exportExcel } from '@/views/govern/reportForms/export.js'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import { getTemplateList } from '@/api/harmonic-boot/luckyexcel'
|
import { querySysExcel } from '@/api/harmonic-boot/luckyexcel'
|
||||||
import { getListByIds } from '@/api/harmonic-boot/cockpit/cockpit'
|
import { getListByIds } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
import Json from './index.json'
|
import { getTime } from '@/utils/formatTime'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const TableHeaderRef = ref()
|
||||||
|
|
||||||
// 报表模板列表
|
// 报表模板列表
|
||||||
const templateList = ref()
|
const templateList = ref()
|
||||||
|
|
||||||
@@ -68,8 +71,8 @@ const initListByIds = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const templateListData = () => {
|
const templateListData = () => {
|
||||||
getTemplateList({}).then(res => {
|
querySysExcel({}).then(res => {
|
||||||
templateList.value = res.data
|
templateList.value = res.data.filter(item => item.excelType == 4)
|
||||||
if (!tableStore.table.params.tempId && templateList.value?.length > 0) {
|
if (!tableStore.table.params.tempId && templateList.value?.length > 0) {
|
||||||
tableStore.table.params.tempId = templateList.value[0].id
|
tableStore.table.params.tempId = templateList.value[0].id
|
||||||
}
|
}
|
||||||
@@ -114,14 +117,16 @@ const tableStore: any = new TableStore({
|
|||||||
exportName: '治理效果报表',
|
exportName: '治理效果报表',
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
// if (!tableStore.table.params.sensitiveUserId && idList.value?.length > 0) {
|
||||||
if (!tableStore.table.params.sensitiveUserId && idList.value?.length > 0) {
|
// tableStore.table.params.sensitiveUserId = idList.value[0].id
|
||||||
tableStore.table.params.sensitiveUserId = idList.value[0].id
|
// }
|
||||||
}
|
// if (!tableStore.table.params.tempId && templateList.value?.length > 0) {
|
||||||
if (!tableStore.table.params.tempId && templateList.value?.length > 0) {
|
// tableStore.table.params.tempId = templateList.value[0].id
|
||||||
tableStore.table.params.tempId = templateList.value[0].id
|
// }
|
||||||
}
|
// if( !tableStore.table.params.tempId){
|
||||||
|
// return ElMessage.warning('请选择模板')
|
||||||
|
// }
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
luckysheet.create({
|
luckysheet.create({
|
||||||
@@ -142,6 +147,27 @@ provide('tableRef', tableRef)
|
|||||||
|
|
||||||
provide('tableStore', tableStore)
|
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(
|
watch(
|
||||||
() => prop.timeKey,
|
() => prop.timeKey,
|
||||||
val => {
|
val => {
|
||||||
@@ -151,12 +177,7 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
v-model="searchForm.index"
|
v-model="searchForm.index"
|
||||||
placeholder="请选择统计指标"
|
placeholder="请选择统计指标"
|
||||||
@change="onIndexChange($event)"
|
@change="onIndexChange($event)"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in indexOptions"
|
v-for="item in indexOptions"
|
||||||
@@ -33,14 +34,15 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="统计类型">
|
<el-form-item label="统计类型">
|
||||||
<el-select
|
<el-select
|
||||||
style="min-width: 120px !important"
|
style="min-width: 90px !important"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
v-model="searchForm.valueType"
|
v-model="searchForm.valueType"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option value="max" label="最大值"></el-option>
|
<el-option value="max" label="最大值"></el-option>
|
||||||
<el-option value="min" label="最小值"></el-option>
|
<el-option value="min" label="最小值"></el-option>
|
||||||
<el-option value="avg" 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-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
@@ -59,11 +61,12 @@
|
|||||||
placeholder="请选择谐波次数"
|
placeholder="请选择谐波次数"
|
||||||
style="width: 100px"
|
style="width: 100px"
|
||||||
class="mr20"
|
class="mr20"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="vv in item.countOptions"
|
v-for="vv in item.countOptions"
|
||||||
:key="vv"
|
:key="vv"
|
||||||
:label="vv"
|
:label="item.name.includes('间谐波') ? vv - 0.5 : vv"
|
||||||
:value="vv"
|
:value="vv"
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -79,11 +82,7 @@
|
|||||||
</TableHeader>
|
</TableHeader>
|
||||||
</div>
|
</div>
|
||||||
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
||||||
<MyEchart
|
<MyEchart ref="historyChart" :options="echartsData" v-if="showEchart" />
|
||||||
ref="historyChart"
|
|
||||||
:options="echartsData"
|
|
||||||
v-if="showEchart"
|
|
||||||
/>
|
|
||||||
<el-empty :style="pageHeight" v-else description="暂无数据" />
|
<el-empty :style="pageHeight" v-else description="暂无数据" />
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -157,28 +156,40 @@ const countOptions: any = ref([])
|
|||||||
const legendDictList: any = ref([])
|
const legendDictList: any = ref([])
|
||||||
|
|
||||||
const initCode = (field: string, title: string) => {
|
const initCode = (field: string, title: string) => {
|
||||||
queryByCode('steady_state_limit_trend').then(res => {
|
queryByCode('gridSide_exceedTheLimit').then(res => {
|
||||||
queryCsDictTree(res.data.id).then(item => {
|
queryCsDictTree(res.data.id).then(item => {
|
||||||
//排序
|
//排序
|
||||||
indexOptions.value = item.data.sort((a: any, b: any) => {
|
indexOptions.value = item.data.sort((a: any, b: any) => {
|
||||||
return a.sort - b.sort
|
return a.sort - b.sort
|
||||||
})
|
})
|
||||||
const titleMap: Record<string, number> = {
|
let codeKey = field.includes('flickerOvertime')
|
||||||
flickerOvertime: 0,
|
? '闪变'
|
||||||
uaberranceOvertime: 3,
|
: field.includes('uharm')
|
||||||
ubalanceOvertime: 4,
|
? '谐波电压'
|
||||||
freqDevOvertime: 5
|
: 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) {
|
// let defaultIndex = 0 // 默认值
|
||||||
defaultIndex = titleMap[field]
|
let defaultIndex = indexOptions.value.findIndex((item: any) => item.name.includes(codeKey)) || 0
|
||||||
} else if (field.includes('uharm')) {
|
// if (field in titleMap) {
|
||||||
defaultIndex = 1
|
// defaultIndex = titleMap[field]
|
||||||
} else if (field.includes('iharm')) {
|
// } else if (field.includes('uharm')) {
|
||||||
defaultIndex = 2
|
// 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
|
searchForm.value.index[0] = indexOptions.value[defaultIndex].id
|
||||||
})
|
})
|
||||||
@@ -202,7 +213,7 @@ const initCode = (field: string, title: string) => {
|
|||||||
if (kk.harmStart && kk.harmEnd) {
|
if (kk.harmStart && kk.harmEnd) {
|
||||||
range(0, 0, 0)
|
range(0, 0, 0)
|
||||||
|
|
||||||
if (kk.showName == '间谐波电压含有率') {
|
if (kk.showName.includes('间谐波电压')) {
|
||||||
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1).map(
|
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1).map(
|
||||||
(item: any) => {
|
(item: any) => {
|
||||||
return item - 0.5
|
return item - 0.5
|
||||||
@@ -284,14 +295,15 @@ const init = async () => {
|
|||||||
let lists: any = []
|
let lists: any = []
|
||||||
let frequencys: any = null
|
let frequencys: any = null
|
||||||
countData.value.map((item: any, index: any) => {
|
countData.value.map((item: any, index: any) => {
|
||||||
if (item.name.includes('谐波含有率')) {
|
if (item.name.includes('谐波')) {
|
||||||
frequencys = item.count
|
frequencys = item.count
|
||||||
} else {
|
} else {
|
||||||
frequencys = ''
|
frequencys = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
lists[index] = {
|
lists[index] = {
|
||||||
statisticalId: item.index,
|
statisticalId: item.index,
|
||||||
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
let obj = {
|
let obj = {
|
||||||
@@ -597,12 +609,12 @@ const formatCountOptions = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
countData.value.map((item: any, key: any) => {
|
countData.value.map((item: any, key: any) => {
|
||||||
if (item.name == '谐波电流有效值') {
|
if (item.name.includes('间谐波电压')) {
|
||||||
item.name = '谐波电流次数'
|
|
||||||
} else if (item.name == '谐波电压含有率') {
|
|
||||||
item.name = '谐波电压次数'
|
|
||||||
} else if (item.name == '间谐波电压含有率') {
|
|
||||||
item.name = '间谐波电压次数'
|
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"
|
v-model="tableStore.table.params.lineId"
|
||||||
placeholder="请选择监测点"
|
placeholder="请选择监测点"
|
||||||
style="width: 150px"
|
style="width: 150px"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in options"
|
v-for="item in options"
|
||||||
:key="item.lineId"
|
:key="item.lineId"
|
||||||
:label="item.name"
|
:label="item.lineName"
|
||||||
:value="item.lineId"
|
:value="item.lineId"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -48,7 +49,7 @@ const loop50 = (key: string) => {
|
|||||||
list.push({
|
list.push({
|
||||||
title: i + '次',
|
title: i + '次',
|
||||||
field: key + i + 'Overtime',
|
field: key + i + 'Overtime',
|
||||||
width: '80',
|
width: '60',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||||
@@ -84,9 +85,9 @@ const tableStore: any = new TableStore({
|
|||||||
width: '150'
|
width: '150'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '闪变越限(%)',
|
title: '长时闪变越限(%)',
|
||||||
field: 'flickerOvertime',
|
field: 'flickerOvertime',
|
||||||
width: '80',
|
width: '90',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||||
@@ -100,16 +101,7 @@ const tableStore: any = new TableStore({
|
|||||||
title: '谐波电流越限(%)',
|
title: '谐波电流越限(%)',
|
||||||
children: loop50('iharm')
|
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: '电压偏差越限(%)',
|
title: '电压偏差越限(%)',
|
||||||
field: 'voltageDevOvertime',
|
field: 'voltageDevOvertime',
|
||||||
width: '100',
|
width: '100',
|
||||||
@@ -119,14 +111,24 @@ const tableStore: any = new TableStore({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '频率偏差越限(%)',
|
title: '三相不平衡度越限(%)',
|
||||||
field: 'freqDevOvertime',
|
field: 'ubalanceOvertime',
|
||||||
width: '100',
|
width: '100',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
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: () => {
|
beforeSearchFun: () => {
|
||||||
},
|
},
|
||||||
@@ -138,16 +140,20 @@ const tableStore: any = new TableStore({
|
|||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
tableStore.table.params.sortBy = ''
|
tableStore.table.params.sortBy = ''
|
||||||
tableStore.table.params.orderBy = ''
|
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
|
dialogVisible.value = true
|
||||||
initCSlineList()
|
options.value = list
|
||||||
|
// initCSlineList()
|
||||||
tableStore.table.params.lineId = row.lineId
|
tableStore.table.params.lineId = row.lineId
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
tableHeaderRef.value.setTimeInterval([searchBeginTime, searchEndTime])
|
tableHeaderRef.value.setInterval(interval)
|
||||||
|
setTimeout(() => {
|
||||||
|
tableHeaderRef.value.setTimeInterval([searchBeginTime, searchEndTime])
|
||||||
tableStore.table.params.searchBeginTime =searchBeginTime
|
tableStore.table.params.searchBeginTime =searchBeginTime
|
||||||
tableStore.table.params.searchEndTime = searchEndTime
|
tableStore.table.params.searchEndTime = searchEndTime
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
|
},100)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<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
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
@@ -27,23 +34,25 @@ import Table from '@/components/table/index.vue'
|
|||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import OverLimitDetails from '@/components/cockpit/gridSideStatistics/components/overLimitDetails.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 { gridSideLimitStatisticsData } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
import { getTime } from '@/utils/formatTime'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
const echartList = ref({})
|
const echartList = ref({})
|
||||||
|
|
||||||
|
const TableHeaderRef = ref()
|
||||||
|
|
||||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
headerHeight.value = height
|
headerHeight.value = height
|
||||||
|
|
||||||
@@ -79,7 +88,7 @@ const initEcharts = () => {
|
|||||||
|
|
||||||
xAxis: {
|
xAxis: {
|
||||||
// name: '(区域)',
|
// name: '(区域)',
|
||||||
data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
data: ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||||
},
|
},
|
||||||
|
|
||||||
yAxis: {
|
yAxis: {
|
||||||
@@ -140,7 +149,7 @@ const tableStore: any = new TableStore({
|
|||||||
title: '越限占比(%)',
|
title: '越限占比(%)',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
title: '闪变',
|
title: '长时闪变',
|
||||||
field: 'flicker',
|
field: 'flicker',
|
||||||
minWidth: '70',
|
minWidth: '70',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
@@ -188,8 +197,8 @@ const tableStore: any = new TableStore({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
tableStore.table.params.interval = TableHeaderRef.value?.datePickerRef?.interval || 3
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||||
@@ -204,18 +213,37 @@ provide('tableStore', tableStore)
|
|||||||
|
|
||||||
// 点击行
|
// 点击行
|
||||||
const cellClickEvent = ({ row, column }: any) => {
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
if (column.field != 'name') {
|
OverLimitDetailsRef.value.open(
|
||||||
OverLimitDetailsRef.value.open(
|
row,
|
||||||
row,
|
tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
||||||
tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
tableStore.table.params.searchEndTime || prop.timeValue?.[1],
|
||||||
tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
tableStore.table.params.interval || prop.interval,
|
||||||
)
|
tableStore.table.data
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tableStore.index()
|
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(
|
watch(
|
||||||
() => prop.timeKey,
|
() => prop.timeKey,
|
||||||
val => {
|
val => {
|
||||||
@@ -226,12 +254,7 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
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>
|
||||||
@@ -5,10 +5,9 @@
|
|||||||
:showReset="false"
|
:showReset="false"
|
||||||
ref="TableHeaderRef"
|
ref="TableHeaderRef"
|
||||||
@selectChange="selectChange"
|
@selectChange="selectChange"
|
||||||
datePicker
|
datePicker
|
||||||
v-if="fullscreen"
|
v-if="fullscreen"
|
||||||
:timeCacheFlag="false"
|
:timeKeyList="prop.timeKey"
|
||||||
:timeKeyList="['3']"
|
|
||||||
></TableHeader>
|
></TableHeader>
|
||||||
<el-calendar
|
<el-calendar
|
||||||
v-model="value"
|
v-model="value"
|
||||||
@@ -33,7 +32,7 @@
|
|||||||
<template #content>
|
<template #content>
|
||||||
<span v-html="getTextForDate(data.day)"></span>
|
<span v-html="getTextForDate(data.day)"></span>
|
||||||
</template>
|
</template>
|
||||||
<div class="details" v-html="getTextForDate(data.day)"></div>
|
<div class="details" v-html="fullscreen ? getTextForDate(data.day) : '有越限'"></div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -52,7 +51,7 @@ const prop = defineProps({
|
|||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object },
|
timeValue: { type: Object },
|
||||||
interval: { type: Number }
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
@@ -98,22 +97,8 @@ const tableStore: any = new TableStore({
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
showPage: false,
|
showPage: false,
|
||||||
column: [],
|
column: [],
|
||||||
// beforeSearchFun: () => {
|
|
||||||
// if (!fullscreen.value && prop.timeValue && Array.isArray(prop.timeValue)) {
|
|
||||||
// tableStore.table.params.searchBeginTime = prop.timeValue[0]
|
|
||||||
// tableStore.table.params.searchEndTime = prop.timeValue[1]
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
const time = getTime(
|
setTime()
|
||||||
prop.interval ?? 0,
|
|
||||||
prop.timeKey,
|
|
||||||
tableStore.table.params.searchBeginTime && tableStore.table.params.searchEndTime
|
|
||||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
|
||||||
: prop.timeValue
|
|
||||||
)
|
|
||||||
tableStore.table.params.searchBeginTime = time[0]
|
|
||||||
tableStore.table.params.searchEndTime = time[1]
|
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
value.value = tableStore.table.params.searchBeginTime
|
value.value = tableStore.table.params.searchBeginTime
|
||||||
@@ -158,43 +143,33 @@ provide('tableStore', tableStore)
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// if (TableHeaderRef.value && typeof TableHeaderRef.value.setDatePicker === 'function') {
|
|
||||||
// TableHeaderRef.value.setDatePicker([{ label: '月份', value: 3 }])
|
|
||||||
// }
|
|
||||||
if (fullscreen.value) {
|
|
||||||
if (prop.interval == 3) {
|
|
||||||
const time = getTime(
|
|
||||||
prop.interval ?? 0,
|
|
||||||
prop.timeKey,
|
|
||||||
tableStore.table.params.searchBeginTime && tableStore.table.params.searchEndTime
|
|
||||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
|
||||||
: prop.timeValue
|
|
||||||
)
|
|
||||||
tableStore.table.params.searchBeginTime = time[0]
|
|
||||||
tableStore.table.params.searchEndTime = time[1]
|
|
||||||
TableHeaderRef.value.setTimeInterval(prop.timeValue)
|
|
||||||
} else {
|
|
||||||
TableHeaderRef.value.setInterval(3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
watch(
|
|
||||||
() => prop.timeKey,
|
const setTime = () => {
|
||||||
val => {
|
const time = getTime(
|
||||||
tableStore.index()
|
(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(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<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>
|
<template v-slot:select>
|
||||||
<el-form-item label="监测点">
|
<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
|
<el-option
|
||||||
v-for="item in lineList"
|
v-for="item in lineList"
|
||||||
:key="item.lineId"
|
:key="item.lineId"
|
||||||
@@ -17,21 +24,30 @@
|
|||||||
</TableHeader>
|
</TableHeader>
|
||||||
<div v-loading="tableStore.table.loading">
|
<div v-loading="tableStore.table.loading">
|
||||||
<my-echart
|
<my-echart
|
||||||
|
v-if="lineShow"
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{
|
:style="{
|
||||||
width: prop.width,
|
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"
|
class="mt10"
|
||||||
:options="echartList1"
|
:options="echartList1"
|
||||||
:style="{
|
:style="{
|
||||||
width: prop.width,
|
width: prop.width,
|
||||||
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||||
}"
|
}"
|
||||||
/>
|
/> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -41,22 +57,26 @@ import TableStore from '@/utils/tableStore'
|
|||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { limitProbabilityData, cslineList } from '@/api/harmonic-boot/cockpit/cockpit'
|
import { limitProbabilityData, cslineList } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
import { getTime } from '@/utils/formatTime'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
const lineShow = ref(true)
|
||||||
// const options = ref(JSON.parse(window.localStorage.getItem('lineIdList') || '[]'))
|
// const options = ref(JSON.parse(window.localStorage.getItem('lineIdList') || '[]'))
|
||||||
|
|
||||||
const lineList = ref()
|
const lineList = ref()
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const TableHeaderRef = ref()
|
||||||
|
|
||||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
headerHeight.value = height
|
headerHeight.value = height
|
||||||
|
|
||||||
@@ -87,6 +107,11 @@ const probabilityData = ref()
|
|||||||
|
|
||||||
const initLineList = async () => {
|
const initLineList = async () => {
|
||||||
cslineList({}).then(res => {
|
cslineList({}).then(res => {
|
||||||
|
if (res.data.length == 0) {
|
||||||
|
lineShow.value = false
|
||||||
|
return (tableStore.table.loading = false)
|
||||||
|
}
|
||||||
|
lineShow.value = true
|
||||||
lineList.value = res.data
|
lineList.value = res.data
|
||||||
tableStore.table.params.lineId = lineList.value[0].lineId
|
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
@@ -110,7 +135,7 @@ const initProbabilityData = () => {
|
|||||||
// 处理接口返回的数据,转换为图表所需格式
|
// 处理接口返回的数据,转换为图表所需格式
|
||||||
if (res.data && Array.isArray(res.data)) {
|
if (res.data && Array.isArray(res.data)) {
|
||||||
// 定义指标类型顺序
|
// 定义指标类型顺序
|
||||||
const indicatorOrder = ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相电压不平衡度', '频率偏差']
|
const indicatorOrder = ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相电压不平衡度', '频率偏差']
|
||||||
// 按照指定顺序排序数据
|
// 按照指定顺序排序数据
|
||||||
const sortedData = [...res.data].sort((a, b) => {
|
const sortedData = [...res.data].sort((a, b) => {
|
||||||
return indicatorOrder.indexOf(a.indexName) - indicatorOrder.indexOf(b.indexName)
|
return indicatorOrder.indexOf(a.indexName) - indicatorOrder.indexOf(b.indexName)
|
||||||
@@ -141,6 +166,9 @@ const initProbabilityData = () => {
|
|||||||
const yAxisData = sortedData.map(item => item.indexName)
|
const yAxisData = sortedData.map(item => item.indexName)
|
||||||
|
|
||||||
echartList.value = {
|
echartList.value = {
|
||||||
|
title: {
|
||||||
|
text: '指标越限概率分布'
|
||||||
|
},
|
||||||
options: {
|
options: {
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@@ -161,14 +189,7 @@ const initProbabilityData = () => {
|
|||||||
return tips
|
return tips
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
title: {
|
|
||||||
text: '指标越限概率分布',
|
|
||||||
x: 'center',
|
|
||||||
textStyle: {
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: 'normal'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// 移除或隐藏 visualMap 组件
|
// 移除或隐藏 visualMap 组件
|
||||||
visualMap: {
|
visualMap: {
|
||||||
show: false, // 设置为 false 隐藏右侧颜色条
|
show: false, // 设置为 false 隐藏右侧颜色条
|
||||||
@@ -187,9 +208,8 @@ const initProbabilityData = () => {
|
|||||||
type: 'category',
|
type: 'category',
|
||||||
name: '越限程度',
|
name: '越限程度',
|
||||||
nameLocation: 'middle',
|
nameLocation: 'middle',
|
||||||
nameGap: 50,
|
nameGap: 50,
|
||||||
data: ['0-20%', '20-40%', '40-60%', '60-80%', '80-100%'],
|
data: ['0-20%', '20-40%', '40-60%', '60-80%', '80-100%']
|
||||||
|
|
||||||
},
|
},
|
||||||
yAxis3D: {
|
yAxis3D: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
@@ -197,7 +217,7 @@ const initProbabilityData = () => {
|
|||||||
nameLocation: 'middle',
|
nameLocation: 'middle',
|
||||||
nameGap: 50,
|
nameGap: 50,
|
||||||
data: yAxisData,
|
data: yAxisData,
|
||||||
|
|
||||||
splitLine: {
|
splitLine: {
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
type: 'dashed',
|
type: 'dashed',
|
||||||
@@ -210,14 +230,14 @@ const initProbabilityData = () => {
|
|||||||
name: '越限次数',
|
name: '越限次数',
|
||||||
nameLocation: 'middle',
|
nameLocation: 'middle',
|
||||||
nameGap: 30,
|
nameGap: 30,
|
||||||
minInterval: 10,
|
minInterval: 10
|
||||||
|
|
||||||
// max: 100
|
// max: 100
|
||||||
},
|
},
|
||||||
grid3D: {
|
grid3D: {
|
||||||
viewControl: {
|
viewControl: {
|
||||||
projection: 'perspective',
|
projection: 'perspective',
|
||||||
distance: 250,
|
distance: 260,
|
||||||
rotateSensitivity: 10,
|
rotateSensitivity: 10,
|
||||||
zoomSensitivity: 2
|
zoomSensitivity: 2
|
||||||
},
|
},
|
||||||
@@ -367,8 +387,7 @@ const tableStore: any = new TableStore({
|
|||||||
showPage: false,
|
showPage: false,
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
// 只有当 lineList 已加载且有数据时才设置默认 lineId
|
// 只有当 lineList 已加载且有数据时才设置默认 lineId
|
||||||
if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) {
|
if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) {
|
||||||
tableStore.table.params.lineId = lineList.value[0].lineId
|
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||||
@@ -392,7 +411,7 @@ const tableStore: any = new TableStore({
|
|||||||
|
|
||||||
echartList1.value = {
|
echartList1.value = {
|
||||||
title: {
|
title: {
|
||||||
text: '越限时间概率分布'
|
text: '指标越限时间概率分布'
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis'
|
trigger: 'axis'
|
||||||
@@ -420,6 +439,25 @@ provide('tableStore', tableStore)
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
initLineList()
|
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(
|
watch(
|
||||||
() => prop.timeKey,
|
() => prop.timeKey,
|
||||||
val => {
|
val => {
|
||||||
@@ -429,12 +467,7 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
v-model="searchForm.index"
|
v-model="searchForm.index"
|
||||||
placeholder="请选择统计指标"
|
placeholder="请选择统计指标"
|
||||||
@change="onIndexChange($event)"
|
@change="onIndexChange($event)"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in indexOptions"
|
v-for="item in indexOptions"
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
style="min-width: 120px !important"
|
style="min-width: 120px !important"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
v-model="searchForm.valueType"
|
v-model="searchForm.valueType"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option value="max" label="最大值"></el-option>
|
<el-option value="max" label="最大值"></el-option>
|
||||||
<el-option value="min" label="最小值"></el-option>
|
<el-option value="min" label="最小值"></el-option>
|
||||||
@@ -59,11 +61,12 @@
|
|||||||
placeholder="请选择谐波次数"
|
placeholder="请选择谐波次数"
|
||||||
style="width: 100px"
|
style="width: 100px"
|
||||||
class="mr20"
|
class="mr20"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="vv in item.countOptions"
|
v-for="vv in item.countOptions"
|
||||||
:key="vv"
|
:key="vv"
|
||||||
:label="vv"
|
:label="item.name.includes('间谐波') ? vv - 0.5 : vv"
|
||||||
:value="vv"
|
:value="vv"
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -78,12 +81,8 @@
|
|||||||
</template>
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
</div>
|
</div>
|
||||||
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
||||||
<MyEchart
|
<MyEchart ref="historyChart" :options="echartsData" v-if="showEchart" />
|
||||||
ref="historyChart"
|
|
||||||
:options="echartsData"
|
|
||||||
v-if="showEchart"
|
|
||||||
/>
|
|
||||||
<el-empty :style="pageHeight" v-else description="暂无数据" />
|
<el-empty :style="pageHeight" v-else description="暂无数据" />
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -157,28 +156,40 @@ const countOptions: any = ref([])
|
|||||||
const legendDictList: any = ref([])
|
const legendDictList: any = ref([])
|
||||||
|
|
||||||
const initCode = (field: string, title: string) => {
|
const initCode = (field: string, title: string) => {
|
||||||
queryByCode('steady_state_limit_trend').then(res => {
|
queryByCode('gridSide_exceedTheLimit').then(res => {
|
||||||
queryCsDictTree(res.data.id).then(item => {
|
queryCsDictTree(res.data.id).then(item => {
|
||||||
//排序
|
//排序
|
||||||
indexOptions.value = item.data.sort((a: any, b: any) => {
|
indexOptions.value = item.data.sort((a: any, b: any) => {
|
||||||
return a.sort - b.sort
|
return a.sort - b.sort
|
||||||
})
|
})
|
||||||
const titleMap: Record<string, number> = {
|
// const titleMap: Record<string, number> = {
|
||||||
flickerOvertime: 0,
|
// flickerOvertime: 0,
|
||||||
uaberranceOvertime: 3,
|
// uaberranceOvertime: 3,
|
||||||
ubalanceOvertime: 4,
|
// ubalanceOvertime: 4,
|
||||||
freqDevOvertime: 5
|
// freqDevOvertime: 5
|
||||||
}
|
// }
|
||||||
|
|
||||||
let defaultIndex = 0 // 默认值
|
// let defaultIndex = 0 // 默认值
|
||||||
|
|
||||||
if (field in titleMap) {
|
// if (field in titleMap) {
|
||||||
defaultIndex = titleMap[field]
|
// defaultIndex = titleMap[field]
|
||||||
} else if (field.includes('uharm')) {
|
// } else if (field.includes('uharm')) {
|
||||||
defaultIndex = 1
|
// defaultIndex = 1
|
||||||
} else if (field.includes('iharm')) {
|
// } else if (field.includes('iharm')) {
|
||||||
defaultIndex = 2
|
// 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
|
searchForm.value.index[0] = indexOptions.value[defaultIndex].id
|
||||||
})
|
})
|
||||||
@@ -291,7 +302,7 @@ const init = async () => {
|
|||||||
}
|
}
|
||||||
lists[index] = {
|
lists[index] = {
|
||||||
statisticalId: item.index,
|
statisticalId: item.index,
|
||||||
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
let obj = {
|
let obj = {
|
||||||
@@ -576,7 +587,6 @@ const setTimeControl = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const selectChange = (flag: boolean, height: any) => {
|
const selectChange = (flag: boolean, height: any) => {
|
||||||
|
|
||||||
pageHeight.value = mainHeight(height * 1.6, 1.6)
|
pageHeight.value = mainHeight(height * 1.6, 1.6)
|
||||||
}
|
}
|
||||||
//导出
|
//导出
|
||||||
|
|||||||
@@ -9,11 +9,12 @@
|
|||||||
v-model="tableStore.table.params.lineId"
|
v-model="tableStore.table.params.lineId"
|
||||||
placeholder="请选择监测点"
|
placeholder="请选择监测点"
|
||||||
style="width: 150px"
|
style="width: 150px"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in options"
|
v-for="item in options"
|
||||||
:key="item.lineId"
|
:key="item.lineId"
|
||||||
:label="item.name"
|
:label="item.lineName"
|
||||||
:value="item.lineId"
|
:value="item.lineId"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -23,11 +24,7 @@
|
|||||||
<Table ref="tableRef" @cell-click="cellClickEvent" isGroup :height="height"></Table>
|
<Table ref="tableRef" @cell-click="cellClickEvent" isGroup :height="height"></Table>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<!-- 谐波电流、谐波电压占有率 -->
|
<!-- 谐波电流、谐波电压占有率 -->
|
||||||
<HarmonicRatio
|
<HarmonicRatio ref="harmonicRatioRef" @close="onHarmonicRatioClose" v-if="dialogFlag" />
|
||||||
ref="harmonicRatioRef"
|
|
||||||
@close="onHarmonicRatioClose"
|
|
||||||
v-if="dialogFlag"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -53,7 +50,7 @@ const loop50 = (key: string) => {
|
|||||||
list.push({
|
list.push({
|
||||||
title: i + '次',
|
title: i + '次',
|
||||||
field: key + i + 'Overtime',
|
field: key + i + 'Overtime',
|
||||||
width: '80',
|
width: '60',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||||
@@ -89,9 +86,9 @@ const tableStore: any = new TableStore({
|
|||||||
width: '150'
|
width: '150'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '闪变越限(分钟)',
|
title: '越限(分钟)',
|
||||||
field: 'flickerOvertime',
|
field: 'flickerOvertime',
|
||||||
width: '80',
|
width: '90',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||||
@@ -104,6 +101,14 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
title: '谐波电流越限(分钟)',
|
title: '谐波电流越限(分钟)',
|
||||||
children: loop50('iharm')
|
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: '三相不平衡度越限(分钟)',
|
title: '三相不平衡度越限(分钟)',
|
||||||
@@ -114,24 +119,16 @@ const tableStore: any = new TableStore({
|
|||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.ubalanceOvertime}</span>`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: '电压偏差越限(分钟)',
|
// {
|
||||||
field: 'uaberranceOvertime',
|
// title: '频率偏差越限(分钟)',
|
||||||
width: '100',
|
// field: 'freqDevOvertime',
|
||||||
render: 'customTemplate',
|
// width: '100',
|
||||||
customTemplate: (row: any) => {
|
// render: 'customTemplate',
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.uaberranceOvertime}</span>`
|
// 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: () => {
|
beforeSearchFun: () => {
|
||||||
},
|
},
|
||||||
@@ -143,9 +140,10 @@ const tableStore: any = new TableStore({
|
|||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
tableStore.table.params.sortBy = ''
|
tableStore.table.params.sortBy = ''
|
||||||
tableStore.table.params.orderBy = ''
|
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
|
dialogVisible.value = true
|
||||||
initCSlineList()
|
// initCSlineList()
|
||||||
|
options.value = data
|
||||||
tableStore.table.params.lineId = row.lineId
|
tableStore.table.params.lineId = row.lineId
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@@ -179,8 +177,8 @@ const onHarmonicRatioClose = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const initCSlineList = async () => {
|
const initCSlineList = async () => {
|
||||||
const res = await cslineList({})
|
// const res = await cslineList({})
|
||||||
options.value = res.data
|
// options.value = res.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<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>
|
<template v-slot:select>
|
||||||
<el-form-item label="关键词">
|
<el-form-item label="关键字筛选">
|
||||||
<el-input v-model="tableStore.table.params.keywords" clearable placeholder="请输关键字" />
|
<el-input v-model="tableStore.table.params.keywords" clearable placeholder="请输入监测点名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
@@ -22,7 +29,7 @@ import { ref, onMounted, provide, reactive, watch, nextTick } from 'vue'
|
|||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import { getTime } from '@/utils/formatTime'
|
import { getTimeOfTheMonth } from '@/utils/formatTime'
|
||||||
import OverLimitDetails from '@/components/cockpit/indicatorFittingChart/components/overLimitDetails.vue'
|
import OverLimitDetails from '@/components/cockpit/indicatorFittingChart/components/overLimitDetails.vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
@@ -32,7 +39,7 @@ const prop = defineProps({
|
|||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object },
|
timeValue: { type: Object },
|
||||||
interval: { type: Number }
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
@@ -42,7 +49,7 @@ const headerHeight = ref(57)
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const timeCacheStore = useTimeCacheStore()
|
const timeCacheStore = useTimeCacheStore()
|
||||||
|
|
||||||
const tableHeaderRef = ref()
|
const TableHeaderRef = ref()
|
||||||
|
|
||||||
// 计算是否全屏展示
|
// 计算是否全屏展示
|
||||||
const fullscreen = computed(() => {
|
const fullscreen = computed(() => {
|
||||||
@@ -59,11 +66,11 @@ const fullscreen = computed(() => {
|
|||||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
headerHeight.value = height
|
headerHeight.value = height
|
||||||
|
|
||||||
if (datePickerValue && datePickerValue.timeValue) {
|
// if (datePickerValue && datePickerValue.timeValue) {
|
||||||
// 更新时间参数
|
// // 更新时间参数
|
||||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
// tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
// tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
@@ -93,29 +100,24 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
title: '监测对象类型',
|
title: '监测对象类型',
|
||||||
field: 'objType',
|
field: 'objType',
|
||||||
minWidth: '90'
|
minWidth: '90',
|
||||||
|
formatter: (row: any) => {
|
||||||
|
return row.cellValue || '/'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '是否治理',
|
title: '是否治理',
|
||||||
field: 'govern',
|
field: 'govern',
|
||||||
minWidth: '70'
|
minWidth: '80',
|
||||||
|
formatter: (row: any) => {
|
||||||
|
return row.cellValue || '/'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{ title: '主要存在的电能质量问题', field: 'problems', minWidth: '150', showOverflow: true }
|
{ title: '主要存在的电能质量问题', field: 'problems', minWidth: '150', showOverflow: true }
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
// tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
// tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
|
|
||||||
const time = getTime(
|
|
||||||
prop.interval ?? 0,
|
|
||||||
prop.timeKey,
|
|
||||||
tableStore.table.params.searchBeginTime && tableStore.table.params.searchEndTime
|
|
||||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
|
||||||
: prop.timeValue
|
|
||||||
)
|
|
||||||
tableStore.table.params.searchBeginTime = time[0]
|
|
||||||
tableStore.table.params.searchEndTime = time[1]
|
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||||
@@ -130,33 +132,45 @@ provide('tableStore', tableStore)
|
|||||||
// 点击行
|
// 点击行
|
||||||
const cellClickEvent = ({ row, column }: any) => {
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
if (column.field == 'lineName') {
|
if (column.field == 'lineName') {
|
||||||
|
|
||||||
|
let time = getTimeOfTheMonth('3');
|
||||||
OverLimitDetailsRef.value.open(
|
OverLimitDetailsRef.value.open(
|
||||||
row,
|
row,
|
||||||
tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
time[0],
|
||||||
tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
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
|
// 在组件挂载时设置缓存值到 DatePicker
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
watch(
|
|
||||||
() => prop.timeKey,
|
|
||||||
val => {
|
|
||||||
tableStore.index()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ const tableStore: any = new TableStore({
|
|||||||
width: '150'
|
width: '150'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '闪变越限(分钟)',
|
title: '长时闪变越限(分钟)',
|
||||||
field: 'flicker',
|
field: 'flicker',
|
||||||
width: '80'
|
width: '80'
|
||||||
},
|
},
|
||||||
@@ -99,26 +99,7 @@ const tableStore: any = new TableStore({
|
|||||||
],
|
],
|
||||||
beforeSearchFun: () => {},
|
beforeSearchFun: () => {},
|
||||||
loadCallback: () => {
|
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'
|
width: '150'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '闪变越限(分钟)',
|
title: '长时闪变越限(分钟)',
|
||||||
field: 'flicker',
|
field: 'flicker',
|
||||||
width: '80',
|
width: '80',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
@selectChange="selectChange"
|
@selectChange="selectChange"
|
||||||
v-if="fullscreen"
|
v-if="fullscreen"
|
||||||
ref="TableHeaderRef"
|
ref="TableHeaderRef"
|
||||||
:timeKeyList="['4', '5']"
|
:timeKeyList="prop.timeKey"
|
||||||
>
|
>
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="监测点">
|
<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
|
<el-option
|
||||||
v-for="item in lineList"
|
v-for="item in lineList"
|
||||||
:key="item.lineId"
|
:key="item.lineId"
|
||||||
@@ -20,7 +20,12 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="用户功率">
|
<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-option v-for="item in powerList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -29,6 +34,7 @@
|
|||||||
style="min-width: 120px !important"
|
style="min-width: 120px !important"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
v-model="tableStore.table.params.valueType"
|
v-model="tableStore.table.params.valueType"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option value="max" label="最大值"></el-option>
|
<el-option value="max" label="最大值"></el-option>
|
||||||
<el-option value="min" label="最小值"></el-option>
|
<el-option value="min" label="最小值"></el-option>
|
||||||
@@ -37,7 +43,12 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="电能质量指标">
|
<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-option v-for="item in indicatorList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -48,6 +59,7 @@
|
|||||||
v-model="tableStore.table.params.harmonicCount"
|
v-model="tableStore.table.params.harmonicCount"
|
||||||
placeholder="请选择谐波次数"
|
placeholder="请选择谐波次数"
|
||||||
style="min-width: 80px !important"
|
style="min-width: 80px !important"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="num in harmonicCountOptions"
|
v-for="num in harmonicCountOptions"
|
||||||
@@ -63,12 +75,21 @@
|
|||||||
<div v-loading="tableStore.table.loading">
|
<div v-loading="tableStore.table.loading">
|
||||||
<my-echart
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
|
v-if="lineShow"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{
|
:style="{
|
||||||
width: prop.width,
|
width: prop.width,
|
||||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px )`
|
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)`
|
||||||
|
}"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -88,7 +109,7 @@ const prop = defineProps({
|
|||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object },
|
timeValue: { type: Object },
|
||||||
interval: { type: Number }
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
@@ -101,10 +122,8 @@ const lineList: any = ref()
|
|||||||
|
|
||||||
const powerList: any = ref()
|
const powerList: any = ref()
|
||||||
|
|
||||||
const countData: any = ref([])
|
|
||||||
|
|
||||||
const chartsList = ref<any>([])
|
const chartsList = ref<any>([])
|
||||||
|
const lineShow = ref(true)
|
||||||
// 计算是否全屏展示
|
// 计算是否全屏展示
|
||||||
const fullscreen = computed(() => {
|
const fullscreen = computed(() => {
|
||||||
const w = Number(prop.w)
|
const w = Number(prop.w)
|
||||||
@@ -131,8 +150,14 @@ const indicatorList = ref()
|
|||||||
|
|
||||||
const initLineList = async () => {
|
const initLineList = async () => {
|
||||||
cslineList({}).then(res => {
|
cslineList({}).then(res => {
|
||||||
|
if (res.data.length == 0) {
|
||||||
|
lineShow.value = false
|
||||||
|
return (tableStore.table.loading = false)
|
||||||
|
}
|
||||||
|
lineShow.value = true
|
||||||
lineList.value = res.data
|
lineList.value = res.data
|
||||||
tableStore.table.params.lineId = lineList.value[0].lineId
|
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||||
|
initCode()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +166,6 @@ const echartList = ref()
|
|||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
headerHeight.value = height
|
headerHeight.value = height
|
||||||
|
|
||||||
if (datePickerValue && datePickerValue.timeValue) {
|
if (datePickerValue && datePickerValue.timeValue) {
|
||||||
// 更新时间参数
|
// 更新时间参数
|
||||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
@@ -159,6 +183,30 @@ const setEchart = () => {
|
|||||||
title: {
|
title: {
|
||||||
text: `${indicatorName}与${powerName}负荷曲线拟合图`
|
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: {
|
xAxis: {
|
||||||
type: 'time',
|
type: 'time',
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
@@ -169,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: {
|
grid: {
|
||||||
left: '10px',
|
left: '10px',
|
||||||
right: '20px'
|
right: '20px'
|
||||||
@@ -196,6 +262,7 @@ const setEchart = () => {
|
|||||||
{
|
{
|
||||||
name: indicatorName, // 动态设置指标名称
|
name: indicatorName, // 动态设置指标名称
|
||||||
type: 'line',
|
type: 'line',
|
||||||
|
step: 'end',
|
||||||
showSymbol: false,
|
showSymbol: false,
|
||||||
// smooth: true,
|
// smooth: true,
|
||||||
data: [],
|
data: [],
|
||||||
@@ -225,7 +292,8 @@ const setEchart = () => {
|
|||||||
item.time,
|
item.time,
|
||||||
item.statisticalData !== null && item.statisticalData !== undefined
|
item.statisticalData !== null && item.statisticalData !== undefined
|
||||||
? parseFloat(item.statisticalData.toFixed(2))
|
? parseFloat(item.statisticalData.toFixed(2))
|
||||||
: null
|
: null,
|
||||||
|
item.unit
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -235,7 +303,8 @@ const setEchart = () => {
|
|||||||
item.time,
|
item.time,
|
||||||
item.statisticalData !== null && item.statisticalData !== undefined
|
item.statisticalData !== null && item.statisticalData !== undefined
|
||||||
? parseFloat(item.statisticalData.toFixed(2))
|
? parseFloat(item.statisticalData.toFixed(2))
|
||||||
: null
|
: null,
|
||||||
|
item.unit
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -265,6 +334,7 @@ const initCode = () => {
|
|||||||
tableStore.table.params.power = powerList.value[0].id
|
tableStore.table.params.power = powerList.value[0].id
|
||||||
tableStore.table.params.indicator = indicatorList.value[0].id
|
tableStore.table.params.indicator = indicatorList.value[0].id
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
// setTime()
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -278,19 +348,7 @@ const tableStore: any = new TableStore({
|
|||||||
exportName: '主要监测点列表',
|
exportName: '主要监测点列表',
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
// 设置时间参数
|
setTime()
|
||||||
// tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
|
||||||
// tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
const time = getTime(
|
|
||||||
prop.interval ?? 0,
|
|
||||||
prop.timeKey,
|
|
||||||
tableStore.table.params.searchBeginTime && tableStore.table.params.searchEndTime
|
|
||||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
|
||||||
: prop.timeValue
|
|
||||||
)
|
|
||||||
tableStore.table.params.searchBeginTime = time[0]
|
|
||||||
tableStore.table.params.searchEndTime = time[1]
|
|
||||||
|
|
||||||
// 只有当 lineList 已加载且有数据时才设置默认 lineId
|
// 只有当 lineList 已加载且有数据时才设置默认 lineId
|
||||||
if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) {
|
if (!tableStore.table.params.lineId && lineList.value && lineList.value.length > 0) {
|
||||||
tableStore.table.params.lineId = lineList.value[0].lineId
|
tableStore.table.params.lineId = lineList.value[0].lineId
|
||||||
@@ -391,49 +449,44 @@ watch(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
if (fullscreen.value) {
|
await initLineList()
|
||||||
if (prop.interval == 4 || prop.interval == 5) {
|
|
||||||
const time = getTime(
|
|
||||||
prop.interval ?? 0,
|
|
||||||
prop.timeKey,
|
|
||||||
tableStore.table.params.searchBeginTime && tableStore.table.params.searchEndTime
|
|
||||||
? [tableStore.table.params.searchBeginTime, tableStore.table.params.searchEndTime]
|
|
||||||
: prop.timeValue
|
|
||||||
)
|
|
||||||
tableStore.table.params.searchBeginTime = time[0]
|
|
||||||
tableStore.table.params.searchEndTime = time[1]
|
|
||||||
TableHeaderRef.value.setTimeInterval(prop.timeValue)
|
|
||||||
} else {
|
|
||||||
TableHeaderRef.value.setInterval(5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
initLineList().then(() => {
|
|
||||||
initCode()
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeKey,
|
() => prop.timeKey,
|
||||||
val => {
|
val => {
|
||||||
tableStore.index()
|
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(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const addMenu = () => {}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
// :deep(.el-select) {
|
// :deep(.el-select) {
|
||||||
|
|||||||
@@ -9,11 +9,12 @@
|
|||||||
v-model="tableStore.table.params.lineId"
|
v-model="tableStore.table.params.lineId"
|
||||||
placeholder="请选择监测点"
|
placeholder="请选择监测点"
|
||||||
style="width: 150px"
|
style="width: 150px"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in options"
|
v-for="item in options"
|
||||||
:key="item.lineId"
|
:key="item.lineId"
|
||||||
:label="item.name"
|
:label="item.lineName"
|
||||||
:value="item.lineId"
|
:value="item.lineId"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -33,7 +34,7 @@ import TableHeader from '@/components/table/header/index.vue'
|
|||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import { mainHeight } from '@/utils/layout'
|
import { mainHeight } from '@/utils/layout'
|
||||||
import HarmonicRatio from '@/components/cockpit/gridSideStatistics/components/harmonicRatio.vue'
|
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 dialogVisible: any = ref(false)
|
||||||
const harmonicRatioRef: any = ref(null)
|
const harmonicRatioRef: any = ref(null)
|
||||||
@@ -48,7 +49,7 @@ const loop50 = (key: string) => {
|
|||||||
list.push({
|
list.push({
|
||||||
title: i + '次',
|
title: i + '次',
|
||||||
field: key + i + 'Overtime',
|
field: key + i + 'Overtime',
|
||||||
width: '80',
|
width: '60',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||||
@@ -84,9 +85,9 @@ const tableStore: any = new TableStore({
|
|||||||
width: '150'
|
width: '150'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '闪变越限(%)',
|
title: '长时闪变越限(%)',
|
||||||
field: 'flickerOvertime',
|
field: 'flickerOvertime',
|
||||||
width: '80',
|
width: '90',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||||
@@ -100,16 +101,7 @@ const tableStore: any = new TableStore({
|
|||||||
title: '谐波电流越限(%)',
|
title: '谐波电流越限(%)',
|
||||||
children: loop50('iharm')
|
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: '电压偏差越限(%)',
|
title: '电压偏差越限(%)',
|
||||||
field: 'voltageDevOvertime',
|
field: 'voltageDevOvertime',
|
||||||
width: '100',
|
width: '100',
|
||||||
@@ -119,14 +111,24 @@ const tableStore: any = new TableStore({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '频率偏差越限(%)',
|
title: '三相不平衡度越限(%)',
|
||||||
field: 'freqDevOvertime',
|
field: 'ubalanceOvertime',
|
||||||
width: '100',
|
width: '100',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
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: () => {
|
beforeSearchFun: () => {
|
||||||
},
|
},
|
||||||
@@ -138,8 +140,10 @@ const tableStore: any = new TableStore({
|
|||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
tableStore.table.params.sortBy = ''
|
tableStore.table.params.sortBy = ''
|
||||||
tableStore.table.params.orderBy = ''
|
tableStore.table.params.orderBy = ''
|
||||||
|
const time:any=ref([])
|
||||||
const open = async (row: any,searchBeginTime:any,searchEndTime:any) => {
|
const open = async (row: any,searchBeginTime:any,searchEndTime:any) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
|
time.value=[searchBeginTime,searchEndTime]
|
||||||
initCSlineList()
|
initCSlineList()
|
||||||
tableStore.table.params.lineId = row.lineId
|
tableStore.table.params.lineId = row.lineId
|
||||||
|
|
||||||
@@ -174,8 +178,19 @@ const onHarmonicRatioClose = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const initCSlineList = async () => {
|
const initCSlineList = async () => {
|
||||||
const res = await cslineList({})
|
// const res = await cslineList({})
|
||||||
options.value = res.data
|
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>
|
<template>
|
||||||
<div>
|
<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
|
<Table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
@cell-click="cellClickEvent"
|
@cell-click="cellClickEvent"
|
||||||
@@ -11,27 +18,35 @@
|
|||||||
<OverLimitDetails ref="OverLimitDetailsRef" />
|
<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
|
<el-upload
|
||||||
ref="uploadRef"
|
ref="uploadRef"
|
||||||
class="upload-demo"
|
class="upload-demo"
|
||||||
:auto-upload="true"
|
action=""
|
||||||
|
accept=".doc,.docx,.PDF"
|
||||||
:on-change="handleChange"
|
:on-change="handleChange"
|
||||||
:before-upload="beforeUpload"
|
:before-upload="beforeUpload"
|
||||||
:http-request="handleUpload"
|
|
||||||
:limit="1"
|
:limit="1"
|
||||||
|
:auto-upload="false"
|
||||||
:on-exceed="handleExceed"
|
:on-exceed="handleExceed"
|
||||||
|
:on-remove="handleRemove"
|
||||||
:file-list="fileList"
|
:file-list="fileList"
|
||||||
>
|
>
|
||||||
<el-button type="primary">点击上传</el-button>
|
<el-button type="primary">点击上传</el-button>
|
||||||
<template #tip>
|
<template #tip>
|
||||||
<div class="el-upload__tip">只能上传Word或PDF文件,且不超过10MB</div>
|
<div class="el-upload__tip">请上传Word或PDF文件</div>
|
||||||
</template>
|
</template>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="uploadDialogVisible = false">取消</el-button>
|
<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>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -46,18 +61,22 @@ import { ElMessage, ElMessageBox } from 'element-plus'
|
|||||||
import OverLimitDetails from '@/components/cockpit/monitoringPointList/components/overLimitDetails.vue'
|
import OverLimitDetails from '@/components/cockpit/monitoringPointList/components/overLimitDetails.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import { uploadReport, getReportUrl } from '@/api/harmonic-boot/cockpit/cockpit'
|
import { uploadReport, getReportUrl } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
import { getTime } from '@/utils/formatTime'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
const TableHeaderRef = ref()
|
||||||
|
|
||||||
// 上传相关
|
// 上传相关
|
||||||
const uploadDialogVisible = ref(false)
|
const uploadDialogVisible = ref(false)
|
||||||
const currentUploadRow = ref<any>(null)
|
const currentUploadRow = ref<any>(null)
|
||||||
@@ -67,11 +86,11 @@ const fileList = ref([])
|
|||||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
headerHeight.value = height
|
headerHeight.value = height
|
||||||
|
|
||||||
if (datePickerValue && datePickerValue.timeValue) {
|
// if (datePickerValue && datePickerValue.timeValue) {
|
||||||
// 更新时间参数
|
// // 更新时间参数
|
||||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
// tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
// 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
|
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: '监测点名称',
|
title: '监测点名称',
|
||||||
field: 'lineName',
|
field: 'lineName',
|
||||||
minWidth: '70',
|
minWidth: '120',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.lineName}</span>`
|
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: '监测点状态',
|
title: '监测点状态',
|
||||||
field: 'runStatus',
|
field: 'runStatus',
|
||||||
minWidth: '60',
|
render: 'tag',
|
||||||
render: 'customTemplate',
|
|
||||||
customTemplate: (row: any) => {
|
width: 100,
|
||||||
return `<span style='color: ${row.runStatus === '中断' ? '#FF0000' : ''}'>${row.runStatus}</span>`
|
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: '最新数据时间',
|
title: '最新数据时间',
|
||||||
field: 'latestTime',
|
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: '操作',
|
title: '报告',
|
||||||
minWidth: 120,
|
field: 'reportFilePath',
|
||||||
// fixed: 'right',
|
minWidth: '120',
|
||||||
|
formatter: (row: any) => {
|
||||||
|
return row.cellValue == null ? '/' : row.cellValue.split('/').pop()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作', fixed: 'right',
|
||||||
|
width: 150,
|
||||||
render: 'buttons',
|
render: 'buttons',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
@@ -186,7 +261,7 @@ const tableStore: any = new TableStore({
|
|||||||
icon: 'el-icon-EditPen',
|
icon: 'el-icon-EditPen',
|
||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
click: row => {
|
click: row => {
|
||||||
downloadTheReport(row.lineId)
|
downloadTheReport(row.lineId, row.reportFilePath)
|
||||||
},
|
},
|
||||||
disabled: row => {
|
disabled: row => {
|
||||||
return row.reportFilePath == null || row.reportFilePath.length == 0
|
return row.reportFilePath == null || row.reportFilePath.length == 0
|
||||||
@@ -209,8 +284,7 @@ const tableStore: any = new TableStore({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||||
@@ -222,6 +296,25 @@ provide('tableRef', tableRef)
|
|||||||
tableStore.table.params.keywords = ''
|
tableStore.table.params.keywords = ''
|
||||||
provide('tableStore', tableStore)
|
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) => {
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
if (column.field == 'lineName') {
|
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) => {
|
getReportUrl({ lineId: lineId }).then((res: any) => {
|
||||||
const link = document.createElement('a')
|
forceDownloadPdf(res.data, name.split('/').pop() || '')
|
||||||
link.href = res.data
|
|
||||||
link.download = '治理报告'
|
|
||||||
document.body.appendChild(link)
|
|
||||||
link.click()
|
|
||||||
document.body.removeChild(link)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
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) => {
|
const uploadReportRow = (row: any) => {
|
||||||
@@ -260,14 +380,18 @@ const handleDialogClosed = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理文件超出限制
|
// 处理文件超出限制
|
||||||
const handleExceed = (files: any, fileList: any) => {
|
const handleExceed = (files: any) => {
|
||||||
ElMessage.warning('只能上传一个文件,请先删除已选择的文件')
|
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
|
const isLt10M = file.size / 1024 / 1024 < 10
|
||||||
|
|
||||||
if (!isValidType) {
|
if (!isValidType) {
|
||||||
ElMessage.error('上传文件只能是 Word 文档(.doc/.docx) 或 PDF 文件(.pdf)!')
|
ElMessage.error('请上传(.doc/.docx/.pdf)格式文件!')
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (!isLt10M) {
|
|
||||||
ElMessage.error('上传文件大小不能超过 10MB!')
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,10 +416,11 @@ const beforeUpload = (file: any) => {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUpload = async (options: any) => {
|
const handleUpload = async () => {
|
||||||
const { file } = options
|
// return
|
||||||
|
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('file', file)
|
formData.append('file', fileList.value[0]?.raw)
|
||||||
formData.append('lineId', currentUploadRow.value?.lineId || currentUploadRow.value?.id || '')
|
formData.append('lineId', currentUploadRow.value?.lineId || currentUploadRow.value?.id || '')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -326,12 +447,7 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
v-model="searchForm.index"
|
v-model="searchForm.index"
|
||||||
placeholder="请选择统计指标"
|
placeholder="请选择统计指标"
|
||||||
@change="onIndexChange($event)"
|
@change="onIndexChange($event)"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in indexOptions"
|
v-for="item in indexOptions"
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
style="min-width: 120px !important"
|
style="min-width: 120px !important"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
v-model="searchForm.valueType"
|
v-model="searchForm.valueType"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option value="max" label="最大值"></el-option>
|
<el-option value="max" label="最大值"></el-option>
|
||||||
<el-option value="min" label="最小值"></el-option>
|
<el-option value="min" label="最小值"></el-option>
|
||||||
@@ -59,11 +61,12 @@
|
|||||||
placeholder="请选择谐波次数"
|
placeholder="请选择谐波次数"
|
||||||
style="width: 100px"
|
style="width: 100px"
|
||||||
class="mr20"
|
class="mr20"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="vv in item.countOptions"
|
v-for="vv in item.countOptions"
|
||||||
:key="vv"
|
:key="vv"
|
||||||
:label="vv"
|
:label="item.name.includes('间谐波') ? vv - 0.5 : vv"
|
||||||
:value="vv"
|
:value="vv"
|
||||||
></el-option>
|
></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -79,11 +82,7 @@
|
|||||||
</TableHeader>
|
</TableHeader>
|
||||||
</div>
|
</div>
|
||||||
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
<div class="history_chart" :style="pageHeight" v-loading="loading">
|
||||||
<MyEchart
|
<MyEchart ref="historyChart" :options="echartsData" v-if="showEchart" />
|
||||||
ref="historyChart"
|
|
||||||
:options="echartsData"
|
|
||||||
v-if="showEchart"
|
|
||||||
/>
|
|
||||||
<el-empty :style="pageHeight" v-else description="暂无数据" />
|
<el-empty :style="pageHeight" v-else description="暂无数据" />
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -157,28 +156,40 @@ const countOptions: any = ref([])
|
|||||||
const legendDictList: any = ref([])
|
const legendDictList: any = ref([])
|
||||||
|
|
||||||
const initCode = (field: string, title: string) => {
|
const initCode = (field: string, title: string) => {
|
||||||
queryByCode('steady_state_limit_trend').then(res => {
|
queryByCode('gridSide_exceedTheLimit').then(res => {
|
||||||
queryCsDictTree(res.data.id).then(item => {
|
queryCsDictTree(res.data.id).then(item => {
|
||||||
//排序
|
//排序
|
||||||
indexOptions.value = item.data.sort((a: any, b: any) => {
|
indexOptions.value = item.data.sort((a: any, b: any) => {
|
||||||
return a.sort - b.sort
|
return a.sort - b.sort
|
||||||
})
|
})
|
||||||
const titleMap: Record<string, number> = {
|
// const titleMap: Record<string, number> = {
|
||||||
flickerOvertime: 0,
|
// flickerOvertime: 0,
|
||||||
uaberranceOvertime: 3,
|
// uaberranceOvertime: 3,
|
||||||
ubalanceOvertime: 4,
|
// ubalanceOvertime: 4,
|
||||||
freqDevOvertime: 5
|
// freqDevOvertime: 5
|
||||||
}
|
// }
|
||||||
|
|
||||||
let defaultIndex = 0 // 默认值
|
// let defaultIndex = 0 // 默认值
|
||||||
|
|
||||||
if (field in titleMap) {
|
// if (field in titleMap) {
|
||||||
defaultIndex = titleMap[field]
|
// defaultIndex = titleMap[field]
|
||||||
} else if (field.includes('uharm')) {
|
// } else if (field.includes('uharm')) {
|
||||||
defaultIndex = 1
|
// defaultIndex = 1
|
||||||
} else if (field.includes('iharm')) {
|
// } else if (field.includes('iharm')) {
|
||||||
defaultIndex = 2
|
// 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
|
searchForm.value.index[0] = indexOptions.value[defaultIndex].id
|
||||||
})
|
})
|
||||||
@@ -202,7 +213,7 @@ const initCode = (field: string, title: string) => {
|
|||||||
if (kk.harmStart && kk.harmEnd) {
|
if (kk.harmStart && kk.harmEnd) {
|
||||||
range(0, 0, 0)
|
range(0, 0, 0)
|
||||||
|
|
||||||
if (kk.showName == '间谐波电压含有率') {
|
if (kk.showName.includes('间谐波电压')) {
|
||||||
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1).map(
|
countDataCopy.value[index].countOptions = range(kk.harmStart, kk.harmEnd, 1).map(
|
||||||
(item: any) => {
|
(item: any) => {
|
||||||
return item - 0.5
|
return item - 0.5
|
||||||
@@ -291,7 +302,7 @@ const init = async () => {
|
|||||||
}
|
}
|
||||||
lists[index] = {
|
lists[index] = {
|
||||||
statisticalId: item.index,
|
statisticalId: item.index,
|
||||||
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
frequency: frequencys !== null && frequencys !== undefined ? String(frequencys) : ''
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
let obj = {
|
let obj = {
|
||||||
@@ -597,12 +608,12 @@ const formatCountOptions = () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
countData.value.map((item: any, key: any) => {
|
countData.value.map((item: any, key: any) => {
|
||||||
if (item.name == '谐波电流有效值') {
|
if (item.name.includes('间谐波电压')) {
|
||||||
item.name = '谐波电流次数'
|
|
||||||
} else if (item.name == '谐波电压含有率') {
|
|
||||||
item.name = '谐波电压次数'
|
|
||||||
} else if (item.name == '间谐波电压含有率') {
|
|
||||||
item.name = '间谐波电压次数'
|
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"
|
v-model="tableStore.table.params.lineId"
|
||||||
placeholder="请选择监测点"
|
placeholder="请选择监测点"
|
||||||
style="width: 150px"
|
style="width: 150px"
|
||||||
|
filterable
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in options"
|
v-for="item in options"
|
||||||
:key="item.lineId"
|
:key="item.lineId"
|
||||||
:label="item.name"
|
:label="item.lineName"
|
||||||
:value="item.lineId"
|
:value="item.lineId"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -48,7 +49,7 @@ const loop50 = (key: string) => {
|
|||||||
list.push({
|
list.push({
|
||||||
title: i + '次',
|
title: i + '次',
|
||||||
field: key + i + 'Overtime',
|
field: key + i + 'Overtime',
|
||||||
width: '80',
|
width: '60',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row[key + i + 'Overtime']}</span>`
|
||||||
@@ -84,9 +85,9 @@ const tableStore: any = new TableStore({
|
|||||||
width: '150'
|
width: '150'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '闪变越限(%)',
|
title: '长时闪变越限(%)',
|
||||||
field: 'flickerOvertime',
|
field: 'flickerOvertime',
|
||||||
width: '80',
|
width: '90',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
customTemplate: (row: any) => {
|
||||||
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
return `<span style='cursor: pointer;text-decoration: underline;'>${row.flickerOvertime}</span>`
|
||||||
@@ -100,16 +101,7 @@ const tableStore: any = new TableStore({
|
|||||||
title: '谐波电流越限(%)',
|
title: '谐波电流越限(%)',
|
||||||
children: loop50('iharm')
|
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: '电压偏差越限(%)',
|
title: '电压偏差越限(%)',
|
||||||
field: 'voltageDevOvertime',
|
field: 'voltageDevOvertime',
|
||||||
width: '100',
|
width: '100',
|
||||||
@@ -119,14 +111,24 @@ const tableStore: any = new TableStore({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '频率偏差越限(%)',
|
title: '三相不平衡度越限(%)',
|
||||||
field: 'freqDevOvertime',
|
field: 'ubalanceOvertime',
|
||||||
width: '100',
|
width: '100',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
customTemplate: (row: any) => {
|
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: () => {
|
beforeSearchFun: () => {
|
||||||
},
|
},
|
||||||
@@ -138,9 +140,10 @@ const tableStore: any = new TableStore({
|
|||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
tableStore.table.params.sortBy = ''
|
tableStore.table.params.sortBy = ''
|
||||||
tableStore.table.params.orderBy = ''
|
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
|
dialogVisible.value = true
|
||||||
initCSlineList()
|
// initCSlineList()
|
||||||
|
options.value = data
|
||||||
tableStore.table.params.lineId = row.lineId
|
tableStore.table.params.lineId = row.lineId
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<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
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
@@ -30,20 +36,21 @@ import OverLimitDetails from '@/components/cockpit/overLimitStatistics/component
|
|||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
import { useTimeCacheStore } from '@/stores/timeCache'
|
||||||
import { totalLimitStatisticsData } from '@/api/harmonic-boot/cockpit/cockpit'
|
import { totalLimitStatisticsData } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
import { getTime } from '@/utils/formatTime'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
const route = useRoute()
|
const TableHeaderRef = ref()
|
||||||
const timeCacheStore = useTimeCacheStore()
|
|
||||||
|
|
||||||
const echartList = ref({})
|
const echartList = ref({})
|
||||||
|
|
||||||
@@ -82,7 +89,7 @@ const initEcharts = () => {
|
|||||||
|
|
||||||
xAxis: {
|
xAxis: {
|
||||||
// name: '(区域)',
|
// name: '(区域)',
|
||||||
data: ['闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
data: ['长时闪变', '谐波电压', '谐波电流', '电压偏差', '三相不平衡']
|
||||||
},
|
},
|
||||||
|
|
||||||
yAxis: {
|
yAxis: {
|
||||||
@@ -143,7 +150,7 @@ const tableStore: any = new TableStore({
|
|||||||
title: '越限占比(%)',
|
title: '越限占比(%)',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
title: '闪变',
|
title: '长时闪变',
|
||||||
field: 'flicker',
|
field: 'flicker',
|
||||||
minWidth: '70',
|
minWidth: '70',
|
||||||
render: 'customTemplate',
|
render: 'customTemplate',
|
||||||
@@ -191,8 +198,7 @@ const tableStore: any = new TableStore({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.height = `calc(${prop.height} - 80px)`
|
tableStore.table.height = `calc(${prop.height} - 80px)`
|
||||||
@@ -211,7 +217,8 @@ const cellClickEvent = ({ row, column }: any) => {
|
|||||||
OverLimitDetailsRef.value.open(
|
OverLimitDetailsRef.value.open(
|
||||||
row,
|
row,
|
||||||
tableStore.table.params.searchBeginTime || prop.timeValue?.[0],
|
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(() => {
|
onMounted(() => {
|
||||||
tableStore.index()
|
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(
|
watch(
|
||||||
() => prop.timeKey,
|
() => prop.timeKey,
|
||||||
val => {
|
val => {
|
||||||
@@ -229,12 +256,7 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
|
|||||||
@@ -1,8 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!--敏感负荷列表 -->
|
<!--敏感负荷列表 -->
|
||||||
<TableHeader :showReset="false" @selectChange="selectChange" datePicker v-if="fullscreen"></TableHeader>
|
<TableHeader
|
||||||
<Table ref="tableRef" @cell-click="cellClickEvent" :height="`calc(${prop.height} - ${headerHeight}px + ${fullscreen ? -58 : 56}px )`" isGroup></Table>
|
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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -10,33 +22,34 @@ import { ref, onMounted, provide, reactive, watch, h } from 'vue'
|
|||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
|
||||||
import { useDictData } from '@/stores/dictData'
|
import { useDictData } from '@/stores/dictData'
|
||||||
|
import { getTime } from '@/utils/formatTime'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number]},
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number]},
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number]},
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number]},
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number]},
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
const dictData = useDictData()
|
const TableHeaderRef = ref()
|
||||||
const sensitiveUserType = dictData.getBasicData('Sensitive_User_Type')
|
|
||||||
|
|
||||||
|
const dictData = useDictData()
|
||||||
|
const sensitiveUserType = dictData.getBasicData('Interference_Source')
|
||||||
|
|
||||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
headerHeight.value = height
|
headerHeight.value = height
|
||||||
|
|
||||||
if (datePickerValue && datePickerValue.timeValue) {
|
// if (datePickerValue && datePickerValue.timeValue) {
|
||||||
// 更新时间参数
|
// // 更新时间参数
|
||||||
tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
// tableStore.table.params.searchBeginTime = datePickerValue.timeValue[0]
|
||||||
tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
// tableStore.table.params.searchEndTime = datePickerValue.timeValue[1]
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算是否全屏展示
|
// 计算是否全屏展示
|
||||||
@@ -51,7 +64,6 @@ const fullscreen = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const OverLimitDetailsRef = ref()
|
const OverLimitDetailsRef = ref()
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/cs-harmonic-boot/pqSensitiveUser/getList',
|
url: '/cs-harmonic-boot/pqSensitiveUser/getList',
|
||||||
@@ -76,28 +88,32 @@ const tableStore: any = new TableStore({
|
|||||||
title: '敏感负荷类型',
|
title: '敏感负荷类型',
|
||||||
field: 'loadType',
|
field: 'loadType',
|
||||||
minWidth: '70',
|
minWidth: '70',
|
||||||
formatter: row => {
|
formatter: row => {
|
||||||
return sensitiveUserType.filter(item => item.id == row.cellValue)[0]?.name
|
return sensitiveUserType.filter(item => item.id == row.cellValue)[0]?.name
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '是否监测',
|
title: '是否监测',
|
||||||
field: 'isMonitor',
|
field: 'isMonitor',
|
||||||
minWidth: '80'
|
minWidth: '80',
|
||||||
|
formatter: (row: any) => {
|
||||||
|
return row.cellValue || '/'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '是否治理',
|
title: '是否治理',
|
||||||
field: 'isGovern',
|
field: 'isGovern',
|
||||||
minWidth: '80'
|
minWidth: '80',
|
||||||
|
formatter: (row: any) => {
|
||||||
|
return row.cellValue || '/'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
loadCallback: () => {
|
loadCallback: () => {}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const tableRef = ref()
|
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(() => {
|
onMounted(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
@@ -127,17 +162,11 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ const tableStore: any = new TableStore({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '波形',
|
title: '波形',
|
||||||
width: '100',
|
minWidth: '100',
|
||||||
render: 'buttons',
|
render: 'buttons',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
@@ -166,8 +166,8 @@ const tableStore: any = new TableStore({
|
|||||||
// ...row,
|
// ...row,
|
||||||
// duration: row.persistTime // 将 persistTime 值赋给 duration
|
// duration: row.persistTime // 将 persistTime 值赋给 duration
|
||||||
// }
|
// }
|
||||||
boxoList.value.featureAmplitude =
|
boxoList.value.featureAmplitude = (row.amplitude - 0) / 100
|
||||||
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
// row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
||||||
boxoList.value.systemType = 'YPT'
|
boxoList.value.systemType = 'YPT'
|
||||||
wp.value = res.data
|
wp.value = res.data
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
@selectChange="selectChange"
|
@selectChange="selectChange"
|
||||||
datePicker
|
datePicker
|
||||||
v-if="fullscreen"
|
v-if="fullscreen"
|
||||||
:timeCacheFlag="false"
|
:timeKeyList="prop.timeKey"
|
||||||
></TableHeader>
|
></TableHeader>
|
||||||
<el-calendar
|
<el-calendar
|
||||||
v-model="value"
|
v-model="value"
|
||||||
@@ -43,9 +43,15 @@
|
|||||||
v-for="item in list?.filter((item:any) => item.name == data.day)"
|
v-for="item in list?.filter((item:any) => item.name == data.day)"
|
||||||
@click="descentClick(item)"
|
@click="descentClick(item)"
|
||||||
>
|
>
|
||||||
<div>电压暂降:{{ item.eventDown || 0 }}</div>
|
<!-- <div>电压暂降:{{ item.eventDown || 0 }}</div>
|
||||||
<div>电压中断:{{ item.eventOff || 0 }}</div>
|
<div>电压中断:{{ item.eventOff || 0 }}</div>
|
||||||
<div>电压暂升:{{ item.eventUp || 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>
|
</div>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
@@ -61,15 +67,16 @@ import TableStore from '@/utils/tableStore'
|
|||||||
import { dayjs } from 'element-plus'
|
import { dayjs } from 'element-plus'
|
||||||
import TransientList from './components/transientList.vue'
|
import TransientList from './components/transientList.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { getTime } from '@/utils/formatTime'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object },
|
timeValue: { type: Object },
|
||||||
interval: { type: [String, Number] }
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
@@ -120,15 +127,7 @@ const tableStore: any = new TableStore({
|
|||||||
column: [],
|
column: [],
|
||||||
|
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
if (!fullscreen.value) {
|
setTime()
|
||||||
if (prop.interval == 3 && prop.timeValue && Array.isArray(prop.timeValue)) {
|
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue[0]
|
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue[1]
|
|
||||||
} else {
|
|
||||||
tableStore.table.params.searchBeginTime = '2025-12-1'
|
|
||||||
tableStore.table.params.searchEndTime = '2025-12-31'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
@@ -154,50 +153,34 @@ provide('tableStore', tableStore)
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (TableHeaderRef.value && typeof TableHeaderRef.value.setDatePicker === 'function') {
|
|
||||||
TableHeaderRef.value.setDatePicker([{ label: '月份', value: 3 }])
|
|
||||||
}
|
|
||||||
if (fullscreen.value) {
|
|
||||||
if (prop.interval == 3 && prop.timeValue && Array.isArray(prop.timeValue)) {
|
|
||||||
tableStore.table.params.searchBeginTime = prop.timeValue[0] || tableStore.table.params.searchBeginTime
|
|
||||||
tableStore.table.params.searchEndTime = prop.timeValue[1] || tableStore.table.params.searchEndTime
|
|
||||||
TableHeaderRef.value.setTimeInterval(prop.timeValue)
|
|
||||||
} else {
|
|
||||||
TableHeaderRef.value.setInterval(3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
watch(
|
|
||||||
() => prop.timeKey,
|
|
||||||
val => {
|
|
||||||
// tableStore.index()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
watch(
|
const setTime = () => {
|
||||||
() => prop.interval,
|
const time = getTime(
|
||||||
val => {
|
(TableHeaderRef.value?.datePickerRef.interval || prop.interval) ?? 0,
|
||||||
if (val == 3) {
|
prop.timeKey,
|
||||||
tableStore.index()
|
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(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
// (newVal, oldVal) => {
|
(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 => {
|
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,30 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<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
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
:style="{
|
:style="{
|
||||||
width: prop.width,
|
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"
|
class="mt10"
|
||||||
:options="echartList1"
|
:options="echartList1"
|
||||||
:style="{
|
:style="{
|
||||||
width: prop.width,
|
width: prop.width,
|
||||||
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
height: `calc(${prop.height} / 2 - ${headerHeight / 2}px + ${fullscreen ? 0 : 28}px )`
|
||||||
}"
|
}"
|
||||||
/>
|
/> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -26,16 +33,20 @@ import TableStore from '@/utils/tableStore'
|
|||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
import { getTime } from '@/utils/formatTime'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const TableHeaderRef = ref()
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
@@ -66,135 +77,6 @@ const echartList = ref({})
|
|||||||
|
|
||||||
const echartList1 = 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[]) => {
|
const processDataForChart = (rawData: any[]) => {
|
||||||
// 将后端返回的扁平数据转换为 ECharts 需要的三维坐标格式 [x, y, z]
|
// 将后端返回的扁平数据转换为 ECharts 需要的三维坐标格式 [x, y, z]
|
||||||
const chartData = rawData.map(item => [item.x, item.y, item.z])
|
const chartData = rawData.map(item => [item.x, item.y, item.z])
|
||||||
@@ -208,8 +90,7 @@ const tableStore: any = new TableStore({
|
|||||||
showPage: false,
|
showPage: false,
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
const processedData = processDataForChart(tableStore.table.data.innerList || [])
|
const processedData = processDataForChart(tableStore.table.data.innerList || [])
|
||||||
@@ -302,15 +183,14 @@ const tableStore: any = new TableStore({
|
|||||||
type: 'category',
|
type: 'category',
|
||||||
name: '特征幅值',
|
name: '特征幅值',
|
||||||
data: xLabels,
|
data: xLabels,
|
||||||
nameGap: 40,
|
nameGap: 40
|
||||||
|
|
||||||
},
|
},
|
||||||
yAxis3D: {
|
yAxis3D: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
name: '持续时间',
|
name: '持续时间',
|
||||||
data: yLabels,
|
data: yLabels,
|
||||||
nameGap: 40,
|
nameGap: 40,
|
||||||
|
|
||||||
splitLine: {
|
splitLine: {
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
type: 'dashed',
|
type: 'dashed',
|
||||||
@@ -322,24 +202,26 @@ const tableStore: any = new TableStore({
|
|||||||
type: 'value',
|
type: 'value',
|
||||||
minInterval: 10,
|
minInterval: 10,
|
||||||
name: '暂态事件次数',
|
name: '暂态事件次数',
|
||||||
nameGap: 30,
|
nameGap: 30
|
||||||
},
|
},
|
||||||
grid3D: {
|
grid3D: {
|
||||||
viewControl: {
|
viewControl: {
|
||||||
projection: 'perspective',
|
projection: 'perspective',
|
||||||
distance: 250
|
distance: 260,
|
||||||
},
|
rotateSensitivity: 10,
|
||||||
|
zoomSensitivity: 2
|
||||||
boxWidth: 200,
|
|
||||||
boxDepth: 80,
|
|
||||||
light: {
|
|
||||||
main: {
|
|
||||||
intensity: 1.2
|
|
||||||
},
|
},
|
||||||
ambient: {
|
boxWidth: 150,
|
||||||
intensity: 0.3
|
boxDepth: 100,
|
||||||
|
boxHeight: 100,
|
||||||
|
light: {
|
||||||
|
main: {
|
||||||
|
intensity: 1.2
|
||||||
|
},
|
||||||
|
ambient: {
|
||||||
|
intensity: 0.4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
@@ -352,9 +234,7 @@ const tableStore: any = new TableStore({
|
|||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
borderWidth: 1
|
borderWidth: 1
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -391,26 +271,41 @@ provide('tableStore', tableStore)
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tableStore.index()
|
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(
|
watch(
|
||||||
() => prop.timeKey,
|
() => prop.timeKey,
|
||||||
val => {
|
val => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const addMenu = () => {}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef" @selectChange="selectChange">
|
<TableHeader datePicker showExport :showReset="false" ref="tableHeaderRef" @selectChange="selectChange">
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="监测点">
|
<el-form-item label="监测点">
|
||||||
<el-select v-model="tableStore.table.params.lineId" placeholder="请选择监测点名称">
|
<el-select filterable v-model="tableStore.table.params.lineId" placeholder="请选择监测点名称">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in options"
|
v-for="item in options"
|
||||||
:key="item.value"
|
:key="item.lineId"
|
||||||
:label="item.label"
|
:label="item.name"
|
||||||
:value="item.value"
|
:value="item.lineId"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -58,9 +58,9 @@ const boxoList: any = ref({})
|
|||||||
const tableHeaderRef = ref()
|
const tableHeaderRef = ref()
|
||||||
|
|
||||||
const options = ref()
|
const options = ref()
|
||||||
const heightRef = ref(mainHeight(168, 2.1).height)
|
const heightRef = ref(mainHeight(168, 2.2).height)
|
||||||
const selectChange = (flag: boolean, h: any) => {
|
const selectChange = (flag: boolean, h: any) => {
|
||||||
heightRef.value = mainHeight(h, 2.1).height
|
heightRef.value = mainHeight(h, 2.2).height
|
||||||
}
|
}
|
||||||
|
|
||||||
const getSimpleLineList = async () => {
|
const getSimpleLineList = async () => {
|
||||||
@@ -68,7 +68,6 @@ const getSimpleLineList = async () => {
|
|||||||
options.value = res.data
|
options.value = res.data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/cs-harmonic-boot/event/pageEvent',
|
url: '/cs-harmonic-boot/event/pageEvent',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -86,27 +85,27 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
title: '暂态时间',
|
title: '暂态时间',
|
||||||
field: 'startTime',
|
field: 'startTime',
|
||||||
minWidth: '150'
|
minWidth: '180'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '测点名称',
|
title: '测点名称',
|
||||||
field: 'lineName',
|
field: 'lineName',
|
||||||
width: '150'
|
minWidth: '150'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '暂态类型',
|
title: '暂态类型',
|
||||||
field: 'tag',
|
field: 'tag',
|
||||||
width: '100'
|
minWidth: '100'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '特征幅值(%)',
|
title: '特征幅值(%)',
|
||||||
field: 'amplitude',
|
field: 'amplitude',
|
||||||
width: '100'
|
minWidth: '100'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '暂降深度(%)',
|
title: '暂降深度(%)',
|
||||||
field: 'depth',
|
field: 'depth',
|
||||||
width: '100',
|
minWidth: '100',
|
||||||
formatter: (row: any) => {
|
formatter: (row: any) => {
|
||||||
// 当暂态类型不是电压暂升时,计算暂降深度 = 100 - 特征幅值
|
// 当暂态类型不是电压暂升时,计算暂降深度 = 100 - 特征幅值
|
||||||
if (row.row.tag !== '电压暂升') {
|
if (row.row.tag !== '电压暂升') {
|
||||||
@@ -124,16 +123,16 @@ const tableStore: any = new TableStore({
|
|||||||
{
|
{
|
||||||
title: '持续时间(S)',
|
title: '持续时间(S)',
|
||||||
field: 'persistTime',
|
field: 'persistTime',
|
||||||
width: '100'
|
minWidth: '100'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '严重度',
|
title: '严重度',
|
||||||
field: 'severity',
|
field: 'severity',
|
||||||
width: '80'
|
minWidth: '80'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '波形',
|
title: '波形',
|
||||||
width: '100',
|
width: '90',
|
||||||
render: 'buttons',
|
render: 'buttons',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
@@ -167,8 +166,9 @@ const tableStore: any = new TableStore({
|
|||||||
// ...row,
|
// ...row,
|
||||||
// duration: row.persistTime // 将 persistTime 值赋给 duration
|
// duration: row.persistTime // 将 persistTime 值赋给 duration
|
||||||
// }
|
// }
|
||||||
boxoList.value.featureAmplitude =
|
// boxoList.value.featureAmplitude =
|
||||||
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
// row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
||||||
|
boxoList.value.featureAmplitude = (row.amplitude - 0) / 100
|
||||||
boxoList.value.systemType = 'YPT'
|
boxoList.value.systemType = 'YPT'
|
||||||
wp.value = res.data
|
wp.value = res.data
|
||||||
}
|
}
|
||||||
@@ -192,7 +192,7 @@ const tableStore: any = new TableStore({
|
|||||||
icon: 'el-icon-DataLine',
|
icon: 'el-icon-DataLine',
|
||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
disabled: row => {
|
disabled: row => {
|
||||||
return !(!row.wavePath && row.evtParamTm < 20)
|
return !!row.wavePath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<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
|
<my-echart
|
||||||
class="tall"
|
class="tall"
|
||||||
:options="echartList"
|
:options="echartList"
|
||||||
@@ -28,18 +34,23 @@ import { useConfig } from '@/stores/config'
|
|||||||
import TransientStatisticsDetail from '@/components/cockpit/transientStatistics/components/transientStatisticsDetail.vue'
|
import TransientStatisticsDetail from '@/components/cockpit/transientStatistics/components/transientStatisticsDetail.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import { netEventEcharts } from '@/api/harmonic-boot/cockpit/cockpit'
|
import { netEventEcharts } from '@/api/harmonic-boot/cockpit/cockpit'
|
||||||
|
import { getTime } from '@/utils/formatTime'
|
||||||
|
|
||||||
const prop = defineProps({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const TableHeaderRef = ref()
|
||||||
|
|
||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
|
|
||||||
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
const selectChange = (showSelect: any, height: any, datePickerValue?: any) => {
|
||||||
headerHeight.value = height
|
headerHeight.value = height
|
||||||
|
|
||||||
@@ -96,8 +107,8 @@ const eventEcharts = () => {
|
|||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
orient: 'vertical',
|
orient: 'vertical',
|
||||||
top: 'center',
|
top: '50',
|
||||||
right: '5%',
|
right: '10',
|
||||||
formatter: function (e: any) {
|
formatter: function (e: any) {
|
||||||
return e + ' ' + data.value.filter((item: any) => item.name == e)[0].value + '次'
|
return e + ' ' + data.value.filter((item: any) => item.name == e)[0].value + '次'
|
||||||
}
|
}
|
||||||
@@ -199,8 +210,7 @@ const tableStore: any = new TableStore({
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
eventEcharts()
|
eventEcharts()
|
||||||
@@ -223,6 +233,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(() => {
|
onMounted(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
@@ -237,12 +266,7 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
|
|||||||
@@ -1,10 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<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>
|
<template v-slot:select>
|
||||||
<el-form-item label="监测对象">
|
<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-option v-for="item in idList" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -69,6 +81,7 @@
|
|||||||
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
height: `calc(${prop.height} - ${headerHeight}px + ${fullscreen ? 0 : 56}px)`
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
|
<!-- <el-empty description="暂无数据" /> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -77,26 +90,24 @@ import TableStore from '@/utils/tableStore'
|
|||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import MyEchart from '@/components/echarts/MyEchart.vue'
|
import MyEchart from '@/components/echarts/MyEchart.vue'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
import { useTimeCacheStore } from '@/stores/timeCache'
|
|
||||||
import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree'
|
import { queryByCode, queryCsDictTree } from '@/api/system-boot/dictTree'
|
||||||
import { getListByIds } from '@/api/harmonic-boot/cockpit/cockpit'
|
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({
|
const prop = defineProps({
|
||||||
w: { type: [String, Number] },
|
w: { type: [String, Number] },
|
||||||
h: { type: [String, Number] },
|
h: { type: [String, Number] },
|
||||||
width: { type: [String, Number] },
|
width: { type: [String, Number] },
|
||||||
height: { type: [String, Number] },
|
height: { type: [String, Number] },
|
||||||
timeKey: { type: [String, Number] },
|
timeKey: { type: Array as () => string[] },
|
||||||
timeValue: { type: Object }
|
timeValue: { type: Object },
|
||||||
|
interval: { type: Number }
|
||||||
})
|
})
|
||||||
|
|
||||||
const route = useRoute()
|
const TableHeaderRef = ref()
|
||||||
const timeCacheStore = useTimeCacheStore()
|
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
|
|
||||||
const lineIdList = ref(JSON.parse(window.localStorage.getItem('lineIdList') || '[]'))
|
|
||||||
|
|
||||||
// 计算是否全屏展示
|
// 计算是否全屏展示
|
||||||
const fullscreen = computed(() => {
|
const fullscreen = computed(() => {
|
||||||
const w = Number(prop.w)
|
const w = Number(prop.w)
|
||||||
@@ -118,14 +129,16 @@ const echartList = ref()
|
|||||||
const headerHeight = ref(57)
|
const headerHeight = ref(57)
|
||||||
|
|
||||||
// 监测对象
|
// 监测对象
|
||||||
const idList = ref()
|
const idList = ref([])
|
||||||
|
|
||||||
// 监测对象
|
// 监测对象
|
||||||
const initListByIds = () => {
|
const initListByIds = () => {
|
||||||
getListByIds({}).then((res: any) => {
|
getListByIds({}).then((res: any) => {
|
||||||
if (res.data.length > 0) {
|
if (res.data?.length > 0) {
|
||||||
idList.value = res.data
|
idList.value = res.data
|
||||||
initCode()
|
initCode()
|
||||||
|
} else {
|
||||||
|
tableStore.index()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -170,7 +183,7 @@ const setEchart = () => {
|
|||||||
if (!beforeGroupedByPhase[phase]) {
|
if (!beforeGroupedByPhase[phase]) {
|
||||||
beforeGroupedByPhase[phase] = []
|
beforeGroupedByPhase[phase] = []
|
||||||
}
|
}
|
||||||
beforeGroupedByPhase[phase].push([item.time, item.statisticalData])
|
beforeGroupedByPhase[phase].push([item.time, item.statisticalData, item.unit, 'solid'])
|
||||||
})
|
})
|
||||||
|
|
||||||
// 处理治理后数据
|
// 处理治理后数据
|
||||||
@@ -179,7 +192,7 @@ const setEchart = () => {
|
|||||||
if (!afterGroupedByPhase[phase]) {
|
if (!afterGroupedByPhase[phase]) {
|
||||||
afterGroupedByPhase[phase] = []
|
afterGroupedByPhase[phase] = []
|
||||||
}
|
}
|
||||||
afterGroupedByPhase[phase].push([item.time, item.statisticalData])
|
afterGroupedByPhase[phase].push([item.time, item.statisticalData, item.unit, 'dotted'])
|
||||||
})
|
})
|
||||||
|
|
||||||
// 构建系列数据
|
// 构建系列数据
|
||||||
@@ -231,7 +244,7 @@ const setEchart = () => {
|
|||||||
data: afterGroupedByPhase[phase],
|
data: afterGroupedByPhase[phase],
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
normal: {
|
normal: {
|
||||||
color:color
|
color: color
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
@@ -250,6 +263,11 @@ const setEchart = () => {
|
|||||||
titleText = afterData[0].anotherName
|
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) => {
|
const legendData = series.map((item: any, index: number) => {
|
||||||
let color = config.layout.elementUiPrimary[0]
|
let color = config.layout.elementUiPrimary[0]
|
||||||
@@ -279,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 = {
|
echartList.value = {
|
||||||
title: {
|
title: {
|
||||||
text: titleText
|
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: {
|
legend: {
|
||||||
data: legendData,
|
data: legendData,
|
||||||
icon: 'rect',
|
icon: 'rect',
|
||||||
@@ -307,7 +359,9 @@ const setEchart = () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
yAxis: {
|
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: {
|
grid: {
|
||||||
left: '10px',
|
left: '10px',
|
||||||
@@ -324,8 +378,7 @@ const tableStore: any = new TableStore({
|
|||||||
exportName: '趋势对比',
|
exportName: '趋势对比',
|
||||||
column: [],
|
column: [],
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
tableStore.table.params.searchBeginTime = tableStore.table.params.searchBeginTime || prop.timeValue?.[0]
|
setTime()
|
||||||
tableStore.table.params.searchEndTime = tableStore.table.params.searchEndTime || prop.timeValue?.[1]
|
|
||||||
if (!tableStore.table.params.sensitiveUserId && idList.value?.length > 0) {
|
if (!tableStore.table.params.sensitiveUserId && idList.value?.length > 0) {
|
||||||
tableStore.table.params.sensitiveUserId = idList.value[0].id
|
tableStore.table.params.sensitiveUserId = idList.value[0].id
|
||||||
}
|
}
|
||||||
@@ -356,12 +409,12 @@ const tableStore: any = new TableStore({
|
|||||||
chartsListBefore.value = tableStore.table.data.before
|
chartsListBefore.value = tableStore.table.data.before
|
||||||
chartsListAfter.value = tableStore.table.data.after
|
chartsListAfter.value = tableStore.table.data.after
|
||||||
setEchart()
|
setEchart()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
tableStore.table.params.indicator = '1'
|
tableStore.table.params.indicator = ''
|
||||||
tableStore.table.params.exceedingTheLimit = '1'
|
tableStore.table.params.exceedingTheLimit = ''
|
||||||
tableStore.table.params.dataLevel = 'Primary'
|
tableStore.table.params.dataLevel = 'Primary'
|
||||||
tableStore.table.params.valueType = 'avg'
|
tableStore.table.params.valueType = 'avg'
|
||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
@@ -370,6 +423,25 @@ onMounted(() => {
|
|||||||
initListByIds()
|
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 = () => {
|
const shouldShowHarmonicCount = () => {
|
||||||
if (!tableStore.table.params.indicator || !indicatorList.value) return false
|
if (!tableStore.table.params.indicator || !indicatorList.value) return false
|
||||||
@@ -378,7 +450,7 @@ const shouldShowHarmonicCount = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
currentIndicator &&
|
currentIndicator &&
|
||||||
(currentIndicator.name.includes('电压谐波含有率') || currentIndicator.name.includes('电流谐波含有率'))
|
(currentIndicator.name.includes('幅值') || currentIndicator.name.includes('含有率'))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,9 +459,9 @@ const getHarmonicTypeName = () => {
|
|||||||
const currentIndicator = indicatorList.value.find((item: any) => item.id === tableStore.table.params.indicator)
|
const currentIndicator = indicatorList.value.find((item: any) => item.id === tableStore.table.params.indicator)
|
||||||
|
|
||||||
if (currentIndicator) {
|
if (currentIndicator) {
|
||||||
if (currentIndicator.name.includes('电压谐波含有率')) {
|
if (currentIndicator.name.includes('电压')) {
|
||||||
return '电压'
|
return '电压'
|
||||||
} else if (currentIndicator.name.includes('电流谐波含有率')) {
|
} else if (currentIndicator.name.includes('电流')) {
|
||||||
return '电流'
|
return '电流'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -405,12 +477,7 @@ watch(
|
|||||||
watch(
|
watch(
|
||||||
() => prop.timeValue,
|
() => prop.timeValue,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
// 当外部时间值变化时,更新表格的时间参数
|
tableStore.index()
|
||||||
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()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true
|
deep: true
|
||||||
@@ -432,8 +499,6 @@ watch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const addMenu = () => {}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
// :deep(.el-select) {
|
// :deep(.el-select) {
|
||||||
|
|||||||
@@ -252,50 +252,52 @@ self.onmessage = function (e) {
|
|||||||
let titles = ''
|
let titles = ''
|
||||||
if (boxoList.systemType == 'pms') {
|
if (boxoList.systemType == 'pms') {
|
||||||
titles =
|
titles =
|
||||||
'变电站名称:' +
|
'变电站名称:' +
|
||||||
boxoList.powerStationName +
|
boxoList.powerStationName +
|
||||||
' 监测点名称:' +
|
' 监测点名称:' +
|
||||||
boxoList.measurementPointName +
|
boxoList.measurementPointName +
|
||||||
' 发生时刻:' +
|
' 发生时刻:' +
|
||||||
boxoList.startTime +
|
boxoList.startTime +
|
||||||
' 残余电压:' +
|
' 暂降(骤升)幅值:' +
|
||||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||||
'% 持续时间:' +
|
'% 持续时间:' +
|
||||||
boxoList.duration +
|
boxoList.duration +
|
||||||
's'
|
's'
|
||||||
} else if (boxoList.systemType == 'ZL') {
|
} else if (boxoList.systemType == 'ZL') {
|
||||||
titles =
|
titles =
|
||||||
' 监测点名称:' +
|
(boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) +
|
||||||
|
' 监测点名称:' +
|
||||||
boxoList.equipmentName +
|
boxoList.equipmentName +
|
||||||
' 发生时刻:' +
|
' 发生时刻:' +
|
||||||
boxoList.startTime +
|
boxoList.startTime +
|
||||||
' 残余电压:' +
|
' 暂降(骤升)幅值:' +
|
||||||
boxoList.evtParamVVaDepth +
|
boxoList.evtParamVVaDepth +
|
||||||
' 持续时间:' +
|
'% 持续时间:' +
|
||||||
boxoList.evtParamTm +
|
boxoList.evtParamTm +
|
||||||
's'
|
's'
|
||||||
} else if (boxoList.systemType == 'YPT') {
|
} else if (boxoList.systemType == 'YPT') {
|
||||||
titles =
|
titles =
|
||||||
' 监测点名称:' +
|
(boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) +
|
||||||
|
' 监测点名称:' +
|
||||||
boxoList.lineName +
|
boxoList.lineName +
|
||||||
' 发生时刻:' +
|
' 发生时刻:' +
|
||||||
boxoList.startTime +
|
boxoList.startTime +
|
||||||
' 残余电压:' +
|
' 暂降(骤升)幅值:' +
|
||||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||||
'% 持续时间:' +
|
'% 持续时间:' +
|
||||||
boxoList.persistTime +
|
boxoList.persistTime +
|
||||||
's'
|
's'
|
||||||
} else {
|
} else {
|
||||||
titles =
|
titles =
|
||||||
'变电站名称:' +
|
' 变电站名称:' +
|
||||||
boxoList.subName +
|
boxoList.subName +
|
||||||
' 监测点名称:' +
|
' 监测点名称:' +
|
||||||
boxoList.lineName +
|
boxoList.lineName +
|
||||||
' 发生时刻:' +
|
' 发生时刻:' +
|
||||||
boxoList.startTime +
|
boxoList.startTime +
|
||||||
' 残余电压:' +
|
' 暂降(骤升)幅值:' +
|
||||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||||
'% 持续时间:' +
|
'% 持续时间:' +
|
||||||
boxoList.duration +
|
boxoList.duration +
|
||||||
's'
|
's'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" style="position: relative; height: 100%">
|
<div v-loading="loading" style="position: relative; height: 100%">
|
||||||
<div id="boxr">
|
<div id="boxr">
|
||||||
<div id="rmsp" :style="`height:${vh};overflow: hidden;`">
|
<div id="rmsp" :style="`height:${vh};overflow: hidden;min-height: 200px;`">
|
||||||
<div class="bx" id="rms"></div>
|
<div class="bx" id="rms" style="min-height: 200px"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -109,7 +109,7 @@ const myChartess5 = ref<echarts.ECharts | null>(null)
|
|||||||
|
|
||||||
const vh = computed(() => {
|
const vh = computed(() => {
|
||||||
if (props.parentHeight == 999) {
|
if (props.parentHeight == 999) {
|
||||||
return '310px'
|
return `calc((60vh - 150px) / 2 )`
|
||||||
} else if (props.parentHeight != 0) {
|
} else if (props.parentHeight != 0) {
|
||||||
return mainHeight(props.parentHeight, 2).height
|
return mainHeight(props.parentHeight, 2).height
|
||||||
}
|
}
|
||||||
@@ -594,13 +594,13 @@ const initWave = (
|
|||||||
for (let step = waveDatas.length - 1; step > 0 && step < waveDatas.length; step--) {
|
for (let step = waveDatas.length - 1; step > 0 && step < waveDatas.length; step--) {
|
||||||
const rmsId = 'rms' + step
|
const rmsId = 'rms' + step
|
||||||
const newDivRms = $(
|
const newDivRms = $(
|
||||||
`<div style="height:${vh.value};overflow: hidden;"><div class='bx' id='${rmsId}'></div></div>`
|
`<div style="height:${vh.value};overflow: hidden;min-height: 200px;"><div class='bx' id='${rmsId}'></div></div>`
|
||||||
)
|
)
|
||||||
newDivRms.insertAfter($('#rmsp'))
|
newDivRms.insertAfter($('#rmsp'))
|
||||||
$(`#${rmsId}`).css('height', picHeight).css('width', vw.value)
|
$(`#${rmsId}`).css('height', picHeight).css('width', vw.value).css('min-height', '200px')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
titleText = `变电站名称:${subName.value} 监测点名称:${lineName.value} 发生时刻:${time} 残余电压:${(
|
titleText = `变电站名称:${subName.value} 监测点名称:${lineName.value} 发生时刻:${time} 暂降(骤升)幅值:${(
|
||||||
Number(eventValue.value) * 1
|
Number(eventValue.value) * 1
|
||||||
).toFixed(0)}% 持续时间:${persistTime.value}s`
|
).toFixed(0)}% 持续时间:${persistTime.value}s`
|
||||||
}
|
}
|
||||||
@@ -749,7 +749,7 @@ const initWave = (
|
|||||||
y: -10
|
y: -10
|
||||||
},
|
},
|
||||||
max: rmscm[0]?.[1] * 1.06 || 0,
|
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%'],
|
boundaryGap: [0, '100%'],
|
||||||
showLastLabel: true,
|
showLastLabel: true,
|
||||||
opposite: false,
|
opposite: false,
|
||||||
@@ -768,7 +768,7 @@ const initWave = (
|
|||||||
fontSize: '12px',
|
fontSize: '12px',
|
||||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||||
formatter: function (value: number) {
|
formatter: function (value: number) {
|
||||||
return (value - 0).toFixed(2)
|
return Math.floor(value * 1000) / 1000
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
splitLine: {
|
splitLine: {
|
||||||
@@ -837,7 +837,7 @@ const initWave = (
|
|||||||
data: rmscu
|
data: rmscu
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '最小残余电压',
|
name: '最小暂降(骤升)幅值',
|
||||||
type: 'scatter',
|
type: 'scatter',
|
||||||
symbol: 'image://' + url2,
|
symbol: 'image://' + url2,
|
||||||
itemStyle: { width: 45, height: 45 },
|
itemStyle: { width: 45, height: 45 },
|
||||||
@@ -1092,7 +1092,8 @@ const drawPics = (
|
|||||||
fontSize: '12px',
|
fontSize: '12px',
|
||||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||||
formatter: function (value: number) {
|
formatter: function (value: number) {
|
||||||
return (value - 0).toFixed(2)
|
// return (value - 0).toFixed(2)
|
||||||
|
return Math.floor(value * 1000) / 1000
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
splitLine: {
|
splitLine: {
|
||||||
|
|||||||
@@ -125,50 +125,52 @@ self.addEventListener('message', function (e) {
|
|||||||
let titles = ''
|
let titles = ''
|
||||||
if (boxoList.systemType == 'pms') {
|
if (boxoList.systemType == 'pms') {
|
||||||
titles =
|
titles =
|
||||||
'变电站名称:' +
|
'变电站名称:' +
|
||||||
boxoList.powerStationName +
|
boxoList.powerStationName +
|
||||||
' 监测点名称:' +
|
' 监测点名称:' +
|
||||||
boxoList.measurementPointName +
|
boxoList.measurementPointName +
|
||||||
' 发生时刻:' +
|
' 发生时刻:' +
|
||||||
boxoList.startTime +
|
boxoList.startTime +
|
||||||
' 残余电压:' +
|
' 暂降(骤升)幅值:' +
|
||||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||||
'% 持续时间:' +
|
'% 持续时间:' +
|
||||||
boxoList.duration +
|
boxoList.duration +
|
||||||
's'
|
's'
|
||||||
} else if (boxoList.systemType == 'ZL') {
|
} else if (boxoList.systemType == 'ZL') {
|
||||||
titles =
|
titles =
|
||||||
' 监测点名称:' +
|
(boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) +
|
||||||
|
' 监测点名称:' +
|
||||||
boxoList.equipmentName +
|
boxoList.equipmentName +
|
||||||
' 发生时刻:' +
|
' 发生时刻:' +
|
||||||
boxoList.startTime +
|
boxoList.startTime +
|
||||||
' 残余电压:' +
|
' 暂降(骤升)幅值:' +
|
||||||
boxoList.evtParamVVaDepth +
|
boxoList.evtParamVVaDepth +
|
||||||
' 持续时间:' +
|
'% 持续时间:' +
|
||||||
boxoList.evtParamTm +
|
boxoList.evtParamTm +
|
||||||
's'
|
's'
|
||||||
} else if (boxoList.systemType == 'YPT') {
|
} else if (boxoList.systemType == 'YPT') {
|
||||||
titles =
|
titles =
|
||||||
' 监测点名称:' +
|
(boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) +
|
||||||
|
' 监测点名称:' +
|
||||||
boxoList.lineName +
|
boxoList.lineName +
|
||||||
' 发生时刻:' +
|
' 发生时刻:' +
|
||||||
boxoList.startTime +
|
boxoList.startTime +
|
||||||
' 残余电压:' +
|
' 暂降(骤升)幅值:' +
|
||||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||||
'% 持续时间:' +
|
'% 持续时间:' +
|
||||||
boxoList.persistTime +
|
boxoList.persistTime +
|
||||||
's'
|
's'
|
||||||
} else {
|
} else {
|
||||||
titles =
|
titles =
|
||||||
'变电站名称:' +
|
'变电站名称:' +
|
||||||
boxoList.subName +
|
boxoList.subName +
|
||||||
' 监测点名称:' +
|
' 监测点名称:' +
|
||||||
boxoList.lineName +
|
boxoList.lineName +
|
||||||
' 发生时刻:' +
|
' 发生时刻:' +
|
||||||
boxoList.startTime +
|
boxoList.startTime +
|
||||||
' 残余电压:' +
|
' 暂降(骤升)幅值:' +
|
||||||
(boxoList.featureAmplitude * 100).toFixed(2) +
|
(boxoList.featureAmplitude * 100).toFixed(2) +
|
||||||
'% 持续时间:' +
|
'% 持续时间:' +
|
||||||
boxoList.duration +
|
boxoList.duration +
|
||||||
's'
|
's'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-loading="loading" class="boxbx" style="position: relative; height: 100%">
|
<div v-loading="loading" class="boxbx" style="position: relative; height: 100%">
|
||||||
<div id="boxsj">
|
<div id="boxsj">
|
||||||
<div id="shushi" :style="`height:${vh};overflow: hidden;`">
|
<div id="shushi" :style="`height:${vh};overflow: hidden;min-height: 200px;`">
|
||||||
<div class="bx" id="wave"></div>
|
<div class="bx" id="wave" style="min-height: 200px"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -88,7 +88,7 @@ const myChartess5 = ref<echarts.ECharts | null>(null)
|
|||||||
|
|
||||||
const vh = computed(() => {
|
const vh = computed(() => {
|
||||||
if (props.parentHeight == 999) {
|
if (props.parentHeight == 999) {
|
||||||
return '310px'
|
return `calc((60vh - 150px) / 2 )`
|
||||||
} else if (props.parentHeight != 0) {
|
} else if (props.parentHeight != 0) {
|
||||||
return mainHeight(props.parentHeight, 2).height
|
return mainHeight(props.parentHeight, 2).height
|
||||||
}
|
}
|
||||||
@@ -327,14 +327,14 @@ const initWave = (
|
|||||||
|
|
||||||
for (let step = waveDatas.length - 1; step > 0 && step < waveDatas.length; step--) {
|
for (let step = waveDatas.length - 1; step > 0 && step < waveDatas.length; step--) {
|
||||||
const waveId = 'wave' + 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 class='bx1' id='${waveId}'></div>
|
||||||
</div>`)
|
</div>`)
|
||||||
newDivShunshi.insertAfter($('#shushi'))
|
newDivShunshi.insertAfter($('#shushi'))
|
||||||
$(`#${waveId}`).css('height', picHeight).css('width', vw.value)
|
$(`#${waveId}`).css('height', picHeight).css('width', vw.value).css('min-height', '200px')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
titleText = `变电站名称:${subName.value} 监测点名称:${lineName.value} 发生时刻:${time} 残余电压:${(
|
titleText = `变电站名称:${subName.value} 监测点名称:${lineName.value} 发生时刻:${time} 暂降(骤升)幅值:${(
|
||||||
Number(eventValue.value) * 1
|
Number(eventValue.value) * 1
|
||||||
).toFixed(0)}% 持续时间:${persistTime.value}s`
|
).toFixed(0)}% 持续时间:${persistTime.value}s`
|
||||||
}
|
}
|
||||||
@@ -499,7 +499,8 @@ const initWave = (
|
|||||||
fontSize: '12px',
|
fontSize: '12px',
|
||||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||||
formatter: function (value: number) {
|
formatter: function (value: number) {
|
||||||
return (value - 0).toFixed(2)
|
// return (value - 0).toFixed(2)
|
||||||
|
return Math.floor(value * 1000) / 1000
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
splitLine: {
|
splitLine: {
|
||||||
@@ -591,7 +592,7 @@ const initWave = (
|
|||||||
|
|
||||||
const drawPics = (
|
const drawPics = (
|
||||||
waveDataTemp: WaveData,
|
waveDataTemp: WaveData,
|
||||||
picHeight: string,
|
picHeight: any,
|
||||||
step: number,
|
step: number,
|
||||||
show: boolean,
|
show: boolean,
|
||||||
myChartes1: echarts.ECharts,
|
myChartes1: echarts.ECharts,
|
||||||
@@ -806,7 +807,8 @@ const drawPics = (
|
|||||||
fontSize: '12px',
|
fontSize: '12px',
|
||||||
color: props.DColor ? '#000' : echartsColor.WordColor,
|
color: props.DColor ? '#000' : echartsColor.WordColor,
|
||||||
formatter: function (value: number) {
|
formatter: function (value: number) {
|
||||||
return (value - 0).toFixed(2)
|
// return (value - 0).toFixed(2)
|
||||||
|
return Math.floor(value * 1000) / 1000
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
splitLine: {
|
splitLine: {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
value-format="YYYY-MM-DD"
|
value-format="YYYY-MM-DD"
|
||||||
:shortcuts="shortcuts"
|
:shortcuts="shortcuts"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<el-button :disabled="backDisabled" type="primary" :icon="DArrowLeft" @click="preClick"></el-button>
|
<el-button :disabled="backDisabled" type="primary" :icon="DArrowLeft" @click="preClick"></el-button>
|
||||||
<el-button type="primary" :icon="VideoPause" @click="nowTime">当前</el-button>
|
<el-button type="primary" :icon="VideoPause" @click="nowTime">当前</el-button>
|
||||||
<el-button :disabled="preDisabled" type="primary" :icon="DArrowRight" @click="next"></el-button>
|
<el-button :disabled="preDisabled" type="primary" :icon="DArrowRight" @click="next"></el-button>
|
||||||
@@ -35,7 +36,7 @@ interface Props {
|
|||||||
theCurrentTime?: boolean
|
theCurrentTime?: boolean
|
||||||
initialInterval?: number
|
initialInterval?: number
|
||||||
initialTimeValue?: any
|
initialTimeValue?: any
|
||||||
timeKeyList?: string[] //日期下拉
|
timeKeyList?: string[] //日期下拉
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@@ -97,10 +98,8 @@ const filteredTimeOptions = computed(() => {
|
|||||||
if (!props.timeKeyList || props.timeKeyList.length === 0) {
|
if (!props.timeKeyList || props.timeKeyList.length === 0) {
|
||||||
return timeOptions.value
|
return timeOptions.value
|
||||||
}
|
}
|
||||||
|
|
||||||
return timeOptions.value.filter((option: any) =>
|
return timeOptions.value.filter((option: any) => props.timeKeyList.includes(option.value.toString()))
|
||||||
props.timeKeyList.includes(option.value.toString())
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -127,9 +126,13 @@ const checkInitialButtonStatus = () => {
|
|||||||
const endTime = timeValue.value[1]
|
const endTime = timeValue.value[1]
|
||||||
const currentDate = window.XEUtils.toDateString(new Date(), 'yyyy-MM-dd')
|
const currentDate = window.XEUtils.toDateString(new Date(), 'yyyy-MM-dd')
|
||||||
|
|
||||||
// 如果结束时间小于当前日期,则不禁用"下一个"按钮
|
// 只有当 props.nextFlag 为 false 时才应用限制
|
||||||
if (new Date(endTime + ' 00:00:00').getTime() < new Date(currentDate + ' 00:00:00').getTime()) {
|
if (!props.nextFlag) {
|
||||||
preDisabled.value = false
|
// 如果结束时间早于当前日期,则按钮可用(preDisabled = false)
|
||||||
|
// 如果结束时间晚于或等于当前日期,则按钮禁用(preDisabled = true)
|
||||||
|
const endDateTime = new Date(endTime).getTime()
|
||||||
|
const currentDateTime = new Date(currentDate).getTime()
|
||||||
|
preDisabled.value = endDateTime >= currentDateTime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,30 +181,15 @@ const timeChange = (e: number) => {
|
|||||||
timeFlag.value = 1
|
timeFlag.value = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查按钮状态
|
nextTick(() => {
|
||||||
checkButtonStatus()
|
// 检查按钮状态
|
||||||
|
checkInitialButtonStatus()
|
||||||
|
})
|
||||||
|
|
||||||
// 触发 change 事件
|
// 触发 change 事件
|
||||||
emitChange()
|
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 = () => {
|
const nowTime = () => {
|
||||||
// console.log(interval.value, '000000000')
|
// console.log(interval.value, '000000000')
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
<el-image
|
<el-image
|
||||||
:hide-on-click-modal="true"
|
:hide-on-click-modal="true"
|
||||||
:preview-teleported="true"
|
:preview-teleported="true"
|
||||||
:preview-src-list="[fieldValue]"
|
:preview-src-list="[imgList[fieldValue]]"
|
||||||
:src="fieldValue.length > 100 ? fieldValue : getUrl(fieldValue)"
|
:src="fieldValue.length > 100 ? fieldValue : getUrl(fieldValue) ? imgList[fieldValue] : ''"
|
||||||
></el-image>
|
></el-image>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -226,10 +226,12 @@ const handlerCommand = (item: OptButton) => {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const imgList: any = ref({})
|
||||||
const getUrl = (url: string) => {
|
const getUrl = (url: string) => {
|
||||||
getFileUrl({ filePath: url }).then(res => {
|
getFileUrl({ filePath: url }).then(res => {
|
||||||
return res.data
|
imgList.value[url] = res.data
|
||||||
})
|
})
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<div ref="tableHeader" class="cn-table-header">
|
<div ref="tableHeader" class="cn-table-header">
|
||||||
<div class="table-header ba-scroll-style" :key="num">
|
<div class="table-header ba-scroll-style" :key="num">
|
||||||
<el-form
|
<el-form
|
||||||
style="flex: 1; height: 34px; margin-right: 20px; display: flex; flex-wrap: wrap"
|
style="flex: 1; height: 34px; margin-right: 0px; display: flex; flex-wrap: wrap"
|
||||||
ref="headerForm"
|
ref="headerForm"
|
||||||
@submit.prevent=""
|
@submit.prevent=""
|
||||||
@keyup.enter="onComSearch"
|
@keyup.enter="onComSearch"
|
||||||
@@ -29,12 +29,27 @@
|
|||||||
<Icon size="14" name="el-icon-ArrowUp" style="color: #fff" v-if="showSelect" />
|
<Icon size="14" name="el-icon-ArrowUp" style="color: #fff" v-if="showSelect" />
|
||||||
<Icon size="14" name="el-icon-ArrowDown" style="color: #fff" v-else />
|
<Icon size="14" name="el-icon-ArrowDown" style="color: #fff" v-else />
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button @click="onComSearch" v-if="showSearch" type="primary" :icon="Search">查询</el-button>
|
<el-button
|
||||||
<el-button @click="onResetForm" v-if="showSearch && showReset" :icon="RefreshLeft">重置</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
|
<el-button
|
||||||
@click="onExport"
|
@click="onExport"
|
||||||
v-if="showExport"
|
v-if="showExport"
|
||||||
:loading="tableStore.table.loading"
|
:loading="tableStore.table.exportLoading"
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-Download"
|
icon="el-icon-Download"
|
||||||
>
|
>
|
||||||
@@ -90,7 +105,7 @@ interface Props {
|
|||||||
showReset?: boolean //是否显示重置
|
showReset?: boolean //是否显示重置
|
||||||
showExport?: boolean //导出控制
|
showExport?: boolean //导出控制
|
||||||
timeCacheFlag?: boolean //是否取缓存时间
|
timeCacheFlag?: boolean //是否取缓存时间
|
||||||
timeKeyList?: Array<string> //日期下拉列表
|
timeKeyList?: string[] //日期下拉列表
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@@ -102,7 +117,7 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
showReset: true,
|
showReset: true,
|
||||||
showExport: false,
|
showExport: false,
|
||||||
timeCacheFlag: true,
|
timeCacheFlag: true,
|
||||||
timeKeyList: () => [] // 修改为箭头函数返回空数组
|
timeKeyList: () => ['1', '2', '3', '4', '5'] // 修改为箭头函数返回空数组
|
||||||
})
|
})
|
||||||
|
|
||||||
// 处理 DatePicker 值变化事件
|
// 处理 DatePicker 值变化事件
|
||||||
|
|||||||
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'
|
:class="menuCollapse ? 'unfold' : ''" size='18' class='fold ml10 menu-collapse'
|
||||||
style='cursor: pointer' v-if='props.canExpand' /> -->
|
style='cursor: pointer' v-if='props.canExpand' /> -->
|
||||||
</div>
|
</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"
|
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'>
|
@check-change="checkTreeNodeChange" :filter-node-method='filterNode' node-key='id' v-bind='$attrs'>
|
||||||
<template #default='{ node, data }'>
|
<template #default='{ node, data }'>
|
||||||
@@ -32,7 +32,6 @@
|
|||||||
<script lang='ts' setup>
|
<script lang='ts' setup>
|
||||||
import useCurrentInstance from '@/utils/useCurrentInstance'
|
import useCurrentInstance from '@/utils/useCurrentInstance'
|
||||||
import { ElTree } from 'element-plus'
|
import { ElTree } from 'element-plus'
|
||||||
import { emit } from 'process';
|
|
||||||
import { ref, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
|
|||||||
@@ -1,27 +1,48 @@
|
|||||||
<!-- 设备管理使用折叠面板渲染多个tree -->
|
<!-- 设备管理使用折叠面板渲染多个tree -->
|
||||||
<template>
|
<template>
|
||||||
<div :style="{ width: menuCollapse ? '40px' : props.width }" style="display: flex; overflow: hidden">
|
<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'"
|
<Icon
|
||||||
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 mt20 menu-collapse"
|
v-show="menuCollapse"
|
||||||
style="cursor: pointer" />
|
@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 class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1 }">
|
||||||
<div style="display: flex; align-items: center" class="mb10">
|
<div style="display: flex; align-items: center" class="mb10">
|
||||||
<!-- <el-form-item> -->
|
<!-- <el-form-item> -->
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="filterText" autocomplete="off"
|
<el-input
|
||||||
placeholder="请输入内容" clearable>
|
maxlength="32"
|
||||||
|
show-word-limit
|
||||||
|
v-model.trim="filterText"
|
||||||
|
autocomplete="off"
|
||||||
|
placeholder="请输入内容"
|
||||||
|
clearable
|
||||||
|
>
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<Icon name="el-icon-Search" style="font-size: 16px" />
|
<Icon name="el-icon-Search" style="font-size: 16px" />
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<!-- </el-form-item> -->
|
<!-- </el-form-item> -->
|
||||||
<Icon @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
<Icon
|
||||||
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 menu-collapse"
|
@click="onMenuCollapse"
|
||||||
style="cursor: pointer" v-if="props.canExpand" />
|
: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>
|
</div>
|
||||||
|
|
||||||
<el-collapse :accordion="true" v-model.trim="activeName" style="flex: 1; height: 100%"
|
<el-collapse
|
||||||
@change="changeDevice">
|
: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-collapse-item title="治理设备" name="0" v-if="zlDeviceData.length != 0">
|
||||||
<el-select v-model.trim="process" clearable placeholder="请选择状态" class="mb10">
|
<el-select v-model.trim="process" clearable placeholder="请选择状态" class="mb10">
|
||||||
<el-option label="功能调试" value="2"></el-option>
|
<el-option label="功能调试" value="2"></el-option>
|
||||||
@@ -29,13 +50,30 @@
|
|||||||
<el-option label="正式投运" value="4"></el-option>
|
<el-option label="正式投运" value="4"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-tree
|
<el-tree
|
||||||
:style="{ height: bxsDeviceData.length != 0 ? 'calc(100vh - 340px)' : 'calc(100vh - 278px)' }"
|
:style="{
|
||||||
ref="treeRef1" :props="defaultProps" highlight-current :filter-node-method="filterNode"
|
height:
|
||||||
node-key="id" :default-expand-all="false" v-bind="$attrs" :data="zlDevList" style="overflow: auto">
|
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 }">
|
<template #default="{ node, data }">
|
||||||
<span class="custom-tree-node">
|
<span class="custom-tree-node">
|
||||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
<Icon
|
||||||
v-if="data.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 style="margin-left: 4px">{{ node.label }}</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -43,29 +81,61 @@
|
|||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
<el-collapse-item title="便携式设备" name="1" v-if="bxsDeviceData.length != 0">
|
<el-collapse-item title="便携式设备" name="1" v-if="bxsDeviceData.length != 0">
|
||||||
<el-tree
|
<el-tree
|
||||||
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 280px)' : 'calc(100vh - 238px)' }"
|
:style="{
|
||||||
ref="treeRef2" :props="defaultProps" highlight-current :default-expand-all="false"
|
height:
|
||||||
:filter-node-method="filterNode" node-key="id" :data="bxsDeviceData" v-bind="$attrs"
|
zlDeviceData.length != 0
|
||||||
style="overflow: auto">
|
? `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 }">
|
<template #default="{ node, data }">
|
||||||
<span class="custom-tree-node">
|
<span class="custom-tree-node">
|
||||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
<Icon
|
||||||
v-if="data.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 style="margin-left: 4px">{{ node.label }}</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
</el-collapse-item>
|
</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
|
<el-tree
|
||||||
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 280px)' : 'calc(100vh - 238px)' }"
|
:style="{
|
||||||
ref="treeRef3" :props="defaultProps" highlight-current :default-expand-all="false"
|
height:
|
||||||
:filter-node-method="filterNode" node-key="id" :data="frontDeviceData" v-bind="$attrs"
|
zlDeviceData.length != 0
|
||||||
style="overflow: auto">
|
? `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 }">
|
<template #default="{ node, data }">
|
||||||
<span class="custom-tree-node">
|
<span class="custom-tree-node">
|
||||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
<Icon
|
||||||
v-if="data.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 style="margin-left: 4px">{{ node.label }}</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -90,13 +160,15 @@ interface Props {
|
|||||||
canExpand?: boolean
|
canExpand?: boolean
|
||||||
type?: string
|
type?: string
|
||||||
data?: any
|
data?: any
|
||||||
|
height?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
width: '280px',
|
width: '280px',
|
||||||
canExpand: true,
|
canExpand: true,
|
||||||
type: '',
|
type: '',
|
||||||
data: []
|
data: [],
|
||||||
|
height: 0
|
||||||
})
|
})
|
||||||
const { proxy } = useCurrentInstance()
|
const { proxy } = useCurrentInstance()
|
||||||
const menuCollapse = ref(false)
|
const menuCollapse = ref(false)
|
||||||
@@ -124,19 +196,18 @@ watch(
|
|||||||
item.children.map((vv: any) => {
|
item.children.map((vv: any) => {
|
||||||
zlDeviceData.value.push(vv)
|
zlDeviceData.value.push(vv)
|
||||||
})
|
})
|
||||||
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
||||||
} else if (item.name == '便携式设备') {
|
} else if (item.name == '便携式设备') {
|
||||||
bxsDeviceData.value = []
|
bxsDeviceData.value = []
|
||||||
item.children.map((vv: any) => {
|
item.children.map((vv: any) => {
|
||||||
bxsDeviceData.value.push(vv)
|
bxsDeviceData.value.push(vv)
|
||||||
})
|
})
|
||||||
}else if (item.name == '在线设备') {
|
} else if (item.name == '监测设备') {
|
||||||
frontDeviceData.value = []
|
frontDeviceData.value = []
|
||||||
|
|
||||||
item.children.map((vv: any) => {
|
item.children.map((vv: any) => {
|
||||||
frontDeviceData.value.push(vv)
|
frontDeviceData.value.push(vv)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -157,8 +228,9 @@ watch(filterText, val => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
watch(process, val => {
|
watch(process, val => {
|
||||||
if (val == '') {
|
if (val == '' || val == undefined) {
|
||||||
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
||||||
|
console.log('🚀 ~ zlDevList.value:', zlDeviceData.value)
|
||||||
} else {
|
} else {
|
||||||
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
|
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
|
||||||
}
|
}
|
||||||
@@ -176,7 +248,7 @@ function filterProcess(nodes: any) {
|
|||||||
const children = node.children ? filterProcess(node.children) : []
|
const children = node.children ? filterProcess(node.children) : []
|
||||||
|
|
||||||
// 如果当前节点的process=4,或者有子节点满足条件,则保留当前节点
|
// 如果当前节点的process=4,或者有子节点满足条件,则保留当前节点
|
||||||
if ( node.process == process.value || children.length > 0) {
|
if (node.process == process.value || children.length > 0) {
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
children: children
|
children: children
|
||||||
@@ -228,7 +300,6 @@ const chooseNode = (value: string, data: any, node: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const changeDevice = (val: any) => {
|
const changeDevice = (val: any) => {
|
||||||
console.log('changeDevice', val)
|
|
||||||
let arr1: any = []
|
let arr1: any = []
|
||||||
|
|
||||||
//zlDeviceData
|
//zlDeviceData
|
||||||
@@ -259,22 +330,30 @@ const changeDevice = (val: any) => {
|
|||||||
arr2.map((item: any) => {
|
arr2.map((item: any) => {
|
||||||
item.checked = false
|
item.checked = false
|
||||||
})
|
})
|
||||||
treeRef1.value && treeRef1.value.setCurrentKey(arr1[0]?.id)
|
|
||||||
emit('changeDeviceType', activeName.value, arr1[0])
|
emit('changeDeviceType', activeName.value, arr1[0])
|
||||||
|
setTimeout(() => {
|
||||||
|
treeRef1.value?.setCurrentKey(arr1[0]?.id)
|
||||||
|
}, 100)
|
||||||
}
|
}
|
||||||
if (val == '1') {
|
if (val == '1') {
|
||||||
arr1.map((item: any) => {
|
arr1.map((item: any) => {
|
||||||
item.checked = false
|
item.checked = false
|
||||||
})
|
})
|
||||||
treeRef2.value && treeRef2.value.setCurrentKey(arr2[0]?.id)
|
|
||||||
emit('changeDeviceType', activeName.value, arr2[0])
|
emit('changeDeviceType', activeName.value, arr2[0])
|
||||||
|
setTimeout(() => {
|
||||||
|
treeRef2.value?.setCurrentKey(arr2[0]?.id)
|
||||||
|
}, 100)
|
||||||
}
|
}
|
||||||
if (val == '2') {
|
if (val == '2') {
|
||||||
arr3.map((item: any) => {
|
arr3.map((item: any) => {
|
||||||
item.checked = false
|
item.checked = false
|
||||||
})
|
})
|
||||||
treeRef3.value && treeRef3.value.setCurrentKey(arr3[0]?.id)
|
|
||||||
emit('changeDeviceType', activeName.value, arr3[0])
|
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 treeRef2 = ref<InstanceType<typeof ElTree>>()
|
||||||
//前置
|
//前置
|
||||||
const treeRef3 = ref<InstanceType<typeof ElTree>>()
|
const treeRef3 = ref<InstanceType<typeof ElTree>>()
|
||||||
defineExpose({ treeRef1, treeRef2 })
|
defineExpose({ treeRef1, treeRef2, treeRef3 })
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (zlDeviceData.value.length != 0) {
|
if (zlDeviceData.value.length != 0) {
|
||||||
@@ -293,6 +372,9 @@ onMounted(() => {
|
|||||||
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length != 0) {
|
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length != 0) {
|
||||||
activeName.value = '1'
|
activeName.value = '1'
|
||||||
}
|
}
|
||||||
|
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length === 0) {
|
||||||
|
activeName.value = '2'
|
||||||
|
}
|
||||||
if (!zlDeviceData.value && !bxsDeviceData.value) {
|
if (!zlDeviceData.value && !bxsDeviceData.value) {
|
||||||
activeName.value = ''
|
activeName.value = ''
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<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>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
@@ -7,14 +7,16 @@ import { ref, nextTick, onMounted, defineProps } from 'vue'
|
|||||||
import Tree from '../index.vue'
|
import Tree from '../index.vue'
|
||||||
import { getLineTree,getCldTree } from '@/api/cs-device-boot/csLedger'
|
import { getLineTree,getCldTree } from '@/api/cs-device-boot/csLedger'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import { getTemplateByDept } from '@/api/harmonic-boot/luckyexcel'
|
import { querySysExcel } from '@/api/harmonic-boot/luckyexcel'
|
||||||
import { useDictData } from '@/stores/dictData'
|
import { useDictData } from '@/stores/dictData'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
template?: boolean
|
template?: boolean
|
||||||
|
showPush?: boolean
|
||||||
}
|
}
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
template: false
|
template: false,
|
||||||
|
showPush: false
|
||||||
})
|
})
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'govern/deviceTree'
|
name: 'govern/deviceTree'
|
||||||
@@ -37,8 +39,8 @@ const info = (selectedNodeId?: string) => {
|
|||||||
let rootData = null;
|
let rootData = null;
|
||||||
if (Array.isArray(res.data)) {
|
if (Array.isArray(res.data)) {
|
||||||
// 旧的数据结构 - 数组
|
// 旧的数据结构 - 数组
|
||||||
rootData = res.data.find((item: any) => item.name == '在线设备');
|
rootData = res.data.find((item: any) => item.name == '监测设备');
|
||||||
} else if (res.data && res.data.name == '在线设备') {
|
} else if (res.data && res.data.name == '监测设备') {
|
||||||
// 新的数据结构 - 单个对象
|
// 新的数据结构 - 单个对象
|
||||||
rootData = res.data;
|
rootData = res.data;
|
||||||
}
|
}
|
||||||
@@ -95,13 +97,16 @@ const info = (selectedNodeId?: string) => {
|
|||||||
tree.value = []
|
tree.value = []
|
||||||
}
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
|
||||||
if (arr1.length) {
|
if (arr1.length) {
|
||||||
// 安全检查 treRef 和 treeRef1 是否存在
|
// 安全检查 treRef 和 treeRef 是否存在
|
||||||
if (treRef.value && treRef.value.treeRef1 && treRef.value.treeRef1.setCurrentKey) {
|
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,则选中该节点,否则选中第一个节点
|
// 如果传入了要选中的节点ID,则选中该节点,否则选中第一个节点
|
||||||
console.log('selectedNodeId:', selectedNodeId);
|
console.log('selectedNodeId:', selectedNodeId);
|
||||||
if (selectedNodeId) {
|
if (selectedNodeId) {
|
||||||
treRef.value.treeRef1.setCurrentKey(selectedNodeId);
|
treRef.value.treeRef.setCurrentKey(selectedNodeId);
|
||||||
// 查找对应的节点数据并触发事件
|
// 查找对应的节点数据并触发事件
|
||||||
let selectedNode = null;
|
let selectedNode = null;
|
||||||
const findNode = (nodes: any[]) => {
|
const findNode = (nodes: any[]) => {
|
||||||
@@ -127,7 +132,7 @@ const info = (selectedNodeId?: string) => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 初始化选中第一个节点
|
// 初始化选中第一个节点
|
||||||
treRef.value.treeRef1.setCurrentKey(arr1[0].id);
|
treRef.value.treeRef.setCurrentKey(arr1[0].id);
|
||||||
emit('init', {
|
emit('init', {
|
||||||
level: 2,
|
level: 2,
|
||||||
...arr1[0]
|
...arr1[0]
|
||||||
@@ -153,7 +158,7 @@ const onAdd = () => {
|
|||||||
emit('onAdd')
|
emit('onAdd')
|
||||||
}
|
}
|
||||||
if (props.template) {
|
if (props.template) {
|
||||||
getTemplateByDept({ id: dictData.state.area[0].id })
|
querySysExcel({ id: dictData.state.area[0]?.id })
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
emit('Policy', res.data)
|
emit('Policy', res.data)
|
||||||
info()
|
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"
|
:default-checked-keys="defaultCheckedKeys"
|
||||||
:show-checkbox="props.showCheckbox"
|
:show-checkbox="props.showCheckbox"
|
||||||
:data="tree"
|
:data="tree"
|
||||||
|
:height="props.height"
|
||||||
@changeDeviceType="changeDeviceType"
|
@changeDeviceType="changeDeviceType"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, nextTick, defineEmits } from 'vue'
|
import { ref, nextTick } from 'vue'
|
||||||
import Tree from '../device.vue'
|
import Tree from '../device.vue'
|
||||||
import { getDeviceTree } from '@/api/cs-device-boot/csLedger'
|
import { getDeviceTree } from '@/api/cs-device-boot/csLedger'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
|
import { throttle } from 'lodash'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'govern/deviceTree'
|
name: 'govern/deviceTree'
|
||||||
})
|
})
|
||||||
@@ -21,10 +23,12 @@ const props = withDefaults(
|
|||||||
defineProps<{
|
defineProps<{
|
||||||
showCheckbox?: boolean
|
showCheckbox?: boolean
|
||||||
defaultCheckedKeys?: any
|
defaultCheckedKeys?: any
|
||||||
|
height?: number
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
showCheckbox: false,
|
showCheckbox: false,
|
||||||
defaultCheckedKeys: []
|
defaultCheckedKeys: [],
|
||||||
|
height: 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const emit = defineEmits(['init', 'checkChange', 'deviceTypeChange'])
|
const emit = defineEmits(['init', 'checkChange', 'deviceTypeChange'])
|
||||||
@@ -32,7 +36,6 @@ const config = useConfig()
|
|||||||
const tree = ref()
|
const tree = ref()
|
||||||
const treRef = ref()
|
const treRef = ref()
|
||||||
const changeDeviceType = (val: any, obj: any) => {
|
const changeDeviceType = (val: any, obj: any) => {
|
||||||
console.log("🚀 ~ changeDeviceType ~ val:", val,obj)
|
|
||||||
emit('deviceTypeChange', val, obj)
|
emit('deviceTypeChange', val, obj)
|
||||||
}
|
}
|
||||||
getDeviceTree().then(res => {
|
getDeviceTree().then(res => {
|
||||||
@@ -49,8 +52,9 @@ getDeviceTree().then(res => {
|
|||||||
item2.icon = 'el-icon-List'
|
item2.icon = 'el-icon-List'
|
||||||
item2.color = config.getColorVal('elementUiPrimary')
|
item2.color = config.getColorVal('elementUiPrimary')
|
||||||
item2.children.forEach((item3: any) => {
|
item2.children.forEach((item3: any) => {
|
||||||
|
item3.pName = '治理设备'
|
||||||
item3.icon = 'el-icon-Platform'
|
item3.icon = 'el-icon-Platform'
|
||||||
item3.level = 2
|
item3.level = 2
|
||||||
item3.color = config.getColorVal('elementUiPrimary')
|
item3.color = config.getColorVal('elementUiPrimary')
|
||||||
if (item3.comFlag === 1) {
|
if (item3.comFlag === 1) {
|
||||||
item3.color = '#e26257 !important'
|
item3.color = '#e26257 !important'
|
||||||
@@ -65,14 +69,15 @@ getDeviceTree().then(res => {
|
|||||||
item.color = config.getColorVal('elementUiPrimary')
|
item.color = config.getColorVal('elementUiPrimary')
|
||||||
item.color = '#e26257 !important'
|
item.color = '#e26257 !important'
|
||||||
item.color = item.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
|
item.color = item.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
|
||||||
|
// item.disabled =true
|
||||||
|
item.pName = '便携式设备'
|
||||||
if (item.type == 'device') {
|
if (item.type == 'device') {
|
||||||
arr2.push(item)
|
arr2.push(item)
|
||||||
}
|
}
|
||||||
item.children.forEach((item2: any) => {
|
item.children.forEach((item2: any) => {
|
||||||
item2.icon = 'el-icon-Platform'
|
item2.icon = 'el-icon-Platform'
|
||||||
item2.color = item2.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
|
item2.color = item2.comFlag === 2 ? config.getColorVal('elementUiPrimary') : '#e26257 !important'
|
||||||
|
item2.pName = '便携式设备'
|
||||||
// item2.children.forEach((item3: any) => {
|
// item2.children.forEach((item3: any) => {
|
||||||
// item3.icon = 'el-icon-Platform'
|
// item3.icon = 'el-icon-Platform'
|
||||||
// item3.color = config.getColorVal('elementUiPrimary')
|
// item3.color = config.getColorVal('elementUiPrimary')
|
||||||
@@ -83,14 +88,15 @@ getDeviceTree().then(res => {
|
|||||||
// })
|
// })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}else if (item.name == '在线设备') {
|
} else if (item.name == '监测设备') {
|
||||||
item.children.forEach((item: any) => {
|
item.children.forEach((item: any) => {
|
||||||
item.icon = 'el-icon-HomeFilled'
|
item.icon = 'el-icon-HomeFilled'
|
||||||
item.color = config.getColorVal('elementUiPrimary')
|
item.color = config.getColorVal('elementUiPrimary')
|
||||||
item.children.forEach((item2: any) => {
|
item.children.forEach((item2: any) => {
|
||||||
item2.icon = 'el-icon-List'
|
item2.icon = 'el-icon-List'
|
||||||
item2.color = config.getColorVal('elementUiPrimary')
|
item2.color = config.getColorVal('elementUiPrimary')
|
||||||
item2.children.forEach((item3: any) => {
|
item2.children.forEach((item3: any) => {
|
||||||
|
item3.pName = '监测设备'
|
||||||
item3.icon = 'el-icon-Platform'
|
item3.icon = 'el-icon-Platform'
|
||||||
item3.color = config.getColorVal('elementUiPrimary')
|
item3.color = config.getColorVal('elementUiPrimary')
|
||||||
if (item3.comFlag === 1) {
|
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
|
tree.value = res.data
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (arr.length) {
|
setTimeout(() => {
|
||||||
treRef.value.treeRef1.setCurrentKey(arr[0].id)
|
if (arr.length > 0) {
|
||||||
// 注册父组件事件
|
treRef.value.treeRef1.setCurrentKey(arr[0].id)
|
||||||
emit('init', {
|
// 注册父组件事件
|
||||||
level: 2,
|
emit('init', {
|
||||||
...arr[0]
|
level: 2,
|
||||||
})
|
...arr[0]
|
||||||
return
|
})
|
||||||
}
|
return
|
||||||
if (arr2.length) {
|
} else if (arr2.length > 0) {
|
||||||
treRef.value.treeRef2.setCurrentKey(arr2[0].id)
|
treRef.value.treeRef2.setCurrentKey(arr2[0].id)
|
||||||
// 注册父组件事件
|
// 注册父组件事件
|
||||||
emit('init', {
|
emit('init', {
|
||||||
level: 2,
|
level: 2,
|
||||||
...arr2[0]
|
...arr2[0]
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
} else if (arr3.length > 0) {
|
||||||
console.log("🚀 ~ file: deviceTree.vue ~ line 33 ~ getDeviceTree ~ tree:", arr3.length)
|
console.log('🚀 ~ arr3:', arr3)
|
||||||
if (arr3.length) {
|
|
||||||
console.log("🚀 ~ file: deviceTree.vue ~ line 33 ~ getDeviceTree ~ tree:", arr3)
|
treRef.value.treeRef3.setCurrentKey(arr3[0].id)
|
||||||
treRef.value.treeRef3.setCurrentKey(arr3[0].id)
|
// 注册父组件事件
|
||||||
// 注册父组件事件
|
emit('init', {
|
||||||
emit('init', {
|
level: 2,
|
||||||
level: 2,
|
...arr3[0]
|
||||||
...arr3[0]
|
})
|
||||||
})
|
return
|
||||||
return
|
} else {
|
||||||
}
|
emit('init')
|
||||||
else {
|
return
|
||||||
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) => {
|
const handleCheckChange = (data: any, checked: any, indeterminate: any) => {
|
||||||
emit('checkChange', {
|
emit('checkChange', {
|
||||||
data,
|
data,
|
||||||
@@ -148,4 +168,7 @@ const handleCheckChange = (data: any, checked: any, indeterminate: any) => {
|
|||||||
indeterminate
|
indeterminate
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
defineExpose({
|
||||||
|
treRef
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { ref, nextTick, onMounted, defineProps } from 'vue'
|
|||||||
import Tree from '../point.vue'
|
import Tree from '../point.vue'
|
||||||
import { getLineTree } from '@/api/cs-device-boot/csLedger'
|
import { getLineTree } from '@/api/cs-device-boot/csLedger'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import { getTemplateByDept } from '@/api/harmonic-boot/luckyexcel'
|
import { querySysExcel } from '@/api/harmonic-boot/luckyexcel'
|
||||||
import { useDictData } from '@/stores/dictData'
|
import { useDictData } from '@/stores/dictData'
|
||||||
// const props = defineProps(['template'])
|
// const props = defineProps(['template'])
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -71,7 +71,7 @@ const info = () => {
|
|||||||
arr2.push(item2)
|
arr2.push(item2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else if (item.name == '在线设备') {
|
} else if (item.name == '监测设备') {
|
||||||
item.children.forEach((item: any) => {
|
item.children.forEach((item: any) => {
|
||||||
item.icon = 'el-icon-HomeFilled'
|
item.icon = 'el-icon-HomeFilled'
|
||||||
item.level = 1
|
item.level = 1
|
||||||
@@ -99,38 +99,38 @@ const info = () => {
|
|||||||
})
|
})
|
||||||
tree.value = res.data
|
tree.value = res.data
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (arr1.length) {
|
setTimeout(() => {
|
||||||
//初始化选中
|
if (arr1.length > 0) {
|
||||||
treRef.value.treeRef1.setCurrentKey(arr1[0].id)
|
//初始化选中
|
||||||
// 注册父组件事件
|
treRef.value?.treeRef1.setCurrentKey(arr1[0].id)
|
||||||
emit('init', {
|
// 注册父组件事件
|
||||||
level: 2,
|
emit('init', {
|
||||||
...arr1[0]
|
level: 2,
|
||||||
})
|
...arr1[0]
|
||||||
return
|
})
|
||||||
}
|
return
|
||||||
if (arr2.length) {
|
} else if (arr2.length > 0) {
|
||||||
//初始化选中
|
//初始化选中
|
||||||
treRef.value.treeRef2.setCurrentKey(arr2[0].id)
|
treRef.value?.treeRef2.setCurrentKey(arr2[0].id)
|
||||||
// 注册父组件事件
|
// 注册父组件事件
|
||||||
emit('init', {
|
emit('init', {
|
||||||
level: 2,
|
level: 2,
|
||||||
...arr2[0]
|
...arr2[0]
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
} else if (arr3.length > 0) {
|
||||||
if(arr3.length){
|
|
||||||
treRef.value.treeRef3.setCurrentKey(arr3[0].id)
|
treRef.value?.treeRef3?.setCurrentKey(arr3[0].id)
|
||||||
emit('init', {
|
emit('init', {
|
||||||
level: 2,
|
level: 2,
|
||||||
...arr3[0]
|
...arr3[0]
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
} else {
|
||||||
else {
|
emit('init')
|
||||||
emit('init')
|
return
|
||||||
return
|
}
|
||||||
}
|
}, 500)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -138,7 +138,7 @@ const changePointType = (val: any, obj: any) => {
|
|||||||
emit('pointTypeChange', val, obj)
|
emit('pointTypeChange', val, obj)
|
||||||
}
|
}
|
||||||
if (props.template) {
|
if (props.template) {
|
||||||
getTemplateByDept({ id: dictData.state.area[0].id })
|
querySysExcel({ id: dictData.state.area[0]?.id })
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
emit('Policy', res.data)
|
emit('Policy', res.data)
|
||||||
info()
|
info()
|
||||||
|
|||||||
@@ -1,181 +1,196 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div style="transition: all 0.3s; overflow: hidden; height: 100%">
|
<div style="transition: all 0.3s; overflow: hidden; height: 100%">
|
||||||
|
<div class="cn-tree">
|
||||||
<div class="cn-tree">
|
<div style="display: flex; align-items: center" class="mb10">
|
||||||
<div style="display: flex; align-items: center" class="mb10">
|
<el-input
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="filterText" placeholder="请输入内容" clearable>
|
maxlength="32"
|
||||||
<template #prefix>
|
show-word-limit
|
||||||
<Icon name="el-icon-Search" style="font-size: 16px" />
|
v-model.trim="filterText"
|
||||||
</template>
|
placeholder="请输入内容"
|
||||||
</el-input>
|
clearable
|
||||||
</div>
|
>
|
||||||
<el-tree style="flex: 1; overflow: auto" :props="defaultProps" highlight-current
|
<template #prefix>
|
||||||
:filter-node-method="filterNode" node-key="id" v-bind="$attrs" default-expand-all :data="tree"
|
<Icon name="el-icon-Search" style="font-size: 16px" />
|
||||||
ref="treRef" @node-click="clickNode" :expand-on-click-node="false">
|
</template>
|
||||||
<template #default="{ node, data }">
|
</el-input>
|
||||||
<span class="custom-tree-node">
|
</div>
|
||||||
<div class="left">
|
<el-tree
|
||||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
style="flex: 1; overflow: auto"
|
||||||
v-if="data.icon" />
|
:props="defaultProps"
|
||||||
<span>{{ node.label }}</span>
|
highlight-current
|
||||||
</div>
|
:filter-node-method="filterNode"
|
||||||
|
node-key="id"
|
||||||
</span>
|
v-bind="$attrs"
|
||||||
</template>
|
default-expand-all
|
||||||
</el-tree>
|
:data="tree"
|
||||||
</div>
|
ref="treRef"
|
||||||
</div>
|
@node-click="clickNode"
|
||||||
</div>
|
:expand-on-click-node="false"
|
||||||
</template>
|
>
|
||||||
|
<template #default="{ node, data }">
|
||||||
<script lang="ts" setup>
|
<span class="custom-tree-node">
|
||||||
import { ref, nextTick, watch, defineProps, defineEmits } from 'vue'
|
<div class="left" style="display: flex; align-items: center">
|
||||||
import { getSchemeTree, getTestRecordInfo } from '@/api/cs-device-boot/planData'
|
<Icon
|
||||||
import { useConfig } from '@/stores/config'
|
:name="data.icon"
|
||||||
import useCurrentInstance from '@/utils/useCurrentInstance'
|
style="font-size: 16px"
|
||||||
import { ElTree } from 'element-plus'
|
:style="{ color: data.color }"
|
||||||
import { getTemplateByDept } from '@/api/harmonic-boot/luckyexcel'
|
v-if="data.icon"
|
||||||
import { useDictData } from '@/stores/dictData'
|
/>
|
||||||
defineOptions({
|
<span style="margin-left: 5px;">{{ node.label }}</span>
|
||||||
name: 'govern/schemeTree'
|
</div>
|
||||||
})
|
</span>
|
||||||
|
</template>
|
||||||
interface Props {
|
</el-tree>
|
||||||
template?: boolean
|
</div>
|
||||||
|
</div>
|
||||||
}
|
</div>
|
||||||
const dictData = useDictData()
|
</template>
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
template: false,
|
<script lang="ts" setup>
|
||||||
|
import { ref, nextTick, watch, defineProps, defineEmits } from 'vue'
|
||||||
})
|
import { getSchemeTree, getTestRecordInfo } from '@/api/cs-device-boot/planData'
|
||||||
const filterText = ref('')
|
import { useConfig } from '@/stores/config'
|
||||||
watch(filterText, val => {
|
import useCurrentInstance from '@/utils/useCurrentInstance'
|
||||||
treRef.value!.filter(val)
|
import { ElTree } from 'element-plus'
|
||||||
})
|
import { querySysExcel } from '@/api/harmonic-boot/luckyexcel'
|
||||||
|
import { useDictData } from '@/stores/dictData'
|
||||||
const filterNode = (value: string, data: any, node: any) => {
|
defineOptions({
|
||||||
if (!value) return true
|
name: 'govern/schemeTree'
|
||||||
// return data.name.includes(value)
|
})
|
||||||
if (data.name) {
|
|
||||||
return chooseNode(value, data, node)
|
interface Props {
|
||||||
}
|
template?: boolean
|
||||||
}
|
}
|
||||||
const chooseNode = (value: string, data: any, node: any) => {
|
const dictData = useDictData()
|
||||||
if (data.name.indexOf(value) !== -1) {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
return true
|
template: false
|
||||||
}
|
})
|
||||||
const level = node.level
|
const filterText = ref('')
|
||||||
// 如果传入的节点本身就是一级节点就不用校验了
|
watch(filterText, val => {
|
||||||
if (level === 1) {
|
treRef.value!.filter(val)
|
||||||
return false
|
})
|
||||||
}
|
|
||||||
// 先取当前节点的父节点
|
const filterNode = (value: string, data: any, node: any) => {
|
||||||
let parentData = node.parent
|
if (!value) return true
|
||||||
// 遍历当前节点的父节点
|
// return data.name.includes(value)
|
||||||
let index = 0
|
if (data.name) {
|
||||||
while (index < level - 1) {
|
return chooseNode(value, data, node)
|
||||||
// 如果匹配到直接返回,此处name值是中文字符,enName是英文字符。判断匹配中英文过滤
|
}
|
||||||
if (parentData.data.name.indexOf(value) !== -1) {
|
}
|
||||||
return true
|
const chooseNode = (value: string, data: any, node: any) => {
|
||||||
}
|
if (data.name.indexOf(value) !== -1) {
|
||||||
// 否则的话再往上一层做匹配
|
return true
|
||||||
parentData = parentData.parent
|
}
|
||||||
index++
|
const level = node.level
|
||||||
}
|
// 如果传入的节点本身就是一级节点就不用校验了
|
||||||
// 没匹配到返回false
|
if (level === 1) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
/** 树形结构数据 */
|
// 先取当前节点的父节点
|
||||||
const defaultProps = {
|
let parentData = node.parent
|
||||||
children: 'children',
|
// 遍历当前节点的父节点
|
||||||
label: 'name',
|
let index = 0
|
||||||
value: 'id'
|
while (index < level - 1) {
|
||||||
}
|
// 如果匹配到直接返回,此处name值是中文字符,enName是英文字符。判断匹配中英文过滤
|
||||||
|
if (parentData.data.name.indexOf(value) !== -1) {
|
||||||
|
return true
|
||||||
const emit = defineEmits(['init', 'checkChange', 'nodeChange', 'editNode', 'getChart', 'Policy'])
|
}
|
||||||
const config = useConfig()
|
// 否则的话再往上一层做匹配
|
||||||
const tree = ref()
|
parentData = parentData.parent
|
||||||
const treRef = ref()
|
index++
|
||||||
const id: any = ref(null)
|
}
|
||||||
const treeData = ref({})
|
// 没匹配到返回false
|
||||||
//获取方案树形数据
|
return false
|
||||||
const getTreeList = () => {
|
}
|
||||||
getSchemeTree().then(res => {
|
/** 树形结构数据 */
|
||||||
let arr: any[] = []
|
const defaultProps = {
|
||||||
|
children: 'children',
|
||||||
res.data.forEach((item: any) => {
|
label: 'name',
|
||||||
item.icon = 'el-icon-Menu'
|
value: 'id'
|
||||||
item.color = config.getColorVal('elementUiPrimary')
|
}
|
||||||
item?.children.forEach((item2: any) => {
|
|
||||||
item2.icon = 'el-icon-Document'
|
const emit = defineEmits(['init', 'checkChange', 'nodeChange', 'editNode', 'getChart', 'Policy'])
|
||||||
item2.color = config.getColorVal('elementUiPrimary')
|
const config = useConfig()
|
||||||
arr.push(item2)
|
const tree = ref()
|
||||||
})
|
const treRef = ref()
|
||||||
})
|
const id: any = ref(null)
|
||||||
tree.value = res.data
|
const treeData = ref({})
|
||||||
nextTick(() => {
|
//获取方案树形数据
|
||||||
if (arr.length) {
|
const getTreeList = () => {
|
||||||
treRef.value.setCurrentKey(id.value || arr[0].id)
|
getSchemeTree().then(res => {
|
||||||
let list = id.value ? arr.find((item: any) => item.id == id.value) : arr[0]
|
let arr: any[] = []
|
||||||
// 注册父组件事件
|
|
||||||
emit('init', {
|
res.data.forEach((item: any) => {
|
||||||
level: 2,
|
item.icon = 'el-icon-Menu'
|
||||||
...list
|
item.color = config.getColorVal('elementUiPrimary')
|
||||||
})
|
item?.children.forEach((item2: any) => {
|
||||||
} else {
|
item2.icon = 'el-icon-Document'
|
||||||
emit('init')
|
item2.color = config.getColorVal('elementUiPrimary')
|
||||||
}
|
arr.push(item2)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
tree.value = res.data
|
||||||
|
nextTick(() => {
|
||||||
//方案id
|
if (arr.length) {
|
||||||
const planId: any = ref('')
|
treRef.value.setCurrentKey(id.value || arr[0].id)
|
||||||
|
let list = id.value ? arr.find((item: any) => item.id == id.value) : arr[0]
|
||||||
const clickNode = (e: anyObj) => {
|
// 注册父组件事件
|
||||||
e?.children ? (planId.value = e.id) : (planId.value = e.pid)
|
emit('init', {
|
||||||
id.value = e.id
|
level: 2,
|
||||||
emit('nodeChange', e)
|
...list
|
||||||
}
|
})
|
||||||
|
} else {
|
||||||
|
emit('init')
|
||||||
if (props.template) {
|
}
|
||||||
getTemplateByDept({ id: dictData.state.area[0].id }).then((res: any) => {
|
})
|
||||||
emit('Policy', res.data)
|
})
|
||||||
getTreeList()
|
}
|
||||||
}).catch(err => {
|
|
||||||
getTreeList()
|
//方案id
|
||||||
})
|
const planId: any = ref('')
|
||||||
} else {
|
|
||||||
getTreeList()
|
const clickNode = (e: anyObj) => {
|
||||||
}
|
e?.children ? (planId.value = e.id) : (planId.value = e.pid)
|
||||||
|
id.value = e.id
|
||||||
</script>
|
emit('nodeChange', e)
|
||||||
<style lang="scss" scoped>
|
}
|
||||||
.cn-tree {
|
|
||||||
flex-shrink: 0;
|
if (props.template) {
|
||||||
display: flex;
|
querySysExcel({ id: dictData.state.area[0]?.id })
|
||||||
flex-direction: column;
|
.then((res: any) => {
|
||||||
box-sizing: border-box;
|
emit('Policy', res.data)
|
||||||
padding: 10px;
|
getTreeList()
|
||||||
height: 100%;
|
})
|
||||||
width: 100%;
|
.catch(err => {
|
||||||
height: calc(100vh - 125px);
|
getTreeList()
|
||||||
overflow-y: auto;
|
})
|
||||||
|
} else {
|
||||||
:deep(.el-tree) {
|
getTreeList()
|
||||||
border: 1px solid var(--el-border-color);
|
}
|
||||||
}
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
:deep(.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content) {
|
.cn-tree {
|
||||||
background-color: var(--el-color-primary-light-7);
|
flex-shrink: 0;
|
||||||
}
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
.menu-collapse {
|
box-sizing: border-box;
|
||||||
color: var(--el-color-primary);
|
padding: 10px;
|
||||||
}
|
height: 100%;
|
||||||
}
|
width: 100%;
|
||||||
</style>
|
height: calc(100vh - 125px);
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
: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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ const info = () => {
|
|||||||
getLineTree().then(res => {
|
getLineTree().then(res => {
|
||||||
//治理设备
|
//治理设备
|
||||||
res.data.map((item: any) => {
|
res.data.map((item: any) => {
|
||||||
if (item.name == '在线设备') {
|
if (item.name == '监测设备') {
|
||||||
item.children.forEach((item: any) => {
|
item.children.forEach((item: any) => {
|
||||||
item.icon = 'el-icon-HomeFilled'
|
item.icon = 'el-icon-HomeFilled'
|
||||||
item.level = 1
|
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(() => {
|
nextTick(() => {
|
||||||
if (arr3.length) {
|
if (arr3.length) {
|
||||||
//初始化选中
|
//初始化选中
|
||||||
@@ -87,7 +87,7 @@ const handleCheckedNodesChange = (nodes: any[]) => {
|
|||||||
|
|
||||||
|
|
||||||
if (props.template) {
|
if (props.template) {
|
||||||
getTemplateByDept({ id: dictData.state.area[0].id })
|
getTemplateByDept({ id: dictData.state.area[0]?.id })
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
emit('Policy', res.data)
|
emit('Policy', res.data)
|
||||||
info()
|
info()
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<Icon name='el-icon-Search' style='font-size: 16px' />
|
<Icon name='el-icon-Search' style='font-size: 16px' />
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<el-tooltip placement="bottom" :hide-after="0">
|
<el-tooltip placement="bottom" :hide-after="0" v-if="props.showPush">
|
||||||
<template #content>
|
<template #content>
|
||||||
<span>台账推送</span>
|
<span>台账推送</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -23,12 +23,12 @@
|
|||||||
:style="{ color: config.getColorVal('elementUiPrimary') }"
|
:style="{ color: config.getColorVal('elementUiPrimary') }"
|
||||||
@click="onAdd" />
|
@click="onAdd" />
|
||||||
</el-tooltip>
|
</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'
|
:class="menuCollapse ? 'unfold' : ''" size='18' class='fold ml10 menu-collapse'
|
||||||
style='cursor: pointer' v-if='props.canExpand' /> -->
|
style='cursor: pointer' v-if='props.canExpand' /> -->
|
||||||
</div>
|
</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"
|
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'>
|
@check-change="checkTreeNodeChange" :filter-node-method='filterNode' node-key='id' v-bind='$attrs'>
|
||||||
<template #default='{ node, data }'>
|
<template #default='{ node, data }'>
|
||||||
@@ -58,11 +58,13 @@ defineOptions({
|
|||||||
interface Props {
|
interface Props {
|
||||||
width?: string
|
width?: string
|
||||||
canExpand?: boolean
|
canExpand?: boolean
|
||||||
|
showPush?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
width: '280px',
|
width: '280px',
|
||||||
canExpand: true
|
canExpand: true,
|
||||||
|
showPush: false
|
||||||
})
|
})
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
const { proxy } = useCurrentInstance()
|
const { proxy } = useCurrentInstance()
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
<!-- 设备监控使用折叠面板渲染多个tree -->
|
<!-- 设备监控使用折叠面板渲染多个tree -->
|
||||||
<template>
|
<template>
|
||||||
<div :style="{ width: menuCollapse ? '40px' : props.width }" style="display: flex; overflow: hidden">
|
<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'"
|
<Icon
|
||||||
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 mt20 menu-collapse" style="cursor: pointer"
|
v-show="menuCollapse"
|
||||||
v-if="route.path != '/admin/govern/reportCore/statistics/index'" />
|
@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 class="cn-tree" :style="{ opacity: menuCollapse ? 0 : 1, display: menuCollapse ? 'none' : '' }">
|
||||||
<div style="display: flex; align-items: center" class="mb10">
|
<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>
|
||||||
@@ -11,13 +18,23 @@
|
|||||||
<Icon name="el-icon-Search" style="font-size: 16px" />
|
<Icon name="el-icon-Search" style="font-size: 16px" />
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<Icon @click="onMenuCollapse" :name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
<Icon
|
||||||
:class="menuCollapse ? 'unfold' : ''" size="18" class="fold ml10 menu-collapse"
|
@click="onMenuCollapse"
|
||||||
|
:name="menuCollapse ? 'el-icon-Expand' : 'el-icon-Fold'"
|
||||||
|
:class="menuCollapse ? 'unfold' : ''"
|
||||||
|
size="18"
|
||||||
|
class="fold ml10 menu-collapse"
|
||||||
style="cursor: pointer"
|
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>
|
</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-collapse-item title="治理设备" name="0" v-if="zlDeviceData.length != 0">
|
||||||
<el-select v-model.trim="process" clearable placeholder="请选择状态" class="mb10">
|
<el-select v-model.trim="process" clearable placeholder="请选择状态" class="mb10">
|
||||||
<el-option label="功能调试" value="2"></el-option>
|
<el-option label="功能调试" value="2"></el-option>
|
||||||
@@ -26,14 +43,25 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
|
|
||||||
<el-tree
|
<el-tree
|
||||||
:style="{ height: bxsDeviceData.length != 0 ? 'calc(100vh - 340px)' : 'calc(100vh - 278px)' }"
|
:style="{ height: bxsDeviceData.length != 0 ? 'calc(100vh - 380px)' : 'calc(100vh - 278px)' }"
|
||||||
ref="treeRef1" :props="defaultProps" highlight-current :filter-node-method="filterNode"
|
ref="treeRef1"
|
||||||
node-key="id" v-bind="$attrs" :data="zlDevList" style="overflow: auto"
|
:props="defaultProps"
|
||||||
:default-expand-all="false">
|
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 }">
|
<template #default="{ node, data }">
|
||||||
<span class="custom-tree-node">
|
<span class="custom-tree-node">
|
||||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
<Icon
|
||||||
v-if="data.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 style="margin-left: 4px">{{ node.label }}</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -41,29 +69,51 @@
|
|||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
<el-collapse-item title="便携式设备" name="1" v-if="bxsDeviceData.length != 0">
|
<el-collapse-item title="便携式设备" name="1" v-if="bxsDeviceData.length != 0">
|
||||||
<el-tree
|
<el-tree
|
||||||
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 330px)' : 'calc(100vh - 238px)' }"
|
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 340px)' : 'calc(100vh - 238px)' }"
|
||||||
ref="treeRef2" :props="defaultProps" highlight-current :default-expand-all="false"
|
ref="treeRef2"
|
||||||
:filter-node-method="filterNode" node-key="id" :data="bxsDeviceData" v-bind="$attrs"
|
:props="defaultProps"
|
||||||
style="overflow: auto" >
|
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 }">
|
<template #default="{ node, data }">
|
||||||
<span class="custom-tree-node">
|
<span class="custom-tree-node">
|
||||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
<Icon
|
||||||
v-if="data.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 style="margin-left: 4px">{{ node.label }}</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-tree>
|
</el-tree>
|
||||||
</el-collapse-item>
|
</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
|
<el-tree
|
||||||
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 330px)' : 'calc(100vh - 238px)' }"
|
:style="{ height: zlDeviceData.length != 0 ? 'calc(100vh - 340px)' : 'calc(100vh - 238px)' }"
|
||||||
ref="treeRef3" :props="defaultProps" highlight-current :default-expand-all="false"
|
ref="treeRef3"
|
||||||
:filter-node-method="filterNode" node-key="id" :data="yqfDeviceData" v-bind="$attrs"
|
:props="defaultProps"
|
||||||
style="overflow: auto">
|
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 }">
|
<template #default="{ node, data }">
|
||||||
<span class="custom-tree-node">
|
<span class="custom-tree-node">
|
||||||
<Icon :name="data.icon" style="font-size: 16px" :style="{ color: data.color }"
|
<Icon
|
||||||
v-if="data.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 style="margin-left: 4px">{{ node.label }}</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -112,33 +162,31 @@ const zlDeviceData = ref<any>([])
|
|||||||
const zlDevList = ref<any>([])
|
const zlDevList = ref<any>([])
|
||||||
//便携式设备数据
|
//便携式设备数据
|
||||||
const bxsDeviceData = ref<any>([])
|
const bxsDeviceData = ref<any>([])
|
||||||
//在线设备数据
|
//监测设备数据
|
||||||
const yqfDeviceData = ref<any>([])
|
const yqfDeviceData = ref<any>([])
|
||||||
watch(
|
watch(
|
||||||
() => props.data,
|
() => props.data,
|
||||||
(val, oldVal) => {
|
(val, oldVal) => {
|
||||||
if (val && val.length != 0) {
|
if (val && val.length != 0) {
|
||||||
|
|
||||||
val.map((item: any) => {
|
val.map((item: any) => {
|
||||||
if (item.name == '治理设备') {
|
if (item.name == '治理设备') {
|
||||||
zlDeviceData.value = []
|
zlDeviceData.value = []
|
||||||
item.children.map((vv: any) => {
|
item.children.map((vv: any) => {
|
||||||
zlDeviceData.value.push(vv)
|
zlDeviceData.value.push(vv)
|
||||||
})
|
})
|
||||||
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
||||||
} else if (item.name == '便携式设备') {
|
} else if (item.name == '便携式设备') {
|
||||||
bxsDeviceData.value = []
|
bxsDeviceData.value = []
|
||||||
item.children.map((vv: any) => {
|
item.children.map((vv: any) => {
|
||||||
bxsDeviceData.value.push(vv)
|
bxsDeviceData.value.push(vv)
|
||||||
})
|
})
|
||||||
}else if (item.name == '在线设备') {
|
} else if (item.name == '监测设备') {
|
||||||
yqfDeviceData.value = []
|
yqfDeviceData.value = []
|
||||||
item.children.map((vv: any) => {
|
item.children.map((vv: any) => {
|
||||||
yqfDeviceData.value.push(vv)
|
yqfDeviceData.value.push(vv)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -157,12 +205,10 @@ watch(filterText, val => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
watch(process, val => {
|
watch(process, val => {
|
||||||
|
if (val == '' || val == undefined) {
|
||||||
if (val == '') {
|
|
||||||
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
zlDevList.value = JSON.parse(JSON.stringify(zlDeviceData.value))
|
||||||
} else {
|
} else {
|
||||||
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
|
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -170,9 +216,8 @@ watch(process, val => {
|
|||||||
}, 0)
|
}, 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const changeDevice = (val: any) => {
|
const changeDevice = (val: any) => {
|
||||||
|
console.log('🚀 ~ changeDevice ~ val:', val)
|
||||||
|
|
||||||
let arr1: any = []
|
let arr1: any = []
|
||||||
//zlDeviceData
|
//zlDeviceData
|
||||||
@@ -206,22 +251,28 @@ const changeDevice = (val: any) => {
|
|||||||
arr2.map((item: any) => {
|
arr2.map((item: any) => {
|
||||||
item.checked = false
|
item.checked = false
|
||||||
})
|
})
|
||||||
treeRef1?.value && treeRef1.value.setCurrentKey(arr1[0]?.id)
|
|
||||||
emit('changePointType', activeName.value, arr1[0])
|
emit('changePointType', activeName.value, arr1[0])
|
||||||
|
setTimeout(() => {
|
||||||
|
treeRef1.value?.setCurrentKey(arr1[0]?.id)
|
||||||
|
}, 100)
|
||||||
}
|
}
|
||||||
if (val == '1') {
|
if (val == '1') {
|
||||||
arr1.map((item: any) => {
|
arr1.map((item: any) => {
|
||||||
item.checked = false
|
item.checked = false
|
||||||
})
|
})
|
||||||
treeRef2?.value && treeRef2.value.setCurrentKey(arr2[0]?.id)
|
|
||||||
emit('changePointType', activeName.value, arr2[0])
|
emit('changePointType', activeName.value, arr2[0])
|
||||||
|
setTimeout(() => {
|
||||||
|
treeRef2.value?.setCurrentKey(arr2[0]?.id)
|
||||||
|
}, 100)
|
||||||
}
|
}
|
||||||
if (val == '2') {
|
if (val == '2') {
|
||||||
arr3.map((item: any) => {
|
arr3.map((item: any) => {
|
||||||
item.checked = false
|
item.checked = false
|
||||||
})
|
})
|
||||||
treeRef3?.value && treeRef3.value.setCurrentKey(arr3[0]?.id)
|
|
||||||
emit('changePointType', activeName.value, arr3[0])
|
emit('changePointType', activeName.value, arr3[0])
|
||||||
|
setTimeout(() => {
|
||||||
|
treeRef3.value?.setCurrentKey(arr3[0]?.id)
|
||||||
|
}, 100)
|
||||||
}
|
}
|
||||||
// if(activeName.value){
|
// if(activeName.value){
|
||||||
// emit('changePointType', activeName.value)
|
// emit('changePointType', activeName.value)
|
||||||
@@ -263,8 +314,7 @@ function filterProcess(nodes: any) {
|
|||||||
// 1. 如果有满足条件的子节点则保留
|
// 1. 如果有满足条件的子节点则保留
|
||||||
// 2. 如果本身 process 值匹配则保留
|
// 2. 如果本身 process 值匹配则保留
|
||||||
// 3. 如果是叶子节点也保留(监测点通常没有子节点)
|
// 3. 如果是叶子节点也保留(监测点通常没有子节点)
|
||||||
if (children.length > 0 || node.process == process.value ||
|
if (children.length > 0 || node.process == process.value || !node.children || node.children.length === 0) {
|
||||||
(!node.children || node.children.length === 0)) {
|
|
||||||
return {
|
return {
|
||||||
...node,
|
...node,
|
||||||
children: children
|
children: children
|
||||||
@@ -276,7 +326,6 @@ function filterProcess(nodes: any) {
|
|||||||
.filter(Boolean) // 移除null节点
|
.filter(Boolean) // 移除null节点
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// function filterProcess(nodes: any) {
|
// function filterProcess(nodes: any) {
|
||||||
// if (process.value == '') {
|
// if (process.value == '') {
|
||||||
// return nodes
|
// return nodes
|
||||||
@@ -332,11 +381,9 @@ const treeRef1 = ref<InstanceType<typeof ElTree>>()
|
|||||||
const treeRef2 = ref<InstanceType<typeof ElTree>>()
|
const treeRef2 = ref<InstanceType<typeof ElTree>>()
|
||||||
//在线
|
//在线
|
||||||
const treeRef3 = ref<InstanceType<typeof ElTree>>()
|
const treeRef3 = ref<InstanceType<typeof ElTree>>()
|
||||||
defineExpose({ treeRef1, treeRef2 })
|
defineExpose({ treeRef1, treeRef2, treeRef3 })
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
||||||
if (zlDeviceData.value.length != 0) {
|
if (zlDeviceData.value.length != 0) {
|
||||||
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
|
zlDevList.value = filterProcess(JSON.parse(JSON.stringify(zlDeviceData.value)))
|
||||||
activeName.value = '0'
|
activeName.value = '0'
|
||||||
@@ -344,8 +391,11 @@ onMounted(() => {
|
|||||||
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length != 0) {
|
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length != 0) {
|
||||||
activeName.value = '1'
|
activeName.value = '1'
|
||||||
}
|
}
|
||||||
|
if (zlDeviceData.value.length === 0 && bxsDeviceData.value.length === 0) {
|
||||||
|
activeName.value = '2'
|
||||||
|
}
|
||||||
if (!zlDeviceData.value && !bxsDeviceData.value) {
|
if (!zlDeviceData.value && !bxsDeviceData.value) {
|
||||||
activeName.value = ''
|
activeName.value = '2'
|
||||||
}
|
}
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
changeDevice(activeName.value)
|
changeDevice(activeName.value)
|
||||||
|
|||||||
@@ -218,11 +218,12 @@ const updateNodeCheckStatus = (currentCount: number) => {
|
|||||||
const allNodes = treeRef.value.store._getAllNodes()
|
const allNodes = treeRef.value.store._getAllNodes()
|
||||||
allNodes.forEach((node: any) => {
|
allNodes.forEach((node: any) => {
|
||||||
if (node.level === 3) { // 监测点层级
|
if (node.level === 3) { // 监测点层级
|
||||||
|
|
||||||
// 如果已达到最大数量且该节点未被选中,则禁用勾选
|
// 如果已达到最大数量且该节点未被选中,则禁用勾选
|
||||||
if (isMaxSelected && !node.checked) {
|
if (isMaxSelected && !node.data.checked) {
|
||||||
node.disabled = true
|
node.data.disabled = true
|
||||||
} else {
|
} else {
|
||||||
node.disabled = false
|
node.data.disabled = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,359 +1,359 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="layout-config-drawer">
|
<div class="layout-config-drawer">
|
||||||
<el-drawer :model-value="configStore.layout.showDrawer" title="布局配置" size="310px" @close="onCloseDrawer">
|
<el-drawer :model-value="configStore.layout.showDrawer" title="布局配置" size="310px" @close="onCloseDrawer">
|
||||||
<el-scrollbar class="layout-mode-style-scrollbar">
|
<el-scrollbar class="layout-mode-style-scrollbar">
|
||||||
<el-form ref="formRef" :model="configStore.layout">
|
<el-form ref="formRef" :model="configStore.layout">
|
||||||
<div class="layout-mode-styles-box">
|
<div class="layout-mode-styles-box">
|
||||||
<el-divider border-style="dashed">全局</el-divider>
|
<el-divider border-style="dashed">全局</el-divider>
|
||||||
<div class="layout-config-global">
|
<div class="layout-config-global">
|
||||||
<el-form-item label="后台页面切换动画">
|
<el-form-item label="后台页面切换动画">
|
||||||
<el-select @change="onCommitState($event, 'mainAnimation')"
|
<el-select @change="onCommitState($event, 'mainAnimation')"
|
||||||
:model-value="configStore.layout.mainAnimation"
|
:model-value="configStore.layout.mainAnimation"
|
||||||
:placeholder="'layouts.Please select an animation name'">
|
:placeholder="'layouts.Please select an animation name'">
|
||||||
<el-option label="slide-right" value="slide-right"></el-option>
|
<el-option label="slide-right" value="slide-right"></el-option>
|
||||||
<el-option label="slide-left" value="slide-left"></el-option>
|
<el-option label="slide-left" value="slide-left"></el-option>
|
||||||
<el-option label="el-fade-in-linear" value="el-fade-in-linear"></el-option>
|
<el-option label="el-fade-in-linear" value="el-fade-in-linear"></el-option>
|
||||||
<el-option label="el-fade-in" value="el-fade-in"></el-option>
|
<el-option label="el-fade-in" value="el-fade-in"></el-option>
|
||||||
<el-option label="el-zoom-in-center" value="el-zoom-in-center"></el-option>
|
<el-option label="el-zoom-in-center" value="el-zoom-in-center"></el-option>
|
||||||
<el-option label="el-zoom-in-top" value="el-zoom-in-top"></el-option>
|
<el-option label="el-zoom-in-top" value="el-zoom-in-top"></el-option>
|
||||||
<el-option label="el-zoom-in-bottom" value="el-zoom-in-bottom"></el-option>
|
<el-option label="el-zoom-in-bottom" value="el-zoom-in-bottom"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="组件主题色">
|
<el-form-item label="组件主题色">
|
||||||
<el-color-picker @change="onCommitColorState($event, 'elementUiPrimary')"
|
<el-color-picker @change="onCommitColorState($event, 'elementUiPrimary')"
|
||||||
:model-value="configStore.getColorVal('elementUiPrimary')" />
|
:model-value="configStore.getColorVal('elementUiPrimary')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="表格标题栏背景颜色">
|
<el-form-item label="表格标题栏背景颜色">
|
||||||
<el-color-picker @change="onCommitColorState($event, 'tableHeaderBackground')"
|
<el-color-picker @change="onCommitColorState($event, 'tableHeaderBackground')"
|
||||||
:model-value="configStore.getColorVal('tableHeaderBackground')" />
|
:model-value="configStore.getColorVal('tableHeaderBackground')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="表格标题栏文字颜色">
|
<el-form-item label="表格标题栏文字颜色">
|
||||||
<el-color-picker @change="onCommitColorState($event, 'tableHeaderColor')"
|
<el-color-picker @change="onCommitColorState($event, 'tableHeaderColor')"
|
||||||
:model-value="configStore.getColorVal('tableHeaderColor')" />
|
:model-value="configStore.getColorVal('tableHeaderColor')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="表格激活栏颜色">
|
<el-form-item label="表格激活栏颜色">
|
||||||
<el-color-picker @change="onCommitColorState($event, 'tableCurrent')"
|
<el-color-picker @change="onCommitColorState($event, 'tableCurrent')"
|
||||||
:model-value="configStore.getColorVal('tableCurrent')" />
|
:model-value="configStore.getColorVal('tableCurrent')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
<el-divider border-style="dashed">侧边栏</el-divider>
|
<el-divider border-style="dashed">侧边栏</el-divider>
|
||||||
<div class="layout-config-aside">
|
<div class="layout-config-aside">
|
||||||
<el-form-item label="侧边菜单栏背景色">
|
<el-form-item label="侧边菜单栏背景色">
|
||||||
<el-color-picker @change="onCommitColorState($event, 'menuBackground')"
|
<el-color-picker @change="onCommitColorState($event, 'menuBackground')"
|
||||||
:model-value="configStore.getColorVal('menuBackground')" />
|
:model-value="configStore.getColorVal('menuBackground')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="侧边菜单文字颜色">
|
<el-form-item label="侧边菜单文字颜色">
|
||||||
<el-color-picker @change="onCommitColorState($event, 'menuColor')"
|
<el-color-picker @change="onCommitColorState($event, 'menuColor')"
|
||||||
:model-value="configStore.getColorVal('menuColor')" />
|
:model-value="configStore.getColorVal('menuColor')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="侧边菜单激活项背景色">
|
<el-form-item label="侧边菜单激活项背景色">
|
||||||
<el-color-picker @change="onCommitColorState($event, 'menuActiveBackground')"
|
<el-color-picker @change="onCommitColorState($event, 'menuActiveBackground')"
|
||||||
:model-value="configStore.getColorVal('menuActiveBackground')" />
|
:model-value="configStore.getColorVal('menuActiveBackground')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="侧边菜单激活项文字色">
|
<el-form-item label="侧边菜单激活项文字色">
|
||||||
<el-color-picker @change="onCommitColorState($event, 'menuActiveColor')"
|
<el-color-picker @change="onCommitColorState($event, 'menuActiveColor')"
|
||||||
:model-value="configStore.getColorVal('menuActiveColor')" />
|
:model-value="configStore.getColorVal('menuActiveColor')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="显示侧边菜单顶栏(LOGO栏)">
|
<el-form-item label="显示侧边菜单顶栏(LOGO栏)">
|
||||||
<el-switch @change="onCommitState($event, 'menuShowTopBar')"
|
<el-switch @change="onCommitState($event, 'menuShowTopBar')"
|
||||||
:model-value="configStore.layout.menuShowTopBar"></el-switch>
|
:model-value="configStore.layout.menuShowTopBar"></el-switch>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="侧边菜单顶栏背景色">
|
<el-form-item label="侧边菜单顶栏背景色">
|
||||||
<el-color-picker @change="onCommitColorState($event, 'menuTopBarBackground')"
|
<el-color-picker @change="onCommitColorState($event, 'menuTopBarBackground')"
|
||||||
:model-value="configStore.getColorVal('menuTopBarBackground')" />
|
:model-value="configStore.getColorVal('menuTopBarBackground')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="侧边菜单宽度(展开时)">
|
<el-form-item label="侧边菜单宽度(展开时)">
|
||||||
<el-input maxlength="32" show-word-limit @input="onCommitState($event, 'menuWidth')"
|
<el-input maxlength="32" show-word-limit @input="onCommitState($event, 'menuWidth')"
|
||||||
type="number" :step="10" :model-value="configStore.layout.menuWidth">
|
type="number" :step="10" :model-value="configStore.layout.menuWidth">
|
||||||
<template #append>px</template>
|
<template #append>px</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item label="侧边菜单默认图标">-->
|
<!-- <el-form-item label="侧边菜单默认图标">-->
|
||||||
<!-- <IconSelector-->
|
<!-- <IconSelector-->
|
||||||
<!-- @change="onCommitMenuDefaultIcon($event, 'menuDefaultIcon')"-->
|
<!-- @change="onCommitMenuDefaultIcon($event, 'menuDefaultIcon')"-->
|
||||||
<!-- :model-value="configStore.layout.menuDefaultIcon"-->
|
<!-- :model-value="configStore.layout.menuDefaultIcon"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </el-form-item>-->
|
<!-- </el-form-item>-->
|
||||||
<!-- <el-form-item label="侧边菜单水平折叠">-->
|
<!-- <el-form-item label="侧边菜单水平折叠">-->
|
||||||
<!-- <el-switch-->
|
<!-- <el-switch-->
|
||||||
<!-- @change="onCommitState($event, 'menuCollapse')"-->
|
<!-- @change="onCommitState($event, 'menuCollapse')"-->
|
||||||
<!-- :model-value="configStore.layout.menuCollapse"-->
|
<!-- :model-value="configStore.layout.menuCollapse"-->
|
||||||
<!-- ></el-switch>-->
|
<!-- ></el-switch>-->
|
||||||
<!-- </el-form-item>-->
|
<!-- </el-form-item>-->
|
||||||
<!-- <el-form-item label="侧边菜单手风琴">-->
|
<!-- <el-form-item label="侧边菜单手风琴">-->
|
||||||
<!-- <el-switch-->
|
<!-- <el-switch-->
|
||||||
<!-- @change="onCommitState($event, 'menuUniqueOpened')"-->
|
<!-- @change="onCommitState($event, 'menuUniqueOpened')"-->
|
||||||
<!-- :model-value="configStore.layout.menuUniqueOpened"-->
|
<!-- :model-value="configStore.layout.menuUniqueOpened"-->
|
||||||
<!-- ></el-switch>-->
|
<!-- ></el-switch>-->
|
||||||
<!-- </el-form-item>-->
|
<!-- </el-form-item>-->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-divider border-style="dashed">顶栏</el-divider>
|
<el-divider border-style="dashed">顶栏</el-divider>
|
||||||
<div class="layout-config-aside">
|
<div class="layout-config-aside">
|
||||||
<el-form-item label="顶栏背景色">
|
<el-form-item label="顶栏背景色">
|
||||||
<el-color-picker @change="onCommitColorState($event, 'headerBarBackground')"
|
<el-color-picker @change="onCommitColorState($event, 'headerBarBackground')"
|
||||||
:model-value="configStore.getColorVal('headerBarBackground')" />
|
:model-value="configStore.getColorVal('headerBarBackground')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="顶栏文字色">
|
<el-form-item label="顶栏文字色">
|
||||||
<el-color-picker @change="onCommitColorState($event, 'headerBarTabColor')"
|
<el-color-picker @change="onCommitColorState($event, 'headerBarTabColor')"
|
||||||
:model-value="configStore.getColorVal('headerBarTabColor')" />
|
:model-value="configStore.getColorVal('headerBarTabColor')" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item label="顶栏悬停时背景色">-->
|
<!-- <el-form-item label="顶栏悬停时背景色">-->
|
||||||
<!-- <el-color-picker-->
|
<!-- <el-color-picker-->
|
||||||
<!-- @change="onCommitColorState($event, 'headerBarHoverBackground')"-->
|
<!-- @change="onCommitColorState($event, 'headerBarHoverBackground')"-->
|
||||||
<!-- :model-value="configStore.getColorVal('headerBarHoverBackground')"-->
|
<!-- :model-value="configStore.getColorVal('headerBarHoverBackground')"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </el-form-item>-->
|
<!-- </el-form-item>-->
|
||||||
<!-- <el-form-item label="顶栏菜单激活项背景色">-->
|
<!-- <el-form-item label="顶栏菜单激活项背景色">-->
|
||||||
<!-- <el-color-picker-->
|
<!-- <el-color-picker-->
|
||||||
<!-- @change="onCommitColorState($event, 'headerBarTabActiveBackground')"-->
|
<!-- @change="onCommitColorState($event, 'headerBarTabActiveBackground')"-->
|
||||||
<!-- :model-value="configStore.getColorVal('headerBarTabActiveBackground')"-->
|
<!-- :model-value="configStore.getColorVal('headerBarTabActiveBackground')"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </el-form-item>-->
|
<!-- </el-form-item>-->
|
||||||
<!-- <el-form-item label="顶栏菜单激活项文字色">-->
|
<!-- <el-form-item label="顶栏菜单激活项文字色">-->
|
||||||
<!-- <el-color-picker-->
|
<!-- <el-color-picker-->
|
||||||
<!-- @change="onCommitColorState($event, 'headerBarTabActiveColor')"-->
|
<!-- @change="onCommitColorState($event, 'headerBarTabActiveColor')"-->
|
||||||
<!-- :model-value="configStore.getColorVal('headerBarTabActiveColor')"-->
|
<!-- :model-value="configStore.getColorVal('headerBarTabActiveColor')"-->
|
||||||
<!-- />-->
|
<!-- />-->
|
||||||
<!-- </el-form-item>-->
|
<!-- </el-form-item>-->
|
||||||
</div>
|
</div>
|
||||||
<el-popconfirm @confirm="restoreDefault" title="确定要恢复全部配置到默认值吗?">
|
<el-popconfirm @confirm="restoreDefault" title="确定要恢复全部配置到默认值吗?">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<div class="ba-center">
|
<div class="ba-center">
|
||||||
<el-button class="w80" type="info">恢复默认</el-button>
|
<el-button class="w80" type="info">恢复默认</el-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-popconfirm>
|
</el-popconfirm>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import { useNavTabs } from '@/stores/navTabs'
|
import { useNavTabs } from '@/stores/navTabs'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import IconSelector from '@/components/baInput/components/iconSelector.vue'
|
import IconSelector from '@/components/baInput/components/iconSelector.vue'
|
||||||
import { STORE_CONFIG } from '@/stores/constant/cacheKey'
|
import { STORE_CONFIG } from '@/stores/constant/cacheKey'
|
||||||
import { Local, Session } from '@/utils/storage'
|
import { Local, Session } from '@/utils/storage'
|
||||||
import type { Layout } from '@/stores/interface'
|
import type { Layout } from '@/stores/interface'
|
||||||
|
|
||||||
const configStore = useConfig()
|
const configStore = useConfig()
|
||||||
const navTabs = useNavTabs()
|
const navTabs = useNavTabs()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const onCommitState = (value: any, name: any) => {
|
const onCommitState = (value: any, name: any) => {
|
||||||
configStore.setLayout(name, value)
|
configStore.setLayout(name, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onCommitColorState = (value: string | null, name: keyof Layout) => {
|
const onCommitColorState = (value: string | null, name: keyof Layout) => {
|
||||||
if (value === null) return
|
if (value === null) return
|
||||||
const colors = configStore.layout[name] as string[]
|
const colors = configStore.layout[name] as string[]
|
||||||
if (configStore.layout.isDark) {
|
if (configStore.layout.isDark) {
|
||||||
colors[1] = value
|
colors[1] = value
|
||||||
} else {
|
} else {
|
||||||
colors[0] = value
|
colors[0] = value
|
||||||
}
|
}
|
||||||
configStore.setLayout(name, colors)
|
configStore.setLayout(name, colors)
|
||||||
}
|
}
|
||||||
|
|
||||||
const setLayoutMode = (mode: string) => {
|
const setLayoutMode = (mode: string) => {
|
||||||
configStore.setLayoutMode(mode)
|
configStore.setLayoutMode(mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改默认菜单图标
|
// 修改默认菜单图标
|
||||||
const onCommitMenuDefaultIcon = (value: any, name: any) => {
|
const onCommitMenuDefaultIcon = (value: any, name: any) => {
|
||||||
configStore.setLayout(name, value)
|
configStore.setLayout(name, value)
|
||||||
|
|
||||||
const menus = navTabs.state.tabsViewRoutes
|
const menus = navTabs.state.tabsViewRoutes
|
||||||
navTabs.setTabsViewRoutes([])
|
navTabs.setTabsViewRoutes([])
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navTabs.setTabsViewRoutes(menus)
|
navTabs.setTabsViewRoutes(menus)
|
||||||
}, 200)
|
}, 200)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onCloseDrawer = () => {
|
const onCloseDrawer = () => {
|
||||||
configStore.setLayout('showDrawer', false)
|
configStore.setLayout('showDrawer', false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const restoreDefault = () => {
|
const restoreDefault = () => {
|
||||||
Local.remove(STORE_CONFIG)
|
Local.remove(STORE_CONFIG)
|
||||||
router.go(0)
|
router.go(0)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.layout-config-drawer :deep(.el-input__inner) {
|
.layout-config-drawer :deep(.el-input__inner) {
|
||||||
padding: 0 0 0 6px;
|
padding: 0 0 0 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-config-drawer :deep(.el-input-group__append) {
|
.layout-config-drawer :deep(.el-input-group__append) {
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-config-drawer :deep(.el-drawer__header) {
|
.layout-config-drawer :deep(.el-drawer__header) {
|
||||||
margin-bottom: 0 !important;
|
margin-bottom: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-config-drawer :deep(.el-drawer__body) {
|
.layout-config-drawer :deep(.el-drawer__body) {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-styles-box {
|
.layout-mode-styles-box {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-box-style-row {
|
.layout-mode-box-style-row {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-style {
|
.layout-mode-style {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
border: 1px solid var(--el-border-color-light);
|
border: 1px solid var(--el-border-color-light);
|
||||||
border-radius: var(--el-border-radius-small);
|
border-radius: var(--el-border-radius-small);
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&.active {
|
&.active {
|
||||||
border: 1px solid var(--el-color-primary);
|
border: 1px solid var(--el-color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-style-name {
|
.layout-mode-style-name {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
color: var(--el-color-primary-light-5);
|
color: var(--el-color-primary-light-5);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
border: 1px solid var(--el-color-primary-light-3);
|
border: 1px solid var(--el-color-primary-light-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-style-box {
|
.layout-mode-style-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.default {
|
&.default {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.layout-mode-style-aside {
|
.layout-mode-style-aside {
|
||||||
width: 18%;
|
width: 18%;
|
||||||
height: 90%;
|
height: 90%;
|
||||||
background-color: var(--el-border-color-lighter);
|
background-color: var(--el-border-color-lighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-style-container-box {
|
.layout-mode-style-container-box {
|
||||||
width: 68%;
|
width: 68%;
|
||||||
height: 90%;
|
height: 90%;
|
||||||
margin-left: 4%;
|
margin-left: 4%;
|
||||||
|
|
||||||
.layout-mode-style-header {
|
.layout-mode-style-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 10%;
|
height: 10%;
|
||||||
background-color: var(--el-border-color-lighter);
|
background-color: var(--el-border-color-lighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-style-container {
|
.layout-mode-style-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 85%;
|
height: 85%;
|
||||||
background-color: var(--el-border-color-extra-light);
|
background-color: var(--el-border-color-extra-light);
|
||||||
margin-top: 5%;
|
margin-top: 5%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.classic {
|
&.classic {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.layout-mode-style-aside {
|
.layout-mode-style-aside {
|
||||||
width: 18%;
|
width: 18%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: var(--el-border-color-lighter);
|
background-color: var(--el-border-color-lighter);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-style-container-box {
|
.layout-mode-style-container-box {
|
||||||
width: 82%;
|
width: 82%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
.layout-mode-style-header {
|
.layout-mode-style-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 10%;
|
height: 10%;
|
||||||
background-color: var(--el-border-color);
|
background-color: var(--el-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-style-container {
|
.layout-mode-style-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 90%;
|
height: 90%;
|
||||||
background-color: var(--el-border-color-extra-light);
|
background-color: var(--el-border-color-extra-light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.streamline {
|
&.streamline {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.layout-mode-style-container-box {
|
.layout-mode-style-container-box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
.layout-mode-style-header {
|
.layout-mode-style-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 10%;
|
height: 10%;
|
||||||
background-color: var(--el-border-color);
|
background-color: var(--el-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-style-container {
|
.layout-mode-style-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 90%;
|
height: 90%;
|
||||||
background-color: var(--el-border-color-extra-light);
|
background-color: var(--el-border-color-extra-light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.double {
|
&.double {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
.layout-mode-style-aside {
|
.layout-mode-style-aside {
|
||||||
width: 18%;
|
width: 18%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: var(--el-border-color);
|
background-color: var(--el-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-style-container-box {
|
.layout-mode-style-container-box {
|
||||||
width: 82%;
|
width: 82%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
.layout-mode-style-header {
|
.layout-mode-style-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 10%;
|
height: 10%;
|
||||||
background-color: var(--el-border-color);
|
background-color: var(--el-border-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.layout-mode-style-container {
|
.layout-mode-style-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 90%;
|
height: 90%;
|
||||||
background-color: var(--el-border-color-extra-light);
|
background-color: var(--el-border-color-extra-light);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.w80 {
|
.w80 {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,81 +1,81 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-scrollbar ref="verticalMenusRef" class="vertical-menus-scrollbar">
|
<el-scrollbar ref="verticalMenusRef" class="vertical-menus-scrollbar">
|
||||||
<el-menu
|
<el-menu
|
||||||
class="layouts-menu-vertical"
|
class="layouts-menu-vertical"
|
||||||
:collapse-transition="false"
|
:collapse-transition="false"
|
||||||
:unique-opened="config.layout.menuUniqueOpened"
|
:unique-opened="config.layout.menuUniqueOpened"
|
||||||
:default-active="state.defaultActive"
|
:default-active="state.defaultActive"
|
||||||
:collapse="config.layout.menuCollapse"
|
:collapse="config.layout.menuCollapse"
|
||||||
>
|
>
|
||||||
<MenuTree :menus="navTabs.state.tabsViewRoutes" />
|
<MenuTree :menus="navTabs.state.tabsViewRoutes" />
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, nextTick, onMounted, reactive, ref } from 'vue'
|
import { computed, nextTick, onMounted, reactive, ref } from 'vue'
|
||||||
import MenuTree from '@/layouts/admin/components/menus/menuTree.vue'
|
import MenuTree from '@/layouts/admin/components/menus/menuTree.vue'
|
||||||
import { useRoute, onBeforeRouteUpdate, type RouteLocationNormalizedLoaded } from 'vue-router'
|
import { useRoute, onBeforeRouteUpdate, type RouteLocationNormalizedLoaded } from 'vue-router'
|
||||||
import type { ScrollbarInstance } from 'element-plus'
|
import type { ScrollbarInstance } from 'element-plus'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useConfig } from '@/stores/config'
|
||||||
import { useNavTabs } from '@/stores/navTabs'
|
import { useNavTabs } from '@/stores/navTabs'
|
||||||
|
|
||||||
const config = useConfig()
|
const config = useConfig()
|
||||||
const navTabs = useNavTabs()
|
const navTabs = useNavTabs()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
|
||||||
const verticalMenusRef = ref<ScrollbarInstance>()
|
const verticalMenusRef = ref<ScrollbarInstance>()
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
defaultActive: '',
|
defaultActive: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
const verticalMenusScrollbarHeight = computed(() => {
|
const verticalMenusScrollbarHeight = computed(() => {
|
||||||
let menuTopBarHeight = 0
|
let menuTopBarHeight = 0
|
||||||
if (config.layout.menuShowTopBar) {
|
if (config.layout.menuShowTopBar) {
|
||||||
menuTopBarHeight = 50
|
menuTopBarHeight = 50
|
||||||
}
|
}
|
||||||
if (config.layout.layoutMode == 'Default') {
|
if (config.layout.layoutMode == 'Default') {
|
||||||
return 'calc(100vh - ' + (32 + menuTopBarHeight) + 'px)'
|
return 'calc(100vh - ' + (32 + menuTopBarHeight) + 'px)'
|
||||||
} else {
|
} else {
|
||||||
return 'calc(100vh - ' + menuTopBarHeight + 'px)'
|
return 'calc(100vh - ' + menuTopBarHeight + 'px)'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 激活当前路由的菜单
|
// 激活当前路由的菜单
|
||||||
const currentRouteActive = (currentRoute: RouteLocationNormalizedLoaded) => {
|
const currentRouteActive = (currentRoute: RouteLocationNormalizedLoaded) => {
|
||||||
state.defaultActive = currentRoute.path
|
state.defaultActive = currentRoute.path
|
||||||
}
|
}
|
||||||
|
|
||||||
// 滚动条滚动到激活菜单所在位置
|
// 滚动条滚动到激活菜单所在位置
|
||||||
const verticalMenusScroll = () => {
|
const verticalMenusScroll = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
let activeMenu: HTMLElement | null = document.querySelector('.el-menu.layouts-menu-vertical li.is-active')
|
let activeMenu: HTMLElement | null = document.querySelector('.el-menu.layouts-menu-vertical li.is-active')
|
||||||
if (!activeMenu) return false
|
if (!activeMenu) return false
|
||||||
verticalMenusRef.value?.setScrollTop(activeMenu.offsetTop)
|
verticalMenusRef.value?.setScrollTop(activeMenu.offsetTop)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
currentRouteActive(route)
|
currentRouteActive(route)
|
||||||
verticalMenusScroll()
|
verticalMenusScroll()
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeRouteUpdate((to) => {
|
onBeforeRouteUpdate((to) => {
|
||||||
currentRouteActive(to)
|
currentRouteActive(to)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.vertical-menus-scrollbar {
|
.vertical-menus-scrollbar {
|
||||||
height: v-bind(verticalMenusScrollbarHeight);
|
height: v-bind(verticalMenusScrollbarHeight);
|
||||||
background-color: v-bind('config.getColorVal("menuBackground")');
|
background-color: v-bind('config.getColorVal("menuBackground")');
|
||||||
}
|
}
|
||||||
.layouts-menu-vertical {
|
.layouts-menu-vertical {
|
||||||
border: 0;
|
border: 0;
|
||||||
padding-bottom: 30px;
|
padding-bottom: 30px;
|
||||||
--el-menu-bg-color: v-bind('config.getColorVal("menuBackground")');
|
--el-menu-bg-color: v-bind('config.getColorVal("menuBackground")');
|
||||||
--el-menu-text-color: v-bind('config.getColorVal("menuColor")');
|
--el-menu-text-color: v-bind('config.getColorVal("menuColor")');
|
||||||
--el-menu-active-color: v-bind('config.getColorVal("menuActiveColor")');
|
--el-menu-active-color: v-bind('config.getColorVal("menuActiveColor")');
|
||||||
--el-menu-hover-color: v-bind('config.getColorVal("menuActiveBackground")');
|
--el-menu-hover-color: v-bind('config.getColorVal("menuActiveBackground")');
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,242 +1,246 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="nav-tabs" ref="tabScrollbarRef">
|
<div class="nav-tabs" ref="tabScrollbarRef">
|
||||||
<div
|
|
||||||
v-for="(item, idx) in navTabs.state.tabsView"
|
<div
|
||||||
@click="onTab(item)"
|
v-for="(item, idx) in navTabs.state.tabsView"
|
||||||
@contextmenu.prevent="onContextmenu(item, $event)"
|
@click="onTab(item)"
|
||||||
class="ba-nav-tab"
|
@contextmenu.prevent="onContextmenu(item, $event)"
|
||||||
:class="navTabs.state.activeIndex == idx ? 'active' : ''"
|
class="ba-nav-tab"
|
||||||
:ref="tabsRefs.set"
|
:class="navTabs.state.activeIndex == idx ? 'active' : ''"
|
||||||
:key="idx"
|
:ref="tabsRefs.set"
|
||||||
>
|
:key="idx"
|
||||||
{{ item.meta.title }}
|
>
|
||||||
<transition @after-leave="selectNavTab(tabsRefs[navTabs.state.activeIndex])" name="el-fade-in">
|
{{ item.meta.title }}
|
||||||
<Icon
|
<transition @after-leave="selectNavTab(tabsRefs[navTabs.state.activeIndex])" name="el-fade-in">
|
||||||
v-if="navTabs.state.tabsView.length > 1"
|
<Icon
|
||||||
class="close-icon"
|
v-if="navTabs.state.tabsView.length > 1"
|
||||||
@click.stop="closeTab(item)"
|
class="close-icon"
|
||||||
size="15"
|
@click.stop="closeTab(item)"
|
||||||
name="el-icon-Close"
|
size="15"
|
||||||
/>
|
name="el-icon-Close"
|
||||||
</transition>
|
/>
|
||||||
</div>
|
</transition>
|
||||||
<!-- <div :style='activeBoxStyle' class='nav-tabs-active-box'></div>-->
|
</div>
|
||||||
</div>
|
<!-- <div :style='activeBoxStyle' class='nav-tabs-active-box'></div>-->
|
||||||
<Contextmenu ref="contextmenuRef" :items="state.contextmenuItems" @contextmenuItemClick="onContextmenuItem" />
|
</div>
|
||||||
</template>
|
<Contextmenu ref="contextmenuRef" :items="state.contextmenuItems" @contextmenuItemClick="onContextmenuItem" />
|
||||||
|
</template>
|
||||||
<script setup lang="ts">
|
|
||||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
<script setup lang="ts">
|
||||||
import { useRoute, useRouter, onBeforeRouteUpdate, type RouteLocationNormalized } from 'vue-router'
|
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||||
import { useConfig } from '@/stores/config'
|
import { useRoute, useRouter, onBeforeRouteUpdate, type RouteLocationNormalized } from 'vue-router'
|
||||||
import { useNavTabs } from '@/stores/navTabs'
|
import { useConfig } from '@/stores/config'
|
||||||
import { useTemplateRefsList } from '@vueuse/core'
|
import { useNavTabs } from '@/stores/navTabs'
|
||||||
import type { ContextMenuItem, ContextmenuItemClickEmitArg } from '@/components/contextmenu/interface'
|
import { useTemplateRefsList } from '@vueuse/core'
|
||||||
import useCurrentInstance from '@/utils/useCurrentInstance'
|
import type { ContextMenuItem, ContextmenuItemClickEmitArg } from '@/components/contextmenu/interface'
|
||||||
import Contextmenu from '@/components/contextmenu/index.vue'
|
import useCurrentInstance from '@/utils/useCurrentInstance'
|
||||||
import horizontalScroll from '@/utils/horizontalScroll'
|
import Contextmenu from '@/components/contextmenu/index.vue'
|
||||||
import { getFirstRoute, routePush } from '@/utils/router'
|
import horizontalScroll from '@/utils/horizontalScroll'
|
||||||
import { adminBaseRoutePath } from '@/router/static'
|
import { getFirstRoute, routePush } from '@/utils/router'
|
||||||
|
import { adminBaseRoutePath } from '@/router/static'
|
||||||
const route = useRoute()
|
|
||||||
const router = useRouter()
|
const route = useRoute()
|
||||||
const config = useConfig()
|
const router = useRouter()
|
||||||
const navTabs = useNavTabs()
|
const config = useConfig()
|
||||||
|
const navTabs = useNavTabs()
|
||||||
const { proxy } = useCurrentInstance()
|
|
||||||
const tabScrollbarRef = ref()
|
const { proxy } = useCurrentInstance()
|
||||||
const tabsRefs = useTemplateRefsList<HTMLDivElement>()
|
const tabScrollbarRef = ref()
|
||||||
|
const tabsRefs = useTemplateRefsList<HTMLDivElement>()
|
||||||
const contextmenuRef = ref()
|
|
||||||
|
const contextmenuRef = ref()
|
||||||
const state: {
|
|
||||||
contextmenuItems: ContextMenuItem[]
|
const state: {
|
||||||
} = reactive({
|
contextmenuItems: ContextMenuItem[]
|
||||||
contextmenuItems: [
|
} = reactive({
|
||||||
{ name: 'refresh', label: '重新加载', icon: 'fa fa-refresh' },
|
contextmenuItems: [
|
||||||
{ name: 'close', label: '关闭标签', icon: 'fa fa-times' },
|
{ name: 'refresh', label: '重新加载', icon: 'fa fa-refresh' },
|
||||||
{ name: 'fullScreen', label: '当前标签全屏', icon: 'el-icon-FullScreen' },
|
{ name: 'close', label: '关闭标签', icon: 'fa fa-times' },
|
||||||
{ name: 'closeOther', label: '关闭其他标签', icon: 'fa fa-minus' },
|
{ name: 'fullScreen', label: '当前标签全屏', icon: 'el-icon-FullScreen' },
|
||||||
{ name: 'closeAll', label: '关闭全部标签', icon: 'fa fa-stop' }
|
{ name: 'closeOther', label: '关闭其他标签', icon: 'fa fa-minus' },
|
||||||
]
|
{ name: 'closeAll', label: '关闭全部标签', icon: 'fa fa-stop' }
|
||||||
})
|
]
|
||||||
|
})
|
||||||
const activeBoxStyle = reactive({
|
|
||||||
width: '0',
|
const activeBoxStyle = reactive({
|
||||||
transform: 'translateX(0px)'
|
width: '0',
|
||||||
})
|
transform: 'translateX(0px)'
|
||||||
|
})
|
||||||
const onTab = (menu: RouteLocationNormalized) => {
|
|
||||||
router.push(menu)
|
const onTab = (menu: RouteLocationNormalized) => {
|
||||||
}
|
router.push(menu)
|
||||||
|
}
|
||||||
const onContextmenu = (menu: RouteLocationNormalized, el: MouseEvent) => {
|
|
||||||
// 禁用刷新
|
const onContextmenu = (menu: RouteLocationNormalized, el: MouseEvent) => {
|
||||||
state.contextmenuItems[0].disabled = route.path !== menu.path
|
|
||||||
// 禁用关闭其他和关闭全部
|
// 禁用刷新
|
||||||
state.contextmenuItems[4].disabled = state.contextmenuItems[3].disabled =
|
state.contextmenuItems[0].disabled = route.path !== menu.path
|
||||||
navTabs.state.tabsView.length == 1 ? true : false
|
|
||||||
|
|
||||||
const { clientX, clientY } = el
|
// 禁用关闭其他和关闭全部
|
||||||
contextmenuRef.value.onShowContextmenu(menu, {
|
state.contextmenuItems[4].disabled = state.contextmenuItems[3].disabled =
|
||||||
x: clientX,
|
navTabs.state.tabsView.length == 1 ? true : false
|
||||||
y: clientY
|
|
||||||
})
|
const { clientX, clientY } = el
|
||||||
}
|
contextmenuRef.value.onShowContextmenu(menu, {
|
||||||
|
x: clientX,
|
||||||
// tab 激活状态切换
|
y: clientY
|
||||||
const selectNavTab = function (dom: HTMLDivElement) {
|
})
|
||||||
if (!dom) {
|
}
|
||||||
return false
|
|
||||||
}
|
// tab 激活状态切换
|
||||||
activeBoxStyle.width = dom.clientWidth + 'px'
|
const selectNavTab = function (dom: HTMLDivElement) {
|
||||||
activeBoxStyle.transform = `translateX(${dom.offsetLeft}px)`
|
if (!dom) {
|
||||||
|
return false
|
||||||
let scrollLeft = dom.offsetLeft + dom.clientWidth - tabScrollbarRef.value.clientWidth
|
}
|
||||||
if (dom.offsetLeft < tabScrollbarRef.value.scrollLeft) {
|
activeBoxStyle.width = dom.clientWidth + 'px'
|
||||||
tabScrollbarRef.value.scrollTo(dom.offsetLeft, 0)
|
activeBoxStyle.transform = `translateX(${dom.offsetLeft}px)`
|
||||||
} else if (scrollLeft > tabScrollbarRef.value.scrollLeft) {
|
|
||||||
tabScrollbarRef.value.scrollTo(scrollLeft, 0)
|
let scrollLeft = dom.offsetLeft + dom.clientWidth - tabScrollbarRef.value.clientWidth
|
||||||
}
|
if (dom.offsetLeft < tabScrollbarRef.value.scrollLeft) {
|
||||||
}
|
tabScrollbarRef.value.scrollTo(dom.offsetLeft, 0)
|
||||||
|
} else if (scrollLeft > tabScrollbarRef.value.scrollLeft) {
|
||||||
const toLastTab = () => {
|
tabScrollbarRef.value.scrollTo(scrollLeft, 0)
|
||||||
const lastTab = navTabs.state.tabsView.slice(-1)[0]
|
}
|
||||||
if (lastTab) {
|
}
|
||||||
router.push(lastTab)
|
|
||||||
} else {
|
const toLastTab = () => {
|
||||||
router.push(adminBaseRoutePath)
|
const lastTab = navTabs.state.tabsView.slice(-1)[0]
|
||||||
}
|
if (lastTab) {
|
||||||
}
|
router.push(lastTab)
|
||||||
|
} else {
|
||||||
const closeTab = (route: RouteLocationNormalized) => {
|
router.push(adminBaseRoutePath)
|
||||||
navTabs.closeTab(route)
|
}
|
||||||
proxy.eventBus.emit('onTabViewClose', route)
|
}
|
||||||
if (navTabs.state.activeRoute?.path === route.path) {
|
|
||||||
toLastTab()
|
const closeTab = (route: RouteLocationNormalized) => {
|
||||||
} else {
|
navTabs.closeTab(route)
|
||||||
navTabs.setActiveRoute(navTabs.state.activeRoute!)
|
proxy.eventBus.emit('onTabViewClose', route)
|
||||||
nextTick(() => {
|
if (navTabs.state.activeRoute?.path === route.path) {
|
||||||
selectNavTab(tabsRefs.value[navTabs.state.activeIndex])
|
toLastTab()
|
||||||
})
|
} else {
|
||||||
}
|
navTabs.setActiveRoute(navTabs.state.activeRoute!)
|
||||||
|
nextTick(() => {
|
||||||
contextmenuRef.value.onHideContextmenu()
|
selectNavTab(tabsRefs.value[navTabs.state.activeIndex])
|
||||||
}
|
})
|
||||||
|
}
|
||||||
const closeOtherTab = (menu: RouteLocationNormalized) => {
|
|
||||||
navTabs.closeTabs(menu)
|
contextmenuRef.value.onHideContextmenu()
|
||||||
navTabs.setActiveRoute(menu)
|
}
|
||||||
if (navTabs.state.activeRoute?.path !== route.path) {
|
|
||||||
router.push(menu!.path)
|
const closeOtherTab = (menu: RouteLocationNormalized) => {
|
||||||
}
|
navTabs.closeTabs(menu)
|
||||||
}
|
navTabs.setActiveRoute(menu)
|
||||||
|
if (navTabs.state.activeRoute?.path !== route.path) {
|
||||||
const closeAllTab = (menu: RouteLocationNormalized) => {
|
router.push(menu!.path)
|
||||||
let firstRoute = getFirstRoute(navTabs.state.tabsViewRoutes)
|
}
|
||||||
if (firstRoute && firstRoute.path == menu.path) {
|
}
|
||||||
return closeOtherTab(menu)
|
|
||||||
}
|
const closeAllTab = (menu: RouteLocationNormalized) => {
|
||||||
if (firstRoute && firstRoute.path == navTabs.state.activeRoute?.path) {
|
let firstRoute = getFirstRoute(navTabs.state.tabsViewRoutes)
|
||||||
return closeOtherTab(navTabs.state.activeRoute)
|
if (firstRoute && firstRoute.path == menu.path) {
|
||||||
}
|
return closeOtherTab(menu)
|
||||||
navTabs.closeTabs(false)
|
}
|
||||||
if (firstRoute) routePush(firstRoute.path)
|
if (firstRoute && firstRoute.path == navTabs.state.activeRoute?.path) {
|
||||||
}
|
return closeOtherTab(navTabs.state.activeRoute)
|
||||||
|
}
|
||||||
const onContextmenuItem = async (item: ContextmenuItemClickEmitArg) => {
|
navTabs.closeTabs(false)
|
||||||
const { name, menu } = item
|
if (firstRoute) routePush(firstRoute.path)
|
||||||
if (!menu) return
|
}
|
||||||
switch (name) {
|
|
||||||
case 'refresh':
|
const onContextmenuItem = async (item: ContextmenuItemClickEmitArg) => {
|
||||||
proxy.eventBus.emit('onTabViewRefresh', menu)
|
const { name, menu } = item
|
||||||
break
|
if (!menu) return
|
||||||
case 'close':
|
switch (name) {
|
||||||
closeTab(menu)
|
case 'refresh':
|
||||||
break
|
proxy.eventBus.emit('onTabViewRefresh', menu)
|
||||||
case 'closeOther':
|
break
|
||||||
closeOtherTab(menu)
|
case 'close':
|
||||||
break
|
closeTab(menu)
|
||||||
case 'closeAll':
|
break
|
||||||
closeAllTab(menu)
|
case 'closeOther':
|
||||||
break
|
closeOtherTab(menu)
|
||||||
case 'fullScreen':
|
break
|
||||||
if (route.path !== menu?.path) {
|
case 'closeAll':
|
||||||
router.push(menu?.path as string)
|
closeAllTab(menu)
|
||||||
}
|
break
|
||||||
navTabs.setFullScreen(true)
|
case 'fullScreen':
|
||||||
break
|
if (route.path !== menu?.path) {
|
||||||
}
|
router.push(menu?.path as string)
|
||||||
}
|
}
|
||||||
|
navTabs.setFullScreen(true)
|
||||||
const updateTab = function (newRoute: RouteLocationNormalized) {
|
break
|
||||||
// 添加tab
|
}
|
||||||
navTabs.addTab(newRoute)
|
}
|
||||||
// 激活当前tab
|
|
||||||
navTabs.setActiveRoute(newRoute)
|
const updateTab = function (newRoute: RouteLocationNormalized) {
|
||||||
|
// 添加tab
|
||||||
nextTick(() => {
|
navTabs.addTab(newRoute)
|
||||||
selectNavTab(tabsRefs.value[navTabs.state.activeIndex])
|
// 激活当前tab
|
||||||
})
|
navTabs.setActiveRoute(newRoute)
|
||||||
}
|
|
||||||
|
nextTick(() => {
|
||||||
onBeforeRouteUpdate(async to => {
|
selectNavTab(tabsRefs.value[navTabs.state.activeIndex])
|
||||||
|
})
|
||||||
|
}
|
||||||
updateTab(to)
|
|
||||||
|
onBeforeRouteUpdate(async to => {
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
updateTab(to)
|
||||||
updateTab(router.currentRoute.value)
|
|
||||||
new horizontalScroll(tabScrollbarRef.value)
|
})
|
||||||
})
|
|
||||||
</script>
|
onMounted(() => {
|
||||||
|
updateTab(router.currentRoute.value)
|
||||||
<style scoped lang="scss">
|
new horizontalScroll(tabScrollbarRef.value)
|
||||||
.dark {
|
})
|
||||||
.close-icon {
|
</script>
|
||||||
color: v-bind('config.getColorVal("headerBarTabColor")') !important;
|
|
||||||
}
|
<style scoped lang="scss">
|
||||||
|
.dark {
|
||||||
.ba-nav-tab.active {
|
.close-icon {
|
||||||
.close-icon {
|
color: v-bind('config.getColorVal("headerBarTabColor")') !important;
|
||||||
color: v-bind('config.getColorVal("headerBarTabActiveColor")') !important;
|
}
|
||||||
}
|
|
||||||
}
|
.ba-nav-tab.active {
|
||||||
}
|
.close-icon {
|
||||||
|
color: v-bind('config.getColorVal("headerBarTabActiveColor")') !important;
|
||||||
.nav-tabs {
|
}
|
||||||
overflow-x: auto;
|
}
|
||||||
overflow-y: hidden;
|
}
|
||||||
margin-right: var(--ba-main-space);
|
|
||||||
scrollbar-width: none;
|
.nav-tabs {
|
||||||
|
overflow-x: auto;
|
||||||
&::-webkit-scrollbar {
|
overflow-y: hidden;
|
||||||
height: 5px;
|
margin-right: var(--ba-main-space);
|
||||||
}
|
// scrollbar-width: none;
|
||||||
|
// overflow-x: auto;
|
||||||
//
|
&::-webkit-scrollbar {
|
||||||
//&::-webkit-scrollbar-thumb {
|
height: 5px;
|
||||||
// background: #eaeaea;
|
}
|
||||||
// border-radius: var(--el-border-radius-base);
|
|
||||||
// box-shadow: none;
|
//
|
||||||
// -webkit-box-shadow: none;
|
//&::-webkit-scrollbar-thumb {
|
||||||
//}
|
// background: #eaeaea;
|
||||||
//
|
// border-radius: var(--el-border-radius-base);
|
||||||
//&::-webkit-scrollbar-track {
|
// box-shadow: none;
|
||||||
// background: v-bind('config.layout.layoutMode == "Default" ? "none":config.getColorVal("headerBarBackground")');
|
// -webkit-box-shadow: none;
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//&:hover {
|
//&::-webkit-scrollbar-track {
|
||||||
// &::-webkit-scrollbar-thumb:hover {
|
// background: v-bind('config.layout.layoutMode == "Default" ? "none":config.getColorVal("headerBarBackground")');
|
||||||
// background: #c8c9cc;
|
//}
|
||||||
// }
|
//
|
||||||
//}
|
//&:hover {
|
||||||
}
|
// &::-webkit-scrollbar-thumb:hover {
|
||||||
|
// background: #c8c9cc;
|
||||||
.ba-nav-tab {
|
// }
|
||||||
white-space: nowrap;
|
//}
|
||||||
height: 40px;
|
}
|
||||||
}
|
|
||||||
</style>
|
.ba-nav-tab {
|
||||||
|
white-space: nowrap;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,238 +1,241 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="nav-menus" :class="configStore.layout.layoutMode">
|
<div class="nav-menus" :class="configStore.layout.layoutMode">
|
||||||
<div @click="savePng" class="nav-menu-item">
|
<!-- <div @click="savePng" class="nav-menu-item">
|
||||||
<Icon
|
<Icon
|
||||||
:color="configStore.getColorVal('headerBarTabColor')"
|
:color="configStore.getColorVal('headerBarTabColor')"
|
||||||
class="nav-menu-icon"
|
class="nav-menu-icon"
|
||||||
name="el-icon-Camera"
|
name="el-icon-Camera"
|
||||||
size="18"
|
size="18"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div @click="onFullScreen" class="nav-menu-item" :class="state.isFullScreen ? 'hover' : ''">
|
<div @click="onFullScreen" class="nav-menu-item" :class="state.isFullScreen ? 'hover' : ''">
|
||||||
<Icon
|
<Icon
|
||||||
:color="configStore.getColorVal('headerBarTabColor')"
|
:color="configStore.getColorVal('headerBarTabColor')"
|
||||||
class="nav-menu-icon"
|
class="nav-menu-icon"
|
||||||
v-if="state.isFullScreen"
|
v-if="state.isFullScreen"
|
||||||
name="fa-solid fa-compress"
|
name="fa-solid fa-compress"
|
||||||
size="18"
|
size="18"
|
||||||
/>
|
/>
|
||||||
<Icon
|
<Icon
|
||||||
:color="configStore.getColorVal('headerBarTabColor')"
|
:color="configStore.getColorVal('headerBarTabColor')"
|
||||||
class="nav-menu-icon"
|
class="nav-menu-icon"
|
||||||
v-else
|
v-else
|
||||||
name="fa-solid fa-expand"
|
name="fa-solid fa-expand"
|
||||||
size="18"
|
size="18"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<el-dropdown style="height: 100%" @command="handleCommand">
|
<el-dropdown style="height: 100%" @command="handleCommand">
|
||||||
<div class="admin-info" :class="state.currentNavMenu == 'adminInfo' ? 'hover' : ''">
|
<div class="admin-info" :class="state.currentNavMenu == 'adminInfo' ? 'hover' : ''">
|
||||||
<el-avatar :size="25" fit="fill">
|
<el-avatar :size="25" fit="fill">
|
||||||
<img src="@/assets/avatar.png" alt="" />
|
<img src="@/assets/avatar.png" alt="" />
|
||||||
</el-avatar>
|
</el-avatar>
|
||||||
<div class="admin-name">{{ adminInfo.nickname }}</div>
|
<div class="admin-name">{{ adminInfo.nickname }}</div>
|
||||||
</div>
|
</div>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item command="adminInfo">个人资料</el-dropdown-item>
|
<el-dropdown-item command="adminInfo">个人资料</el-dropdown-item>
|
||||||
<el-dropdown-item command="changePwd">修改密码</el-dropdown-item>
|
<el-dropdown-item command="changePwd">修改密码</el-dropdown-item>
|
||||||
<el-dropdown-item command="layout">退出登录</el-dropdown-item>
|
<el-dropdown-item command="layout">退出登录</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
<!-- <div @click="configStore.setLayout('showDrawer', true)" class="nav-menu-item">
|
<!-- <div @click="configStore.setLayout('showDrawer', true)" class="nav-menu-item">
|
||||||
<Icon
|
<Icon
|
||||||
:color="configStore.getColorVal('headerBarTabColor')"
|
:color="configStore.getColorVal('headerBarTabColor')"
|
||||||
class="nav-menu-icon"
|
class="nav-menu-icon"
|
||||||
name="fa fa-cogs"
|
name="fa fa-cogs"
|
||||||
size="18"
|
size="18"
|
||||||
/>
|
/>
|
||||||
</div> -->"
|
</div> -->
|
||||||
|
"
|
||||||
<Config />
|
|
||||||
<PopupPwd ref="popupPwd" />
|
<Config />
|
||||||
<AdminInfo ref="popupAdminInfo" />
|
<PopupPwd ref="popupPwd" />
|
||||||
<!-- <TerminalVue /> -->
|
<AdminInfo ref="popupAdminInfo" />
|
||||||
</div>
|
<!-- <TerminalVue /> -->
|
||||||
</template>
|
</div>
|
||||||
|
</template>
|
||||||
<script lang="ts" setup>
|
|
||||||
import { reactive, ref } from 'vue'
|
<script lang="ts" setup>
|
||||||
import screenfull from 'screenfull'
|
import { reactive, ref } from 'vue'
|
||||||
import { useConfig } from '@/stores/config'
|
import screenfull from 'screenfull'
|
||||||
import { ElMessage } from 'element-plus'
|
import { useConfig } from '@/stores/config'
|
||||||
import Config from './config.vue'
|
import { ElMessage } from 'element-plus'
|
||||||
import { useAdminInfo } from '@/stores/adminInfo'
|
import Config from './config.vue'
|
||||||
import router from '@/router'
|
import { useAdminInfo } from '@/stores/adminInfo'
|
||||||
import { routePush } from '@/utils/router'
|
import router from '@/router'
|
||||||
import { fullUrl } from '@/utils/common'
|
import { routePush } from '@/utils/router'
|
||||||
import html2canvas from 'html2canvas'
|
import { fullUrl } from '@/utils/common'
|
||||||
import PopupPwd from './popup/password.vue'
|
import html2canvas from 'html2canvas'
|
||||||
import AdminInfo from './popup/adminInfo.vue'
|
import PopupPwd from './popup/password.vue'
|
||||||
import { useNavTabs } from '@/stores/navTabs'
|
import AdminInfo from './popup/adminInfo.vue'
|
||||||
|
import { useNavTabs } from '@/stores/navTabs'
|
||||||
|
|
||||||
const adminInfo = useAdminInfo()
|
const adminInfo = useAdminInfo()
|
||||||
const navTabs = useNavTabs()
|
const navTabs = useNavTabs()
|
||||||
const configStore = useConfig()
|
const configStore = useConfig()
|
||||||
const popupPwd = ref()
|
const popupPwd = ref()
|
||||||
const popupAdminInfo = ref()
|
const popupAdminInfo = ref()
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
isFullScreen: false,
|
isFullScreen: false,
|
||||||
currentNavMenu: '',
|
currentNavMenu: '',
|
||||||
showLayoutDrawer: false,
|
showLayoutDrawer: false,
|
||||||
showAdminInfoPopover: false
|
showAdminInfoPopover: false
|
||||||
})
|
})
|
||||||
|
|
||||||
const savePng = () => {
|
const savePng = () => {
|
||||||
html2canvas(document.body, {
|
html2canvas(document.body, {
|
||||||
scale: 1,
|
scale: 1,
|
||||||
useCORS: true
|
useCORS: true
|
||||||
}).then(function (canvas) {
|
}).then(function (canvas) {
|
||||||
var link = document.createElement('a')
|
var link = document.createElement('a')
|
||||||
link.href = canvas.toDataURL('image/png')
|
link.href = canvas.toDataURL('image/png')
|
||||||
link.download = 'screenshot.png'
|
link.download = 'screenshot.png'
|
||||||
link.click()
|
link.click()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const onFullScreen = () => {
|
const onFullScreen = () => {
|
||||||
if (!screenfull.isEnabled) {
|
if (!screenfull.isEnabled) {
|
||||||
ElMessage.warning('layouts.Full screen is not supported')
|
ElMessage.warning('layouts.Full screen is not supported')
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
screenfull.toggle()
|
screenfull.toggle()
|
||||||
screenfull.onchange(() => {
|
screenfull.onchange(() => {
|
||||||
state.isFullScreen = screenfull.isFullscreen
|
state.isFullScreen = screenfull.isFullscreen
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCommand = (key: string) => {
|
const handleCommand = async (key: string) => {
|
||||||
// console.log(key)
|
// console.log(key)
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'adminInfo':
|
case 'adminInfo':
|
||||||
popupAdminInfo.value.open()
|
popupAdminInfo.value.open()
|
||||||
break
|
break
|
||||||
case 'changePwd':
|
case 'changePwd':
|
||||||
popupPwd.value.open()
|
popupPwd.value.open()
|
||||||
break
|
break
|
||||||
case 'layout':
|
case 'layout':
|
||||||
navTabs.closeTabs()
|
await window.location.reload()
|
||||||
window.localStorage.clear()
|
setTimeout(() => {
|
||||||
adminInfo.reset()
|
navTabs.closeTabs()
|
||||||
router.push({ name: 'login' })
|
window.localStorage.clear()
|
||||||
break
|
adminInfo.reset()
|
||||||
default:
|
router.push({ name: 'login' })
|
||||||
break
|
}, 0)
|
||||||
}
|
break
|
||||||
}
|
default:
|
||||||
</script>
|
break
|
||||||
|
}
|
||||||
<style scoped lang="scss">
|
}
|
||||||
.nav-menus.Default {
|
</script>
|
||||||
border-radius: var(--el-border-radius-base);
|
|
||||||
box-shadow: var(--el-box-shadow-light);
|
<style scoped lang="scss">
|
||||||
}
|
.nav-menus.Default {
|
||||||
|
border-radius: var(--el-border-radius-base);
|
||||||
.nav-menus {
|
box-shadow: var(--el-box-shadow-light);
|
||||||
display: flex;
|
}
|
||||||
align-items: center;
|
|
||||||
height: 100%;
|
.nav-menus {
|
||||||
margin-left: auto;
|
display: flex;
|
||||||
background-color: v-bind('configStore.getColorVal("headerBarBackground")');
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
.nav-menu-item {
|
margin-left: auto;
|
||||||
height: 100%;
|
background-color: v-bind('configStore.getColorVal("headerBarBackground")');
|
||||||
width: 40px;
|
|
||||||
display: flex;
|
.nav-menu-item {
|
||||||
align-items: center;
|
height: 100%;
|
||||||
justify-content: center;
|
width: 40px;
|
||||||
cursor: pointer;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
.nav-menu-icon {
|
justify-content: center;
|
||||||
box-sizing: content-box;
|
cursor: pointer;
|
||||||
color: v-bind('configStore.getColorVal("headerBarTabColor")');
|
|
||||||
}
|
.nav-menu-icon {
|
||||||
|
box-sizing: content-box;
|
||||||
&:hover {
|
color: v-bind('configStore.getColorVal("headerBarTabColor")');
|
||||||
.icon {
|
}
|
||||||
animation: twinkle 0.3s ease-in-out;
|
|
||||||
}
|
&:hover {
|
||||||
}
|
.icon {
|
||||||
}
|
animation: twinkle 0.3s ease-in-out;
|
||||||
|
}
|
||||||
.admin-info {
|
}
|
||||||
display: flex;
|
}
|
||||||
height: 100%;
|
|
||||||
padding: 0 10px;
|
.admin-info {
|
||||||
align-items: center;
|
display: flex;
|
||||||
cursor: pointer;
|
height: 100%;
|
||||||
user-select: none;
|
padding: 0 10px;
|
||||||
color: v-bind('configStore.getColorVal("headerBarTabColor")');
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
&:hover {
|
user-select: none;
|
||||||
color: v-bind('configStore.getColorVal("headerBarTabActiveColor")');
|
color: v-bind('configStore.getColorVal("headerBarTabColor")');
|
||||||
}
|
|
||||||
}
|
&:hover {
|
||||||
|
color: v-bind('configStore.getColorVal("headerBarTabActiveColor")');
|
||||||
.admin-name {
|
}
|
||||||
padding-left: 6px;
|
}
|
||||||
white-space: nowrap;
|
|
||||||
}
|
.admin-name {
|
||||||
|
padding-left: 6px;
|
||||||
.nav-menu-item:hover,
|
white-space: nowrap;
|
||||||
.admin-info:hover,
|
}
|
||||||
.nav-menu-item.hover,
|
|
||||||
.admin-info.hover {
|
.nav-menu-item:hover,
|
||||||
background: v-bind('configStore.getColorVal("headerBarHoverBackground")');
|
.admin-info:hover,
|
||||||
|
.nav-menu-item.hover,
|
||||||
.nav-menu-icon {
|
.admin-info.hover {
|
||||||
color: v-bind('configStore.getColorVal("headerBarTabActiveColor")') !important;
|
background: v-bind('configStore.getColorVal("headerBarHoverBackground")');
|
||||||
}
|
|
||||||
}
|
.nav-menu-icon {
|
||||||
}
|
color: v-bind('configStore.getColorVal("headerBarTabActiveColor")') !important;
|
||||||
|
}
|
||||||
.dropdown-menu-box :deep(.el-dropdown-menu__item) {
|
}
|
||||||
justify-content: center;
|
}
|
||||||
}
|
|
||||||
|
.dropdown-menu-box :deep(.el-dropdown-menu__item) {
|
||||||
.admin-info-base {
|
justify-content: center;
|
||||||
display: flex;
|
}
|
||||||
justify-content: center;
|
|
||||||
flex-wrap: wrap;
|
.admin-info-base {
|
||||||
padding-top: 10px;
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
.admin-info-other {
|
flex-wrap: wrap;
|
||||||
display: block;
|
padding-top: 10px;
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
.admin-info-other {
|
||||||
padding: 10px 0;
|
display: block;
|
||||||
|
width: 100%;
|
||||||
.admin-info-name {
|
text-align: center;
|
||||||
font-size: var(--el-font-size-large);
|
padding: 10px 0;
|
||||||
}
|
|
||||||
}
|
.admin-info-name {
|
||||||
}
|
font-size: var(--el-font-size-large);
|
||||||
|
}
|
||||||
.admin-info-footer {
|
}
|
||||||
padding: 10px 0;
|
}
|
||||||
margin: 0 -12px -12px -12px;
|
|
||||||
display: flex;
|
.admin-info-footer {
|
||||||
justify-content: space-around;
|
padding: 10px 0;
|
||||||
}
|
margin: 0 -12px -12px -12px;
|
||||||
|
display: flex;
|
||||||
.pt2 {
|
justify-content: space-around;
|
||||||
padding-top: 2px;
|
}
|
||||||
}
|
|
||||||
|
.pt2 {
|
||||||
@keyframes twinkle {
|
padding-top: 2px;
|
||||||
0% {
|
}
|
||||||
transform: scale(0);
|
|
||||||
}
|
@keyframes twinkle {
|
||||||
80% {
|
0% {
|
||||||
transform: scale(1.2);
|
transform: scale(0);
|
||||||
}
|
}
|
||||||
100% {
|
80% {
|
||||||
transform: scale(1);
|
transform: scale(1.2);
|
||||||
}
|
}
|
||||||
}
|
100% {
|
||||||
</style>
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,109 +1,123 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog draggable width="500px" v-model.trim="dialogVisible" :title="title">
|
<el-dialog draggable width="500px" v-model.trim="dialogVisible" :title="title">
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<el-form :inline="false" :model="form" label-width="120px" :rules="rules" class="form-one" ref="formRef">
|
<el-form :inline="false" :model="form" label-width="120px" :rules="rules" class="form-one" ref="formRef">
|
||||||
<el-form-item label="校验密码:" prop="password">
|
<el-form-item label="校验密码:" prop="password">
|
||||||
<el-input v-model.trim="form.password" type="password" placeholder="请输入校验密码" show-password />
|
<el-input v-model.trim="form.password" type="password" placeholder="请输入校验密码" show-password />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="新密码:" prop="newPwd">
|
<el-form-item label="新密码:" prop="newPwd">
|
||||||
<el-input v-model.trim="form.newPwd" type="password" placeholder="请输入新密码" show-password />
|
<el-input v-model.trim="form.newPwd" type="password" placeholder="请输入新密码" show-password />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="确认密码:" prop="confirmPwd">
|
<el-form-item label="确认密码:" prop="confirmPwd">
|
||||||
<el-input v-model.trim="form.confirmPwd" type="password" placeholder="请输入确认密码" show-password />
|
<el-input
|
||||||
</el-form-item>
|
v-model.trim="form.confirmPwd"
|
||||||
</el-form>
|
type="password"
|
||||||
</el-scrollbar>
|
placeholder="请输入确认密码"
|
||||||
<template #footer>
|
show-password
|
||||||
<span class="dialog-footer">
|
/>
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
</el-form-item>
|
||||||
<el-button type="primary" @click="submit">确认</el-button>
|
</el-form>
|
||||||
</span>
|
</el-scrollbar>
|
||||||
</template>
|
<template #footer>
|
||||||
</el-dialog>
|
<span class="dialog-footer">
|
||||||
</template>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
<script lang="ts" setup>
|
<el-button type="primary" @click="submit">确认</el-button>
|
||||||
import { ref, inject } from 'vue'
|
</span>
|
||||||
import { reactive } from 'vue'
|
</template>
|
||||||
import { ElMessage } from 'element-plus'
|
</el-dialog>
|
||||||
import { passwordConfirm, updatePassword } from '@/api/user-boot/user'
|
</template>
|
||||||
import { validatePwd } from '@/utils/common'
|
<script lang="ts" setup>
|
||||||
import { useAdminInfo } from '@/stores/adminInfo'
|
import { ref, inject } from 'vue'
|
||||||
|
import { reactive } from 'vue'
|
||||||
const adminInfo = useAdminInfo()
|
import { ElMessage } from 'element-plus'
|
||||||
const dialogVisible = ref(false)
|
import { passwordConfirm, updatePassword } from '@/api/user-boot/user'
|
||||||
const title = ref('修改密码')
|
import { validatePwd } from '@/utils/common'
|
||||||
const formRef = ref()
|
import { useAdminInfo } from '@/stores/adminInfo'
|
||||||
// 注意不要和表单ref的命名冲突
|
import router from '@/router'
|
||||||
const form = reactive({
|
import { useNavTabs } from '@/stores/navTabs'
|
||||||
password: '',
|
const adminInfo = useAdminInfo()
|
||||||
newPwd: '',
|
const navTabs = useNavTabs()
|
||||||
confirmPwd: ''
|
const dialogVisible = ref(false)
|
||||||
})
|
const title = ref('修改密码')
|
||||||
const rules = {
|
const formRef = ref()
|
||||||
password: [
|
// 注意不要和表单ref的命名冲突
|
||||||
{ required: true, message: '请输入校验密码', trigger: 'blur' },
|
const form = reactive({
|
||||||
{
|
password: '',
|
||||||
min: 6,
|
newPwd: '',
|
||||||
max: 16,
|
confirmPwd: ''
|
||||||
message: '长度在 6 到 16 个字符',
|
})
|
||||||
trigger: 'blur'
|
const rules = {
|
||||||
}
|
password: [
|
||||||
],
|
{ required: true, message: '请输入校验密码', trigger: 'blur' },
|
||||||
newPwd: [
|
{
|
||||||
{ required: true, message: '请输入密码', trigger: 'blur' },
|
min: 6,
|
||||||
{
|
max: 16,
|
||||||
min: 6,
|
message: '长度在 6 到 16 个字符',
|
||||||
max: 16,
|
trigger: 'blur'
|
||||||
message: '长度在 6 到 16 个字符',
|
}
|
||||||
trigger: 'blur'
|
],
|
||||||
},
|
newPwd: [
|
||||||
{ validator: validatePwd, trigger: 'blur' }
|
{ required: true, message: '请输入密码', trigger: 'blur' },
|
||||||
],
|
{
|
||||||
confirmPwd: [
|
min: 6,
|
||||||
{ required: true, message: '请确认密码', trigger: 'blur' },
|
max: 16,
|
||||||
{
|
message: '长度在 6 到 16 个字符',
|
||||||
min: 6,
|
trigger: 'blur'
|
||||||
max: 16,
|
},
|
||||||
message: '长度在 6 到 16 个字符',
|
{ validator: validatePwd, trigger: 'blur' }
|
||||||
trigger: 'blur'
|
],
|
||||||
},
|
confirmPwd: [
|
||||||
{
|
{ required: true, message: '请确认密码', trigger: 'blur' },
|
||||||
validator: (rule: any, value: string, callback: any) => {
|
{
|
||||||
if (value === '') {
|
min: 6,
|
||||||
callback(new Error('请再次输入密码'))
|
max: 16,
|
||||||
} else if (value !== form.newPwd) {
|
message: '长度在 6 到 16 个字符',
|
||||||
callback(new Error('两次输入密码不一致!'))
|
trigger: 'blur'
|
||||||
} else {
|
},
|
||||||
callback()
|
{
|
||||||
}
|
validator: (rule: any, value: string, callback: any) => {
|
||||||
},
|
if (value === '') {
|
||||||
trigger: 'blur',
|
callback(new Error('请再次输入密码'))
|
||||||
required: true
|
} else if (value !== form.newPwd) {
|
||||||
}
|
callback(new Error('两次输入密码不一致!'))
|
||||||
]
|
} else {
|
||||||
}
|
callback()
|
||||||
|
}
|
||||||
const open = () => {
|
},
|
||||||
dialogVisible.value = true
|
trigger: 'blur',
|
||||||
form.password = ''
|
required: true
|
||||||
form.newPwd = ''
|
}
|
||||||
form.confirmPwd = ''
|
]
|
||||||
}
|
}
|
||||||
const submit = () => {
|
|
||||||
formRef.value.validate(async (valid: boolean) => {
|
const open = () => {
|
||||||
if (valid) {
|
dialogVisible.value = true
|
||||||
passwordConfirm(form.password).then(res => {
|
form.password = ''
|
||||||
updatePassword({
|
form.newPwd = ''
|
||||||
id: adminInfo.$state.userIndex,
|
form.confirmPwd = ''
|
||||||
newPassword: form.newPwd
|
}
|
||||||
}).then((res: any) => {
|
const submit = () => {
|
||||||
ElMessage.success('密码修改成功')
|
formRef.value.validate(async (valid: boolean) => {
|
||||||
dialogVisible.value = false
|
if (valid) {
|
||||||
})
|
passwordConfirm(form.password).then(res => {
|
||||||
})
|
updatePassword({
|
||||||
}
|
id: adminInfo.$state.userIndex,
|
||||||
})
|
newPassword: form.newPwd
|
||||||
}
|
}).then(async (res: any) => {
|
||||||
|
ElMessage.success('密码修改成功')
|
||||||
defineExpose({ open })
|
dialogVisible.value = false
|
||||||
</script>
|
|
||||||
|
setTimeout(() => {
|
||||||
|
navTabs.closeTabs()
|
||||||
|
window.localStorage.clear()
|
||||||
|
adminInfo.reset()
|
||||||
|
router.push({ name: 'login' })
|
||||||
|
}, 0)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -1,47 +1,47 @@
|
|||||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||||
import staticRoutes from '@/router/static'
|
import staticRoutes from '@/router/static'
|
||||||
import { useAdminInfo } from '@/stores/adminInfo'
|
import { useAdminInfo } from '@/stores/adminInfo'
|
||||||
import NProgress from 'nprogress'
|
import NProgress from 'nprogress'
|
||||||
import { loading } from '@/utils/loading'
|
import { loading } from '@/utils/loading'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHashHistory(),
|
history: createWebHashHistory(),
|
||||||
routes: staticRoutes
|
routes: staticRoutes
|
||||||
})
|
})
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
NProgress.configure({ showSpinner: false })
|
NProgress.configure({ showSpinner: false })
|
||||||
NProgress.start()
|
NProgress.start()
|
||||||
if (!window.existLoading) {
|
if (!window.existLoading) {
|
||||||
loading.show()
|
loading.show()
|
||||||
window.existLoading = true
|
window.existLoading = true
|
||||||
}
|
}
|
||||||
if (to.path == '/login' || to.path == '/404'|| to.path == '/policy'|| to.path == '/agreement') {
|
if (to.path == '/login' || to.path == '/404'|| to.path == '/policy'|| to.path == '/agreement') {
|
||||||
// 登录或者注册才可以往下进行
|
// 登录或者注册才可以往下进行
|
||||||
next()
|
next()
|
||||||
} else {
|
} else {
|
||||||
// 获取 token
|
// 获取 token
|
||||||
const adminInfo = useAdminInfo()
|
const adminInfo = useAdminInfo()
|
||||||
const token = adminInfo.getToken()
|
const token = adminInfo.getToken()
|
||||||
// token 不存在
|
// token 不存在
|
||||||
if (token === null || token === '') {
|
if (token === null || token === '') {
|
||||||
ElMessage.error('您还没有登录,请先登录')
|
// ElMessage.error('您还没有登录,请先登录')
|
||||||
next('/login')
|
next('/login')
|
||||||
} else {
|
} else {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// next()
|
// next()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 路由加载后
|
// 路由加载后
|
||||||
router.afterEach(() => {
|
router.afterEach(() => {
|
||||||
if (window.existLoading) {
|
if (window.existLoading) {
|
||||||
loading.hide()
|
loading.hide()
|
||||||
}
|
}
|
||||||
NProgress.done()
|
NProgress.done()
|
||||||
})
|
})
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|||||||
@@ -1,108 +1,168 @@
|
|||||||
import { reactive } from 'vue'
|
import { reactive } from 'vue'
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { STORE_TAB_VIEW_CONFIG } from '@/stores/constant/cacheKey'
|
import { STORE_TAB_VIEW_CONFIG } from '@/stores/constant/cacheKey'
|
||||||
import type { NavTabs } from '@/stores/interface/index'
|
import type { NavTabs } from '@/stores/interface/index'
|
||||||
import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'
|
import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router'
|
||||||
import { adminBaseRoutePath } from '@/router/static'
|
import { adminBaseRoutePath } from '@/router/static'
|
||||||
|
import { set } from 'lodash'
|
||||||
export const useNavTabs = defineStore(
|
|
||||||
'navTabs',
|
export const useNavTabs = defineStore(
|
||||||
() => {
|
'navTabs',
|
||||||
const state: NavTabs = reactive({
|
() => {
|
||||||
// 激活tab的index
|
const state: NavTabs = reactive({
|
||||||
activeIndex: 0,
|
// 激活tab的index
|
||||||
// 激活的tab
|
activeIndex: 0,
|
||||||
activeRoute: null,
|
// 激活的tab
|
||||||
// tab列表
|
activeRoute: null,
|
||||||
tabsView: [],
|
// tab列表
|
||||||
// 当前tab是否全屏
|
tabsView: [],
|
||||||
tabFullScreen: false,
|
// 当前tab是否全屏
|
||||||
// 从后台加载到的菜单路由列表
|
tabFullScreen: false,
|
||||||
tabsViewRoutes: [],
|
// 从后台加载到的菜单路由列表
|
||||||
// 按钮权限节点
|
tabsViewRoutes: [],
|
||||||
authNode: new Map(),
|
// 按钮权限节点
|
||||||
})
|
authNode: new Map()
|
||||||
|
})
|
||||||
function addTab(route: RouteLocationNormalized) {
|
|
||||||
if (!route.meta.addtab) return
|
function addTab(route: RouteLocationNormalized) {
|
||||||
for (const key in state.tabsView) {
|
if (!route.meta.addtab) return
|
||||||
if (state.tabsView[key].path === route.path) {
|
for (const key in state.tabsView) {
|
||||||
state.tabsView[key].params = route.params ? route.params : state.tabsView[key].params
|
if (state.tabsView[key].path === route.path) {
|
||||||
state.tabsView[key].query = route.query ? route.query : state.tabsView[key].query
|
state.tabsView[key].params = route.params ? route.params : state.tabsView[key].params
|
||||||
return
|
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
|
||||||
state.tabsView.push(route)
|
}
|
||||||
}
|
}
|
||||||
|
state.tabsView.push(route)
|
||||||
function closeTab(route: RouteLocationNormalized) {
|
}
|
||||||
state.tabsView.map((v, k) => {
|
|
||||||
if (v.path == route.path) {
|
function closeTab(route: RouteLocationNormalized) {
|
||||||
state.tabsView.splice(k, 1)
|
state.tabsView.map((v, k) => {
|
||||||
return
|
if (v.path == route.path) {
|
||||||
}
|
state.tabsView.splice(k, 1)
|
||||||
})
|
return
|
||||||
}
|
}
|
||||||
|
})
|
||||||
/**
|
}
|
||||||
* 关闭多个标签
|
|
||||||
* @param retainMenu 需要保留的标签,否则关闭全部标签
|
/**
|
||||||
*/
|
* 关闭多个标签
|
||||||
const closeTabs = (retainMenu: RouteLocationNormalized | false = false) => {
|
* @param retainMenu 需要保留的标签,否则关闭全部标签
|
||||||
if (retainMenu) {
|
*/
|
||||||
state.tabsView = [retainMenu]
|
const closeTabs = (retainMenu: RouteLocationNormalized | false = false) => {
|
||||||
} else {
|
if (retainMenu) {
|
||||||
state.tabsView = []
|
state.tabsView = [retainMenu]
|
||||||
}
|
} else {
|
||||||
}
|
state.tabsView = []
|
||||||
|
}
|
||||||
const setActiveRoute = (route: RouteLocationNormalized): void => {
|
}
|
||||||
const currentRouteIndex: number = state.tabsView.findIndex((item: RouteLocationNormalized) => {
|
|
||||||
return item.path === route.path
|
const setActiveRoute = (route: RouteLocationNormalized): void => {
|
||||||
})
|
const currentRouteIndex: number = state.tabsView.findIndex((item: RouteLocationNormalized) => {
|
||||||
if (currentRouteIndex === -1) return
|
return item.path === route.path
|
||||||
state.activeRoute = route
|
})
|
||||||
state.activeIndex = currentRouteIndex
|
if (currentRouteIndex === -1) return
|
||||||
}
|
state.activeRoute = route
|
||||||
|
state.activeIndex = currentRouteIndex
|
||||||
const setTabsViewRoutes = (data: RouteRecordRaw[]): void => {
|
}
|
||||||
state.tabsViewRoutes = encodeRoutesURI(data)
|
|
||||||
}
|
const setTabsViewRoutes = (data: RouteRecordRaw[]): void => {
|
||||||
|
state.tabsViewRoutes = encodeRoutesURI(JSON.parse(JSON.stringify(data)))
|
||||||
const setAuthNode = (key: string, data: string[]) => {
|
}
|
||||||
state.authNode.set(key, data)
|
|
||||||
}
|
const setAuthNode = (key: string, data: string[]) => {
|
||||||
|
state.authNode.set(key, data)
|
||||||
const fillAuthNode = (data: Map<string, string[]>) => {
|
}
|
||||||
state.authNode = data
|
|
||||||
}
|
const fillAuthNode = (data: Map<string, string[]>) => {
|
||||||
|
state.authNode = data
|
||||||
const setFullScreen = (fullScreen: boolean): void => {
|
}
|
||||||
state.tabFullScreen = fullScreen
|
|
||||||
}
|
const setFullScreen = (fullScreen: boolean): void => {
|
||||||
|
state.tabFullScreen = fullScreen
|
||||||
return { state, addTab, closeTab, closeTabs, setActiveRoute, setTabsViewRoutes, setAuthNode, fillAuthNode, setFullScreen }
|
}
|
||||||
},
|
|
||||||
{
|
const refresh = () => {
|
||||||
persist: {
|
// setTimeout(() => {
|
||||||
key: STORE_TAB_VIEW_CONFIG,
|
// console.log(123, state.tabsViewRoutes)
|
||||||
paths: ['state.tabFullScreen'],
|
|
||||||
},
|
let list = matchAndReturnRouteData(state.tabsViewRoutes, state.tabsView)
|
||||||
}
|
state.tabsView = []
|
||||||
)
|
list.forEach(item => {
|
||||||
|
addTab(item)
|
||||||
/**
|
})
|
||||||
* 对iframe的url进行编码
|
// }, 1000)
|
||||||
*/
|
}
|
||||||
function encodeRoutesURI(data: RouteRecordRaw[]) {
|
return {
|
||||||
data.forEach((item) => {
|
state,
|
||||||
if (item.meta?.menu_type == 'iframe') {
|
addTab,
|
||||||
item.path = adminBaseRoutePath + '/iframe/' + encodeURIComponent(item.path)
|
closeTab,
|
||||||
}
|
closeTabs,
|
||||||
|
setActiveRoute,
|
||||||
if (item.children && item.children.length) {
|
setTabsViewRoutes,
|
||||||
item.children = encodeRoutesURI(item.children)
|
setAuthNode,
|
||||||
}
|
fillAuthNode,
|
||||||
})
|
setFullScreen,
|
||||||
return data
|
refresh
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
persist: {
|
||||||
|
key: STORE_TAB_VIEW_CONFIG,
|
||||||
|
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 => {
|
||||||
|
if (item.meta?.menu_type == 'iframe') {
|
||||||
|
item.path = adminBaseRoutePath + '/iframe/' + encodeURIComponent(item.path)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.children && item.children.length) {
|
||||||
|
item.children = encodeRoutesURI(item.children)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|||||||
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}
|
||||||
@@ -1,84 +1,87 @@
|
|||||||
// .vxe-table--body-wrapper,
|
// .vxe-table--body-wrapper,
|
||||||
// .boxbx {
|
// .boxbx {
|
||||||
// &::-webkit-scrollbar {
|
// &::-webkit-scrollbar {
|
||||||
// width: 10px;
|
// width: 10px;
|
||||||
// height: 10px;
|
// height: 10px;
|
||||||
// }
|
// }
|
||||||
// &::-webkit-scrollbar-thumb {
|
// &::-webkit-scrollbar-thumb {
|
||||||
// border-radius: 5px;
|
// border-radius: 5px;
|
||||||
// height: 3px;
|
// height: 3px;
|
||||||
// background-color: var(--el-color-primary) !important;
|
// background-color: var(--el-color-primary) !important;
|
||||||
// border-radius: 30px !important;
|
// border-radius: 30px !important;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// .vxe-table--body-wrapper::-webkit-scrollbar-thumb {
|
// .vxe-table--body-wrapper::-webkit-scrollbar-thumb {
|
||||||
// border-radius: 5px;
|
// border-radius: 5px;
|
||||||
// height: 3px;
|
// height: 3px;
|
||||||
// background-color: var(--el-color-primary) !important;
|
// background-color: var(--el-color-primary) !important;
|
||||||
// border-radius: 30px !important;
|
// border-radius: 30px !important;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
.vxe-header--row {
|
.vxe-header--row {
|
||||||
background: var(--vxe-table-header-background-color);
|
background: var(--vxe-table-header-background-color);
|
||||||
color: var(--vxe-table-header-font-color);
|
color: var(--vxe-table-header-font-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.is--checked.vxe-checkbox,
|
.is--checked.vxe-checkbox,
|
||||||
.is--checked.vxe-checkbox .vxe-checkbox--icon,
|
.is--checked.vxe-checkbox .vxe-checkbox--icon,
|
||||||
.is--checked.vxe-custom--checkbox-option,
|
.is--checked.vxe-custom--checkbox-option,
|
||||||
.is--checked.vxe-custom--checkbox-option .vxe-checkbox--icon,
|
.is--checked.vxe-custom--checkbox-option .vxe-checkbox--icon,
|
||||||
.is--checked.vxe-export--panel-column-option,
|
.is--checked.vxe-export--panel-column-option,
|
||||||
.is--checked.vxe-export--panel-column-option .vxe-checkbox--icon,
|
.is--checked.vxe-export--panel-column-option .vxe-checkbox--icon,
|
||||||
.is--checked.vxe-table--filter-option,
|
.is--checked.vxe-table--filter-option,
|
||||||
.is--checked.vxe-table--filter-option .vxe-checkbox--icon,
|
.is--checked.vxe-table--filter-option .vxe-checkbox--icon,
|
||||||
.is--indeterminate.vxe-checkbox,
|
.is--indeterminate.vxe-checkbox,
|
||||||
.is--indeterminate.vxe-checkbox .vxe-checkbox--icon,
|
.is--indeterminate.vxe-checkbox .vxe-checkbox--icon,
|
||||||
.is--indeterminate.vxe-custom--checkbox-option,
|
.is--indeterminate.vxe-custom--checkbox-option,
|
||||||
.is--indeterminate.vxe-custom--checkbox-option .vxe-checkbox--icon,
|
.is--indeterminate.vxe-custom--checkbox-option .vxe-checkbox--icon,
|
||||||
.is--indeterminate.vxe-export--panel-column-option,
|
.is--indeterminate.vxe-export--panel-column-option,
|
||||||
.is--indeterminate.vxe-export--panel-column-option .vxe-checkbox--icon,
|
.is--indeterminate.vxe-export--panel-column-option .vxe-checkbox--icon,
|
||||||
.is--indeterminate.vxe-table--filter-option,
|
.is--indeterminate.vxe-table--filter-option,
|
||||||
.is--indeterminate.vxe-table--filter-option .vxe-checkbox--icon,
|
.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-table--render-default .is--checked.vxe-cell--checkbox .vxe-checkbox--icon,
|
.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-table--render-default .is--indeterminate.vxe-cell--checkbox .vxe-checkbox--icon,
|
.vxe-table--render-default .is--indeterminate.vxe-cell--checkbox .vxe-checkbox--icon,
|
||||||
.vxe-table--render-default .is--checked.vxe-cell--radio .vxe-radio--icon {
|
.vxe-table--render-default .is--checked.vxe-cell--radio .vxe-radio--icon {
|
||||||
color: var(--el-color-primary-light-3);
|
color: var(--el-color-primary-light-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.vxe-checkbox:not(.is--disabled):hover .vxe-checkbox--icon,
|
.vxe-checkbox:not(.is--disabled):hover .vxe-checkbox--icon,
|
||||||
.vxe-custom--checkbox-option: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-export--panel-column-option:not(.is--disabled):hover .vxe-checkbox--icon,
|
||||||
.vxe-table--filter-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-table--render-default .vxe-cell--checkbox:not(.is--disabled):hover .vxe-checkbox--icon,
|
||||||
.vxe-radio:not(.is--disabled):hover .vxe-radio--icon,
|
.vxe-radio:not(.is--disabled):hover .vxe-radio--icon,
|
||||||
.vxe-custom--radio-option: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-export--panel-column-option:not(.is--disabled):hover .vxe-radio--icon,
|
||||||
.vxe-table--filter-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 {
|
.vxe-table--render-default .vxe-cell--radio:not(.is--disabled):hover .vxe-radio--icon {
|
||||||
color: var(--el-color-primary-light-5);
|
color: var(--el-color-primary-light-5);
|
||||||
}
|
}
|
||||||
|
.vxe-table--render-default .vxe-body--row.row--current,
|
||||||
// .vxe-table--render-default .is--disabled.vxe-cell--checkbox .vxe-checkbox--icon{
|
.vxe-table--render-default .vxe-body--row.row--current:hover {
|
||||||
// color: #fff0;
|
background-color: var(--el-color-primary-light-8);
|
||||||
// }
|
}
|
||||||
.vxe-table--tooltip-wrapper {
|
// .vxe-table--render-default .is--disabled.vxe-cell--checkbox .vxe-checkbox--icon{
|
||||||
z-index: 10000 !important;
|
// color: #fff0;
|
||||||
}
|
// }
|
||||||
.is--disabled {
|
.vxe-table--tooltip-wrapper {
|
||||||
background-color: var(--vxe-input-disabled-color);
|
z-index: 10000 !important;
|
||||||
}
|
}
|
||||||
|
.is--disabled {
|
||||||
.vxe-modal--wrapper {
|
background-color: var(--vxe-input-disabled-color);
|
||||||
z-index: 5000 !important;
|
}
|
||||||
}
|
|
||||||
.vxe-table--body .vxe-body--row:nth-child(even) {
|
.vxe-modal--wrapper {
|
||||||
background-color: #f9f9f9;
|
z-index: 5000 !important;
|
||||||
// background-color: var(--el-color-primary-light-9);
|
}
|
||||||
}
|
// .vxe-table--body .vxe-body--row:nth-child(even) {
|
||||||
|
// background-color: #f9f9f9;
|
||||||
.vxe-table--body .vxe-body--row:nth-child(odd) {
|
// // background-color: var(--el-color-primary-light-9);
|
||||||
background-color: #ffffff;
|
// }
|
||||||
}
|
|
||||||
|
// .vxe-table--body .vxe-body--row:nth-child(odd) {
|
||||||
|
// background-color: #ffffff;
|
||||||
|
// }
|
||||||
|
|||||||
@@ -1,79 +1,79 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog width="600px" v-model.trim='dialogVisible' :title='title'>
|
<el-dialog width="600px" v-model.trim='dialogVisible' :title='title'>
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<el-form :inline='false' :model='form' label-width='auto' class="form-one" :rules='rules' ref='formRef'>
|
<el-form :inline='false' :model='form' label-width='auto' class="form-one" :rules='rules' ref='formRef'>
|
||||||
<el-form-item label='角色名称'>
|
<el-form-item label='角色名称'>
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim='form.name' placeholder='请输入菜单名称' />
|
<el-input maxlength="32" show-word-limit v-model.trim='form.name' placeholder='请输入菜单名称' />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label='角色编码'>
|
<el-form-item 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>
|
||||||
<el-form-item label='角色描述'>
|
<el-form-item label='角色描述'>
|
||||||
<el-input maxlength="300" show-word-limit v-model.trim='form.remark' :rows='2' type='textarea'
|
<el-input maxlength="300" show-word-limit v-model.trim='form.remark' :rows='2' type='textarea'
|
||||||
placeholder='请输入描述' />
|
placeholder='请输入描述' />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class='dialog-footer'>
|
<span class='dialog-footer'>
|
||||||
<el-button @click='dialogVisible = false'>取消</el-button>
|
<el-button @click='dialogVisible = false'>取消</el-button>
|
||||||
<el-button type='primary' @click='submit'>确认</el-button>
|
<el-button type='primary' @click='submit'>确认</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script lang='ts' setup>
|
<script lang='ts' setup>
|
||||||
import { ref, inject } from 'vue'
|
import { ref, inject } from 'vue'
|
||||||
import { reactive } from 'vue'
|
import { reactive } from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import TableStore from '@/utils/tableStore' // 若不是列表页面弹框可删除
|
import TableStore from '@/utils/tableStore' // 若不是列表页面弹框可删除
|
||||||
|
|
||||||
|
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const title = ref('')
|
const title = ref('')
|
||||||
const tableStore = inject('tableStore') as TableStore
|
const tableStore = inject('tableStore') as TableStore
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
// 注意不要和表单ref的命名冲突
|
// 注意不要和表单ref的命名冲突
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
code: '',
|
code: '',
|
||||||
name: '',
|
name: '',
|
||||||
remark: '',
|
remark: '',
|
||||||
id: ''
|
id: ''
|
||||||
})
|
})
|
||||||
const rules = {
|
const rules = {
|
||||||
name: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
|
name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
|
||||||
code: [{ required: true, message: '角色编码不能为空', trigger: 'blur' }]
|
code: [{ required: true, message: '请输入角色编码', trigger: 'blur' }]
|
||||||
}
|
}
|
||||||
|
|
||||||
const open = (text: string, data?: anyObj) => {
|
const open = (text: string, data?: anyObj) => {
|
||||||
title.value = text
|
title.value = text
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
if (data) {
|
if (data) {
|
||||||
// 表单赋值
|
// 表单赋值
|
||||||
for (let key in form) {
|
for (let key in form) {
|
||||||
form[key] = data[key]
|
form[key] = data[key]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 在此处恢复默认表单
|
// 在此处恢复默认表单
|
||||||
for (let key in form) {
|
for (let key in form) {
|
||||||
form[key] = ''
|
form[key] = ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
formRef.value.validate(async (valid) => {
|
formRef.value.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
if (form.id) {
|
if (form.id) {
|
||||||
// await update(form)
|
// await update(form)
|
||||||
} else {
|
} else {
|
||||||
// await create(form)
|
// await create(form)
|
||||||
}
|
}
|
||||||
ElMessage.success('保存成功')
|
ElMessage.success('保存成功')
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ open })
|
defineExpose({ open })
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ const calculateValue = (o: number, value: number, num: number, isMin: boolean) =
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (base === 0.1) {
|
if (base === 0.1) {
|
||||||
return parseFloat(calculatedValue.toFixed(1))
|
// return parseFloat(calculatedValue.toFixed(1))
|
||||||
|
return Math.ceil(calculatedValue * 10) / 10
|
||||||
} else if (isMin) {
|
} else if (isMin) {
|
||||||
return Math.floor(calculatedValue / base) * base
|
return Math.floor(calculatedValue / base) * base
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -352,7 +352,9 @@ export function getTimeOfTheMonth(key: any): [string, string] {
|
|||||||
const dayOfWeek = now.getDay() // 0是周日
|
const dayOfWeek = now.getDay() // 0是周日
|
||||||
const diff = now.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1) // 调整为周一
|
const diff = now.getDate() - dayOfWeek + (dayOfWeek === 0 ? -6 : 1) // 调整为周一
|
||||||
const weekStart = new Date(year, month, diff)
|
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': // 日
|
case '5': // 日
|
||||||
return [formatDate(now, 'YYYY-MM-DD'), formatDate(now, 'YYYY-MM-DD')]
|
return [formatDate(now, 'YYYY-MM-DD'), formatDate(now, 'YYYY-MM-DD')]
|
||||||
@@ -365,28 +367,19 @@ export function getTimeOfTheMonth(key: any): [string, string] {
|
|||||||
/**
|
/**
|
||||||
* 获取当月时间
|
* 获取当月时间
|
||||||
* @param interval 组件外部时间 1 年 2 季 3 月 4 周 5 日
|
* @param interval 组件外部时间 1 年 2 季 3 月 4 周 5 日
|
||||||
* @param timeList 组件勾选时间 []
|
* @param timeList 驾驶舱里面组件勾选时间 []
|
||||||
* @param externalTime //外部传入时间
|
* @param externalTime //外部传入时间
|
||||||
|
* @param fullscreen // 全屏是否全屏
|
||||||
*/
|
*/
|
||||||
export function getTime(interval: number, timeList: any, externalTime: any) {
|
export function getTime(interval: number | 3, timeList: any, externalTime: any) {
|
||||||
|
// console.log('🚀 ~ getTime ~ timeList:', timeList)
|
||||||
// 1、先匹配时间
|
// 1、先匹配时间
|
||||||
// 检查 interval 是否在 timeList 中
|
// 检查 interval 是否在 timeList 中
|
||||||
if (timeList && timeList.includes(interval.toString())) {
|
if (timeList && timeList.includes(interval.toString())) {
|
||||||
// 匹配上了,返回外部传入时间 externalTime
|
return [externalTime[0], externalTime[1], interval]
|
||||||
if (externalTime && externalTime.length >= 2) {
|
|
||||||
return [externalTime[0], externalTime[1]]
|
|
||||||
} else {
|
|
||||||
// 如果 externalTime 无效,回退到默认逻辑
|
|
||||||
return getTimeOfTheMonth(interval.toString())
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 没有匹配上,返回 timeList 中最后一项的时间范围
|
|
||||||
if (timeList && timeList.length > 0) {
|
if (timeList && timeList.length > 0) {
|
||||||
const lastItem = timeList[timeList.length - 1]
|
return [...getTimeOfTheMonth(timeList[0]), timeList[0]]
|
||||||
return getTimeOfTheMonth(lastItem)
|
|
||||||
} else {
|
|
||||||
// 如果 timeList 为空,使用 interval 参数
|
|
||||||
return getTimeOfTheMonth(interval.toString())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { useAdminInfo } from '@/stores/adminInfo'
|
|||||||
|
|
||||||
window.requests = []
|
window.requests = []
|
||||||
window.tokenRefreshing = false
|
window.tokenRefreshing = false
|
||||||
let loginExpireTimer:any=null
|
let loginExpireTimer: any = null
|
||||||
const pendingMap = new Map()
|
const pendingMap = new Map()
|
||||||
const loadingInstance: LoadingInstance = {
|
const loadingInstance: LoadingInstance = {
|
||||||
target: null,
|
target: null,
|
||||||
@@ -65,10 +65,18 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
|
|||||||
if (
|
if (
|
||||||
!(
|
!(
|
||||||
config.url == '/system-boot/file/upload' ||
|
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/grid/getAssessOverview' ||
|
||||||
config.url == '/harmonic-boot/gridDiagram/getGridDiagramAreaData' ||
|
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/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)
|
removePending(config)
|
||||||
@@ -106,11 +114,11 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
|
|||||||
response => {
|
response => {
|
||||||
removePending(response.config)
|
removePending(response.config)
|
||||||
options.loading && closeLoading(options) // 关闭loading
|
options.loading && closeLoading(options) // 关闭loading
|
||||||
if (
|
if (
|
||||||
response.data.code === 'A0000' ||
|
response.data.code === 'A0000' ||
|
||||||
response.data.type === 'application/json' ||
|
response.data.type === 'application/json' ||
|
||||||
Array.isArray(response.data) ||
|
Array.isArray(response.data) ||
|
||||||
response.data.size
|
response.data.size
|
||||||
// ||
|
// ||
|
||||||
// response.data.type === 'application/octet-stream' ||
|
// response.data.type === 'application/octet-stream' ||
|
||||||
// response.data.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
// response.data.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||||
@@ -145,7 +153,7 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if (response.data.code == 'A0024') {
|
} else if (response.data.code == 'A0024') {
|
||||||
// // 登录失效
|
// // 登录失效
|
||||||
// 清除上一次的定时器
|
// 清除上一次的定时器
|
||||||
if (loginExpireTimer) {
|
if (loginExpireTimer) {
|
||||||
clearTimeout(loginExpireTimer)
|
clearTimeout(loginExpireTimer)
|
||||||
@@ -174,6 +182,7 @@ function createAxios<Data = any, T = ApiPromise<Data>>(
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
ElMessage.error(response.data.message || '未知错误')
|
ElMessage.error(response.data.message || '未知错误')
|
||||||
}, 6000)
|
}, 6000)
|
||||||
|
} else if (response.config.url == '/cs-harmonic-boot/cspage/getByUserId') {
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error(response.data.message || '未知错误')
|
ElMessage.error(response.data.message || '未知错误')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ export const getMenu = () => {
|
|||||||
}
|
}
|
||||||
handlerMenu(res.data)
|
handlerMenu(res.data)
|
||||||
handleAdminRoute(res.data)
|
handleAdminRoute(res.data)
|
||||||
if (route.params.to) {
|
if (route?.params?.to) {
|
||||||
const lastRoute = JSON.parse(route.params.to as string)
|
const lastRoute = JSON.parse(route.params.to as string)
|
||||||
if (lastRoute.path != adminBaseRoutePath) {
|
if (lastRoute.path != adminBaseRoutePath) {
|
||||||
let query = !isEmpty(lastRoute.query) ? lastRoute.query : {}
|
let query = !isEmpty(lastRoute.query) ? lastRoute.query : {}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ export default class TableStore {
|
|||||||
pageSize: 20
|
pageSize: 20
|
||||||
},
|
},
|
||||||
loading: true,
|
loading: true,
|
||||||
|
exportLoading: false,
|
||||||
column: [],
|
column: [],
|
||||||
loadCallback: null,
|
loadCallback: null,
|
||||||
resetCallback: null,
|
resetCallback: null,
|
||||||
@@ -196,6 +197,7 @@ export default class TableStore {
|
|||||||
[
|
[
|
||||||
'export',
|
'export',
|
||||||
() => {
|
() => {
|
||||||
|
this.table.exportLoading = true
|
||||||
// this.index()
|
// this.index()
|
||||||
let params = { ...this.table.params, pageNum: 1, pageSize: this.table.total }
|
let params = { ...this.table.params, pageNum: 1, pageSize: this.table.total }
|
||||||
createAxios(
|
createAxios(
|
||||||
@@ -206,11 +208,16 @@ export default class TableStore {
|
|||||||
},
|
},
|
||||||
requestPayload(this.method, params, this.paramsPOST)
|
requestPayload(this.method, params, this.paramsPOST)
|
||||||
)
|
)
|
||||||
).then(res => {
|
)
|
||||||
this.table.allData = filtration(res.data.records || res.data)
|
.then(res => {
|
||||||
this.table.exportProcessingData && this.table.exportProcessingData()
|
this.table.allData = filtration(res.data.records || res.data)
|
||||||
this.table.allFlag = data.showAllFlag || true
|
this.table.exportProcessingData && this.table.exportProcessingData()
|
||||||
})
|
this.table.allFlag = data.showAllFlag || true
|
||||||
|
this.table.exportLoading = false
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.table.exportLoading = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -1,136 +1,136 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main">
|
<div class="default-main">
|
||||||
<div class="custom-table-header">
|
<div class="custom-table-header">
|
||||||
<div class="title">待审核用户</div>
|
<div class="title">待审核用户</div>
|
||||||
<el-button :icon="Check" type="primary" @click="addRole" class="ml10">审核通过</el-button>
|
<el-button :icon="Check" type="primary" @click="addRole" class="ml10">审核通过</el-button>
|
||||||
</div>
|
</div>
|
||||||
<Table ref="tableRef" />
|
<Table ref="tableRef" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Check } from '@element-plus/icons-vue'
|
import { Check } from '@element-plus/icons-vue'
|
||||||
import { ref, onMounted, provide } from 'vue'
|
import { ref, onMounted, provide } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { checkUser } from '@/api/user-boot/user'
|
import { checkUser } from '@/api/user-boot/user'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'auth/audit'
|
name: 'auth/audit'
|
||||||
})
|
})
|
||||||
const tableStore = new TableStore({
|
const tableStore = new TableStore({
|
||||||
showPage: false,
|
showPage: false,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: '/user-boot/user/checkUserList',
|
url: '/user-boot/user/checkUserList',
|
||||||
column: [
|
column: [
|
||||||
// { width: '60', type: 'checkbox' },
|
{ width: '60', type: 'checkbox' },
|
||||||
{ title: '名称', field: 'name' },
|
{ title: '名称', field: 'name' },
|
||||||
{ title: '登录名', field: 'loginName' },
|
{ title: '登录名', field: 'loginName' },
|
||||||
{ title: '角色', field: 'roleName' },
|
{ title: '角色', field: 'roleName' },
|
||||||
// { title: '部门', field: 'deptId' },
|
// { title: '部门', field: 'deptId' },
|
||||||
{ title: '电话', field: 'phoneShow' },
|
{ title: '电话', field: 'phoneShow' },
|
||||||
{ title: '注册时间', field: 'registerTime', sortable: true },
|
{ title: '注册时间', field: 'registerTime', sortable: true },
|
||||||
{ title: '类型', field: 'casualUserName' },
|
{ title: '类型', field: 'casualUserName' },
|
||||||
{ title: '状态', field: 'stateName' },
|
{ title: '状态', field: 'stateName' },
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作', fixed: 'right',
|
||||||
width: '180',
|
width: '180',
|
||||||
render: 'buttons',
|
render: 'buttons',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
name: 'edit',
|
name: 'edit',
|
||||||
title: '审核通过',
|
title: '审核通过',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
icon: 'el-icon-Check',
|
icon: 'el-icon-Check',
|
||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
click: row => {
|
click: row => {
|
||||||
checkUser([row.id]).then(res => {
|
checkUser([row.id]).then(res => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
ElMessage.success('操作成功')
|
ElMessage.success('操作成功')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'del',
|
name: 'del',
|
||||||
title: '审核不通过',
|
title: '审核不通过',
|
||||||
type: 'danger',
|
type: 'danger',
|
||||||
icon: 'el-icon-Close',
|
icon: 'el-icon-Close',
|
||||||
render: 'confirmButton',
|
render: 'confirmButton',
|
||||||
popconfirm: {
|
popconfirm: {
|
||||||
confirmButtonText: '确认',
|
confirmButtonText: '确认',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
confirmButtonType: 'danger',
|
confirmButtonType: 'danger',
|
||||||
title: '确定不通过该角色吗?'
|
title: '确定不通过该角色吗?'
|
||||||
},
|
},
|
||||||
click: row => {
|
click: row => {
|
||||||
ElMessage.warning('功能尚未实现')
|
ElMessage.warning('功能尚未实现')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data.forEach((item: any) => {
|
tableStore.table.data.forEach((item: any) => {
|
||||||
item.deptId = item.deptId || '/'
|
item.deptId = item.deptId || '/'
|
||||||
item.phoneShow = item.phone || '/'
|
item.phoneShow = item.phone || '/'
|
||||||
item.roleName = item.role.length ? item.role : '/'
|
item.roleName = item.role.length ? item.role : '/'
|
||||||
switch (item.casualUser) {
|
switch (item.casualUser) {
|
||||||
case 0:
|
case 0:
|
||||||
item.casualUserName = '临时用户'
|
item.casualUserName = '临时用户'
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
item.casualUserName = '长期用户'
|
item.casualUserName = '长期用户'
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
item.casualUserName = '/'
|
item.casualUserName = '/'
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch (item.state) {
|
switch (item.state) {
|
||||||
case 0:
|
case 0:
|
||||||
item.stateName = '注销'
|
item.stateName = '注销'
|
||||||
break
|
break
|
||||||
case 1:
|
case 1:
|
||||||
item.stateName = '正常'
|
item.stateName = '正常'
|
||||||
break
|
break
|
||||||
case 2:
|
case 2:
|
||||||
item.stateName = '锁定'
|
item.stateName = '锁定'
|
||||||
break
|
break
|
||||||
case 3:
|
case 3:
|
||||||
item.stateName = '待审核'
|
item.stateName = '待审核'
|
||||||
break
|
break
|
||||||
case 4:
|
case 4:
|
||||||
item.stateName = '休眠'
|
item.stateName = '休眠'
|
||||||
break
|
break
|
||||||
case 5:
|
case 5:
|
||||||
item.stateName = '密码过期'
|
item.stateName = '密码过期'
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
item.stateName = '/'
|
item.stateName = '/'
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
tableStore.table.params.casualUser = 0
|
tableStore.table.params.casualUser = 0
|
||||||
tableStore.table.params.searchState = 0
|
tableStore.table.params.searchState = 0
|
||||||
tableStore.table.params.searchValue = ''
|
tableStore.table.params.searchValue = ''
|
||||||
tableStore.table.params.searchBeginTime = ''
|
tableStore.table.params.searchBeginTime = ''
|
||||||
tableStore.table.params.searchEndTime = ''
|
tableStore.table.params.searchEndTime = ''
|
||||||
tableStore.table.params.sortBy = ''
|
tableStore.table.params.sortBy = ''
|
||||||
tableStore.table.params.orderBy = ''
|
tableStore.table.params.orderBy = ''
|
||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
|
|
||||||
const addRole = () => {
|
const addRole = () => {
|
||||||
if (!tableStore.table.selection.length) {
|
if (!tableStore.table.selection.length) {
|
||||||
ElMessage.warning('请选择用户')
|
ElMessage.warning('请选择用户')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
checkUser(tableStore.table.selection.map((item: any) => item.id)).then(res => {
|
checkUser(tableStore.table.selection.map((item: any) => item.id)).then(res => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
ElMessage.success('操作成功')
|
ElMessage.success('操作成功')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,116 +1,136 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="custom-table-header">
|
<div class="custom-table-header">
|
||||||
<div class="title">接口权限列表</div>
|
<div class="title">接口权限列表</div>
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue"
|
<el-input
|
||||||
style="width: 240px" placeholder="请输入菜单名称" class="ml10" clearable @input="search" />
|
maxlength="32"
|
||||||
<el-button :icon="Plus" type="primary" @click="addMenu" class="ml10" :disabled="!props.id">新增</el-button>
|
show-word-limit
|
||||||
</div>
|
v-model.trim="tableStore.table.params.searchValue"
|
||||||
<Table ref="tableRef" />
|
style="width: 240px"
|
||||||
<popupApi ref="popupRef" @init="tableStore.index()"></popupApi>
|
placeholder="请输入菜单名称"
|
||||||
</div>
|
class="ml10"
|
||||||
</template>
|
clearable
|
||||||
<script setup lang="ts">
|
@input="search"
|
||||||
import { Plus } from '@element-plus/icons-vue'
|
/>
|
||||||
import { ref, Ref, inject, provide, watch } from 'vue'
|
<el-button :icon="Plus" type="primary" @click="addMenu" class="ml10" :disabled="!props.id">新增</el-button>
|
||||||
import TableStore from '@/utils/tableStore'
|
</div>
|
||||||
import Table from '@/components/table/index.vue'
|
<Table ref="tableRef" />
|
||||||
import popupApi from './popupApi.vue'
|
<popupApi ref="popupRef" @init="tableStore.index()"></popupApi>
|
||||||
import { deleteMenu } from '@/api/user-boot/function'
|
</div>
|
||||||
|
</template>
|
||||||
defineOptions({
|
<script setup lang="ts">
|
||||||
name: 'auth/menu/api'
|
import { Plus } from '@element-plus/icons-vue'
|
||||||
})
|
import { ref, Ref, inject, provide, watch } from 'vue'
|
||||||
const emits = defineEmits<{
|
import TableStore from '@/utils/tableStore'
|
||||||
(e: 'init'): void
|
import Table from '@/components/table/index.vue'
|
||||||
}>()
|
import popupApi from './popupApi.vue'
|
||||||
const props = defineProps({
|
import { deleteMenu } from '@/api/user-boot/function'
|
||||||
id: {
|
import { ElMessage } from 'element-plus'
|
||||||
type: String,
|
defineOptions({
|
||||||
default: ''
|
name: 'auth/menu/api'
|
||||||
}
|
})
|
||||||
})
|
const emits = defineEmits<{
|
||||||
const tableRef = ref()
|
(e: 'init'): void
|
||||||
const popupRef = ref()
|
}>()
|
||||||
const apiList = ref([])
|
const props = defineProps({
|
||||||
const tableStore = new TableStore({
|
id: {
|
||||||
showPage: false,
|
type: String,
|
||||||
url: '/user-boot/function/getButtonById',
|
default: ''
|
||||||
publicHeight: 60,
|
}
|
||||||
column: [
|
})
|
||||||
{ title: '普通接口/接口名称', field: 'name' },
|
const tableRef = ref()
|
||||||
{
|
const popupRef = ref()
|
||||||
title: '接口类型',
|
const apiList = ref([])
|
||||||
field: 'type',
|
const tableStore = new TableStore({
|
||||||
formatter: row => {
|
showPage: false,
|
||||||
return row.cellValue == 1 ? '普通接口' : '公用接口'
|
url: '/user-boot/function/getButtonById',
|
||||||
}
|
publicHeight: 60,
|
||||||
},
|
column: [
|
||||||
{ title: 'URL接口路径', field: 'path' },
|
{
|
||||||
{
|
field: 'index',
|
||||||
title: '操作',
|
title: '序号',
|
||||||
align: 'center',
|
width: '80',
|
||||||
width: '180',
|
formatter: (row: any) => {
|
||||||
render: 'buttons',
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
buttons: [
|
}
|
||||||
{
|
},
|
||||||
name: 'edit',
|
{ title: '普通接口/接口名称', field: 'name', minWidth: '180' },
|
||||||
title: '编辑',
|
{
|
||||||
type: 'primary',
|
title: '接口类型',
|
||||||
icon: 'el-icon-EditPen',
|
field: 'type',
|
||||||
render: 'basicButton',
|
minWidth: '140',
|
||||||
click: row => {
|
formatter: row => {
|
||||||
popupRef.value.open('编辑接口权限', row)
|
return row.cellValue == 1 ? '普通接口' : '公用接口'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{ title: 'URL接口路径', field: 'path', minWidth: '200' },
|
||||||
name: 'del',
|
{
|
||||||
title: '删除',
|
title: '操作',
|
||||||
type: 'danger',
|
fixed: 'right',
|
||||||
icon: 'el-icon-Delete',
|
align: 'center',
|
||||||
render: 'confirmButton',
|
width: '140',
|
||||||
popconfirm: {
|
render: 'buttons',
|
||||||
confirmButtonText: '确认',
|
buttons: [
|
||||||
cancelButtonText: '取消',
|
{
|
||||||
confirmButtonType: 'danger',
|
name: 'edit',
|
||||||
title: '确定删除该菜单吗?'
|
title: '编辑',
|
||||||
},
|
type: 'primary',
|
||||||
click: row => {
|
icon: 'el-icon-EditPen',
|
||||||
deleteMenu(row.id).then(() => {
|
render: 'basicButton',
|
||||||
tableStore.index()
|
click: row => {
|
||||||
})
|
popupRef.value.open('编辑接口权限', row)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
]
|
{
|
||||||
}
|
name: 'del',
|
||||||
],
|
title: '删除',
|
||||||
loadCallback: () => {
|
type: 'danger',
|
||||||
apiList.value = tableStore.table.data
|
icon: 'el-icon-Delete',
|
||||||
search()
|
render: 'confirmButton',
|
||||||
}
|
popconfirm: {
|
||||||
})
|
confirmButtonText: '确认',
|
||||||
tableStore.table.loading = false
|
cancelButtonText: '取消',
|
||||||
watch(
|
confirmButtonType: 'danger',
|
||||||
() => props.id,
|
title: '确定删除该菜单吗?'
|
||||||
() => {
|
},
|
||||||
tableStore.table.params.id = props.id
|
click: row => {
|
||||||
tableStore.index()
|
deleteMenu(row.id).then(() => {
|
||||||
}
|
ElMessage.success('删除成功!')
|
||||||
)
|
|
||||||
provide('tableStore', tableStore)
|
tableStore.index()
|
||||||
|
})
|
||||||
const addMenu = () => {
|
}
|
||||||
console.log(popupRef)
|
}
|
||||||
popupRef.value.open('新增接口权限', {
|
]
|
||||||
pid: props.id
|
}
|
||||||
})
|
],
|
||||||
}
|
loadCallback: () => {
|
||||||
const search = () => {
|
apiList.value = tableStore.table.data
|
||||||
tableStore.table.data = apiList.value.filter(
|
search()
|
||||||
(item: any) =>
|
}
|
||||||
!tableStore.table.params.searchValue ||
|
})
|
||||||
item.name.indexOf(tableStore.table.params.searchValue) !== -1 ||
|
tableStore.table.loading = false
|
||||||
item.path.indexOf(tableStore.table.params.searchValue) !== -1
|
watch(
|
||||||
)
|
() => props.id,
|
||||||
}
|
() => {
|
||||||
</script>
|
tableStore.table.params.id = props.id
|
||||||
|
tableStore.index()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
provide('tableStore', tableStore)
|
||||||
|
|
||||||
|
const addMenu = () => {
|
||||||
|
console.log(popupRef)
|
||||||
|
popupRef.value.open('新增接口权限', {
|
||||||
|
pid: props.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const search = () => {
|
||||||
|
tableStore.table.data = apiList.value.filter(
|
||||||
|
(item: any) =>
|
||||||
|
!tableStore.table.params.searchValue ||
|
||||||
|
item.name.indexOf(tableStore.table.params.searchValue) !== -1 ||
|
||||||
|
item.path.indexOf(tableStore.table.params.searchValue) !== -1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -1,140 +1,142 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="custom-table-header">
|
<div class="custom-table-header">
|
||||||
<div class="title">菜单列表</div>
|
<div class="title">菜单列表</div>
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue"
|
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue"
|
||||||
style="width: 310px" placeholder="请输入菜单名称" class="ml10" clearable @input="search" />
|
style="width: 310px" placeholder="请输入菜单名称" class="ml10" clearable @input="search" />
|
||||||
<el-button :icon="Plus" type="primary" @click="addMenu" class="ml10">新增</el-button>
|
<el-button :icon="Plus" type="primary" @click="addMenu" class="ml10">新增</el-button>
|
||||||
</div>
|
</div>
|
||||||
<Table @currentChange="currentChange" />
|
<Table @currentChange="currentChange" />
|
||||||
<popupMenu ref="popupRef" @init="emits('init')"></popupMenu>
|
<popupMenu ref="popupRef" @init="emits('init')"></popupMenu>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Plus } from '@element-plus/icons-vue'
|
import { Plus } from '@element-plus/icons-vue'
|
||||||
import { ref, nextTick, inject, provide, watch } from 'vue'
|
import { ref, nextTick, inject, provide, watch } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import popupMenu from './popupMenu.vue'
|
import popupMenu from './popupMenu.vue'
|
||||||
import { delMenu } from '@/api/systerm'
|
import { delMenu } from '@/api/systerm'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'auth/menu/menu'
|
name: 'auth/menu/menu'
|
||||||
})
|
})
|
||||||
const emits = defineEmits<{
|
const emits = defineEmits<{
|
||||||
(e: 'init'): void
|
(e: 'init'): void
|
||||||
(e: 'select', row: any): void
|
(e: 'select', row: any): void
|
||||||
}>()
|
}>()
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<{
|
defineProps<{
|
||||||
menuData: treeData[]
|
menuData: treeData[]
|
||||||
}>(),
|
}>(),
|
||||||
{
|
{
|
||||||
menuData: () => {
|
menuData: () => {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
const popupRef = ref()
|
const popupRef = ref()
|
||||||
const tableStore = new TableStore({
|
const tableStore = new TableStore({
|
||||||
showPage: false,
|
showPage: false,
|
||||||
url: '/user-boot/function/functionTree',
|
url: '/user-boot/function/functionTree',
|
||||||
publicHeight: 60,
|
publicHeight: 60,
|
||||||
column: [
|
column: [
|
||||||
{ title: '菜单名称', field: 'title', align: 'left', treeNode: true },
|
{ title: '菜单名称', field: 'title', align: 'left', treeNode: true },
|
||||||
{
|
{
|
||||||
title: '图标',
|
title: '图标',
|
||||||
field: 'icon',
|
field: 'icon',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: '60',
|
width: '60',
|
||||||
render: 'icon'
|
render: 'icon'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作', fixed: 'right',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: '180',
|
width: '180',
|
||||||
render: 'buttons',
|
render: 'buttons',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
name: 'edit',
|
name: 'edit',
|
||||||
text: '新增',
|
text: '新增',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
icon: 'el-icon-Plus',
|
icon: 'el-icon-Plus',
|
||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
click: row => {
|
click: row => {
|
||||||
popupRef.value.open('新增菜单', { pid: row.id })
|
popupRef.value.open('新增菜单', { pid: row.id })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'edit',
|
name: 'edit',
|
||||||
text: '编辑',
|
text: '编辑',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
icon: 'el-icon-EditPen',
|
icon: 'el-icon-EditPen',
|
||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
click: row => {
|
click: row => {
|
||||||
popupRef.value.open('编辑菜单', row)
|
popupRef.value.open('编辑菜单', row)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'del',
|
name: 'del',
|
||||||
text: '删除',
|
text: '删除',
|
||||||
type: 'danger',
|
type: 'danger',
|
||||||
icon: 'el-icon-Delete',
|
icon: 'el-icon-Delete',
|
||||||
render: 'confirmButton',
|
render: 'confirmButton',
|
||||||
popconfirm: {
|
popconfirm: {
|
||||||
confirmButtonText: '确认',
|
confirmButtonText: '确认',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
confirmButtonType: 'danger',
|
confirmButtonType: 'danger',
|
||||||
title: '确定删除该菜单吗?'
|
title: '确定删除该菜单吗?'
|
||||||
},
|
},
|
||||||
click: row => {
|
click: row => {
|
||||||
delMenu(row.id).then(() => {
|
delMenu(row.id).then(() => {
|
||||||
emits('init')
|
ElMessage.success('删除成功!')
|
||||||
})
|
|
||||||
}
|
emits('init')
|
||||||
}
|
})
|
||||||
]
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
}
|
||||||
tableStore.table.loading = false
|
]
|
||||||
watch(
|
})
|
||||||
() => props.menuData,
|
tableStore.table.loading = false
|
||||||
() => {
|
watch(
|
||||||
search()
|
() => props.menuData,
|
||||||
}
|
() => {
|
||||||
)
|
search()
|
||||||
provide('tableStore', tableStore)
|
}
|
||||||
|
)
|
||||||
const addMenu = () => {
|
provide('tableStore', tableStore)
|
||||||
popupRef.value.open('新增菜单', {})
|
|
||||||
}
|
const addMenu = () => {
|
||||||
const currentChange = (newValue: any) => {
|
popupRef.value.open('新增菜单', {})
|
||||||
emits('select', newValue.row.id)
|
}
|
||||||
}
|
const currentChange = (newValue: any) => {
|
||||||
const search = () => {
|
emits('select', newValue.row.id)
|
||||||
tableStore.table.data = filterData(JSON.parse(JSON.stringify(props.menuData)))
|
}
|
||||||
if (tableStore.table.params.searchValue) {
|
const search = () => {
|
||||||
nextTick(() => {
|
tableStore.table.data = filterData(JSON.parse(JSON.stringify(props.menuData)))
|
||||||
tableStore.table.ref?.setAllTreeExpand(true)
|
if (tableStore.table.params.searchValue) {
|
||||||
})
|
nextTick(() => {
|
||||||
}
|
tableStore.table.ref?.setAllTreeExpand(true)
|
||||||
}
|
})
|
||||||
|
}
|
||||||
// 过滤
|
}
|
||||||
const filterData = (arr: treeData[]): treeData[] => {
|
|
||||||
if (!tableStore.table.params.searchValue) {
|
// 过滤
|
||||||
return arr
|
const filterData = (arr: treeData[]): treeData[] => {
|
||||||
}
|
if (!tableStore.table.params.searchValue) {
|
||||||
return arr.filter((item: treeData) => {
|
return arr
|
||||||
if (item.title.includes(tableStore.table.params.searchValue)) {
|
}
|
||||||
return true
|
return arr.filter((item: treeData) => {
|
||||||
} else if (item.children?.length > 0) {
|
if (item.title.includes(tableStore.table.params.searchValue)) {
|
||||||
item.children = filterData(item.children)
|
return true
|
||||||
return item.children.length > 0
|
} else if (item.children?.length > 0) {
|
||||||
} else {
|
item.children = filterData(item.children)
|
||||||
return false
|
return item.children.length > 0
|
||||||
}
|
} else {
|
||||||
})
|
return false
|
||||||
}
|
}
|
||||||
</script>
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -1,104 +1,134 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog width="700px" v-model.trim="dialogVisible" :title="title">
|
<el-dialog width="700px" v-model.trim="dialogVisible" :title="title">
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<el-form :mode="form" :inline="false" :model="form" label-width="120px" :rules="rules" class="form-one">
|
<el-form
|
||||||
<el-form-item prop="name" label="接口/按钮名称">
|
:mode="form"
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入接口名称" />
|
:inline="false"
|
||||||
</el-form-item>
|
ref="formRef"
|
||||||
<el-form-item prop="code" label="接口/按钮标识">
|
:model="form"
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.code" placeholder="请输入英文接口标识" />
|
label-width="120px"
|
||||||
</el-form-item>
|
:rules="rules"
|
||||||
<el-form-item prop="path" label="接口路径">
|
class="form-one"
|
||||||
<el-input v-model.trim="form.path" placeholder="请输入接口路径" />
|
>
|
||||||
</el-form-item>
|
<el-form-item prop="name" label="接口/按钮名称">
|
||||||
<el-form-item prop="type" label="接口类型">
|
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入接口名称" />
|
||||||
<el-radio-group v-model.trim="form.type">
|
</el-form-item>
|
||||||
<el-radio :label="1">普通接口</el-radio>
|
<el-form-item prop="code" label="接口/按钮标识">
|
||||||
<el-radio :label="2">公用接口</el-radio>
|
<el-input
|
||||||
</el-radio-group>
|
maxlength="32"
|
||||||
</el-form-item>
|
show-word-limit
|
||||||
<el-form-item prop="sort" label="排序">
|
v-model.trim="form.code"
|
||||||
<el-input maxlength="32" show-word-limit-number v-model.trim="form.sort" :min="0" />
|
placeholder="请输入英文接口标识"
|
||||||
</el-form-item>
|
/>
|
||||||
<el-form-item prop="remark" label="接口/按钮描述">
|
</el-form-item>
|
||||||
<el-input maxlength="300" show-word-limit v-model.trim="form.remark" :rows="2" type="textarea"
|
<el-form-item prop="path" label="接口路径">
|
||||||
placeholder="请输入描述" />
|
<el-input v-model.trim="form.path" placeholder="请输入接口路径" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
<el-form-item prop="type" label="接口类型">
|
||||||
</el-scrollbar>
|
<el-radio-group v-model.trim="form.type">
|
||||||
|
<el-radio :label="1">普通接口</el-radio>
|
||||||
<template #footer>
|
<el-radio :label="2">公用接口</el-radio>
|
||||||
<span class="dialog-footer">
|
</el-radio-group>
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
</el-form-item>
|
||||||
<el-button type="primary" @click="submit">确认</el-button>
|
<el-form-item prop="sort" label="排序">
|
||||||
</span>
|
<el-input maxlength="32" show-word-limit-number v-model.number="form.sort" :min="0" />
|
||||||
</template>
|
</el-form-item>
|
||||||
</el-dialog>
|
<el-form-item prop="remark" label="接口/按钮描述">
|
||||||
</template>
|
<el-input
|
||||||
<script lang="ts" setup>
|
maxlength="300"
|
||||||
import { ref, inject } from 'vue'
|
show-word-limit
|
||||||
import { reactive } from 'vue'
|
v-model.trim="form.remark"
|
||||||
import { update, add } from '@/api/user-boot/function'
|
:rows="2"
|
||||||
|
type="textarea"
|
||||||
defineOptions({
|
placeholder="请输入描述"
|
||||||
name: 'auth/menu/popupApi'
|
/>
|
||||||
})
|
</el-form-item>
|
||||||
const emits = defineEmits<{
|
</el-form>
|
||||||
(e: 'init'): void
|
</el-scrollbar>
|
||||||
}>()
|
|
||||||
const form: any = reactive({
|
<template #footer>
|
||||||
id: '',
|
<span class="dialog-footer">
|
||||||
pid: '0',
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
code: '',
|
<el-button type="primary" @click="submit">确认</el-button>
|
||||||
name: '',
|
</span>
|
||||||
path: '',
|
</template>
|
||||||
type: 1,
|
</el-dialog>
|
||||||
sort: 100,
|
</template>
|
||||||
remark: ''
|
<script lang="ts" setup>
|
||||||
})
|
import { ref, inject } from 'vue'
|
||||||
const rules = {
|
import { reactive } from 'vue'
|
||||||
code: [
|
import { update, add } from '@/api/user-boot/function'
|
||||||
{ required: true, message: '标识不能为空', trigger: 'blur' },
|
import { ElMessage } from 'element-plus'
|
||||||
{
|
defineOptions({
|
||||||
pattern: /^[a-zA-Z_]{1}[a-zA-Z0-9_]{2,20}$/,
|
name: 'auth/menu/popupApi'
|
||||||
message: '请输入至少3-20位英文',
|
})
|
||||||
min: 3,
|
const emits = defineEmits<{
|
||||||
max: 20,
|
(e: 'init'): void
|
||||||
trigger: 'blur'
|
}>()
|
||||||
}
|
const formRef = ref()
|
||||||
],
|
const form: any = reactive({
|
||||||
name: [{ required: true, message: '请输入接口名称', trigger: 'blur' }],
|
id: '',
|
||||||
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
pid: '0',
|
||||||
path: [{ required: true, message: '请输入接口路径', trigger: 'blur' }]
|
code: '',
|
||||||
}
|
name: '',
|
||||||
const dialogVisible = ref(false)
|
path: '',
|
||||||
const title = ref('新增菜单')
|
type: 1,
|
||||||
const open = (text: string, data: anyObj) => {
|
sort: 100,
|
||||||
title.value = text
|
remark: ''
|
||||||
// 重置表单
|
})
|
||||||
for (let key in form) {
|
const rules = {
|
||||||
form[key] = ''
|
code: [
|
||||||
}
|
{ required: true, message: '请输入标识', trigger: 'blur' },
|
||||||
form.type = 1
|
{
|
||||||
form.pid = data.pid
|
pattern: /^[a-zA-Z_]{1}[a-zA-Z0-9_]{2,20}$/,
|
||||||
if (data.id) {
|
message: '请输入至少3-20位英文',
|
||||||
for (let key in form) {
|
min: 3,
|
||||||
form[key] = data[key] || ''
|
max: 20,
|
||||||
}
|
trigger: 'blur'
|
||||||
}
|
}
|
||||||
dialogVisible.value = true
|
],
|
||||||
}
|
name: [{ required: true, message: '请输入接口名称', trigger: 'blur' }],
|
||||||
const submit = async () => {
|
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }],
|
||||||
if (form.id) {
|
path: [{ required: true, message: '请输入接口路径', trigger: 'blur' }]
|
||||||
await update(form)
|
}
|
||||||
} else {
|
const dialogVisible = ref(false)
|
||||||
let obj = JSON.parse(JSON.stringify(form))
|
const title = ref('新增菜单')
|
||||||
delete obj.id
|
const open = (text: string, data: anyObj) => {
|
||||||
await add(obj)
|
formRef.value?.resetFields()
|
||||||
}
|
title.value = text
|
||||||
emits('init')
|
// 重置表单
|
||||||
dialogVisible.value = false
|
for (let key in form) {
|
||||||
}
|
form[key] = ''
|
||||||
|
}
|
||||||
defineExpose({ open })
|
form.type = 1
|
||||||
</script>
|
form.sort = 100
|
||||||
|
form.pid = data.pid
|
||||||
|
if (data.id) {
|
||||||
|
for (let key in form) {
|
||||||
|
form[key] = data[key] || ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
const submit = async () => {
|
||||||
|
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 })
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -1,107 +1,141 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog class="cn-operate-dialog" width="700px" v-model.trim="dialogVisible" :title="title">
|
<el-dialog class="cn-operate-dialog" width="700px" v-model.trim="dialogVisible" :title="title">
|
||||||
<el-scrollbar>
|
<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-form-item label="上级菜单">
|
||||||
<el-cascader v-model.trim="form.pid" :options="tableStore.table.data" :props="cascaderProps"
|
<el-cascader
|
||||||
style="width: 100%" />
|
v-model.trim="form.pid"
|
||||||
</el-form-item>
|
:options="tableStore.table.data"
|
||||||
<el-form-item label="菜单名称">
|
:props="cascaderProps"
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入菜单名称" />
|
clearable
|
||||||
</el-form-item>
|
style="width: 100%"
|
||||||
<el-form-item label="图标">
|
/>
|
||||||
<IconSelector v-model.trim="form.icon" placeholder="请选择图标" />
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="菜单名称" prop="name">
|
||||||
<el-form-item label="菜单路由">
|
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入菜单名称" />
|
||||||
<el-input v-model.trim="form.path" placeholder="请输入菜单名称" />
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="图标">
|
||||||
<el-form-item label="组件路径">
|
<IconSelector v-model.trim="form.icon" placeholder="请选择图标" />
|
||||||
<el-input v-model.trim="form.routeName" placeholder="请输入组件路径,如/src/views/dashboard/index.vue" />
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="菜单路由" prop="path">
|
||||||
<el-form-item label="排序">
|
<el-input v-model.trim="form.path" placeholder="请输入菜单名称" />
|
||||||
<el-input maxlength="32" show-word-limit-number v-model.trim="form.sort" :min="0" />
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="组件路径" prop="routeName">
|
||||||
<el-form-item label="菜单描述">
|
<el-input
|
||||||
<el-input maxlength="300" show-word-limit v-model.trim="form.remark" :rows="2" type="textarea"
|
v-model.trim="form.routeName"
|
||||||
placeholder="请输入描述" />
|
placeholder="请输入组件路径,如/src/views/dashboard/index.vue"
|
||||||
</el-form-item>
|
/>
|
||||||
</el-form>
|
</el-form-item>
|
||||||
</el-scrollbar>
|
<el-form-item label="排序" prop="sort">
|
||||||
|
<el-input maxlength="32" show-word-limit-number v-model.number="form.sort" :min="0" />
|
||||||
<template #footer>
|
</el-form-item>
|
||||||
<span class="dialog-footer">
|
<el-form-item label="菜单描述">
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-input
|
||||||
<el-button type="primary" @click="submit">确认</el-button>
|
maxlength="300"
|
||||||
</span>
|
show-word-limit
|
||||||
</template>
|
v-model.trim="form.remark"
|
||||||
</el-dialog>
|
:rows="2"
|
||||||
</template>
|
type="textarea"
|
||||||
<script lang="ts" setup>
|
placeholder="请输入描述"
|
||||||
import { ref, inject } from 'vue'
|
/>
|
||||||
import { reactive } from 'vue'
|
</el-form-item>
|
||||||
import TableStore from '@/utils/tableStore'
|
</el-form>
|
||||||
import IconSelector from '@/components/baInput/components/iconSelector.vue'
|
</el-scrollbar>
|
||||||
import { updateMenu, addMenu } from '@/api/systerm'
|
|
||||||
|
<template #footer>
|
||||||
defineOptions({
|
<span class="dialog-footer">
|
||||||
name: 'auth/menu/popupMenu'
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
})
|
<el-button type="primary" @click="submit">确认</el-button>
|
||||||
const emits = defineEmits<{
|
</span>
|
||||||
(e: 'init'): void
|
</template>
|
||||||
}>()
|
</el-dialog>
|
||||||
const tableStore = inject('tableStore') as TableStore
|
</template>
|
||||||
const cascaderProps = {
|
<script lang="ts" setup>
|
||||||
label: 'title',
|
import { ref, inject } from 'vue'
|
||||||
value: 'id',
|
import { reactive } from 'vue'
|
||||||
checkStrictly: true,
|
import TableStore from '@/utils/tableStore'
|
||||||
emitPath: false
|
import IconSelector from '@/components/baInput/components/iconSelector.vue'
|
||||||
}
|
import { updateMenu, addMenu } from '@/api/systerm'
|
||||||
const form: any = reactive({
|
import { ElMessage } from 'element-plus'
|
||||||
code: '',
|
defineOptions({
|
||||||
icon: '',
|
name: 'auth/menu/popupMenu'
|
||||||
id: '',
|
})
|
||||||
name: '',
|
const formRef = ref()
|
||||||
path: '',
|
const emits = defineEmits<{
|
||||||
pid: '0',
|
(e: 'init'): void
|
||||||
remark: '',
|
}>()
|
||||||
routeName: '',
|
const tableStore = inject('tableStore') as TableStore
|
||||||
sort: 100,
|
const cascaderProps = {
|
||||||
type: 0
|
label: 'title',
|
||||||
})
|
value: 'id',
|
||||||
|
checkStrictly: true,
|
||||||
const dialogVisible = ref(false)
|
emitPath: false
|
||||||
const title = ref('新增菜单')
|
}
|
||||||
const open = (text: string, data: anyObj) => {
|
const form: any = reactive({
|
||||||
title.value = text
|
code: '',
|
||||||
// 重置表单
|
icon: '',
|
||||||
for (let key in form) {
|
id: '',
|
||||||
form[key] = ''
|
name: '',
|
||||||
}
|
path: '',
|
||||||
form.pid = data.pid || '0'
|
pid: '0',
|
||||||
form.sort = 100
|
remark: '',
|
||||||
form.type = 0
|
routeName: '',
|
||||||
|
sort: 100,
|
||||||
if (data.id) {
|
type: 0
|
||||||
for (let key in form) {
|
})
|
||||||
form[key] = data[key] ? data[key] : data[key] === 0 ? 0 : ''
|
|
||||||
}
|
const dialogVisible = ref(false)
|
||||||
form.path = data.routePath || ''
|
const title = ref('新增菜单')
|
||||||
form.name = data.title || ''
|
const rules = {
|
||||||
}
|
name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
|
||||||
dialogVisible.value = true
|
path: [{ required: true, message: '请输入菜单路由', trigger: 'blur' }],
|
||||||
}
|
icon: [{ required: true, message: '请选择图标', trigger: 'blur' }],
|
||||||
const submit = async () => {
|
routeName: [{ required: true, message: '请输入组件路径', trigger: 'blur' }],
|
||||||
if (form.id) {
|
sort: [{ required: true, message: '请输入排序', trigger: 'blur' }]
|
||||||
await updateMenu(form)
|
}
|
||||||
} else {
|
const open = (text: string, data: anyObj) => {
|
||||||
form.code = 'menu'
|
formRef.value?.resetFields()
|
||||||
let obj = JSON.parse(JSON.stringify(form))
|
title.value = text
|
||||||
delete obj.id
|
// 重置表单
|
||||||
await addMenu(obj)
|
for (let key in form) {
|
||||||
}
|
form[key] = ''
|
||||||
emits('init')
|
}
|
||||||
dialogVisible.value = false
|
form.pid = data.pid || '0'
|
||||||
}
|
form.sort = 100
|
||||||
|
form.type = 0
|
||||||
defineExpose({ open })
|
|
||||||
</script>
|
if (data.id) {
|
||||||
|
for (let key in form) {
|
||||||
|
form[key] = data[key] ? data[key] : data[key] === 0 ? 0 : ''
|
||||||
|
}
|
||||||
|
form.path = data.routePath || ''
|
||||||
|
form.name = data.title || ''
|
||||||
|
}
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
const submit = async () => {
|
||||||
|
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 })
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -5,18 +5,36 @@
|
|||||||
<div class="title">角色列表</div>
|
<div class="title">角色列表</div>
|
||||||
<el-button :icon="Plus" type="primary" @click="addRole" class="ml10">新增</el-button>
|
<el-button :icon="Plus" type="primary" @click="addRole" class="ml10">新增</el-button>
|
||||||
</div>
|
</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>
|
</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>
|
<PopupForm ref="popupRef"></PopupForm>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -26,23 +44,27 @@ import { ref, onMounted, provide } from 'vue'
|
|||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import Tree from '@/components/tree/index.vue'
|
import Tree from '@/components/tree/allocation.vue'
|
||||||
import { functionTree } from '@/api/user-boot/function'
|
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 { mainHeight } from '@/utils/layout'
|
||||||
import { del } from '@/api/user-boot/role'
|
import { del } from '@/api/user-boot/role'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import PopupForm from './popupForm.vue'
|
import PopupForm from './popupForm.vue'
|
||||||
import { useAdminInfo } from '@/stores/adminInfo'
|
import { useAdminInfo } from '@/stores/adminInfo'
|
||||||
|
import { useDictData } from '@/stores/dictData'
|
||||||
|
const dictData = useDictData()
|
||||||
|
const systemList = dictData.getBasicData('System_Type')
|
||||||
const adminInfo = useAdminInfo()
|
const adminInfo = useAdminInfo()
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'auth/role'
|
name: 'auth/role'
|
||||||
})
|
})
|
||||||
|
const systemIds = ref([])
|
||||||
const height = mainHeight(20).height
|
const height = mainHeight(20).height
|
||||||
const treeRef = ref()
|
const treeRef = ref()
|
||||||
const menuTree = ref<treeData[]>([])
|
const menuTree = ref<treeData[]>([])
|
||||||
const popupRef = ref()
|
const popupRef = ref()
|
||||||
|
const tableRef = ref()
|
||||||
const checkStrictly = ref(true)
|
const checkStrictly = ref(true)
|
||||||
const menuListId = ref('')
|
const menuListId = ref('')
|
||||||
const tableStore = new TableStore({
|
const tableStore = new TableStore({
|
||||||
@@ -68,7 +90,7 @@ const tableStore = new TableStore({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作', fixed: 'right',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: '180',
|
width: '180',
|
||||||
render: 'buttons',
|
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 = ''
|
tableStore.table.params.searchValue = ''
|
||||||
|
|
||||||
@@ -134,6 +162,12 @@ const currentChange = (data: any) => {
|
|||||||
menuListId.value = data.row.id
|
menuListId.value = data.row.id
|
||||||
getFunctionsByRoleIndex({ id: data.row.id }).then((res: any) => {
|
getFunctionsByRoleIndex({ id: data.row.id }).then((res: any) => {
|
||||||
treeRef.value.treeRef.setCheckedKeys(res.data.map((item: any) => item.id))
|
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
|
checkStrictly.value = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (timeout.value) {
|
|
||||||
clearTimeout(timeout.value)
|
updateRoleMenu({
|
||||||
}
|
id: menuListId.value,
|
||||||
timeout.value = setTimeout(() => {
|
idList: treeRef.value.treeRef.getCheckedNodes(false, true).map((node: any) => node.id)
|
||||||
updateRoleMenu({
|
})
|
||||||
id: menuListId.value,
|
.then(() => {
|
||||||
idList: treeRef.value.treeRef.getCheckedNodes(false, true).map((node: any) => node.id)
|
|
||||||
}).then(() => {
|
|
||||||
ElMessage.success('操作成功!')
|
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(() => {
|
onMounted(() => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
@@ -162,3 +210,17 @@ const addRole = () => {
|
|||||||
popupRef.value.open('新增角色')
|
popupRef.value.open('新增角色')
|
||||||
}
|
}
|
||||||
</script>
|
</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,74 +1,86 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog class="cn-operate-dialog" width="700px" v-model.trim="dialogVisible" :title="title">
|
<el-dialog class="cn-operate-dialog" width="500px" v-model.trim="dialogVisible" :title="title">
|
||||||
<el-form :inline="false" :model="form" label-width="auto" class="form-one" :rules="rules">
|
<el-form :inline="false" ref="formRef" :model="form" label-width="auto" class="form-one" :rules="rules">
|
||||||
<el-form-item label="角色名称">
|
<el-form-item label="角色名称" prop="name">
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入菜单名称" />
|
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入菜单名称" />
|
||||||
</el-form-item>
|
</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-input maxlength="32" show-word-limit v-model.trim="form.code" placeholder="请输入菜单名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="角色描述">
|
<el-form-item label="角色描述">
|
||||||
<el-input maxlength="300" show-word-limit v-model.trim="form.remark" :rows="2" type="textarea"
|
<el-input
|
||||||
placeholder="请输入描述" />
|
maxlength="300"
|
||||||
</el-form-item>
|
show-word-limit
|
||||||
</el-form>
|
v-model.trim="form.remark"
|
||||||
|
:rows="2"
|
||||||
<template #footer>
|
type="textarea"
|
||||||
<span class="dialog-footer">
|
placeholder="请输入描述"
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
/>
|
||||||
<el-button type="primary" @click="submit">确认</el-button>
|
</el-form-item>
|
||||||
</span>
|
</el-form>
|
||||||
</template>
|
|
||||||
</el-dialog>
|
<template #footer>
|
||||||
</template>
|
<span class="dialog-footer">
|
||||||
<script lang="ts" setup>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
import { ref, inject } from 'vue'
|
<el-button type="primary" @click="submit">确认</el-button>
|
||||||
import { reactive } from 'vue'
|
</span>
|
||||||
import TableStore from '@/utils/tableStore'
|
</template>
|
||||||
import { ElMessage } from 'element-plus'
|
</el-dialog>
|
||||||
import { add, update } from '@/api/user-boot/role'
|
</template>
|
||||||
import { useAdminInfo } from '@/stores/adminInfo'
|
<script lang="ts" setup>
|
||||||
|
import { ref, inject } from 'vue'
|
||||||
const adminInfo = useAdminInfo()
|
import { reactive } from 'vue'
|
||||||
const tableStore = inject('tableStore') as TableStore
|
import TableStore from '@/utils/tableStore'
|
||||||
// do not use same name with ref
|
import { ElMessage } from 'element-plus'
|
||||||
const form = reactive({
|
import { add, update } from '@/api/user-boot/role'
|
||||||
code: '',
|
import { useAdminInfo } from '@/stores/adminInfo'
|
||||||
name: '',
|
|
||||||
remark: '',
|
const adminInfo = useAdminInfo()
|
||||||
id: '',
|
const tableStore = inject('tableStore') as TableStore
|
||||||
type: 0
|
// do not use same name with ref
|
||||||
})
|
const form = reactive({
|
||||||
const rules = {
|
code: '',
|
||||||
name: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
|
name: '',
|
||||||
code: [{ required: true, message: '角色编码不能为空', trigger: 'blur' }]
|
remark: '',
|
||||||
}
|
id: '',
|
||||||
const dialogVisible = ref(false)
|
type: 0
|
||||||
const title = ref('新增菜单')
|
})
|
||||||
const open = (text: string, data?: anyObj) => {
|
const rules = {
|
||||||
title.value = text
|
name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
|
||||||
dialogVisible.value = true
|
code: [{ required: true, message: '请输入角色编码', trigger: 'blur' }]
|
||||||
if (data) {
|
}
|
||||||
for (let key in form) {
|
const dialogVisible = ref(false)
|
||||||
form[key] = data[key]
|
const title = ref('新增菜单')
|
||||||
}
|
const formRef = ref()
|
||||||
} else {
|
const open = (text: string, data?: anyObj) => {
|
||||||
for (let key in form) {
|
formRef.value?.resetFields()
|
||||||
form[key] = ''
|
title.value = text
|
||||||
}
|
dialogVisible.value = true
|
||||||
}
|
if (data) {
|
||||||
}
|
for (let key in form) {
|
||||||
const submit = async () => {
|
form[key] = data[key]
|
||||||
if (form.id) {
|
}
|
||||||
await update(form)
|
} else {
|
||||||
} else {
|
for (let key in form) {
|
||||||
form.type = adminInfo.$state.userType + 1
|
form[key] = ''
|
||||||
await add(form)
|
}
|
||||||
}
|
}
|
||||||
ElMessage.success('保存成功')
|
}
|
||||||
tableStore.index()
|
const submit = async () => {
|
||||||
dialogVisible.value = false
|
formRef.value.validate(async valid => {
|
||||||
}
|
if (valid) {
|
||||||
|
if (form.id) {
|
||||||
defineExpose({ open })
|
await update(form)
|
||||||
</script>
|
} else {
|
||||||
|
form.type = adminInfo.$state.userType + 1
|
||||||
|
await add(form)
|
||||||
|
}
|
||||||
|
ElMessage.success('保存成功')
|
||||||
|
tableStore.index()
|
||||||
|
dialogVisible.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -79,10 +79,10 @@ const tableStore = new TableStore({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作', fixed: 'right',
|
||||||
width: '180',
|
width: '180',
|
||||||
render: 'buttons',
|
render: 'buttons',
|
||||||
fixed: 'right',
|
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
name: 'edit',
|
name: 'edit',
|
||||||
@@ -95,6 +95,7 @@ const tableStore = new TableStore({
|
|||||||
},
|
},
|
||||||
click: row => {
|
click: row => {
|
||||||
popupEditRef.value.open('编辑用户', row)
|
popupEditRef.value.open('编辑用户', row)
|
||||||
|
console.log("🚀 ~ row:", row)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,245 +1,277 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog class="cn-operate-dialog" v-model.trim="dialogVisible" :title="title">
|
<el-dialog class="cn-operate-dialog" v-model.trim="dialogVisible" :title="title">
|
||||||
|
<el-form :model="form" ref="formRef" label-width="auto" class="form-two" :rules="rules">
|
||||||
<el-form :model="form" label-width="auto" class="form-two" :rules="rules">
|
<el-form-item label="用户名" prop="name">
|
||||||
<el-form-item label="用户名" prop="name">
|
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入昵称" />
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.name" placeholder="请输入昵称" />
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="登录名" prop="loginName">
|
||||||
<el-form-item label="登录名" prop="loginName">
|
<el-input maxlength="32" show-word-limit v-model.trim="form.loginName" placeholder="请输入登录名" />
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.loginName" placeholder="请输入登录名" />
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="默认密码" prop="password" v-if="title === '新增用户'">
|
||||||
<el-form-item label="默认密码" prop="password" v-if="title === '新增用户'">
|
<el-input
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.password" placeholder="请输入密码" disabled />
|
maxlength="32"
|
||||||
</el-form-item>
|
show-word-limit
|
||||||
<el-form-item label="权限类型" prop="type">
|
v-model.trim="form.password"
|
||||||
<el-select v-model.trim="form.type" @change="changeValue" disabled placeholder="请选择权限类型">
|
placeholder="请输入密码"
|
||||||
<el-option v-for="(item, index) in UserTypeOption" :label="item.label" :value="item.value"
|
disabled
|
||||||
:key="index"></el-option>
|
/>
|
||||||
</el-select>
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="权限类型" prop="type">
|
||||||
<el-form-item label="用户类型" prop="casualUser">
|
<el-select v-model.trim="form.type" @change="changeValue" disabled placeholder="请选择权限类型">
|
||||||
<el-select v-model.trim="form.casualUser" placeholder="请选择权限类型">
|
<el-option
|
||||||
<el-option v-for="(item, index) in TypeOptions" :label="item.label" :value="item.value"
|
v-for="(item, index) in UserTypeOption"
|
||||||
:key="index"></el-option>
|
:label="item.label"
|
||||||
</el-select>
|
:value="item.value"
|
||||||
</el-form-item>
|
:key="index"
|
||||||
<!-- <el-form-item label="所属部门" prop="deptId">
|
></el-option>
|
||||||
<Area v-model.trim="form.deptId" />
|
</el-select>
|
||||||
</el-form-item> -->
|
</el-form-item>
|
||||||
<el-form-item label="角色" prop="role">
|
<el-form-item label="用户类型" prop="casualUser">
|
||||||
<el-select v-model.trim="form.role" placeholder="请选择角色" multiple collapse-tags>
|
<el-select v-model.trim="form.casualUser" placeholder="请选择权限类型">
|
||||||
<el-option v-for="(item, index) in roleOptions" :label="item.label" :value="item.value"
|
<el-option
|
||||||
:key="index"></el-option>
|
v-for="(item, index) in TypeOptions"
|
||||||
</el-select>
|
:label="item.label"
|
||||||
</el-form-item>
|
:value="item.value"
|
||||||
|
:key="index"
|
||||||
<el-form-item label="手机号" prop="phone">
|
></el-option>
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.phone" placeholder="请输入手机号" />
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="邮箱" prop="email">
|
<!-- <el-form-item label="所属部门" prop="deptId">
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.email" placeholder="请输入描述" />
|
<Area v-model.trim="form.deptId" />
|
||||||
</el-form-item>
|
</el-form-item> -->
|
||||||
<el-form-item label="时间段" prop="limitTime">
|
<el-form-item label="角色" prop="role">
|
||||||
<el-slider v-model.trim="form.limitTime" style="width: 95%" range show-stops :max="24" />
|
<el-select v-model.trim="form.role" placeholder="请选择角色" multiple collapse-tags>
|
||||||
</el-form-item>
|
<el-option
|
||||||
<el-form-item label="起始IP" prop="limitIpStart">
|
v-for="(item, index) in roleOptions"
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.limitIpStart" placeholder="请输入描述" />
|
:label="item.label"
|
||||||
</el-form-item>
|
:value="item.value"
|
||||||
<el-form-item label="结束IP" prop="limitIpEnd">
|
:key="index"
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="form.limitIpEnd" placeholder="请输入描述" />
|
></el-option>
|
||||||
</el-form-item>
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="短信通知" prop="smsNotice">
|
|
||||||
<el-radio-group v-model.trim="form.smsNotice" style="width: 200px">
|
<el-form-item label="手机号" prop="phone">
|
||||||
<el-radio-button :label="0">是</el-radio-button>
|
<el-input maxlength="32" show-word-limit v-model.trim="form.phone" placeholder="请输入手机号" />
|
||||||
<el-radio-button :label="1">否</el-radio-button>
|
</el-form-item>
|
||||||
</el-radio-group>
|
<el-form-item label="邮箱" prop="email">
|
||||||
</el-form-item>
|
<el-input maxlength="32" show-word-limit v-model.trim="form.email" placeholder="请输入描述" />
|
||||||
<el-form-item label="邮件通知" prop="emailNotice">
|
</el-form-item>
|
||||||
<el-radio-group v-model.trim="form.emailNotice" style="width: 200px">
|
<el-form-item label="时间段" prop="limitTime">
|
||||||
<el-radio-button :label="0">是</el-radio-button>
|
<el-slider v-model.trim="form.limitTime" style="width: 95%" range show-stops :max="24" />
|
||||||
<el-radio-button :label="1">否</el-radio-button>
|
</el-form-item>
|
||||||
</el-radio-group>
|
<el-form-item label="起始IP" prop="limitIpStart">
|
||||||
</el-form-item>
|
<el-input maxlength="32" show-word-limit v-model.trim="form.limitIpStart" placeholder="请输入描述" />
|
||||||
<el-form-item label="用户ID">
|
</el-form-item>
|
||||||
<div style="display: flex; width: 100%">
|
<el-form-item label="结束IP" prop="limitIpEnd">
|
||||||
<el-radio-group v-model.trim="useId">
|
<el-input maxlength="32" show-word-limit v-model.trim="form.limitIpEnd" placeholder="请输入描述" />
|
||||||
<el-radio-button :label="1">是</el-radio-button>
|
</el-form-item>
|
||||||
<el-radio-button :label="0">否</el-radio-button>
|
|
||||||
</el-radio-group>
|
<el-form-item label="短信通知" prop="smsNotice">
|
||||||
<el-input maxlength="32" show-word-limit :disabled="title !== '新增用户'" v-model.trim="form.id"
|
<el-radio-group v-model.trim="form.smsNotice" style="width: 200px">
|
||||||
placeholder="请输入用户id" v-if="useId" style="flex: 1;" class="ml10"></el-input>
|
<el-radio-button :label="0">是</el-radio-button>
|
||||||
</div>
|
<el-radio-button :label="1">否</el-radio-button>
|
||||||
</el-form-item>
|
</el-radio-group>
|
||||||
</el-form>
|
</el-form-item>
|
||||||
|
<el-form-item label="邮件通知" prop="emailNotice">
|
||||||
<template #footer>
|
<el-radio-group v-model.trim="form.emailNotice" style="width: 200px">
|
||||||
<span class="dialog-footer">
|
<el-radio-button :label="0">是</el-radio-button>
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-radio-button :label="1">否</el-radio-button>
|
||||||
<el-button type="primary" @click="submit">确认</el-button>
|
</el-radio-group>
|
||||||
</span>
|
</el-form-item>
|
||||||
</template>
|
<el-form-item label="用户ID">
|
||||||
</el-dialog>
|
<div style="display: flex; width: 100%">
|
||||||
</template>
|
<el-radio-group v-model.trim="useId">
|
||||||
<script lang="ts" setup>
|
<el-radio-button :label="1">是</el-radio-button>
|
||||||
import { ref, inject } from 'vue'
|
<el-radio-button :label="0">否</el-radio-button>
|
||||||
import { reactive } from 'vue'
|
</el-radio-group>
|
||||||
import TableStore from '@/utils/tableStore'
|
<el-input
|
||||||
import { ElMessage, FormItemRule } from 'element-plus'
|
maxlength="32"
|
||||||
import { roleList } from '@/api/user-boot/role'
|
show-word-limit
|
||||||
import { add, edit } from '@/api/user-boot/user'
|
:disabled="title !== '新增用户'"
|
||||||
import { useAdminInfo } from '@/stores/adminInfo'
|
v-model.trim="form.id"
|
||||||
import Area from '@/components/form/area/index.vue'
|
placeholder="请输入用户id"
|
||||||
import { Arrayable } from 'element-plus/es/utils'
|
v-if="useId"
|
||||||
|
style="flex: 1"
|
||||||
const adminInfo = useAdminInfo()
|
class="ml10"
|
||||||
const tableStore = inject('tableStore') as TableStore
|
></el-input>
|
||||||
// do not use same name with ref
|
</div>
|
||||||
const form = reactive({
|
</el-form-item>
|
||||||
id: '',
|
</el-form>
|
||||||
name: '',
|
|
||||||
password: '123456',
|
<template #footer>
|
||||||
email: '',
|
<span class="dialog-footer">
|
||||||
limitIpStart: '',
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
deptId: '',
|
<el-button type="primary" @click="submit">确认</el-button>
|
||||||
deptName: '',
|
</span>
|
||||||
casualUser: 1,
|
</template>
|
||||||
loginName: '',
|
</el-dialog>
|
||||||
phone: '',
|
</template>
|
||||||
limitIpEnd: '',
|
<script lang="ts" setup>
|
||||||
limitTime: [1, 2],
|
import { ref, inject } from 'vue'
|
||||||
role: [],
|
import { reactive } from 'vue'
|
||||||
smsNotice: 0,
|
import TableStore from '@/utils/tableStore'
|
||||||
emailNotice: 0,
|
import { ElMessage, FormItemRule } from 'element-plus'
|
||||||
type: 0
|
import { roleList } from '@/api/user-boot/role'
|
||||||
})
|
import { add, edit } from '@/api/user-boot/user'
|
||||||
const rules: Partial<Record<string, Arrayable<FormItemRule>>> = {
|
import { useAdminInfo } from '@/stores/adminInfo'
|
||||||
name: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
|
import Area from '@/components/form/area/index.vue'
|
||||||
role: [{ required: true, message: '角色不能为空', trigger: 'blur' }],
|
import { Arrayable } from 'element-plus/es/utils'
|
||||||
password: [{ required: true, message: '用户密码不能为空', trigger: 'blur' }],
|
|
||||||
loginName: [{ required: true, message: '登录名不能为空', trigger: 'blur' }],
|
const adminInfo = useAdminInfo()
|
||||||
casualUser: [{ required: true, message: '用户类型不能为空', trigger: 'blur' }],
|
const tableStore = inject('tableStore') as TableStore
|
||||||
smsNotice: [{ required: true, message: '短信通知不能为空', trigger: 'blur' }],
|
// do not use same name with ref
|
||||||
emailNotice: [{ required: true, message: '邮件通知不能为空', trigger: 'blur' }],
|
const form = reactive({
|
||||||
email: [
|
id: '',
|
||||||
{ required: false, message: '邮箱不能为空', trigger: 'blur' },
|
name: '',
|
||||||
{
|
password: '123456',
|
||||||
type: 'email',
|
email: '',
|
||||||
message: "'请输入正确的邮箱地址",
|
limitIpStart: '',
|
||||||
trigger: ['blur', 'change']
|
deptId: '',
|
||||||
}
|
deptName: '',
|
||||||
],
|
casualUser: 1,
|
||||||
phone: [
|
loginName: '',
|
||||||
{ required: false, message: '手机号不能为空', trigger: 'blur' },
|
phone: '',
|
||||||
{
|
limitIpEnd: '',
|
||||||
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
limitTime: [1, 2],
|
||||||
message: '请输入正确的手机号码',
|
role: [],
|
||||||
trigger: 'blur'
|
smsNotice: 0,
|
||||||
}
|
emailNotice: 0,
|
||||||
],
|
type: 0
|
||||||
limitTime: [{ required: true, message: '时间段不能为空', trigger: 'blur' }],
|
})
|
||||||
limitIpStart: [
|
const formRef = ref()
|
||||||
{ required: true, message: '起始IP不能为空', trigger: 'blur' },
|
const rules: Partial<Record<string, Arrayable<FormItemRule>>> = {
|
||||||
{
|
name: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
||||||
required: true,
|
role: [{ required: true, message: '请输入角色', trigger: 'blur' }],
|
||||||
validator: (rule: any, value: string, callback: any) => {
|
password: [{ required: true, message: '请输入用户密码', trigger: 'blur' }],
|
||||||
let regexp = /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/
|
loginName: [{ required: true, message: '请输入登录名', trigger: 'blur' }],
|
||||||
let isCorrect = regexp.test(value)
|
casualUser: [{ required: true, message: '请输入用户类型', trigger: 'blur' }],
|
||||||
if (value == '') {
|
smsNotice: [{ required: true, message: '请输入短信通知', trigger: 'blur' }],
|
||||||
return callback(new Error('请输入IP地址'))
|
emailNotice: [{ required: true, message: '请输入邮件通知', trigger: 'blur' }],
|
||||||
} else if (!isCorrect) {
|
email: [
|
||||||
callback(new Error('请输入正确的IP地址'))
|
{ required: false, message: '请输入邮箱', trigger: 'blur' },
|
||||||
} else {
|
{
|
||||||
callback()
|
type: 'email',
|
||||||
}
|
message: "'请输入正确的邮箱地址",
|
||||||
},
|
trigger: ['blur', 'change']
|
||||||
trigger: 'blur'
|
}
|
||||||
}
|
],
|
||||||
],
|
phone: [
|
||||||
limitIpEnd: [
|
{ required: false, message: '请输入手机号', trigger: 'blur' },
|
||||||
{ required: true, message: '结束IP不能为空', trigger: 'blur' },
|
{
|
||||||
{
|
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
|
||||||
required: true,
|
message: '请输入正确的手机号码',
|
||||||
validator: (rule: any, value: string, callback: any) => {
|
trigger: 'blur'
|
||||||
let regexp = /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/
|
}
|
||||||
let isCorrect = regexp.test(value)
|
],
|
||||||
if (value == '') {
|
limitTime: [{ required: true, message: '请选择时间段', trigger: 'blur' }],
|
||||||
return callback(new Error('请输入IP地址'))
|
limitIpStart: [
|
||||||
} else if (!isCorrect) {
|
{ required: true, message: '请输入起始IP', trigger: 'blur' },
|
||||||
callback(new Error('请输入正确的IP地址'))
|
{
|
||||||
} else {
|
required: true,
|
||||||
callback()
|
validator: (rule: any, value: string, callback: any) => {
|
||||||
}
|
let regexp = /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/
|
||||||
},
|
let isCorrect = regexp.test(value)
|
||||||
trigger: 'blur'
|
if (value == '') {
|
||||||
}
|
return callback(new Error('请输入IP地址'))
|
||||||
]
|
} else if (!isCorrect) {
|
||||||
}
|
callback(new Error('请输入正确的IP地址'))
|
||||||
const UserTypeOption = [
|
} else {
|
||||||
{ label: '管理员', value: 1 },
|
callback()
|
||||||
{ label: '普通用户', value: 2 }
|
}
|
||||||
]
|
},
|
||||||
const TypeOptions = [
|
trigger: 'blur'
|
||||||
{ label: '临时用户', value: 0 },
|
}
|
||||||
{ label: '长期用户', value: 1 }
|
],
|
||||||
]
|
limitIpEnd: [
|
||||||
const useId = ref(1)
|
{ required: true, message: '请输入结束IP', trigger: 'blur' },
|
||||||
const roleOptions = ref<treeData>()
|
{
|
||||||
const queryRole = () => {
|
required: true,
|
||||||
roleList(adminInfo.$state.userType).then((res: any) => {
|
validator: (rule: any, value: string, callback: any) => {
|
||||||
roleOptions.value = res.data.map((item: any) => {
|
let regexp = /^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$/
|
||||||
return {
|
let isCorrect = regexp.test(value)
|
||||||
label: item.name,
|
if (value == '') {
|
||||||
value: item.id
|
return callback(new Error('请输入IP地址'))
|
||||||
}
|
} else if (!isCorrect) {
|
||||||
})
|
callback(new Error('请输入正确的IP地址'))
|
||||||
})
|
} else {
|
||||||
}
|
callback()
|
||||||
queryRole()
|
}
|
||||||
const dialogVisible = ref(false)
|
},
|
||||||
const title = ref('新增菜单')
|
trigger: 'blur'
|
||||||
const open = (text: string, data?: anyObj) => {
|
}
|
||||||
title.value = text
|
]
|
||||||
dialogVisible.value = true
|
}
|
||||||
if (data) {
|
const UserTypeOption = [
|
||||||
for (let key in form) {
|
{ label: '管理员', value: 1 },
|
||||||
form[key] = data[key]
|
{ label: '普通用户', value: 2 }
|
||||||
}
|
]
|
||||||
form.limitTime = data.limitTime.split('-')
|
const TypeOptions = [
|
||||||
form.role = data.roleList
|
{ label: '临时用户', value: 0 },
|
||||||
} else {
|
{ label: '长期用户', value: 1 }
|
||||||
for (let key in form) {
|
]
|
||||||
form[key] = ''
|
const useId = ref(1)
|
||||||
}
|
const roleOptions = ref<treeData>()
|
||||||
form.casualUser = 1
|
const queryRole = () => {
|
||||||
form.limitTime = [0, 24]
|
roleList(adminInfo.$state.userType).then((res: any) => {
|
||||||
form.role = []
|
roleOptions.value = res.data.map((item: any) => {
|
||||||
form.smsNotice = 0
|
return {
|
||||||
form.emailNotice = 0
|
label: item.name,
|
||||||
useId.value = 1
|
value: item.id
|
||||||
form.id = ''
|
}
|
||||||
form.limitIpStart = '0.0.0.0'
|
})
|
||||||
form.limitIpEnd = '255.255.255.255'
|
})
|
||||||
form.password = '123456'
|
}
|
||||||
}
|
queryRole()
|
||||||
form.type = adminInfo.$state.userType + 1
|
const dialogVisible = ref(false)
|
||||||
}
|
const title = ref('新增菜单')
|
||||||
const submit = async () => {
|
const open = (text: string, data?: anyObj) => {
|
||||||
let obj = JSON.parse(JSON.stringify(form))
|
formRef.value?.resetFields()
|
||||||
obj.limitTime = obj.limitTime.join('-')
|
title.value = text
|
||||||
delete obj.password
|
dialogVisible.value = true
|
||||||
if (form.id) {
|
|
||||||
await edit(obj)
|
if (data) {
|
||||||
ElMessage.success('修改成功')
|
for (let key in form) {
|
||||||
} else {
|
form[key] = data[key]
|
||||||
form.type = adminInfo.$state.userType + 1
|
}
|
||||||
await add(obj)
|
form.limitTime = data.limitTime.split('-')
|
||||||
ElMessage.success('新增成功')
|
form.role = data.roleList
|
||||||
}
|
} else {
|
||||||
tableStore.index()
|
for (let key in form) {
|
||||||
dialogVisible.value = false
|
form[key] = ''
|
||||||
}
|
}
|
||||||
|
form.casualUser = 1
|
||||||
const changeValue = () => { }
|
form.limitTime = [0, 24]
|
||||||
defineExpose({ open })
|
form.role = []
|
||||||
</script>
|
form.smsNotice = 0
|
||||||
|
form.emailNotice = 0
|
||||||
|
useId.value = 1
|
||||||
|
form.id = ''
|
||||||
|
form.limitIpStart = '0.0.0.0'
|
||||||
|
form.limitIpEnd = '255.255.255.255'
|
||||||
|
form.password = '123456'
|
||||||
|
form.type = adminInfo.$state.userType + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const submit = async () => {
|
||||||
|
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 = () => {}
|
||||||
|
defineExpose({ open })
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
@change="sourceChange"
|
@change="sourceChange"
|
||||||
:options="deviceTreeOptions"
|
:options="deviceTreeOptions"
|
||||||
:show-all-levels="false"
|
:show-all-levels="false"
|
||||||
:props="{ checkStrictly: true }"
|
:props="{ checkStrictly: true, value: 'id', label: 'name' }"
|
||||||
clearable
|
clearable
|
||||||
></el-cascader>
|
></el-cascader>
|
||||||
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
|
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
|
||||||
@@ -57,17 +57,33 @@ const tabsList = ref([
|
|||||||
])
|
])
|
||||||
const rankOptions = ref([
|
const rankOptions = ref([
|
||||||
{
|
{
|
||||||
value: '1',
|
value: '1,7',
|
||||||
label: '1级'
|
label: '1级(ERROR)'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '2',
|
value: '2,6',
|
||||||
label: '2级'
|
label: '2级(WARN)'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: '3',
|
value: '3,4,5',
|
||||||
label: '3级'
|
label: '3级(DEBUG,NORMAL)'
|
||||||
}
|
},
|
||||||
|
// {
|
||||||
|
// value: '4',
|
||||||
|
// label: 'DEBUG'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// value: '5',
|
||||||
|
// label: 'NORMAL'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// value: '6',
|
||||||
|
// label: 'WARN'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// value: '7',
|
||||||
|
// label: 'ERROR'
|
||||||
|
// }
|
||||||
])
|
])
|
||||||
|
|
||||||
const tableStore = new TableStore({
|
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
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ title: '设备名称', field: 'equipmentName', align: 'center' },
|
{ title: '设备名称', field: 'equipmentName', align: 'center', width: 120 },
|
||||||
{ title: '工程名称', field: 'engineeringName', align: 'center' },
|
{ title: '工程名称', field: 'engineeringName', align: 'center', width: 120 },
|
||||||
{ title: '项目名称', field: 'projectName', align: 'center' },
|
{ title: '项目名称', field: 'projectName', align: 'center', width: 120 },
|
||||||
{ title: '发生时刻', field: 'startTime', align: 'center', width: 180, sortable: true },
|
{ title: '发生时刻', field: 'startTime', align: 'center', width: 180, sortable: true },
|
||||||
{
|
{
|
||||||
title: '模块信息',
|
title: '模块信息',
|
||||||
field: 'moduleNo',
|
field: 'moduleNo',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
width: 100,
|
||||||
formatter: (row: any) => {
|
formatter: (row: any) => {
|
||||||
return row.cellValue ? row.cellValue : '/'
|
return row.cellValue ? row.cellValue : '/'
|
||||||
}
|
}
|
||||||
@@ -107,7 +124,7 @@ const tableStore = new TableStore({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '事件描述',
|
title: '事件描述',
|
||||||
minWidth: 220,
|
minWidth: 250,
|
||||||
field: 'showName'
|
field: 'showName'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -116,14 +133,24 @@ const tableStore = new TableStore({
|
|||||||
width: 100,
|
width: 100,
|
||||||
render: 'tag',
|
render: 'tag',
|
||||||
custom: {
|
custom: {
|
||||||
|
// 1:Ⅰ级 2:Ⅱ级 3:Ⅲ级 4:DEBUG 5:NORMAL 6:WARN 7:ERROR
|
||||||
|
|
||||||
1: 'danger',
|
1: 'danger',
|
||||||
2: 'warning',
|
2: 'warning',
|
||||||
3: 'success'
|
3: 'success',
|
||||||
|
4: 'warning',
|
||||||
|
5: 'success',
|
||||||
|
6: 'warning',
|
||||||
|
7: 'danger'
|
||||||
},
|
},
|
||||||
replaceValue: {
|
replaceValue: {
|
||||||
1: '1级',
|
1: '1级',
|
||||||
2: '2级',
|
2: '2级',
|
||||||
3: '3级'
|
3: '3级',
|
||||||
|
4: 'DEBUG',
|
||||||
|
5: 'NORMAL',
|
||||||
|
6: 'WARN',
|
||||||
|
7: 'ERROR'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
@@ -135,7 +162,25 @@ const tableStore = new TableStore({
|
|||||||
// }
|
// }
|
||||||
],
|
],
|
||||||
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)
|
provide('tableStore', tableStore)
|
||||||
@@ -177,6 +222,7 @@ const sourceChange = (e: any) => {
|
|||||||
tableStore.table.params.deviceTypeId = e[0] || ''
|
tableStore.table.params.deviceTypeId = e[0] || ''
|
||||||
tableStore.table.params.engineeringid = e[1] || ''
|
tableStore.table.params.engineeringid = e[1] || ''
|
||||||
tableStore.table.params.projectId = e[2] || ''
|
tableStore.table.params.projectId = e[2] || ''
|
||||||
|
tableStore.table.params.deviceId = e[3] || ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<TableHeader datePicker ref="refheader" showExport>
|
<TableHeader datePicker ref="refheader" showExport>
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="关键词">
|
<el-form-item label="关键字筛选">
|
||||||
<el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入前置服务器名称,ip" />
|
<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>
|
</el-form-item>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<!-- <div style="height: 300px;"> -->
|
<!-- <div style="height: 300px;"> -->
|
||||||
@@ -21,7 +35,36 @@ import { mainHeight } from '@/utils/layout'
|
|||||||
const props = defineProps(['deviceTree'])
|
const props = defineProps(['deviceTree'])
|
||||||
|
|
||||||
const refheader = ref()
|
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({
|
const tableStore = new TableStore({
|
||||||
url: '/cs-harmonic-boot/eventUser/frontWarnInfo',
|
url: '/cs-harmonic-boot/eventUser/frontWarnInfo',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@@ -35,33 +78,79 @@ const tableStore = new TableStore({
|
|||||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ title: '前置服务器名称', field: 'lineId', align: 'center' },
|
{ title: '前置服务器名称', field: 'lineId', align: 'center', width: 120 },
|
||||||
{ title: '前置服务器ip', field: 'wavePath', align: 'center' },
|
{ title: '前置服务器ip', field: 'wavePath', align: 'center', width: 120 },
|
||||||
{ title: '进程号', field: 'clDid', align: 'center' },
|
{ title: '进程号', field: 'clDid', align: 'center', width: 60 },
|
||||||
{ title: '发生时刻', field: 'startTime', align: 'center', minWidth: 80, sortable: true },
|
{ title: '发生时刻', field: 'startTime', align: 'center', width: 180, sortable: true },
|
||||||
|
|
||||||
{
|
{
|
||||||
title: '事件描述',
|
title: '事件描述',
|
||||||
field: 'tag',
|
field: 'tag',
|
||||||
minWidth: 350
|
minWidth: 350
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '告警代码',
|
title: '告警代码',
|
||||||
field: 'code',
|
field: 'code',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
width: 100,
|
||||||
|
|
||||||
formatter: (row: any) => {
|
formatter: (row: any) => {
|
||||||
return row.cellValue ? '\u200B' + row.cellValue : '/'
|
return row.cellValue ? '\u200B' + row.cellValue : '/'
|
||||||
},
|
},
|
||||||
sortable: true
|
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)
|
provide('tableStore', tableStore)
|
||||||
tableStore.table.params.searchValue = ''
|
tableStore.table.params.searchValue = ''
|
||||||
|
tableStore.table.params.level = ''
|
||||||
const deviceTreeOptions = ref<any>(props.deviceTree)
|
const deviceTreeOptions = ref<any>(props.deviceTree)
|
||||||
deviceTreeOptions.value.map((item: any, index: any) => {
|
deviceTreeOptions.value.map((item: any, index: any) => {
|
||||||
if (item.children.length == 0) {
|
if (item.children.length == 0) {
|
||||||
@@ -75,6 +164,5 @@ onMounted(() => {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// tableStore.table.height = mainHeight(200).height as any
|
// tableStore.table.height = mainHeight(200).height as any
|
||||||
}, 0)
|
}, 0)
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
<style></style>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
@change="sourceChange"
|
@change="sourceChange"
|
||||||
:options="deviceTreeOptions"
|
:options="deviceTreeOptions"
|
||||||
:show-all-levels="false"
|
:show-all-levels="false"
|
||||||
:props="{ checkStrictly: true }"
|
:props="{ checkStrictly: true, value: 'id', label: 'name' }"
|
||||||
clearable
|
clearable
|
||||||
></el-cascader>
|
></el-cascader>
|
||||||
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
|
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
|
||||||
@@ -133,6 +133,7 @@ const sourceChange = (e: any) => {
|
|||||||
tableStore.table.params.deviceTypeId = e[0] || ''
|
tableStore.table.params.deviceTypeId = e[0] || ''
|
||||||
tableStore.table.params.engineeringid = e[1] || ''
|
tableStore.table.params.engineeringid = e[1] || ''
|
||||||
tableStore.table.params.projectId = e[2] || ''
|
tableStore.table.params.projectId = e[2] || ''
|
||||||
|
tableStore.table.params.deviceId = e[3] || ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="refheader" v-if="!isWaveCharts">
|
<div ref="refheader" v-show="!isWaveCharts" style="width: 100%;">
|
||||||
<TableHeader datePicker showExport>
|
<TableHeader datePicker showExport>
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="数据来源">
|
<el-form-item label="数据来源">
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
v-model.trim="tableStore.table.params.cascader"
|
v-model.trim="tableStore.table.params.cascader"
|
||||||
:options="deviceTreeOptions"
|
:options="deviceTreeOptions"
|
||||||
:show-all-levels="false"
|
:show-all-levels="false"
|
||||||
:props="{ checkStrictly: true }"
|
:props="{ checkStrictly: true, value: 'id', label: 'name' }"
|
||||||
clearable
|
clearable
|
||||||
></el-cascader>
|
></el-cascader>
|
||||||
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
|
<!-- <el-input maxlength="32" show-word-limit v-model.trim="tableStore.table.params.searchValue" placeholder="请输入设备名称" /> -->
|
||||||
@@ -121,28 +121,30 @@ const tableStore = new TableStore({
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
publicHeight: 65,
|
publicHeight: 65,
|
||||||
exportName: '暂态事件',
|
exportName: '暂态事件',
|
||||||
column: [ {
|
column: [
|
||||||
|
{
|
||||||
title: '序号',
|
title: '序号',
|
||||||
width: 80,
|
width: 80,
|
||||||
formatter: (row: any) => {
|
formatter: (row: any) => {
|
||||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ title: '设备名称', field: 'equipmentName', align: 'center' },
|
{ title: '设备名称', field: 'equipmentName', minWidth: 120, align: 'center' },
|
||||||
{ title: '工程名称', field: 'engineeringName', align: 'center' },
|
{ title: '工程名称', field: 'engineeringName', minWidth: 120, align: 'center' },
|
||||||
{ title: '项目名称', field: 'projectName', align: 'center' },
|
{ title: '项目名称', field: 'projectName', minWidth: 120, align: 'center' },
|
||||||
{ title: '发生时刻', field: 'startTime', align: 'center', width: '240',sortable: true },
|
{ title: '发生时刻', field: 'startTime', align: 'center', minWidth: 180, sortable: true },
|
||||||
{ title: '监测点名称', field: 'lineName', align: 'center' },
|
{ title: '监测点名称', field: 'lineName', minWidth: 120, align: 'center' },
|
||||||
{ title: '事件描述', field: 'showName', align: 'center' },
|
{ title: '事件描述', field: 'showName', minWidth: 120, align: 'center' },
|
||||||
{ title: '事件发生位置', field: 'evtParamPosition', align: 'center' },
|
{ title: '事件发生位置', field: 'evtParamPosition', minWidth: 150, align: 'center' },
|
||||||
{ title: '相别', field: 'evtParamPhase', align: 'center' },
|
{ title: '相别', field: 'evtParamPhase', minWidth: 80, align: 'center' },
|
||||||
{ title: '持续时间(s)', field: 'evtParamTm', align: 'center',sortable: true },
|
{ title: '持续时间(s)', field: 'evtParamTm', minWidth: 80, align: 'center', sortable: true },
|
||||||
{ title: '暂降(聚升)幅值(%)', minWidth: 100, field: 'evtParamVVaDepth', align: 'center',sortable: true },
|
{ title: '暂降(聚升)幅值(%)', minWidth: 100, field: 'evtParamVVaDepth', align: 'center', sortable: true },
|
||||||
|
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作', fixed: 'right',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: '180',
|
width: '180',
|
||||||
|
|
||||||
render: 'buttons',
|
render: 'buttons',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
@@ -153,7 +155,7 @@ const tableStore = new TableStore({
|
|||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
loading: 'loading1',
|
loading: 'loading1',
|
||||||
disabled: row => {
|
disabled: row => {
|
||||||
return !row.wavePath
|
return !row.wavePath
|
||||||
},
|
},
|
||||||
click: async row => {
|
click: async row => {
|
||||||
row.loading1 = true
|
row.loading1 = true
|
||||||
@@ -164,9 +166,10 @@ const tableStore = new TableStore({
|
|||||||
row.loading1 = false
|
row.loading1 = false
|
||||||
if (res != undefined) {
|
if (res != undefined) {
|
||||||
boxoList.value = row
|
boxoList.value = row
|
||||||
|
boxoList.value.persistTime = row.evtParamTm
|
||||||
boxoList.value.featureAmplitude =
|
boxoList.value.featureAmplitude =
|
||||||
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
row.evtParamVVaDepth != '-' ? (row.evtParamVVaDepth - 0) / 100 : null
|
||||||
boxoList.value.systemType = 'WX'
|
boxoList.value.systemType = 'YPT'
|
||||||
wp.value = res.data
|
wp.value = res.data
|
||||||
}
|
}
|
||||||
loading.value = false
|
loading.value = false
|
||||||
@@ -234,24 +237,24 @@ const tableStore = new TableStore({
|
|||||||
icon: 'el-icon-DataLine',
|
icon: 'el-icon-DataLine',
|
||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
disabled: row => {
|
disabled: row => {
|
||||||
return row.showName != '未知';
|
return row.showName != '未知'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'edit',
|
name: 'edit',
|
||||||
title: '波形补召',
|
title: '波形补召',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
icon: 'el-icon-Check',
|
icon: 'el-icon-Check',
|
||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
disabled: row => {
|
disabled: row => {
|
||||||
return row.wavePath || row.showName === '未知';
|
return row.wavePath || row.showName === '未知'
|
||||||
},
|
},
|
||||||
click: row => {
|
click: row => {
|
||||||
getFileByEventId(row.id).then(res => {
|
getFileByEventId(row.id).then(res => {
|
||||||
ElMessage.success(res.message)
|
ElMessage.success(res.message)
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -312,8 +315,8 @@ const sourceChange = (e: any) => {
|
|||||||
tableStore.table.params.deviceTypeId = e[0] || ''
|
tableStore.table.params.deviceTypeId = e[0] || ''
|
||||||
tableStore.table.params.engineeringid = e[1] || ''
|
tableStore.table.params.engineeringid = e[1] || ''
|
||||||
tableStore.table.params.projectId = e[2] || ''
|
tableStore.table.params.projectId = e[2] || ''
|
||||||
|
tableStore.table.params.deviceId = e[3] || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// tableStore.table.params.engineeringid = e[1] || ''
|
// tableStore.table.params.engineeringid = e[1] || ''
|
||||||
|
|||||||
@@ -7,15 +7,15 @@
|
|||||||
<el-tab-pane label="前置告警" name="2">
|
<el-tab-pane label="前置告警" name="2">
|
||||||
<Front v-if="activeName == '2'" :deviceTree="deviceTree" :key="key" />
|
<Front v-if="activeName == '2'" :deviceTree="deviceTree" :key="key" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="稳态越限告警" name="3">
|
<!-- <el-tab-pane label="稳态越限告警" name="3">
|
||||||
<Steady v-if="activeName == '3'" :deviceTree="deviceTree" :key="key" />
|
<Steady v-if="activeName == '3'" :deviceTree="deviceTree" :key="key" />
|
||||||
</el-tab-pane>
|
</el-tab-pane> -->
|
||||||
<el-tab-pane label="暂态事件" name="4">
|
<el-tab-pane label="暂态事件" name="4">
|
||||||
<Transient v-if="activeName == '4'" :deviceTree="deviceTree" :key="key" />
|
<Transient v-if="activeName == '4'" :deviceTree="deviceTree" :key="key" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="异常事件" name="5">
|
<!-- <el-tab-pane label="异常事件" name="5">
|
||||||
<Abnormal v-if="activeName == '5'" :deviceTree="deviceTree" :key="key" />
|
<Abnormal v-if="activeName == '5'" :deviceTree="deviceTree" :key="key" />
|
||||||
</el-tab-pane>
|
</el-tab-pane> -->
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -31,24 +31,25 @@ defineOptions({
|
|||||||
name: 'govern/alarm/index'
|
name: 'govern/alarm/index'
|
||||||
})
|
})
|
||||||
const deviceTree = ref([])
|
const deviceTree = ref([])
|
||||||
const activeName = ref('1')
|
const activeName = ref('0')
|
||||||
const key = ref(0)
|
const key = ref(0)
|
||||||
getDeviceTree().then(res => {
|
getDeviceTree().then(res => {
|
||||||
res.data.forEach((item: any) => {
|
// res.data.forEach((item: any) => {
|
||||||
item.value = item.id
|
// item.value = item.id
|
||||||
item.label = item.name
|
// item.label = item.name
|
||||||
item.children.forEach((child: any) => {
|
// item.children.forEach((child: any) => {
|
||||||
child.value = child.id
|
// child.value = child.id
|
||||||
child.label = child.name
|
// child.label = child.name
|
||||||
child.children.forEach((grand: any) => {
|
// child.children.forEach((grand: any) => {
|
||||||
grand.value = grand.id
|
// grand.value = grand.id
|
||||||
grand.label = grand.name
|
// grand.label = grand.name
|
||||||
delete grand.children
|
// delete grand.children
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
deviceTree.value = res.data
|
deviceTree.value = res.data
|
||||||
key.value += 1
|
key.value += 1
|
||||||
|
activeName.value = '1'
|
||||||
})
|
})
|
||||||
onMounted(() => { })
|
onMounted(() => { })
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
v-model.trim="formInline.statisticalId"
|
v-model.trim="formInline.statisticalId"
|
||||||
filterable
|
filterable
|
||||||
@change="frequencyFlag"
|
@change="frequencyFlag"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in zblist"
|
v-for="item in zblist"
|
||||||
@@ -158,6 +158,7 @@ const nodeClick = async (e: anyObj) => {
|
|||||||
getDevCapacity(formInline.devId)
|
getDevCapacity(formInline.devId)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
devCapacity.value = res.data
|
devCapacity.value = res.data
|
||||||
|
|
||||||
search()
|
search()
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
|||||||
@@ -1,294 +1,315 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main">
|
<div class="default-main">
|
||||||
<div class="analyze-dvr" v-show="!isWaveCharts" :style="{ height: pageHeight.height }" v-loading="loading">
|
<div class="analyze-dvr" v-show="!isWaveCharts" :style="{ height: pageHeight.height }" v-loading="loading">
|
||||||
<DeviceTree @node-click="nodeClick" @init="nodeClick" @deviceTypeChange="deviceTypeChange"></DeviceTree>
|
<DeviceTree @node-click="nodeClick" @init="nodeClick" @deviceTypeChange="deviceTypeChange"></DeviceTree>
|
||||||
<div class="analyze-dvr-right" v-if="tableStore.table.params.deviceId">
|
<div class="analyze-dvr-right" v-if="tableStore.table.params.deviceId">
|
||||||
<TableHeader datePicker showExport>
|
<TableHeader datePicker showExport>
|
||||||
<template v-slot:select>
|
<template v-slot:select>
|
||||||
<el-form-item label="事件类型">
|
<el-form-item label="事件类型">
|
||||||
<el-select
|
<el-select
|
||||||
v-model.trim="tableStore.table.params.eventType"
|
v-model.trim="tableStore.table.params.eventType"
|
||||||
clearable
|
clearable
|
||||||
placeholder="请选择事件类型"
|
placeholder="请选择事件类型"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in eventList"
|
v-for="item in eventList"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="位置">
|
<el-form-item label="位置">
|
||||||
<el-select
|
<el-select
|
||||||
v-model.trim="tableStore.table.params.location"
|
v-model.trim="tableStore.table.params.location"
|
||||||
clearable
|
clearable
|
||||||
placeholder="请选择位置"
|
placeholder="请选择位置"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in locationList"
|
v-for="item in locationList"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</template>
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<Table v-if="view" ref="tableRef"></Table>
|
<Table v-if="view" ref="tableRef"></Table>
|
||||||
</div>
|
</div>
|
||||||
<el-empty v-else description="请选择设备" class="analyze-dvr-right" />
|
<el-empty v-else description="请选择设备" class="analyze-dvr-right" />
|
||||||
</div>
|
</div>
|
||||||
<waveFormAnalysis
|
<waveFormAnalysis
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
v-if="isWaveCharts"
|
v-if="isWaveCharts"
|
||||||
ref="waveFormAnalysisRef"
|
ref="waveFormAnalysisRef"
|
||||||
@handleHideCharts="isWaveCharts = false"
|
@handleHideCharts="isWaveCharts = false"
|
||||||
:wp="wp"
|
:wp="wp"
|
||||||
style="padding: 10px"
|
style="padding: 10px"
|
||||||
/>
|
/>
|
||||||
<!-- <div :style="{ height: pageHeight.height }" style="padding: 10px; overflow: hidden" v-if="!view">
|
<!-- <div :style="{ height: pageHeight.height }" style="padding: 10px; overflow: hidden" v-if="!view">
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<div v-if="view2" style="display: flex">
|
<div v-if="view2" style="display: flex">
|
||||||
<el-radio-group v-model.trim="value" @change="changeView">
|
<el-radio-group v-model.trim="value" @change="changeView">
|
||||||
<el-radio-button label="一次值" :value="1" />
|
<el-radio-button label="一次值" :value="1" />
|
||||||
<el-radio-button label="二次值" :value="2" />
|
<el-radio-button label="二次值" :value="2" />
|
||||||
|
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-button v-if="view2" @click="backbxlb" class="el-icon-refresh-right" icon="el-icon-Back"
|
<el-button v-if="view2" @click="backbxlb" class="el-icon-refresh-right" icon="el-icon-Back"
|
||||||
style="float: right">
|
style="float: right">
|
||||||
返回
|
返回
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-tabs v-if="view2" class="default-main" v-model.trim="bxactiveName" @tab-click="bxhandleClick">
|
<el-tabs v-if="view2" class="default-main" v-model.trim="bxactiveName" @tab-click="bxhandleClick">
|
||||||
<el-tab-pane label="瞬时波形" name="ssbx" class="boxbx pt10 pb10"
|
<el-tab-pane label="瞬时波形" name="ssbx" class="boxbx pt10 pb10"
|
||||||
:style="'height:' + bxecharts + ';overflow-y: scroll;'">
|
:style="'height:' + bxecharts + ';overflow-y: scroll;'">
|
||||||
<shushiboxi v-if="bxactiveName == 'ssbx' && showBoxi" :value="value" :boxoList="boxoList" :wp="wp">
|
<shushiboxi v-if="bxactiveName == 'ssbx' && showBoxi" :value="value" :boxoList="boxoList" :wp="wp">
|
||||||
</shushiboxi>
|
</shushiboxi>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="RMS波形" class="boxbx pt10 pb10" name="rmsbx"
|
<el-tab-pane label="RMS波形" class="boxbx pt10 pb10" name="rmsbx"
|
||||||
:style="'height:' + bxecharts + ';overflow-y: scroll;'">
|
:style="'height:' + bxecharts + ';overflow-y: scroll;'">
|
||||||
<rmsboxi v-if="bxactiveName == 'rmsbx' && showBoxi" :value="value" :boxoList="boxoList" :wp="wp">
|
<rmsboxi v-if="bxactiveName == 'rmsbx' && showBoxi" :value="value" :boxoList="boxoList" :wp="wp">
|
||||||
</rmsboxi>
|
</rmsboxi>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div> -->
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, nextTick, provide, onMounted } from 'vue'
|
import { ref, nextTick, provide, onMounted } from 'vue'
|
||||||
import { mainHeight } from '@/utils/layout'
|
import { mainHeight } from '@/utils/layout'
|
||||||
import DeviceTree from '@/components/tree/govern/deviceTree.vue'
|
import DeviceTree from '@/components/tree/govern/deviceTree.vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
|
import waveFormAnalysis from '@/views/govern/device/control/tabs/components/waveFormAnalysis.vue'
|
||||||
import { analyseWave } from '@/api/common'
|
import { analyseWave } from '@/api/common'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
|
|
||||||
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
import { getFileZip } from '@/api/cs-harmonic-boot/datatrend'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'govern/analyze/DVR/index'
|
name: 'govern/analyze/DVR/index'
|
||||||
})
|
})
|
||||||
const pageHeight = mainHeight(20)
|
const pageHeight = mainHeight(20)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const view = ref(true)
|
const view = ref(true)
|
||||||
const view2 = ref(false)
|
const view2 = ref(false)
|
||||||
const showBoxi = ref(true)
|
const showBoxi = ref(true)
|
||||||
const isWaveCharts = ref(false)
|
const isWaveCharts = ref(false)
|
||||||
const bxactiveName = ref('ssbx')
|
const bxactiveName = ref('ssbx')
|
||||||
const boxoList: any = ref({})
|
const boxoList: any = ref({})
|
||||||
const wp = ref({})
|
const wp = ref({})
|
||||||
const eventList = ref([
|
const eventList = ref([
|
||||||
{
|
{
|
||||||
value: 'Evt_Sys_DipStr',
|
value: 'Evt_Sys_DipStr',
|
||||||
label: '电压暂降'
|
label: '电压暂降'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'Evt_Sys_SwlStr',
|
value: 'Evt_Sys_SwlStr',
|
||||||
label: '电压暂升'
|
label: '电压暂升'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'Evt_Sys_IntrStr',
|
value: 'Evt_Sys_IntrStr',
|
||||||
label: '电压中断'
|
label: '电压中断'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const locationList = ref([
|
const locationList = ref([
|
||||||
{
|
{
|
||||||
value: 'grid',
|
value: 'grid',
|
||||||
label: '电网侧'
|
label: '电网侧'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 'load',
|
value: 'load',
|
||||||
label: '负载侧'
|
label: '负载侧'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const waveFormAnalysisRef = ref()
|
const waveFormAnalysisRef = ref()
|
||||||
|
|
||||||
const tableStore = new TableStore({
|
const tableStore = new TableStore({
|
||||||
url: '/cs-harmonic-boot/eventUser/queryEventpageWeb',
|
url: '/cs-harmonic-boot/eventUser/queryEventpageWeb',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
column: [
|
column: [
|
||||||
{ title: '事件描述', field: 'showName' },
|
{
|
||||||
{ title: '发生位置', field: 'evtParamPosition' },
|
field: 'index',
|
||||||
{ title: '持续时间(s)', field: 'evtParamTm', sortable: true },
|
title: '序号',
|
||||||
{
|
width: '80',
|
||||||
title: '暂降(聚升)幅值(%)',
|
formatter: (row: any) => {
|
||||||
field: 'evtParamVVaDepth',
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
formatter: (row: any) => {
|
}
|
||||||
let a = row.cellValue.split('%')[0] - 0
|
},
|
||||||
console.log('🚀 ~ a:', a)
|
{ title: '事件描述', field: 'showName', minWidth: 150 },
|
||||||
return a ? a.toFixed(2) : '/'
|
{ title: '发生位置', field: 'evtParamPosition', minWidth: 150 },
|
||||||
}, sortable: true
|
{
|
||||||
},
|
title: '持续时间(s)',
|
||||||
{ title: '发生时刻', field: 'startTime', sortable: true },
|
field: 'evtParamTm',
|
||||||
{
|
sortable: true,
|
||||||
title: '操作',
|
minWidth: 110,
|
||||||
align: 'center',
|
formatter: (row: any) => {
|
||||||
width: '180',
|
return Math.floor(row.cellValue * 10000) / 100
|
||||||
render: 'buttons',
|
}
|
||||||
buttons: [
|
},
|
||||||
{
|
{
|
||||||
name: 'edit',
|
title: '暂降(聚升)幅值(%)',
|
||||||
text: '波形分析',
|
field: 'evtParamVVaDepth',
|
||||||
type: 'primary',
|
minWidth: 150,
|
||||||
icon: 'el-icon-DataLine',
|
formatter: (row: any) => {
|
||||||
render: 'basicButton',
|
let a = row.cellValue.split('%')[0] - 0
|
||||||
disabled: row => {
|
return a ? a.toFixed(2) : '/'
|
||||||
return !row.wavePath && row.evtParamTm < 20
|
},
|
||||||
},
|
sortable: true
|
||||||
|
},
|
||||||
click: async row => {
|
{ title: '发生时刻', field: 'startTime', sortable: true, minWidth: 180 },
|
||||||
row.loading1 = true
|
{
|
||||||
loading.value = true
|
title: '操作',
|
||||||
isWaveCharts.value = true
|
fixed: 'right',
|
||||||
await analyseWave(row.id)
|
align: 'center',
|
||||||
.then(res => {
|
width: '180',
|
||||||
row.loading1 = false
|
render: 'buttons',
|
||||||
if (res != undefined) {
|
buttons: [
|
||||||
boxoList.value = row
|
{
|
||||||
boxoList.value.featureAmplitude =
|
name: 'edit',
|
||||||
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth - 0 : null
|
text: '波形分析',
|
||||||
// boxoList.value.systemType = 'WX'
|
type: 'primary',
|
||||||
wp.value = res.data
|
icon: 'el-icon-DataLine',
|
||||||
}
|
render: 'basicButton',
|
||||||
loading.value = false
|
disabled: row => {
|
||||||
})
|
return !row.wavePath && row.evtParamTm < 20
|
||||||
.catch(() => {
|
},
|
||||||
row.loading1 = false
|
|
||||||
loading.value = false
|
click: async row => {
|
||||||
})
|
row.loading1 = true
|
||||||
|
loading.value = true
|
||||||
nextTick(() => {
|
isWaveCharts.value = true
|
||||||
waveFormAnalysisRef.value &&
|
await analyseWave(row.id)
|
||||||
waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
|
.then(res => {
|
||||||
waveFormAnalysisRef.value && waveFormAnalysisRef.value.setHeight(false, 150)
|
row.loading1 = false
|
||||||
})
|
if (res != undefined) {
|
||||||
}
|
boxoList.value = row
|
||||||
},
|
boxoList.value.featureAmplitude =
|
||||||
{
|
row.evtParamVVaDepth != '-' ? row.evtParamVVaDepth.split('%')[0] / 100 : null
|
||||||
name: 'edit',
|
boxoList.value.persistTime =
|
||||||
text: '暂无波形',
|
row.evtParamTm != '-' ? Math.floor(row.evtParamTm * 10000) / 100 : null
|
||||||
type: 'info',
|
// boxoList.value.systemType = 'WX'
|
||||||
icon: 'el-icon-DataLine',
|
boxoList.value.systemType = 'YPT'
|
||||||
render: 'basicButton',
|
wp.value = res.data
|
||||||
disabled: row => {
|
}
|
||||||
return !(!row.wavePath && row.evtParamTm < 20)
|
loading.value = false
|
||||||
}
|
})
|
||||||
},
|
.catch(() => {
|
||||||
{
|
row.loading1 = false
|
||||||
name: 'edit',
|
loading.value = false
|
||||||
title: '波形下载',
|
})
|
||||||
type: 'primary',
|
|
||||||
icon: 'el-icon-Check',
|
nextTick(() => {
|
||||||
loading: 'loading2',
|
waveFormAnalysisRef.value &&
|
||||||
render: 'basicButton',
|
waveFormAnalysisRef.value.getWpData(wp.value, boxoList.value, true)
|
||||||
disabled: row => {
|
waveFormAnalysisRef.value && waveFormAnalysisRef.value.setHeight(false, 150)
|
||||||
// && row.evtParamTm < 20
|
})
|
||||||
return !row.wavePath
|
}
|
||||||
},
|
},
|
||||||
click: row => {
|
{
|
||||||
getFileZip({ eventId: row.id }).then(res => {
|
name: 'edit',
|
||||||
let blob = new Blob([res], { type: 'application/zip' }) // console.log(blob) // var href = window.URL.createObjectURL(blob); //创建下载的链接
|
text: '暂无波形',
|
||||||
const url = window.URL.createObjectURL(blob)
|
type: 'info',
|
||||||
const link = document.createElement('a') // 创建a标签
|
icon: 'el-icon-DataLine',
|
||||||
link.href = url
|
render: 'basicButton',
|
||||||
link.download = row.wavePath.split('/')[2] || '波形文件' // 设置下载的文件名
|
disabled: row => {
|
||||||
document.body.appendChild(link)
|
return !(!row.wavePath && row.evtParamTm < 20)
|
||||||
link.click() //执行下载
|
}
|
||||||
document.body.removeChild(link) //释放标签
|
},
|
||||||
})
|
{
|
||||||
}
|
name: 'edit',
|
||||||
}
|
title: '波形下载',
|
||||||
]
|
type: 'primary',
|
||||||
}
|
icon: 'el-icon-Check',
|
||||||
],
|
loading: 'loading2',
|
||||||
loadCallback: () => {
|
render: 'basicButton',
|
||||||
tableStore.table.data.forEach((item: any) => {
|
disabled: row => {
|
||||||
item.loading = false
|
// && row.evtParamTm < 20
|
||||||
item.evtParamTm = item.evtParamTm.split('s')[0]
|
return !row.wavePath
|
||||||
})
|
},
|
||||||
}
|
click: row => {
|
||||||
})
|
getFileZip({ eventId: row.id }).then(res => {
|
||||||
const flag = ref(false)
|
let blob = new Blob([res], { type: 'application/zip' }) // console.log(blob) // var href = window.URL.createObjectURL(blob); //创建下载的链接
|
||||||
tableStore.table.params.type = 0
|
const url = window.URL.createObjectURL(blob)
|
||||||
tableStore.table.params.eventType = ''
|
const link = document.createElement('a') // 创建a标签
|
||||||
tableStore.table.params.location = ''
|
link.href = url
|
||||||
provide('tableStore', tableStore)
|
link.download = row.wavePath.split('/')[2] || '波形文件' // 设置下载的文件名
|
||||||
const deviceTypeChange = (val: any, obj: any) => {
|
document.body.appendChild(link)
|
||||||
flag.value = true
|
link.click() //执行下载
|
||||||
nodeClick(obj)
|
document.body.removeChild(link) //释放标签
|
||||||
}
|
})
|
||||||
const nodeClick = async (e: anyObj) => {
|
}
|
||||||
// console.log("🚀 ~ nodeClick ~ e:", e)
|
}
|
||||||
if (e.level == 2&& flag.value) {
|
]
|
||||||
loading.value = false
|
}
|
||||||
tableStore.table.params.deviceId = e.id
|
],
|
||||||
nextTick(() => {
|
loadCallback: () => {
|
||||||
tableStore.index()
|
tableStore.table.data.forEach((item: any) => {
|
||||||
})
|
item.loading = false
|
||||||
}
|
item.evtParamTm = item.evtParamTm.split('s')[0]
|
||||||
}
|
})
|
||||||
|
}
|
||||||
const changeView = () => {
|
})
|
||||||
showBoxi.value = false
|
const flag = ref(false)
|
||||||
setTimeout(() => {
|
tableStore.table.params.type = 0
|
||||||
showBoxi.value = true
|
tableStore.table.params.eventType = ''
|
||||||
}, 0)
|
tableStore.table.params.location = ''
|
||||||
}
|
provide('tableStore', tableStore)
|
||||||
const bxhandleClick = (tab: any) => {
|
const deviceTypeChange = (val: any, obj: any) => {
|
||||||
if (tab.name == 'ssbx') {
|
flag.value = true
|
||||||
bxactiveName.value = 'ssbx'
|
nodeClick(obj)
|
||||||
} else if (tab.name == 'rmsbx') {
|
}
|
||||||
bxactiveName.value = 'rmsbx'
|
const nodeClick = async (e: anyObj) => {
|
||||||
}
|
// console.log("🚀 ~ nodeClick ~ e:", e)
|
||||||
// console.log(tab, event);
|
if (e.level == 2 && flag.value) {
|
||||||
}
|
loading.value = false
|
||||||
const backbxlb = () => {
|
tableStore.table.params.deviceId = e.id
|
||||||
view.value = true
|
nextTick(() => {
|
||||||
view2.value = false
|
tableStore.index()
|
||||||
}
|
})
|
||||||
const bxecharts = mainHeight(95).height as any
|
}
|
||||||
</script>
|
}
|
||||||
|
|
||||||
<style lang="scss">
|
const changeView = () => {
|
||||||
.analyze-dvr {
|
showBoxi.value = false
|
||||||
display: flex;
|
setTimeout(() => {
|
||||||
|
showBoxi.value = true
|
||||||
&-right {
|
}, 0)
|
||||||
height: 100%;
|
}
|
||||||
overflow: hidden;
|
const bxhandleClick = (tab: any) => {
|
||||||
flex: 1;
|
if (tab.name == 'ssbx') {
|
||||||
padding: 10px 10px 10px 0;
|
bxactiveName.value = 'ssbx'
|
||||||
display: flex;
|
} else if (tab.name == 'rmsbx') {
|
||||||
flex-direction: column;
|
bxactiveName.value = 'rmsbx'
|
||||||
}
|
}
|
||||||
}
|
// console.log(tab, event);
|
||||||
</style>
|
}
|
||||||
|
const backbxlb = () => {
|
||||||
|
view.value = true
|
||||||
|
view2.value = false
|
||||||
|
}
|
||||||
|
const bxecharts = mainHeight(95).height as any
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.analyze-dvr {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&-right {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px 10px 10px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,176 +1,176 @@
|
|||||||
<!-- 补召日志 -->
|
<!-- 补召日志 -->
|
||||||
<template>
|
<template>
|
||||||
<el-dialog modal-class="analysisList" v-model.trim="dialogVisible" title="补召日志" width="70%" draggable
|
<el-dialog modal-class="analysisList" v-model.trim="dialogVisible" title="补召日志" width="70%" draggable
|
||||||
@closed="close">
|
@closed="close">
|
||||||
<TableHeader date-picker :showReset="false">
|
<TableHeader date-picker :showReset="false">
|
||||||
<template #operation>
|
<template #operation>
|
||||||
<el-button type="primary" icon="el-icon-Connection" @click="handleImport">
|
<el-button type="primary" icon="el-icon-Connection" @click="handleImport">
|
||||||
离线补召
|
离线补召
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="primary" icon="el-icon-Monitor" @click="handleaddDevice">
|
<el-button type="primary" icon="el-icon-Monitor" @click="handleaddDevice">
|
||||||
在线补召
|
在线补召
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<Table ref="tableRef" />
|
<Table ref="tableRef" :height="`calc(45vh - 50px)`"/>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
<popup ref="detailRef"></popup>
|
<popup ref="detailRef"></popup>
|
||||||
<!-- 离线数据导入组件 -->
|
<!-- 离线数据导入组件 -->
|
||||||
<!-- <offLineDataImport ref="offLineDataImportRef"></offLineDataImport> -->
|
<!-- <offLineDataImport ref="offLineDataImportRef"></offLineDataImport> -->
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, provide, onBeforeUnmount } from 'vue'
|
import { ref, onMounted, provide, onBeforeUnmount } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import Table from '@/components/table/index.vue'
|
import Table from '@/components/table/index.vue'
|
||||||
import TableHeader from '@/components/table/header/index.vue'
|
import TableHeader from '@/components/table/header/index.vue'
|
||||||
import offLineDataImport from '../offLineDataImport/index.vue'
|
import offLineDataImport from '../offLineDataImport/index.vue'
|
||||||
import popup from './popup.vue'
|
import popup from './popup.vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'offLineDataImport'
|
name: 'offLineDataImport'
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['back'])
|
const emit = defineEmits(['back'])
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const height = ref(0)
|
const height = ref(0)
|
||||||
height.value = window.innerHeight < 1080 ? 230 : 450
|
height.value = window.innerHeight < 1080 ? 230 : 450
|
||||||
const detailRef: any = ref()
|
const detailRef: any = ref()
|
||||||
const lineId = ref('')
|
const lineId = ref('')
|
||||||
const deviceId = ref('')
|
const deviceId = ref('')
|
||||||
const deviceData = ref({})
|
const deviceData = ref({})
|
||||||
const { push, options, currentRoute } = useRouter()
|
const { push, options, currentRoute } = useRouter()
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '/cs-device-boot/portableOfflLog/queryMainLogPage',
|
url: '/cs-device-boot/portableOfflLog/queryMainLogPage',
|
||||||
publicHeight: 420,
|
publicHeight: 420,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
column: [
|
column: [
|
||||||
// { width: '60', type: 'checkbox', fixed: 'left' },
|
// { width: '60', type: 'checkbox', fixed: 'left' },
|
||||||
{
|
{
|
||||||
title: '序号', width: 80, formatter: (row: any) => {
|
title: '序号', width: 80, formatter: (row: any) => {
|
||||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'projectName',
|
field: 'projectName',
|
||||||
title: '工程名称',
|
title: '工程名称',
|
||||||
minWidth: 170,
|
minWidth: 170,
|
||||||
formatter: row => {
|
formatter: row => {
|
||||||
return row.cellValue ? row.cellValue : '/'
|
return row.cellValue ? row.cellValue : '/'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ field: 'successCount', title: '成功解析数', minWidth: 150 },
|
{ field: 'successCount', title: '成功解析数', minWidth: 150 },
|
||||||
{ field: 'startTime', title: '导入开始时间', minWidth: 170, sortable: true },
|
{ field: 'startTime', title: '导入开始时间', minWidth: 170, sortable: true },
|
||||||
{ field: 'endTime', title: '导入结束时间', minWidth: 170 , sortable: true},
|
{ field: 'endTime', title: '导入结束时间', minWidth: 170 , sortable: true},
|
||||||
{
|
{
|
||||||
title: '解析状态',
|
title: '解析状态',
|
||||||
field: 'status',
|
field: 'status',
|
||||||
width: 100,
|
width: 100,
|
||||||
render: 'tag',
|
render: 'tag',
|
||||||
custom: {
|
custom: {
|
||||||
0: 'warning',
|
0: 'warning',
|
||||||
1: 'success',
|
1: 'success',
|
||||||
2: 'danger',
|
2: 'danger',
|
||||||
3: 'primary'
|
3: 'primary'
|
||||||
},
|
},
|
||||||
replaceValue: {
|
replaceValue: {
|
||||||
0: '未解析',
|
0: '未解析',
|
||||||
1: '解析成功',
|
1: '解析成功',
|
||||||
2: '解析失败',
|
2: '解析失败',
|
||||||
3: '文件不存在'
|
3: '文件不存在'
|
||||||
}
|
}
|
||||||
// formatter: row => {
|
// formatter: row => {
|
||||||
// return row.cellValue == 1 ? '未注册' : row.cellValue == 2 ? '注册' : '接入'
|
// return row.cellValue == 1 ? '未注册' : row.cellValue == 2 ? '注册' : '接入'
|
||||||
// },
|
// },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作', fixed: 'right',
|
||||||
width: '100',
|
width: '100',
|
||||||
render: 'buttons',
|
render: 'buttons',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
name: 'edit',
|
name: 'edit',
|
||||||
title: '详情',
|
title: '详情',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
icon: 'el-icon-EditPen',
|
icon: 'el-icon-EditPen',
|
||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
click: row => {
|
click: row => {
|
||||||
// console.log(row.portableOfflLogList)
|
// console.log(row.portableOfflLogList)
|
||||||
detailRef.value.open(row.portableOfflLogList)
|
detailRef.value.open(row.portableOfflLogList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
beforeSearchFun: () => {
|
beforeSearchFun: () => {
|
||||||
// tableStore.table.params.devId = tableParams.value.devId
|
// tableStore.table.params.devId = tableParams.value.devId
|
||||||
// tableStore.table.params.lineId = tableParams.value.lineId
|
// tableStore.table.params.lineId = tableParams.value.lineId
|
||||||
// tableStore.table.params.list = tableParams.value.list
|
// tableStore.table.params.list = tableParams.value.list
|
||||||
// tableStore.table.params.type = 3
|
// tableStore.table.params.type = 3
|
||||||
},
|
},
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
// tableStore.table.data=[]
|
// tableStore.table.data=[]
|
||||||
tableStore.table.height = 400
|
tableStore.table.height = 400
|
||||||
// console.log(tableStore.table.publicHeight, 'tableStore.table.data')
|
// console.log(tableStore.table.publicHeight, 'tableStore.table.data')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
provide('tableStore', tableStore)
|
provide('tableStore', tableStore)
|
||||||
//返回
|
//返回
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
emit('back')
|
emit('back')
|
||||||
}
|
}
|
||||||
const open = (row: any) => {
|
const open = (row: any) => {
|
||||||
lineId.value = row.lineId
|
lineId.value = row.lineId
|
||||||
deviceData.value = row.deviceData
|
deviceData.value = row.deviceData
|
||||||
deviceId.value = row.deviceId
|
deviceId.value = row.deviceId
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
}, 10)
|
}, 10)
|
||||||
}
|
}
|
||||||
const close = () => {
|
const close = () => {
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
const updateViewportHeight = async () => {
|
const updateViewportHeight = async () => {
|
||||||
// height.value = window.innerHeight;
|
// height.value = window.innerHeight;
|
||||||
height.value = window.innerHeight < 1080 ? 230 : 450
|
height.value = window.innerHeight < 1080 ? 230 : 450
|
||||||
// tableStore.table.publicHeight = height.value
|
// tableStore.table.publicHeight = height.value
|
||||||
// await tableStore.index()
|
// await tableStore.index()
|
||||||
}
|
}
|
||||||
//设备补召
|
//设备补召
|
||||||
const handleaddDevice = () => {
|
const handleaddDevice = () => {
|
||||||
push({
|
push({
|
||||||
path: '/supplementaryRecruitment',
|
path: '/supplementaryRecruitment',
|
||||||
query: {
|
query: {
|
||||||
activeName: '0',
|
activeName: '0',
|
||||||
id: lineId.value,
|
id: lineId.value,
|
||||||
ndid: deviceData.value?.ndid,
|
ndid: deviceData.value?.ndid,
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const offLineDataImportRef = ref()
|
const offLineDataImportRef = ref()
|
||||||
const handleImport = () => {
|
const handleImport = () => {
|
||||||
//设备devId&监测点lineId带入组件
|
//设备devId&监测点lineId带入组件
|
||||||
// offLineDataImportRef.value && offLineDataImportRef.value.open(deviceId.value, lineId.value)
|
// offLineDataImportRef.value && offLineDataImportRef.value.open(deviceId.value, lineId.value)
|
||||||
push({
|
push({
|
||||||
path: '/supplementaryRecruitment',
|
path: '/supplementaryRecruitment',
|
||||||
query: {
|
query: {
|
||||||
activeName: '1',
|
activeName: '1',
|
||||||
lineId: lineId.value,
|
lineId: lineId.value,
|
||||||
deviceId: deviceId.value,
|
deviceId: deviceId.value,
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
updateViewportHeight() // 初始化视口高度
|
updateViewportHeight() // 初始化视口高度
|
||||||
window.addEventListener('resize', updateViewportHeight) // 监听窗口大小变化
|
window.addEventListener('resize', updateViewportHeight) // 监听窗口大小变化
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
window.removeEventListener('resize', updateViewportHeight) // 移除监听
|
window.removeEventListener('resize', updateViewportHeight) // 移除监听
|
||||||
})
|
})
|
||||||
defineExpose({ open })
|
defineExpose({ open })
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@@ -1,123 +1,123 @@
|
|||||||
<!-- 解析列表 -->
|
<!-- 解析列表 -->
|
||||||
<template>
|
<template>
|
||||||
<el-dialog v-model.trim="dialogVisible" title="详情" width="70%" draggable @closed="close">
|
<el-dialog v-model.trim="dialogVisible" title="详情" width="70%" draggable @closed="close">
|
||||||
<div :style="tableHeight">
|
<div :style="tableHeight">
|
||||||
<vxe-table border auto-resize height="auto" :data="tableData" v-bind="defaultAttribute">
|
<vxe-table border auto-resize height="auto" :data="tableData" v-bind="defaultAttribute">
|
||||||
<vxe-column field="name" align="center" title="文件名称"></vxe-column>
|
<vxe-column field="name" align="center" title="文件名称"></vxe-column>
|
||||||
<vxe-column field="createTime" align="center" title="导入时间"></vxe-column>
|
<vxe-column field="createTime" align="center" title="导入时间"></vxe-column>
|
||||||
<vxe-column field="allCount" align="center" title="数据总数(条)" width="120"></vxe-column>
|
<vxe-column field="allCount" align="center" title="数据总数(条)" width="120"></vxe-column>
|
||||||
<vxe-column field="realCount" align="center" title="已入库总数(条)" width="120"></vxe-column>
|
<vxe-column field="realCount" align="center" title="已入库总数(条)" width="120"></vxe-column>
|
||||||
<vxe-column field="state" align="center" title="解析状态" width="100">
|
<vxe-column field="state" align="center" title="解析状态" width="100">
|
||||||
<template v-slot:default="scoped">
|
<template v-slot:default="scoped">
|
||||||
<el-tag type="warning" v-if="scoped.row.state == 0">未解析</el-tag>
|
<el-tag type="warning" v-if="scoped.row.state == 0">未解析</el-tag>
|
||||||
<el-tag type="success" v-if="scoped.row.state == 1">解析成功</el-tag>
|
<el-tag type="success" v-if="scoped.row.state == 1">解析成功</el-tag>
|
||||||
<el-tag type="danger" v-if="scoped.row.state == 2">解析失败</el-tag>
|
<el-tag type="danger" v-if="scoped.row.state == 2">解析失败</el-tag>
|
||||||
<el-tag type="primary" v-if="scoped.row.state == 3">文件不存在</el-tag>
|
<el-tag type="primary" v-if="scoped.row.state == 3">文件不存在</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</vxe-column>
|
</vxe-column>
|
||||||
</vxe-table>
|
</vxe-table>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
||||||
import TableStore from '@/utils/tableStore'
|
import TableStore from '@/utils/tableStore'
|
||||||
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
import { defaultAttribute } from '@/components/table/defaultAttribute'
|
||||||
import { mainHeight } from '@/utils/layout'
|
import { mainHeight } from '@/utils/layout'
|
||||||
const emit = defineEmits(['back'])
|
const emit = defineEmits(['back'])
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const tableHeight = mainHeight(440)
|
const tableHeight = mainHeight(440)
|
||||||
const height = ref(0)
|
const height = ref(0)
|
||||||
height.value = window.innerHeight < 1080 ? 230 : 450
|
height.value = window.innerHeight < 1080 ? 230 : 450
|
||||||
|
|
||||||
const tableStore: any = new TableStore({
|
const tableStore: any = new TableStore({
|
||||||
url: '',
|
url: '',
|
||||||
// publicHeight: height.value,
|
// publicHeight: height.value,
|
||||||
showPage: false,
|
showPage: false,
|
||||||
column: [
|
column: [
|
||||||
{ width: '60', type: 'checkbox', fixed: 'left' },
|
{ width: '60', type: 'checkbox', fixed: 'left' },
|
||||||
{
|
{
|
||||||
title: '序号', width: 80, formatter: (row: any) => {
|
title: '序号', width: 80, formatter: (row: any) => {
|
||||||
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
return (tableStore.table.params.pageNum - 1) * tableStore.table.params.pageSize + row.rowIndex + 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ field: 'name', title: '文件名称', minWidth: 170 },
|
{ field: 'name', title: '文件名称', minWidth: 170 },
|
||||||
{ field: 'createTime', title: '导入时间', minWidth: 170 , sortable: true},
|
{ field: 'createTime', title: '导入时间', minWidth: 170 , sortable: true},
|
||||||
{ field: 'allCount', title: '数据总数(条)', minWidth: 170 , sortable: true},
|
{ field: 'allCount', title: '数据总数(条)', minWidth: 170 , sortable: true},
|
||||||
{ field: 'realCount', title: '已入库总数(条)', minWidth: 170, sortable: true },
|
{ field: 'realCount', title: '已入库总数(条)', minWidth: 170, sortable: true },
|
||||||
{
|
{
|
||||||
title: '解析状态',
|
title: '解析状态',
|
||||||
field: 'state',
|
field: 'state',
|
||||||
width: 100,
|
width: 100,
|
||||||
render: 'tag',
|
render: 'tag',
|
||||||
custom: {
|
custom: {
|
||||||
0: 'warning',
|
0: 'warning',
|
||||||
1: 'success',
|
1: 'success',
|
||||||
2: 'danger',
|
2: 'danger',
|
||||||
3: 'primary'
|
3: 'primary'
|
||||||
},
|
},
|
||||||
replaceValue: {
|
replaceValue: {
|
||||||
0: '未解析',
|
0: '未解析',
|
||||||
1: '解析成功',
|
1: '解析成功',
|
||||||
2: '解析失败',
|
2: '解析失败',
|
||||||
3: '文件不存在'
|
3: '文件不存在'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作', fixed: 'right',
|
||||||
width: '180',
|
width: '180',
|
||||||
render: 'buttons',
|
render: 'buttons',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
name: 'edit',
|
name: 'edit',
|
||||||
title: '详情',
|
title: '详情',
|
||||||
type: 'primary',
|
type: 'primary',
|
||||||
icon: 'el-icon-EditPen',
|
icon: 'el-icon-EditPen',
|
||||||
render: 'basicButton',
|
render: 'basicButton',
|
||||||
click: row => {
|
click: row => {
|
||||||
// console.log(row.portableOfflLogList)
|
// console.log(row.portableOfflLogList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
loadCallback: () => {
|
loadCallback: () => {
|
||||||
tableStore.table.data = []
|
tableStore.table.data = []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
//返回
|
//返回
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
emit('back')
|
emit('back')
|
||||||
}
|
}
|
||||||
const tableData: any = ref()
|
const tableData: any = ref()
|
||||||
const open = (val: any) => {
|
const open = (val: any) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
tableData.value = val
|
tableData.value = val
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
tableStore.index()
|
tableStore.index()
|
||||||
}, 10)
|
}, 10)
|
||||||
}
|
}
|
||||||
const close = () => {
|
const close = () => {
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
const updateViewportHeight = async () => {
|
const updateViewportHeight = async () => {
|
||||||
height.value = window.innerHeight < 1080 ? 230 : 450
|
height.value = window.innerHeight < 1080 ? 230 : 450
|
||||||
tableStore.table.publicHeight = height.value
|
tableStore.table.publicHeight = height.value
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
updateViewportHeight() // 初始化视口高度
|
updateViewportHeight() // 初始化视口高度
|
||||||
window.addEventListener('resize', updateViewportHeight) // 监听窗口大小变化
|
window.addEventListener('resize', updateViewportHeight) // 监听窗口大小变化
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
window.removeEventListener('resize', updateViewportHeight) // 移除监听
|
window.removeEventListener('resize', updateViewportHeight) // 移除监听
|
||||||
})
|
})
|
||||||
defineExpose({ open })
|
defineExpose({ open })
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
::v-deep .el-dialog__body {
|
::v-deep .el-dialog__body {
|
||||||
overflow-y: none !important;
|
overflow-y: none !important;
|
||||||
max-height: 70vh !important;
|
max-height: 70vh !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -50,10 +50,18 @@
|
|||||||
</el-descriptions-item> -->
|
</el-descriptions-item> -->
|
||||||
|
|
||||||
<el-descriptions-item label="PT变比" width="160">
|
<el-descriptions-item label="PT变比" width="160">
|
||||||
{{ devData.ptRatio || '/' }}
|
{{
|
||||||
|
devData.ptRatio == null
|
||||||
|
? '/'
|
||||||
|
: devData.ptRatio + (devData.pt2Ratio == null ? '' : ':' + devData.pt2Ratio)
|
||||||
|
}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="CT变比" width="160">
|
<el-descriptions-item label="CT变比" width="160">
|
||||||
{{ devData.ctRatio || '/' }}
|
{{
|
||||||
|
devData.ctRatio == null
|
||||||
|
? '/'
|
||||||
|
: devData.ctRatio + (devData.ct2Ratio == null ? '' : ':' + devData.ct2Ratio)
|
||||||
|
}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
<!-- <el-descriptions-item label="名称">
|
<!-- <el-descriptions-item label="名称">
|
||||||
@@ -77,17 +85,17 @@
|
|||||||
</el-descriptions-item> -->
|
</el-descriptions-item> -->
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
<el-tabs v-model.trim="dataSet" type="border-card" class="device-control-box-card" @tab-click="handleClick">
|
<el-tabs v-model.trim="dataSet" type="border-card" class="device-control-box-card" @tab-click="handleClick">
|
||||||
|
|
||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
lazy
|
lazy
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:name="item.id"
|
:name="item.id"
|
||||||
v-for="(item, index) in deviceData.dataSetList"
|
v-for="(item, index) in deviceData.dataSetList"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
:disabled="tableLoading"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<span class="custom-tabs-label">
|
<span class="custom-tabs-label">
|
||||||
<el-icon>
|
<!-- <el-icon>
|
||||||
<TrendCharts v-if="item.name == 'APF模块数据'" />
|
<TrendCharts v-if="item.name == 'APF模块数据'" />
|
||||||
<DataLine v-if="item.name == '历史APF模块数据'" />
|
<DataLine v-if="item.name == '历史APF模块数据'" />
|
||||||
<DataAnalysis v-if="item.name.includes('趋势数据')" />
|
<DataAnalysis v-if="item.name.includes('趋势数据')" />
|
||||||
@@ -113,7 +121,7 @@
|
|||||||
!item.name.includes('暂态事件')
|
!item.name.includes('暂态事件')
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</el-icon>
|
</el-icon> -->
|
||||||
<span>{{ item.name }}</span>
|
<span>{{ item.name }}</span>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -157,7 +165,7 @@
|
|||||||
</el-select> -->
|
</el-select> -->
|
||||||
<el-radio-group
|
<el-radio-group
|
||||||
v-model.trim="formInline.dataLevel"
|
v-model.trim="formInline.dataLevel"
|
||||||
v-if="!dataSet.includes('_moduleData')"
|
v-if="!dataSet.includes('_moduleData') && TrendList?.lineType == 1"
|
||||||
:disabled="TrendList?.lineType != 1"
|
:disabled="TrendList?.lineType != 1"
|
||||||
@change="handleClick"
|
@change="handleClick"
|
||||||
>
|
>
|
||||||
@@ -701,7 +709,7 @@ const handleTrend = async () => {
|
|||||||
// }
|
// }
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
ElMessage.success('装置应答失败')
|
ElMessage.warning('装置应答失败')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
@@ -733,14 +741,14 @@ const handleHarmonicSpectrum = async () => {
|
|||||||
// getRealDataMqttMsg()
|
// getRealDataMqttMsg()
|
||||||
await getBasicRealData(lineId.value).then((res: any) => {
|
await getBasicRealData(lineId.value).then((res: any) => {
|
||||||
if (res.code == 'A0000') {
|
if (res.code == 'A0000') {
|
||||||
ElMessage.success('装置应答成功')
|
ElMessage.success('装置应答成功')
|
||||||
// mqttMessage.value = {}
|
// mqttMessage.value = {}
|
||||||
|
|
||||||
realDataTimer.value = window.setInterval(() => {
|
realDataTimer.value = window.setInterval(() => {
|
||||||
if (!dataSet.value.includes('_realtimedata')) return
|
if (!dataSet.value.includes('_realtimedata')) return
|
||||||
|
|
||||||
getBasicRealData(lineId.value).then((res: any) => {
|
getBasicRealData(lineId.value).then((res: any) => {
|
||||||
console.log(res, '获取基础实时数据')
|
console.log(res, '获取基础实时数据')
|
||||||
})
|
})
|
||||||
}, 30000)
|
}, 30000)
|
||||||
}
|
}
|
||||||
@@ -749,11 +757,13 @@ const handleHarmonicSpectrum = async () => {
|
|||||||
//返回
|
//返回
|
||||||
const handleReturn = async () => {
|
const handleReturn = async () => {
|
||||||
if (realDataTimer.value) {
|
if (realDataTimer.value) {
|
||||||
clearInterval(realDataTimer.value)
|
window.clearInterval(realDataTimer.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trendTimer.value) {
|
if (trendTimer.value) {
|
||||||
clearInterval(trendTimer.value)
|
window.clearInterval(trendTimer.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
realTimeFlag.value = true
|
realTimeFlag.value = true
|
||||||
sonTab.value = null
|
sonTab.value = null
|
||||||
activeTrendName.value = 0
|
activeTrendName.value = 0
|
||||||
@@ -838,7 +848,8 @@ const devData: any = ref({})
|
|||||||
const lineId: any = ref('')
|
const lineId: any = ref('')
|
||||||
const dataLevel: any = ref('')
|
const dataLevel: any = ref('')
|
||||||
const dataSource = ref([])
|
const dataSource = ref([])
|
||||||
const nodeClick = async (e: anyObj) => {
|
const engineeringName = ref('')
|
||||||
|
const nodeClick = async (e: anyObj, node: any) => {
|
||||||
if (e == undefined || e.level == 2) {
|
if (e == undefined || e.level == 2) {
|
||||||
return (loading.value = false)
|
return (loading.value = false)
|
||||||
}
|
}
|
||||||
@@ -854,6 +865,8 @@ const nodeClick = async (e: anyObj) => {
|
|||||||
|
|
||||||
//选中设备名称后,点击标签页也能查询数据,要求点击设备名称后,点击标签页默认查询第一个监测点数据
|
//选中设备名称后,点击标签页也能查询数据,要求点击设备名称后,点击标签页默认查询第一个监测点数据
|
||||||
if (e.level == 3 || e.level == 2) {
|
if (e.level == 3 || e.level == 2) {
|
||||||
|
engineeringName.value = node?.parent.parent.data.name
|
||||||
|
|
||||||
await queryDictType({
|
await queryDictType({
|
||||||
lineId: e?.id,
|
lineId: e?.id,
|
||||||
conType: e.conType
|
conType: e.conType
|
||||||
@@ -984,44 +997,42 @@ const getRealDataMqttMsg = async () => {
|
|||||||
// JSON.parse(JSON.stringify(JSON.parse(new TextDecoder().decode(message))))
|
// JSON.parse(JSON.stringify(JSON.parse(new TextDecoder().decode(message))))
|
||||||
// )
|
// )
|
||||||
let obj = JSON.parse(JSON.stringify(JSON.parse(new TextDecoder().decode(message))))
|
let obj = JSON.parse(JSON.stringify(JSON.parse(new TextDecoder().decode(message))))
|
||||||
|
|
||||||
if (lineId.value != obj.lineId || adminInfo.userIndex != obj.userId) return
|
if (lineId.value != obj.lineId || adminInfo.userIndex != obj.userId) return
|
||||||
|
|
||||||
//处理mqtt数据 1转2除 2转1乘
|
//处理mqtt数据 1转2除 2转1乘
|
||||||
//如果消息返回值是二次值,下拉框是二次值只需要单位换算 除以1000
|
//如果消息返回值是二次值,下拉框是二次值只需要单位换算 除以1000
|
||||||
//如果消息返回值是一次值,下拉框是一次值只需要单位换算 除以1000
|
//如果消息返回值是一次值,下拉框是一次值只需要单位换算 除以1000
|
||||||
if (obj.dataLevel == formInline.dataLevel) {
|
if (obj.dataLevel == formInline.dataLevel) {
|
||||||
|
|
||||||
obj = {
|
obj = {
|
||||||
...obj,
|
...obj,
|
||||||
// 电压有效值
|
// 电压有效值
|
||||||
vRmsA: obj.vRmsA ,
|
vRmsA: obj.vRmsA,
|
||||||
vRmsB: obj.vRmsB ,
|
vRmsB: obj.vRmsB,
|
||||||
vRmsC: obj.vRmsC ,
|
vRmsC: obj.vRmsC,
|
||||||
//基波电压幅值
|
//基波电压幅值
|
||||||
v1A: obj.v1A ,
|
v1A: obj.v1A,
|
||||||
v1B: obj.v1B ,
|
v1B: obj.v1B,
|
||||||
v1C: obj.v1C ,
|
v1C: obj.v1C,
|
||||||
//有功功率
|
//有功功率
|
||||||
pA: obj.pA ,
|
pA: obj.pA,
|
||||||
pB: obj.pB ,
|
pB: obj.pB,
|
||||||
pC: obj.pC ,
|
pC: obj.pC,
|
||||||
pTot: obj.pTot ,
|
pTot: obj.pTot,
|
||||||
//无功功率
|
//无功功率
|
||||||
qA: obj.qA ,
|
qA: obj.qA,
|
||||||
qB: obj.qB ,
|
qB: obj.qB,
|
||||||
qC: obj.qC ,
|
qC: obj.qC,
|
||||||
qTot: obj.qTot ,
|
qTot: obj.qTot,
|
||||||
//视在功率
|
//视在功率
|
||||||
sA: obj.sA ,
|
sA: obj.sA,
|
||||||
sB: obj.sB ,
|
sB: obj.sB,
|
||||||
sC: obj.sC ,
|
sC: obj.sC,
|
||||||
sTot: obj.sTot
|
sTot: obj.sTot
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//如果消息返回值是二次值,下拉框是一次值需要单位换算 除以1000 并且乘以pt ct
|
//如果消息返回值是二次值,下拉框是一次值需要单位换算 除以1000 并且乘以pt ct
|
||||||
if (obj.dataLevel == 'Secondary' && formInline.dataLevel == 'Primary') {
|
if (obj.dataLevel == 'Secondary' && formInline.dataLevel == 'Primary') {
|
||||||
|
|
||||||
obj = {
|
obj = {
|
||||||
...obj,
|
...obj,
|
||||||
// 电压有效值
|
// 电压有效值
|
||||||
@@ -1102,9 +1113,11 @@ const getRealDataMqttMsg = async () => {
|
|||||||
}
|
}
|
||||||
if (obj.hasOwnProperty('pA') && obj.hasOwnProperty('pB')) {
|
if (obj.hasOwnProperty('pA') && obj.hasOwnProperty('pB')) {
|
||||||
mqttMessage.value = obj
|
mqttMessage.value = obj
|
||||||
|
|
||||||
//更新实时数据主页面值
|
//更新实时数据主页面值
|
||||||
realTimeFlag.value && realTimeRef.value && realTimeRef.value.setRealData(mqttMessage.value,formInline.dataLevel)
|
realTimeFlag.value &&
|
||||||
|
realTimeRef.value &&
|
||||||
|
realTimeRef.value.setRealData(mqttMessage.value, formInline.dataLevel)
|
||||||
tableLoading.value = false
|
tableLoading.value = false
|
||||||
//更新实时趋势折线图数据
|
//更新实时趋势折线图数据
|
||||||
if (sonTab.value == 2) {
|
if (sonTab.value == 2) {
|
||||||
@@ -1150,10 +1163,10 @@ const mqttMessage = ref<any>({})
|
|||||||
const handleClick = async (tab?: any) => {
|
const handleClick = async (tab?: any) => {
|
||||||
tableLoading.value = true
|
tableLoading.value = true
|
||||||
if (realDataTimer.value) {
|
if (realDataTimer.value) {
|
||||||
clearInterval(realDataTimer.value)
|
window.clearInterval(realDataTimer.value)
|
||||||
}
|
}
|
||||||
if (trendTimer.value) {
|
if (trendTimer.value) {
|
||||||
clearInterval(trendTimer.value)
|
window.clearInterval(trendTimer.value)
|
||||||
}
|
}
|
||||||
sonTab.value = null
|
sonTab.value = null
|
||||||
activeTrendName.value = 0
|
activeTrendName.value = 0
|
||||||
@@ -1228,6 +1241,7 @@ const handleClick = async (tab?: any) => {
|
|||||||
let obj = {
|
let obj = {
|
||||||
devId: deviceId.value, //e.id
|
devId: deviceId.value, //e.id
|
||||||
lineId: lineId.value, //e.pid
|
lineId: lineId.value, //e.pid
|
||||||
|
engineeringName: engineeringName.value, //e.name
|
||||||
type: 3,
|
type: 3,
|
||||||
list: [
|
list: [
|
||||||
{
|
{
|
||||||
@@ -1422,9 +1436,7 @@ const echoName = (value: any, arr: any[]) => {
|
|||||||
return value ? arr.find(item => item.value == value)?.label : '/'
|
return value ? arr.find(item => item.value == value)?.label : '/'
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {})
|
||||||
|
|
||||||
})
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
clearInterval(realDataTimer.value)
|
clearInterval(realDataTimer.value)
|
||||||
clearInterval(trendTimer.value)
|
clearInterval(trendTimer.value)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -16,14 +16,19 @@
|
|||||||
<el-button type="primary" :icon="Setting" @click="handleUpDevice">补召</el-button>
|
<el-button type="primary" :icon="Setting" @click="handleUpDevice">补召</el-button>
|
||||||
<el-button :icon="Back" @click="go(-1)">返回</el-button>
|
<el-button :icon="Back" @click="go(-1)">返回</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<!-- 设备补召 -->
|
<!-- 设备补召 -->
|
||||||
<div class=" current_device" v-loading="loading">
|
<div class="current_device" v-loading="loading">
|
||||||
|
|
||||||
<div class="current_body" ref="tbodyRef">
|
<div class="current_body" ref="tbodyRef">
|
||||||
<vxe-table border ref="tableRef" :data="dirList" align="center" height="auto"
|
<vxe-table
|
||||||
:style="{ height: tableHeight }" @radio-change="radioChangeEvent">
|
border
|
||||||
|
ref="tableRef"
|
||||||
|
:data="dirList"
|
||||||
|
align="center"
|
||||||
|
height="auto"
|
||||||
|
:style="{ height: tableHeight }"
|
||||||
|
@radio-change="radioChangeEvent"
|
||||||
|
>
|
||||||
<vxe-column type="radio" width="60">
|
<vxe-column type="radio" width="60">
|
||||||
<template #header>
|
<template #header>
|
||||||
<vxe-button mode="text" @click="clearRadioRowEvent" :disabled="!selectRow">取消</vxe-button>
|
<vxe-button mode="text" @click="clearRadioRowEvent" :disabled="!selectRow">取消</vxe-button>
|
||||||
@@ -34,13 +39,20 @@
|
|||||||
<vxe-column field="status" title="补召进度">
|
<vxe-column field="status" title="补召进度">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="finish" v-if="row.status == 100">
|
<div class="finish" v-if="row.status == 100">
|
||||||
<SuccessFilled style="width: 16px;" /><span class="ml5">补召完成</span>
|
<SuccessFilled style="width: 16px" />
|
||||||
|
<span class="ml5">补召完成</span>
|
||||||
</div>
|
</div>
|
||||||
<el-progress v-model.trim="row.status" v-else :class="row.status == 100 ? 'progress' : ''"
|
<el-progress
|
||||||
:format="format" :stroke-width="10" striped :percentage="row.status" :duration="30"
|
v-model.trim="row.status"
|
||||||
striped-flow />
|
v-else
|
||||||
|
:class="row.status == 100 ? 'progress' : ''"
|
||||||
|
:format="format"
|
||||||
|
:stroke-width="10"
|
||||||
|
striped
|
||||||
|
:percentage="row.status"
|
||||||
|
:duration="30"
|
||||||
|
striped-flow
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</vxe-column>
|
</vxe-column>
|
||||||
<vxe-column field="startTime" title="起始时间"></vxe-column>
|
<vxe-column field="startTime" title="起始时间"></vxe-column>
|
||||||
@@ -58,10 +70,7 @@ import { useRouter, useRoute } from 'vue-router'
|
|||||||
import { mainHeight } from '@/utils/layout'
|
import { mainHeight } from '@/utils/layout'
|
||||||
import { VxeUI, VxeTableInstance, VxeTableEvents } from 'vxe-table'
|
import { VxeUI, VxeTableInstance, VxeTableEvents } from 'vxe-table'
|
||||||
import { SuccessFilled } from '@element-plus/icons-vue'
|
import { SuccessFilled } from '@element-plus/icons-vue'
|
||||||
import {
|
import { Back, Setting, Search } from '@element-plus/icons-vue'
|
||||||
Back,
|
|
||||||
Setting, Search
|
|
||||||
} from '@element-plus/icons-vue'
|
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import mqtt from 'mqtt'
|
import mqtt from 'mqtt'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
@@ -75,7 +84,7 @@ const loading = ref(false)
|
|||||||
const dirList = ref([])
|
const dirList = ref([])
|
||||||
const route: any = ref({})
|
const route: any = ref({})
|
||||||
const datePickerRef = ref()
|
const datePickerRef = ref()
|
||||||
const format = (percentage) => (percentage === 100 ? '完成' : `${percentage}%`)
|
const format = percentage => (percentage === 100 ? '完成' : `${percentage}%`)
|
||||||
const getMakeUpDataList = (row: any) => {
|
const getMakeUpDataList = (row: any) => {
|
||||||
route.value = row
|
route.value = row
|
||||||
loading.value = true
|
loading.value = true
|
||||||
@@ -139,11 +148,11 @@ const handleUpDevice = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const radioChangeEvent: VxeTableEvents.RadioChange = ({ row }) => {
|
const radioChangeEvent: VxeTableEvents.RadioChange = ({ row }) => {
|
||||||
|
datePickerRef.value.timeValue = [row.startTime.split(' ')[0] , row.endTime.split(' ')[0] ]
|
||||||
selectRow.value = row
|
selectRow.value = row
|
||||||
// console.log('单选事件')
|
// console.log('单选事件')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const clearRadioRowEvent = () => {
|
const clearRadioRowEvent = () => {
|
||||||
const $table = tableRef.value
|
const $table = tableRef.value
|
||||||
if ($table) {
|
if ($table) {
|
||||||
@@ -152,7 +161,7 @@ const clearRadioRowEvent = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const mqttRef = ref()
|
const mqttRef = ref()
|
||||||
const url: any = window.localStorage.getItem('MQTTURL')
|
const url: any = window.localStorage.getItem('MQTTURL')
|
||||||
const connectMqtt = () => {
|
const connectMqtt = () => {
|
||||||
if (mqttRef.value) {
|
if (mqttRef.value) {
|
||||||
if (mqttRef.value.connected) {
|
if (mqttRef.value.connected) {
|
||||||
@@ -173,10 +182,10 @@ const connectMqtt = () => {
|
|||||||
const handleSearch = () => {
|
const handleSearch = () => {
|
||||||
getMakeUpDataList(route.value)
|
getMakeUpDataList(route.value)
|
||||||
}
|
}
|
||||||
function parseStringToObject(str:string) {
|
function parseStringToObject(str: string) {
|
||||||
const content = str.replace(/^{|}$/g, '')
|
const content = str.replace(/^{|}$/g, '')
|
||||||
const pairs = content.split(',')
|
const pairs = content.split(',')
|
||||||
const result:any = {}
|
const result: any = {}
|
||||||
pairs.forEach(pair => {
|
pairs.forEach(pair => {
|
||||||
const [key, value] = pair.split(':')
|
const [key, value] = pair.split(':')
|
||||||
// 尝试将数字转换为Number类型
|
// 尝试将数字转换为Number类型
|
||||||
@@ -210,7 +219,6 @@ mqttRef.value.on('message', (topic: any, message: any) => {
|
|||||||
let percentage = parseInt(Number((mqttMessage.value.nowStep / mqttMessage.value.allStep) * 100)) || 0
|
let percentage = parseInt(Number((mqttMessage.value.nowStep / mqttMessage.value.allStep) * 100)) || 0
|
||||||
if (percentage > 5) {
|
if (percentage > 5) {
|
||||||
item.status = percentage
|
item.status = percentage
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// })
|
// })
|
||||||
@@ -226,6 +234,8 @@ mqttRef.value.on('close', function () {
|
|||||||
console.log('mqtt客户端已断开连接.....')
|
console.log('mqtt客户端已断开连接.....')
|
||||||
})
|
})
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
datePickerRef.value.setInterval(5)
|
||||||
|
datePickerRef.value.setTimeOptions([{ label: '自定义', value: 5 }])
|
||||||
})
|
})
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
if (mqttRef.value) {
|
if (mqttRef.value) {
|
||||||
@@ -261,14 +271,21 @@ defineExpose({ getMakeUpDataList })
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
:deep(.el-progress-bar__inner--striped) {
|
:deep(.el-progress-bar__inner--striped) {
|
||||||
background-image: linear-gradient(45deg, rgba(255, 255, 255, .3) 25%, transparent 0, transparent 50%, rgba(255, 255, 255, .3) 0, rgba(255, 255, 255, .3) 75%, transparent 0, transparent);
|
background-image: linear-gradient(
|
||||||
|
45deg,
|
||||||
|
rgba(255, 255, 255, 0.3) 25%,
|
||||||
|
transparent 0,
|
||||||
|
transparent 50%,
|
||||||
|
rgba(255, 255, 255, 0.3) 0,
|
||||||
|
rgba(255, 255, 255, 0.3) 75%,
|
||||||
|
transparent 0,
|
||||||
|
transparent
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.progress) {
|
:deep(.progress) {
|
||||||
.el-progress__text {
|
.el-progress__text {
|
||||||
color: green;
|
color: green;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,6 +293,6 @@ defineExpose({ getMakeUpDataList })
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-weight: 550;
|
font-weight: 550;
|
||||||
color: #009688
|
color: #009688;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
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