diff --git a/src/components/PreviewFile/index.vue b/src/components/PreviewFile/index.vue index 886ac96d..00636d13 100644 --- a/src/components/PreviewFile/index.vue +++ b/src/components/PreviewFile/index.vue @@ -30,7 +30,7 @@ import { downloadFile } from '@/api/system-boot/file' import { previewFile } from '@/utils/fileDownLoad' const { push, options, currentRoute } = useRouter() -const VITE_FLAG = import.meta.env.VITE_NAME == 'jibei' +const VITE_FLAG = false//import.meta.env.VITE_NAME == 'jibei' // const url = 'http://192.168.1.22:9009/excelreport' + currentRoute.value.href?.split('?')[1] const url = ref('') const excelOptions = ref({}) diff --git a/src/components/echarts/rmsWorker.js b/src/components/echarts/rmsWorker.js new file mode 100644 index 00000000..562b4db5 --- /dev/null +++ b/src/components/echarts/rmsWorker.js @@ -0,0 +1,322 @@ +// 辅助函数 +const getMax = (temp, tempA, tempB, tempC) => { + temp = temp > tempA ? temp : tempA + temp = temp > tempB ? temp : tempB + if (tempC !== undefined) { + temp = temp > tempC ? temp : tempC + } + return temp +} + +const getMaxTwo = (temp, tempA, tempB) => { + temp = temp > tempA ? temp : tempA + temp = temp > tempB ? temp : tempB + return temp +} + +const getMin = (temp, tempA, tempB, tempC) => { + temp = temp < tempA ? temp : tempA + temp = temp < tempB ? temp : tempB + if (tempC !== undefined) { + temp = temp < tempC ? temp : tempC + } + return temp +} + +const getMinOpen = (temp, tempA, tempB) => { + temp = temp < tempA ? temp : tempA + temp = temp < tempB ? temp : tempB + return temp +} + +// 数据处理函数 +const fliteWaveData = (wp, step, iphasicValue, isOpen) => { + const rmsData = wp.listRmsData + const pt = Number(wp.pt) / 1000 + const ct = Number(wp.ct) + const titleList = wp.waveTitle + let xishu = pt + let aTitle = '', + bTitle = '', + cTitle = '', + unit = '电压' + let rmsvFirstX = 0, + rmsvFirstY = 0, + rmsvSecondX = 0, + rmsvSecondY = 0, + firstZhou = 'a', + secondeZhou = 'a' + let ifmax = 0, + ifmin = 0, + ismax = 0, + ismin = 0, + rfmax = 0, + rfmin = 0, + rsmax = 0, + rsmin = 0 + + const shunshiFA = [] + const shunshiFB = [] + const shunshiFC = [] + const shunshiSA = [] + const shunshiSB = [] + const shunshiSC = [] + const rmsFA = [] + const rmsFB = [] + const rmsFC = [] + const rmsSA = [] + const rmsSB = [] + const rmsSC = [] + + if (titleList[iphasicValue * step + 1]?.substring(0, 1) !== 'U') { + xishu = ct + unit = '电流' + } + + for (let i = 1; i <= iphasicValue; i++) { + switch (i) { + case 1: + aTitle = titleList[iphasicValue * step + i]?.substring(1) || '' + break + case 2: + bTitle = titleList[iphasicValue * step + i]?.substring(1) || '' + break + case 3: + cTitle = titleList[iphasicValue * step + i]?.substring(1) || '' + break + } + } + + if (rmsData[0] && rmsData[0][iphasicValue * step + 1] !== undefined) { + rfmax = rmsData[0][iphasicValue * step + 1] * xishu + rfmin = rmsData[0][iphasicValue * step + 1] * xishu + rmsvFirstY = rmsData[0][iphasicValue * step + 1] * xishu + rmsvFirstX = rmsData[0][0] + rsmax = rmsData[0][iphasicValue * step + 1] + rsmin = rmsData[0][iphasicValue * step + 1] + rmsvSecondY = rmsData[0][iphasicValue * step + 1] + rmsvSecondX = rmsData[0][0] + } + + for (let rms = 0; rms < rmsData.length; rms++) { + if (!rmsData[rms] || rmsData[rms][iphasicValue * step + 1] === undefined) { + break + } + + switch (iphasicValue) { + case 1: + const rmsFirstA = rmsData[rms][iphasicValue * step + 1] * xishu + rmsFA.push([rmsData[rms][0], rmsFirstA]) + rfmax = rfmax > rmsFirstA ? rfmax : rmsFirstA + rfmin = rfmin < rmsFirstA ? rfmin : rmsFirstA + if (rfmin < rmsvFirstY) { + rmsvFirstY = rfmin + firstZhou = 'a' + rmsvFirstX = rmsData[rms][0] + } + + const rmsSecondA = rmsData[rms][iphasicValue * step + 1] + rmsSA.push([rmsData[rms][0], rmsSecondA]) + rsmax = rsmax > rmsSecondA ? rsmax : rmsSecondA + rsmin = rsmin < rmsSecondA ? rsmin : rmsSecondA + if (rsmin < rmsvSecondY) { + rmsvSecondY = rsmin + secondeZhou = 'a' + rmsvSecondX = rmsData[rms][0] + } + break + case 2: + const rmsFirstA2 = rmsData[rms][iphasicValue * step + 1] * xishu + const rmsFirstB2 = rmsData[rms][iphasicValue * step + 2] * xishu + rmsFA.push([rmsData[rms][0], rmsFirstA2]) + rmsFB.push([rmsData[rms][0], rmsFirstB2]) + rfmax = getMaxTwo(rfmax, rmsFirstA2, rmsFirstB2) + rfmin = getMinOpen(rfmin, rmsFirstA2, rmsFirstB2) + if (rfmin < rmsvFirstY) { + rmsvFirstY = rfmin + if (rfmin === rmsFirstA2) { + firstZhou = 'a' + } else if (rfmin === rmsFirstB2) { + firstZhou = 'b' + } + rmsvFirstX = rmsData[rms][0] + } + + const rmsSecondA2 = rmsData[rms][iphasicValue * step + 1] + const rmsSecondB2 = rmsData[rms][iphasicValue * step + 2] + rmsSA.push([rmsData[rms][0], rmsSecondA2]) + rmsSB.push([rmsData[rms][0], rmsSecondB2]) + rsmax = getMaxTwo(rsmax, rmsSecondA2, rmsSecondB2) + rsmin = getMinOpen(rsmin, rmsSecondA2, rmsSecondB2) + if (rsmin < rmsvSecondY) { + rmsvSecondY = rsmin + if (rsmin === rmsSecondA2) { + secondeZhou = 'a' + } else if (rsmin === rmsSecondB2) { + secondeZhou = 'b' + } + rmsvSecondX = rmsData[rms][0] + } + break + case 3: + const rmsFirstA3 = rmsData[rms][iphasicValue * step + 1] * xishu + const rmsFirstB3 = rmsData[rms][iphasicValue * step + 2] * xishu + const rmsFirstC3 = rmsData[rms][iphasicValue * step + 3] * xishu + rmsFA.push([rmsData[rms][0], rmsFirstA3]) + rmsFB.push([rmsData[rms][0], rmsFirstB3]) + rmsFC.push([rmsData[rms][0], rmsFirstC3]) + rfmax = getMax(rfmax, rmsFirstA3, rmsFirstB3, rmsFirstC3) + rfmin = isOpen + ? getMinOpen(rfmin, rmsFirstA3, rmsFirstC3) + : getMin(rfmin, rmsFirstA3, rmsFirstB3, rmsFirstC3) + if (rfmin < rmsvFirstY) { + rmsvFirstY = rfmin + if (rfmin === rmsFirstA3) { + firstZhou = 'a' + } else if (rfmin === rmsFirstB3) { + firstZhou = 'b' + } else { + firstZhou = 'c' + } + rmsvFirstX = rmsData[rms][0] + } + + const rmsSecondA3 = rmsData[rms][iphasicValue * step + 1] + const rmsSecondB3 = rmsData[rms][iphasicValue * step + 2] + const rmsSecondC3 = rmsData[rms][iphasicValue * step + 3] + rmsSA.push([rmsData[rms][0], rmsSecondA3]) + rmsSB.push([rmsData[rms][0], rmsSecondB3]) + rmsSC.push([rmsData[rms][0], rmsSecondC3]) + rsmax = getMax(rsmax, rmsSecondA3, rmsSecondB3, rmsSecondC3) + rsmin = isOpen + ? getMinOpen(rsmin, rmsSecondA3, rmsSecondC3) + : getMin(rsmin, rmsSecondA3, rmsSecondB3, rmsSecondC3) + if (rsmin < rmsvSecondY) { + rmsvSecondY = rsmin + if (rsmin === rmsSecondA3) { + secondeZhou = 'a' + } else if (rsmin === rmsSecondB3) { + secondeZhou = 'b' + } else { + secondeZhou = 'c' + } + rmsvSecondX = rmsData[rms][0] + } + break + } + } + + const instantF = { max: ifmax, min: ifmin } + const instantS = { max: ismax, min: ismin } + const RMSF = { max: rfmax, min: rfmin } + const RMSS = { max: rsmax, min: rsmin } + const RMSFMinDetail = { rmsvFirstX, rmsvFirstY, firstZhou } + const RMSSMinDetail = { rmsvSecondX, rmsvSecondY, secondeZhou } + const shunshiF = { shunshiFA, shunshiFB, shunshiFC } + const shunshiS = { shunshiSA, shunshiSB, shunshiSC } + const RMSFWave = { rmsFA, rmsFB, rmsFC } + const RMSSWave = { rmsSA, rmsSB, rmsSC } + const title = { aTitle, bTitle, cTitle, unit } + + return { + instantF, + instantS, + RMSF, + RMSS, + RMSFMinDetail, + RMSSMinDetail, + shunshiF, + shunshiS, + RMSFWave, + RMSSWave, + title, + unit + } +} + +// 监听消息 +self.onmessage = function (e) { + const { wp, isOpen, value, boxoList, requestId } = e.data + + try { + const iphasicValue = wp.iphasic || 1 + + const picCounts = (wp.waveTitle.length - 1) / iphasicValue + const waveDatas = [] + + for (let i = 0; i < picCounts; i++) { + const data = fliteWaveData(wp, i, iphasicValue, isOpen, boxoList) + waveDatas.push(data) + } + // 处理标题 + let titles = '' + if (boxoList.systemType == 'pms') { + titles = + '变电站名称:' + + boxoList.powerStationName + + ' 监测点名称:' + + boxoList.measurementPointName + + ' 发生时刻:' + + boxoList.startTime + + ' 暂降(骤升)幅值:' + + (boxoList.featureAmplitude * 100).toFixed(2) + + '%  持续时间:' + + boxoList.duration + + 's' + } else if (boxoList.systemType == 'ZL') { + titles = + (boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) + + ' 监测点名称:' + + boxoList.equipmentName + + ' 发生时刻:' + + boxoList.startTime + + ' 暂降(骤升)幅值:' + + boxoList.evtParamVVaDepth + + '% 持续时间:' + + boxoList.evtParamTm + + 's' + } else if (boxoList.systemType == 'YPT') { + titles = + (boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) + + ' 监测点名称:' + + boxoList.lineName + + ' 发生时刻:' + + boxoList.startTime + + ' 暂降(骤升)幅值:' + + (boxoList.featureAmplitude * 100).toFixed(2) + + '% 持续时间:' + + boxoList.persistTime + + 's' + } else { + titles = + ' 变电站名称:' + + boxoList.subName + + ' 监测点名称:' + + boxoList.lineName + + ' 发生时刻:' + + boxoList.startTime + + ' 暂降(骤升)幅值:' + + (boxoList.featureAmplitude * 100).toFixed(2) + + '% 持续时间:' + + boxoList.duration + + 's' + } + // 发送处理结果回主线程 + self.postMessage({ + requestId, + titles: titles, + success: true, + waveDatas, + time: wp.time, + type: wp.waveType, + severity: wp.yzd, + iphasic: iphasicValue + }) + } catch (error) { + self.postMessage({ + requestId, + success: false, + error: error.message + }) + } +} diff --git a/src/components/echarts/rmsboxi.vue b/src/components/echarts/rmsboxi.vue index 45c4713e..8e9cd872 100644 --- a/src/components/echarts/rmsboxi.vue +++ b/src/components/echarts/rmsboxi.vue @@ -1,686 +1,241 @@ - diff --git a/src/components/echarts/shuWorker.js b/src/components/echarts/shuWorker.js new file mode 100644 index 00000000..79152f52 --- /dev/null +++ b/src/components/echarts/shuWorker.js @@ -0,0 +1,207 @@ +// waveData.worker.js +self.addEventListener('message', function (e) { + const { wp, value, iphasic, isOpen, boxoList, requestId } = e.data + + // 处理波形数据的函数 + const fliteWaveData = (wp, step) => { + // 将原有的fliteWaveData函数实现复制到这里 + const shunData = wp.listWaveData + const pt = Number(wp.pt) / 1000 + const ct = Number(wp.ct) + const titleList = wp.waveTitle + let xishu = pt + let aTitle = '', + bTitle = '', + cTitle = '', + unit = '电压' + let ifmax = 0, + ifmin = 0, + ismax = 0, + ismin = 0 + + const shunshiFA = [] + const shunshiFB = [] + const shunshiFC = [] + const shunshiSA = [] + const shunshiSB = [] + const shunshiSC = [] + + if (shunData.length > 0) { + if (titleList[iphasic * step + 1]?.substring(0, 1) !== 'U') { + xishu = ct + unit = '电流' + } + + for (let i = 1; i <= iphasic; i++) { + switch (i) { + case 1: + aTitle = titleList[iphasic * step + i]?.substring(1) || '' + break + case 2: + bTitle = titleList[iphasic * step + i]?.substring(1) || '' + break + case 3: + cTitle = titleList[iphasic * step + i]?.substring(1) || '' + break + } + } + + if (shunData[0][iphasic * step + 1] !== undefined) { + ifmax = shunData[0][iphasic * step + 1] * xishu + ifmin = shunData[0][iphasic * step + 1] * xishu + ismax = shunData[0][iphasic * step + 1] + ismin = shunData[0][iphasic * step + 1] + } + + for (let shun = 0; shun < shunData.length; shun++) { + if (shunData[shun][iphasic * step + 1] === undefined) { + break + } + + switch (iphasic) { + case 1: + const shunFirstA = shunData[shun][iphasic * step + 1] * xishu + shunshiFA.push([shunData[shun][0], shunFirstA]) + ifmax = Math.max(ifmax, shunFirstA) + ifmin = Math.min(ifmin, shunFirstA) + + const shunSecondA = shunData[shun][iphasic * step + 1] + shunshiSA.push([shunData[shun][0], shunSecondA]) + ismax = Math.max(ismax, shunSecondA) + ismin = Math.min(ismin, shunSecondA) + break + case 2: + const shunFirstA2 = shunData[shun][iphasic * step + 1] * xishu + const shunFirstB2 = shunData[shun][iphasic * step + 2] * xishu + shunshiFA.push([shunData[shun][0], shunFirstA2]) + shunshiFB.push([shunData[shun][0], shunFirstB2]) + ifmax = Math.max(ifmax, shunFirstA2, shunFirstB2) + ifmin = Math.min(ifmin, shunFirstA2, shunFirstB2) + + const shunSecondA2 = shunData[shun][iphasic * step + 1] + const shunSecondB2 = shunData[shun][iphasic * step + 2] + shunshiSA.push([shunData[shun][0], shunSecondA2]) + shunshiSB.push([shunData[shun][0], shunSecondB2]) + ismax = Math.max(ismax, shunSecondA2, shunSecondB2) + ismin = Math.min(ismin, shunSecondA2, shunSecondB2) + break + case 3: + const shunFirstA3 = shunData[shun][iphasic * step + 1] * xishu + const shunFirstB3 = shunData[shun][iphasic * step + 2] * xishu + const shunFirstC3 = shunData[shun][iphasic * step + 3] * xishu + shunshiFA.push([shunData[shun][0], shunFirstA3]) + shunshiFB.push([shunData[shun][0], shunFirstB3]) + shunshiFC.push([shunData[shun][0], shunFirstC3]) + ifmax = Math.max(ifmax, shunFirstA3, shunFirstB3, shunFirstC3) + ifmin = isOpen + ? Math.min(ifmin, shunFirstA3, shunFirstC3) + : Math.min(ifmin, shunFirstA3, shunFirstB3, shunFirstC3) + + const shunSecondA3 = shunData[shun][iphasic * step + 1] + const shunSecondB3 = shunData[shun][iphasic * step + 2] + const shunSecondC3 = shunData[shun][iphasic * step + 3] + shunshiSA.push([shunData[shun][0], shunSecondA3]) + shunshiSB.push([shunData[shun][0], shunSecondB3]) + shunshiSC.push([shunData[shun][0], shunSecondC3]) + ismax = Math.max(ismax, shunSecondA3, shunSecondB3, shunSecondC3) + ismin = isOpen + ? Math.min(ismin, shunSecondA3, shunSecondC3) + : Math.min(ismin, shunSecondA3, shunSecondB3, shunSecondC3) + break + } + } + } + + const instantF = { max: ifmax, min: ifmin } + const instantS = { max: ismax, min: ismin } + const shunshiF = { shunshiFA, shunshiFB, shunshiFC } + const shunshiS = { shunshiSA, shunshiSB, shunshiSC } + const title = { aTitle, bTitle, cTitle, unit } + + return { instantF, instantS, shunshiF, shunshiS, title, unit } + } + + // 处理标题 + let titles = '' + if (boxoList.systemType == 'pms') { + titles = + '变电站名称:' + + boxoList.powerStationName + + ' 监测点名称:' + + boxoList.measurementPointName + + ' 发生时刻:' + + boxoList.startTime + + ' 暂降(骤升)幅值:' + + (boxoList.featureAmplitude * 100).toFixed(2) + + '% 持续时间:' + + boxoList.duration + + 's' + } else if (boxoList.systemType == 'ZL') { + titles = + (boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) + + ' 监测点名称:' + + boxoList.equipmentName + + ' 发生时刻:' + + boxoList.startTime + + ' 暂降(骤升)幅值:' + + boxoList.evtParamVVaDepth + + '% 持续时间:' + + boxoList.evtParamTm + + 's' + } else if (boxoList.systemType == 'YPT') { + titles = + (boxoList.engineeringName == undefined ? '' : ' 项目名称:' + boxoList.engineeringName) + + ' 监测点名称:' + + boxoList.lineName + + ' 发生时刻:' + + boxoList.startTime + + ' 暂降(骤升)幅值:' + + (boxoList.featureAmplitude * 100).toFixed(2) + + '% 持续时间:' + + boxoList.persistTime + + 's' + } else { + titles = + '变电站名称:' + + boxoList.subName + + ' 监测点名称:' + + boxoList.lineName + + ' 发生时刻:' + + boxoList.startTime + + ' 暂降(骤升)幅值:' + + (boxoList.featureAmplitude * 100).toFixed(2) + + '% 持续时间:' + + boxoList.duration + + 's' + } + + const iphasicValue = wp.iphasic || 1 + const picCounts = (wp.waveTitle.length - 1) / iphasicValue + const waveDatas = [] + + for (let i = 0; i < picCounts; i++) { + const data = fliteWaveData(wp, i) + waveDatas.push(data) + } + + const time = wp.time + const type = wp.waveType + let severity = wp.yzd + + if (severity < 0) { + severity = '/' + type = '/' + } + + // 将处理结果发送回主线程 + self.postMessage({ + requestId, + success: true, + waveDatas, + time, + type, + severity, + titles, + iphasic: iphasicValue + }) +}) diff --git a/src/components/echarts/shushiboxi.vue b/src/components/echarts/shushiboxi.vue index 9e38eeb1..0a4402b7 100644 --- a/src/components/echarts/shushiboxi.vue +++ b/src/components/echarts/shushiboxi.vue @@ -1,1228 +1,999 @@ - diff --git a/src/components/echarts/waveForm.vue b/src/components/echarts/waveForm.vue index 0f7e871f..fb509276 100644 --- a/src/components/echarts/waveForm.vue +++ b/src/components/echarts/waveForm.vue @@ -2,7 +2,7 @@
- 值类型选择: + + + + + @@ -24,37 +28,18 @@ 返回 -
- - - +
+ + + - - + + @@ -100,7 +85,7 @@ const options = ref([ } ]) const shushiboxiRef = ref() -const bxecharts = ref(mainHeight(95).height as any) +const bxecharts = ref(mainHeight(145).height as any) const view2 = ref(true) const boxoList: any = ref(null) const wp = ref(null) @@ -128,9 +113,6 @@ const open = async (row: any) => { }) } const bxhandleClick = (tab: any) => { - if (shushiboxiRef.value) shushiboxiRef.value.backbxlb() - if (rmsboxiRef.value) rmsboxiRef.value.backbxlb() - loading.value = true if (tab.name == 'ssbx') { bxactiveName.value = 'ssbx' @@ -145,8 +127,7 @@ const bxhandleClick = (tab: any) => { const backbxlb = () => { boxoList.value = null wp.value = null - if (shushiboxiRef.value) shushiboxiRef.value.backbxlb() - if (rmsboxiRef.value) rmsboxiRef.value.backbxlb() + emit('backbxlb') } diff --git a/src/components/table/index.vue b/src/components/table/index.vue index 18b96052..b136c29b 100644 --- a/src/components/table/index.vue +++ b/src/components/table/index.vue @@ -1,24 +1,44 @@ diff --git a/src/layouts/admin/components/globalPopUp.vue b/src/layouts/admin/components/globalPopUp.vue index 01b72954..9fc348cf 100644 --- a/src/layouts/admin/components/globalPopUp.vue +++ b/src/layouts/admin/components/globalPopUp.vue @@ -11,25 +11,25 @@ :data="eventList.slice((pageNum - 1) * pageSize, pageNum * pageSize)" > - - - - - - - + + + + + + +
{ const url = localStorage.getItem('WebSocketUrl3') || 'null' //'ws://192.168.2.130:10203/event/' - // const url = 'ws://192.168.1.68:10203/event/' diff --git a/src/utils/chartAxisHelper.ts b/src/utils/chartAxisHelper.ts new file mode 100644 index 00000000..36abddef --- /dev/null +++ b/src/utils/chartAxisHelper.ts @@ -0,0 +1,59 @@ +const AXIS_DECIMALS = 2 + +export function roundAxisValue(val: number, decimals = AXIS_DECIMALS): number { + if (!Number.isFinite(val)) return 0 + const factor = 10 ** decimals + return Math.round(val * factor) / factor +} + +/** Y 轴刻度:最多 2 位小数,末尾 0 去掉(如 1.00 → 1,0.10 → 0.1) */ +export function formatAxisLabel(value: number): string { + if (!Number.isFinite(value)) return '0' + return String(Number(roundAxisValue(value).toFixed(AXIS_DECIMALS))) +} + +/** 瞬间波形 Y 轴范围 */ +export function calcShuYAxisRange(dataMin: number, dataMax: number): { min: number; max: number } { + const min = Number(dataMin) + const max = Number(dataMax) + if (!Number.isFinite(min) || !Number.isFinite(max)) { + return { min: 0, max: 1 } + } + + let axisMax = max * 1.1 + let axisMin = min > 0 ? min - min * 0.1 : min * 1.1 + + if (axisMax <= axisMin) { + const pad = Math.abs(max) * 0.1 || 0.01 + axisMax = max + pad + axisMin = min - pad + } + + return { + min: roundAxisValue(axisMin), + max: roundAxisValue(axisMax) + } +} + +/** RMS 波形 Y 轴范围 */ +export function calcRmsYAxisRange(dataMin: number, dataMax: number): { min: number; max: number } { + const min = Number(dataMin) + const max = Number(dataMax) + if (!Number.isFinite(min) || !Number.isFinite(max)) { + return { min: 0, max: 1 } + } + + let axisMax = max * 1.06 * 1.1 + let axisMin = min - min * 0.2 + + if (axisMax <= axisMin) { + const pad = Math.abs(max - min) * 0.1 || Math.abs(max) * 0.1 || 0.01 + axisMax = max + pad + axisMin = min - pad + } + + return { + min: roundAxisValue(axisMin), + max: roundAxisValue(axisMax) + } +} diff --git a/src/utils/waveCache.ts b/src/utils/waveCache.ts new file mode 100644 index 00000000..d114d78f --- /dev/null +++ b/src/utils/waveCache.ts @@ -0,0 +1,42 @@ +const MAX_CACHE_SIZE = 30 + +const cache = new Map() + +function dataFingerprint(data: unknown[][] | undefined): string { + if (!data?.length) return '0' + const first = data[0] + const last = data[data.length - 1] + return `${data.length}:${first?.[0]}:${last?.[0]}` +} + +export function buildWaveCacheKey( + type: 'shu' | 'rms', + wp: Record | undefined, + value: number, + isOpen: boolean, + boxoList: Record +): string { + if (!wp) return '' + const waveFp = + type === 'shu' ? dataFingerprint(wp.listWaveData) : dataFingerprint(wp.listRmsData) + const boxoFp = boxoList?.startTime ?? boxoList?.lineName ?? boxoList?.equipmentName ?? '' + return `${type}|${wp.time}|${wp.waveType}|${wp.iphasic}|${value}|${isOpen}|${waveFp}|${boxoFp}` +} + +export function getWaveCache(key: string): T | null { + if (!key || !cache.has(key)) return null + const value = cache.get(key) as T + cache.delete(key) + cache.set(key, value) + return value +} + +export function setWaveCache(key: string, value: unknown): void { + if (!key) return + if (cache.has(key)) cache.delete(key) + cache.set(key, value) + while (cache.size > MAX_CACHE_SIZE) { + const oldest = cache.keys().next().value + if (oldest !== undefined) cache.delete(oldest) + } +} diff --git a/src/utils/waveWorkerPool.ts b/src/utils/waveWorkerPool.ts new file mode 100644 index 00000000..0f1dd327 --- /dev/null +++ b/src/utils/waveWorkerPool.ts @@ -0,0 +1,96 @@ +import { toRaw } from 'vue' + +type WorkerMessageHandler = (data: any) => void + +let shuWorker: Worker | null = null +let rmsWorker: Worker | null = null + +/** 递归剥离 Vue 响应式代理,得到可 structuredClone 的纯对象 */ +export function toPlainDeep(value: T): T { + const raw = toRaw(value as object) as T + if (Array.isArray(raw)) { + return raw.map(item => toPlainDeep(item)) as T + } + if (raw !== null && typeof raw === 'object') { + const out: Record = {} + for (const [key, val] of Object.entries(raw)) { + out[key] = toPlainDeep(val) + } + return out as T + } + return raw +} + +const BOXO_LIST_KEYS = [ + 'systemType', + 'powerStationName', + 'measurementPointName', + 'startTime', + 'featureAmplitude', + 'duration', + 'engineeringName', + 'equipmentName', + 'evtParamVVaDepth', + 'evtParamTm', + 'lineName', + 'persistTime', + 'subName' +] as const + +export function buildWorkerPayload( + type: 'shu' | 'rms', + wp: Record, + boxoList: Record, + extras: { requestId: number; value: number; isOpen: boolean; iphasic?: number } +) { + const plainWp = toPlainDeep(wp) + const wpPayload: Record = { + pt: plainWp.pt, + ct: plainWp.ct, + waveTitle: plainWp.waveTitle, + iphasic: plainWp.iphasic, + time: plainWp.time, + waveType: plainWp.waveType, + yzd: plainWp.yzd + } + if (type === 'shu') { + wpPayload.listWaveData = plainWp.listWaveData + } else { + wpPayload.listRmsData = plainWp.listRmsData + } + + const plainBoxo: Record = {} + const rawBoxo = toPlainDeep(boxoList) + for (const key of BOXO_LIST_KEYS) { + if (rawBoxo[key] !== undefined) { + plainBoxo[key] = rawBoxo[key] + } + } + + return { + requestId: extras.requestId, + value: extras.value, + isOpen: extras.isOpen, + iphasic: extras.iphasic, + wp: wpPayload, + boxoList: plainBoxo + } +} + +export function getShuWorker(onMessage: WorkerMessageHandler): Worker { + if (!shuWorker) { + shuWorker = new Worker(new URL('../components/echarts/shuWorker.js', import.meta.url)) + } + shuWorker.onmessage = e => onMessage(e.data) + shuWorker.onerror = error => console.error('Shu worker error:', error) + return shuWorker +} + +export function getRmsWorker(onMessage: WorkerMessageHandler): Worker { + if (!rmsWorker) { + rmsWorker = new Worker(new URL('../components/echarts/rmsWorker.js', import.meta.url)) + } + rmsWorker.onmessage = e => onMessage(e.data) + rmsWorker.onerror = error => console.error('Rms worker error:', error) + return rmsWorker +} diff --git a/src/utils/webSocketClient.ts b/src/utils/webSocketClient.ts index 6c4e4e5f..0e06281b 100644 --- a/src/utils/webSocketClient.ts +++ b/src/utils/webSocketClient.ts @@ -58,7 +58,7 @@ export default class SocketService { } // 处理连接成功事件 private handleOpen(): void { - ElMessage.success('webSocket连接服务端成功了') + // ElMessage.success('webSocket连接服务端成功了') console.log('连接服务端成功了') this.connected = true this.connectRetryCount = 0 @@ -110,7 +110,7 @@ export default class SocketService { } } else { this.callBackMapping['message']!({ Flag: false }) - ElMessage.error(event.data) + // ElMessage.error(event.data) } } diff --git a/src/views/LN/newEnergy/highAndLowPressure/index.vue b/src/views/LN/newEnergy/highAndLowPressure/index.vue index a1ee9f3a..a612b31f 100644 --- a/src/views/LN/newEnergy/highAndLowPressure/index.vue +++ b/src/views/LN/newEnergy/highAndLowPressure/index.vue @@ -1,423 +1,423 @@ - - - + + + diff --git a/src/views/pqs/database/standard/index.vue b/src/views/pqs/database/standard/index.vue index 384fd83e..e91875f8 100644 --- a/src/views/pqs/database/standard/index.vue +++ b/src/views/pqs/database/standard/index.vue @@ -79,7 +79,7 @@ onMounted(() => { }) const urlKey=ref('') -const VITE_FLAG = import.meta.env.VITE_NAME == 'jibei' +const VITE_FLAG = false//import.meta.env.VITE_NAME == 'jibei' const handleNodeClick = (data: any, node: any) => { // console.log("🚀 ~ handleNodeClick ~ data:", data) dotList.value = data diff --git a/src/views/pqs/harmonicMonitoring/area/TransientEventList/index.vue b/src/views/pqs/harmonicMonitoring/area/TransientEventList/index.vue index 856b09eb..24c2a181 100644 --- a/src/views/pqs/harmonicMonitoring/area/TransientEventList/index.vue +++ b/src/views/pqs/harmonicMonitoring/area/TransientEventList/index.vue @@ -4,7 +4,13 @@