修改文件上传问题
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<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;min-height: 200px;`">
|
<div id="rmsp" :style="`height:${vh};overflow: hidden;min-height: 200px;`">
|
||||||
@@ -19,6 +19,8 @@ import url from '@/assets/img/point.png'
|
|||||||
import url2 from '@/assets/img/dw.png'
|
import url2 from '@/assets/img/dw.png'
|
||||||
import { buildWaveCacheKey, getWaveCache, setWaveCache } from '@/utils/waveCache'
|
import { buildWaveCacheKey, getWaveCache, setWaveCache } from '@/utils/waveCache'
|
||||||
import { getRmsWorker, buildWorkerPayload } from '@/utils/waveWorkerPool'
|
import { getRmsWorker, buildWorkerPayload } from '@/utils/waveWorkerPool'
|
||||||
|
import { compactRmsWaveResult } from '@/utils/waveDisplayHelper'
|
||||||
|
import { getWaveRawList } from '@/utils/waveRawStore'
|
||||||
|
|
||||||
let waveRequestId = 0
|
let waveRequestId = 0
|
||||||
const pendingCacheKeys = new Map<number, string>()
|
const pendingCacheKeys = new Map<number, string>()
|
||||||
@@ -98,7 +100,6 @@ const eventValue = ref('')
|
|||||||
const persistTime = ref('')
|
const persistTime = ref('')
|
||||||
const lineName = ref('')
|
const lineName = ref('')
|
||||||
const subName = ref('')
|
const subName = ref('')
|
||||||
const waveDatas = ref<WaveData[]>([])
|
|
||||||
const ptpass = ref('')
|
const ptpass = ref('')
|
||||||
const color = ref('#006565')
|
const color = ref('#006565')
|
||||||
const charts = ref({})
|
const charts = ref({})
|
||||||
@@ -144,19 +145,19 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const applyWorkerResult = (data: any) => {
|
const applyWorkerResult = (data: any) => {
|
||||||
titles.value = data.titles
|
const compacted = compactRmsWaveResult(data, props.value)
|
||||||
waveDatas.value = data.waveDatas
|
titles.value = compacted.titles
|
||||||
time.value = data.time
|
time.value = compacted.time
|
||||||
type.value = data.type
|
type.value = compacted.type
|
||||||
severity.value = data.severity
|
severity.value = compacted.severity
|
||||||
iphasic.value = data.iphasic
|
iphasic.value = compacted.iphasic
|
||||||
|
|
||||||
if (Number(severity.value) < 0) {
|
if (Number(severity.value) < 0) {
|
||||||
severity.value = '/'
|
severity.value = '/'
|
||||||
type.value = '/'
|
type.value = '/'
|
||||||
}
|
}
|
||||||
|
|
||||||
initWave(waveDatas.value, time.value, type.value, severity.value, isOpen.value)
|
initWave(compacted.waveDatas, time.value, type.value, severity.value, isOpen.value)
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +175,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
const cacheKey = pendingCacheKeys.get(data.requestId)
|
const cacheKey = pendingCacheKeys.get(data.requestId)
|
||||||
if (cacheKey) {
|
if (cacheKey) {
|
||||||
setWaveCache(cacheKey, data)
|
setWaveCache(cacheKey, compactRmsWaveResult(data, props.value))
|
||||||
pendingCacheKeys.delete(data.requestId)
|
pendingCacheKeys.delete(data.requestId)
|
||||||
}
|
}
|
||||||
applyWorkerResult(data)
|
applyWorkerResult(data)
|
||||||
@@ -252,7 +253,10 @@ const waveData = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const initWaves = () => {
|
const initWaves = () => {
|
||||||
if (!props.wp?.listRmsData?.length) {
|
const hasData =
|
||||||
|
props.wp?.listRmsData?.length ||
|
||||||
|
getWaveRawList('rms', props.wp?.waveStoreKey)?.length
|
||||||
|
if (!hasData) {
|
||||||
initWave(null, null, null, null, null)
|
initWave(null, null, null, null, null)
|
||||||
loading.value = false
|
loading.value = false
|
||||||
return
|
return
|
||||||
@@ -715,8 +719,8 @@ const initWave = (
|
|||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'value',
|
type: 'value',
|
||||||
name: '时间\n(ms)',
|
name: '时间\n(ms)',
|
||||||
min: props.wp?.listRmsData[0][0] || 0,
|
min: props.wp?.waveTimeRange?.min ?? props.wp?.listRmsData?.[0]?.[0] ?? 0,
|
||||||
max: props.wp?.listRmsData[props.wp?.listRmsData.length - 1][0] + 1 || 1,
|
max: props.wp?.waveTimeRange?.max ?? ((props.wp?.listRmsData?.[props.wp?.listRmsData?.length - 1]?.[0] ?? 0) + 1),
|
||||||
boundaryGap: false,
|
boundaryGap: false,
|
||||||
title: {
|
title: {
|
||||||
text: 'ms',
|
text: 'ms',
|
||||||
@@ -1047,8 +1051,8 @@ const drawPics = (
|
|||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'value',
|
type: 'value',
|
||||||
name: '时间\n(ms)',
|
name: '时间\n(ms)',
|
||||||
min: props.wp.listRmsData[0][0],
|
min: props.wp?.waveTimeRange?.min ?? props.wp?.listRmsData?.[0]?.[0] ?? 0,
|
||||||
max: props.wp.listRmsData[props.wp.listRmsData.length - 1][0] + 1,
|
max: props.wp?.waveTimeRange?.max ?? ((props.wp?.listRmsData?.[props.wp?.listRmsData?.length - 1]?.[0] ?? 0) + 1),
|
||||||
boundaryGap: false,
|
boundaryGap: false,
|
||||||
title: {
|
title: {
|
||||||
text: 'ms',
|
text: 'ms',
|
||||||
@@ -1210,7 +1214,6 @@ const drawPics = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const backbxlb = () => {
|
const backbxlb = () => {
|
||||||
waveDatas.value = []
|
|
||||||
const charts = [
|
const charts = [
|
||||||
myChartess.value,
|
myChartess.value,
|
||||||
myChartess1.value,
|
myChartess1.value,
|
||||||
@@ -1261,4 +1264,6 @@ const getMinOpen = (temp: number, tempA: number, tempB: number): number => {
|
|||||||
temp = temp < tempB ? temp : tempB
|
temp = temp < tempB ? temp : tempB
|
||||||
return temp
|
return temp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineExpose({ backbxlb })
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import { calcShuYAxisRange, formatAxisLabel } from '@/utils/chartAxisHelper'
|
|||||||
import url from '@/assets/img/point.png'
|
import url from '@/assets/img/point.png'
|
||||||
import { buildWaveCacheKey, getWaveCache, setWaveCache } from '@/utils/waveCache'
|
import { buildWaveCacheKey, getWaveCache, setWaveCache } from '@/utils/waveCache'
|
||||||
import { getShuWorker, buildWorkerPayload } from '@/utils/waveWorkerPool'
|
import { getShuWorker, buildWorkerPayload } from '@/utils/waveWorkerPool'
|
||||||
|
import { compactShuWaveResult } from '@/utils/waveDisplayHelper'
|
||||||
|
import { getWaveRawList } from '@/utils/waveRawStore'
|
||||||
|
|
||||||
let waveRequestId = 0
|
let waveRequestId = 0
|
||||||
const pendingCacheKeys = new Map<number, string>()
|
const pendingCacheKeys = new Map<number, string>()
|
||||||
@@ -75,7 +77,6 @@ const eventValue = ref('')
|
|||||||
const persistTime = ref('')
|
const persistTime = ref('')
|
||||||
const lineName = ref('')
|
const lineName = ref('')
|
||||||
const subName = ref('')
|
const subName = ref('')
|
||||||
const waveDatas = ref<WaveData[]>([])
|
|
||||||
const ptpass = ref('')
|
const ptpass = ref('')
|
||||||
const waveHeight = ref<number>()
|
const waveHeight = ref<number>()
|
||||||
const rmsHeight = ref<number>()
|
const rmsHeight = ref<number>()
|
||||||
@@ -156,12 +157,13 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const applyWorkerResult = (data: any) => {
|
const applyWorkerResult = (data: any) => {
|
||||||
titles.value = data.titles
|
const compacted = compactShuWaveResult(data, props.value)
|
||||||
iphasic.value = data.iphasic
|
titles.value = compacted.titles
|
||||||
time.value = data.time
|
iphasic.value = compacted.iphasic
|
||||||
type.value = data.type
|
time.value = compacted.time
|
||||||
severity.value = data.severity
|
type.value = compacted.type
|
||||||
initWave(data.waveDatas, data.time, data.type, data.severity, isOpen.value)
|
severity.value = compacted.severity
|
||||||
|
initWave(compacted.waveDatas, compacted.time, compacted.type, compacted.severity, isOpen.value)
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +181,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
const cacheKey = pendingCacheKeys.get(data.requestId)
|
const cacheKey = pendingCacheKeys.get(data.requestId)
|
||||||
if (cacheKey) {
|
if (cacheKey) {
|
||||||
setWaveCache(cacheKey, data)
|
setWaveCache(cacheKey, compactShuWaveResult(data, props.value))
|
||||||
pendingCacheKeys.delete(data.requestId)
|
pendingCacheKeys.delete(data.requestId)
|
||||||
}
|
}
|
||||||
applyWorkerResult(data)
|
applyWorkerResult(data)
|
||||||
@@ -240,7 +242,10 @@ const waveData = (instantF: any, instantS: any, shunshiF: any, shunshiS: any, ti
|
|||||||
|
|
||||||
// 在组件中修改initWaves函数
|
// 在组件中修改initWaves函数
|
||||||
const initWaves = () => {
|
const initWaves = () => {
|
||||||
if (!props.wp?.listWaveData?.length) {
|
const hasData =
|
||||||
|
props.wp?.listWaveData?.length ||
|
||||||
|
getWaveRawList('shu', props.wp?.waveStoreKey)?.length
|
||||||
|
if (!hasData) {
|
||||||
initWave(null, null, null, null, null)
|
initWave(null, null, null, null, null)
|
||||||
loading.value = false
|
loading.value = false
|
||||||
return
|
return
|
||||||
@@ -480,8 +485,8 @@ const initWave = (
|
|||||||
type: 'value',
|
type: 'value',
|
||||||
name: '时间\n(ms)',
|
name: '时间\n(ms)',
|
||||||
boundaryGap: false,
|
boundaryGap: false,
|
||||||
min: props.wp?.listWaveData[0][0] || 0,
|
min: props.wp?.waveTimeRange?.min ?? props.wp?.listWaveData?.[0]?.[0] ?? 0,
|
||||||
max: props.wp?.listWaveData[props.wp?.listWaveData.length - 1][0] + 1 || 1,
|
max: props.wp?.waveTimeRange?.max ?? ((props.wp?.listWaveData?.[props.wp?.listWaveData?.length - 1]?.[0] ?? 0) + 1),
|
||||||
title: {
|
title: {
|
||||||
text: 'ms',
|
text: 'ms',
|
||||||
textStyle: {
|
textStyle: {
|
||||||
@@ -789,8 +794,8 @@ const drawPics = (
|
|||||||
type: 'value',
|
type: 'value',
|
||||||
name: '时间\n(ms)',
|
name: '时间\n(ms)',
|
||||||
boundaryGap: false,
|
boundaryGap: false,
|
||||||
min: props.wp.listWaveData[0][0],
|
min: props.wp?.waveTimeRange?.min ?? props.wp?.listWaveData?.[0]?.[0] ?? 0,
|
||||||
max: props.wp.listWaveData[props.wp.listWaveData.length - 1][0] + 1,
|
max: props.wp?.waveTimeRange?.max ?? ((props.wp?.listWaveData?.[props.wp?.listWaveData?.length - 1]?.[0] ?? 0) + 1),
|
||||||
title: {
|
title: {
|
||||||
text: 'ms',
|
text: 'ms',
|
||||||
textStyle: {
|
textStyle: {
|
||||||
@@ -944,7 +949,6 @@ const drawPics = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const backbxlb = () => {
|
const backbxlb = () => {
|
||||||
waveDatas.value = []
|
|
||||||
const charts = [
|
const charts = [
|
||||||
myChartess.value,
|
myChartess.value,
|
||||||
myChartess1.value,
|
myChartess1.value,
|
||||||
@@ -996,4 +1000,6 @@ const getMinOpen = (temp: number, tempA: number, tempB: number): number => {
|
|||||||
temp = temp < tempB ? temp : tempB
|
temp = temp < tempB ? temp : tempB
|
||||||
return temp
|
return temp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineExpose({ backbxlb })
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -55,10 +55,12 @@
|
|||||||
import shushiboxi from '@/components/echarts/shushiboxi.vue'
|
import shushiboxi from '@/components/echarts/shushiboxi.vue'
|
||||||
import rmsboxi from '@/components/echarts/rmsboxi.vue'
|
import rmsboxi from '@/components/echarts/rmsboxi.vue'
|
||||||
import analytics from '@/components/echarts/analytics.vue'
|
import analytics from '@/components/echarts/analytics.vue'
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, shallowRef } from 'vue'
|
||||||
import { analysis } from '@/api/advance-boot/analyse'
|
import { analysis } from '@/api/advance-boot/analyse'
|
||||||
import { mainHeight } from '@/utils/layout'
|
import { mainHeight } from '@/utils/layout'
|
||||||
import { getMonitorEventAnalyseWave, downloadWaveFile } from '@/api/event-boot/transient'
|
import { getMonitorEventAnalyseWave, downloadWaveFile } from '@/api/event-boot/transient'
|
||||||
|
import { buildWaveStoreKey, registerWaveRaw, buildSlimWp, releaseWaveRaw } from '@/utils/waveRawStore'
|
||||||
|
import { clearWaveCache } from '@/utils/waveCache'
|
||||||
const emit = defineEmits(['backbxlb'])
|
const emit = defineEmits(['backbxlb'])
|
||||||
interface Props {
|
interface Props {
|
||||||
// boxoList: any
|
// boxoList: any
|
||||||
@@ -88,7 +90,7 @@ const shushiboxiRef = ref()
|
|||||||
const bxecharts = ref(mainHeight(145).height as any)
|
const bxecharts = ref(mainHeight(145).height as any)
|
||||||
const view2 = ref(true)
|
const view2 = ref(true)
|
||||||
const boxoList: any = ref(null)
|
const boxoList: any = ref(null)
|
||||||
const wp = ref(null)
|
const wp = shallowRef<any>(null)
|
||||||
const showBoxi = ref(true)
|
const showBoxi = ref(true)
|
||||||
const view3 = ref(false)
|
const view3 = ref(false)
|
||||||
const view4 = ref(false)
|
const view4 = ref(false)
|
||||||
@@ -102,7 +104,9 @@ const open = async (row: any) => {
|
|||||||
if (res != undefined) {
|
if (res != undefined) {
|
||||||
boxoList.value = row
|
boxoList.value = row
|
||||||
boxoList.value.pt = res.data.pt
|
boxoList.value.pt = res.data.pt
|
||||||
wp.value = res.data
|
const storeKey = buildWaveStoreKey(row)
|
||||||
|
registerWaveRaw(storeKey, res.data)
|
||||||
|
wp.value = buildSlimWp(res.data, storeKey)
|
||||||
loading.value = false
|
loading.value = false
|
||||||
view4.value = true
|
view4.value = true
|
||||||
}
|
}
|
||||||
@@ -125,6 +129,9 @@ const bxhandleClick = (tab: any) => {
|
|||||||
// console.log(tab, event);
|
// console.log(tab, event);
|
||||||
}
|
}
|
||||||
const backbxlb = () => {
|
const backbxlb = () => {
|
||||||
|
const storeKey = wp.value?.waveStoreKey
|
||||||
|
releaseWaveRaw(storeKey, 'all')
|
||||||
|
clearWaveCache()
|
||||||
boxoList.value = null
|
boxoList.value = null
|
||||||
wp.value = null
|
wp.value = null
|
||||||
|
|
||||||
@@ -154,8 +161,8 @@ const AdvancedAnalytics = () => {
|
|||||||
view2.value = false
|
view2.value = false
|
||||||
}
|
}
|
||||||
const changeView = () => {
|
const changeView = () => {
|
||||||
if (shushiboxiRef.value) shushiboxiRef.value.backbxlb()
|
shushiboxiRef.value?.backbxlb?.()
|
||||||
if (rmsboxiRef.value) rmsboxiRef.value.backbxlb()
|
rmsboxiRef.value?.backbxlb?.()
|
||||||
showBoxi.value = false
|
showBoxi.value = false
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
showBoxi.value = true
|
showBoxi.value = true
|
||||||
|
|||||||
@@ -51,13 +51,13 @@
|
|||||||
<el-descriptions-item label="基准容量(MVA)">
|
<el-descriptions-item label="基准容量(MVA)">
|
||||||
{{ details.standardCapacity }}
|
{{ details.standardCapacity }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="最小短路容量(MVA)">
|
|
||||||
{{ details.shortCapacity }}
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="供电设备容量(MVA)">
|
<el-descriptions-item label="供电设备容量(MVA)">
|
||||||
{{ details.devCapacity }}
|
{{ details.devCapacity }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="用户协议容量(MVA)">
|
<el-descriptions-item label="最小短路容量(MW)">
|
||||||
|
{{ details.shortCapacity }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="用户协议容量(MW)">
|
||||||
{{ details.dealCapacity }}
|
{{ details.dealCapacity }}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
@@ -187,7 +187,7 @@ const open = (data: any) => {
|
|||||||
|
|
||||||
getLineDetailData(data.id).then(res => {
|
getLineDetailData(data.id).then(res => {
|
||||||
details.value = res.data
|
details.value = res.data
|
||||||
|
res.data.objName ? (title.value = res.data.objName + '_' + title.value) : ''
|
||||||
})
|
})
|
||||||
getLineOverLimitData(data.id).then(res => {
|
getLineOverLimitData(data.id).then(res => {
|
||||||
limitValue.value = res.data
|
limitValue.value = res.data
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { downloadFile } from '@/api/system-boot/file'
|
import { downloadFile } from '@/api/system-boot/file'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
const sanitizeUrl = (url: string): string => {
|
const sanitizeUrl = (url: string): string => {
|
||||||
return url.replace(/\[/g, '(').replace(/\]/g, ')')
|
return url.replace(/\[/g, '(').replace(/\]/g, ')')
|
||||||
@@ -7,7 +8,7 @@ const sanitizeUrl = (url: string): string => {
|
|||||||
// 下载文件
|
// 下载文件
|
||||||
export const download = (urls: string) => {
|
export const download = (urls: string) => {
|
||||||
//console.log('下载', urls)
|
//console.log('下载', urls)
|
||||||
|
ElMessage.info('下载中...')
|
||||||
downloadFile({ filePath: urls })
|
downloadFile({ filePath: urls })
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
// 1. 确定文件MIME类型(优化:用更简洁的方式)
|
// 1. 确定文件MIME类型(优化:用更简洁的方式)
|
||||||
@@ -43,8 +44,12 @@ export const download = (urls: string) => {
|
|||||||
// 4. 清理资源(优化)
|
// 4. 清理资源(优化)
|
||||||
link.remove()
|
link.remove()
|
||||||
window.URL.revokeObjectURL(url) // 释放blob URL
|
window.URL.revokeObjectURL(url) // 释放blob URL
|
||||||
|
setTimeout(() => {
|
||||||
|
ElMessage.success('下载成功')
|
||||||
|
}, 1000)
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
ElMessage.warning('下载失败:', err)
|
||||||
console.error('下载失败:', err)
|
console.error('下载失败:', err)
|
||||||
// 可添加错误提示(如Toast)
|
// 可添加错误提示(如Toast)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
const MAX_CACHE_SIZE = 30
|
import { getWaveRawList } from './waveRawStore'
|
||||||
|
|
||||||
|
const MAX_CACHE_SIZE = 6
|
||||||
|
|
||||||
const cache = new Map<string, unknown>()
|
const cache = new Map<string, unknown>()
|
||||||
|
|
||||||
@@ -17,8 +19,10 @@ export function buildWaveCacheKey(
|
|||||||
boxoList: Record<string, any>
|
boxoList: Record<string, any>
|
||||||
): string {
|
): string {
|
||||||
if (!wp) return ''
|
if (!wp) return ''
|
||||||
const waveFp =
|
const rawList = wp.waveStoreKey
|
||||||
type === 'shu' ? dataFingerprint(wp.listWaveData) : dataFingerprint(wp.listRmsData)
|
? getWaveRawList(type, wp.waveStoreKey)
|
||||||
|
: ((type === 'shu' ? wp.listWaveData : wp.listRmsData) as unknown[][] | undefined)
|
||||||
|
const waveFp = dataFingerprint(rawList)
|
||||||
const boxoFp = boxoList?.startTime ?? boxoList?.lineName ?? boxoList?.equipmentName ?? ''
|
const boxoFp = boxoList?.startTime ?? boxoList?.lineName ?? boxoList?.equipmentName ?? ''
|
||||||
return `${type}|${wp.time}|${wp.waveType}|${wp.iphasic}|${value}|${isOpen}|${waveFp}|${boxoFp}`
|
return `${type}|${wp.time}|${wp.waveType}|${wp.iphasic}|${value}|${isOpen}|${waveFp}|${boxoFp}`
|
||||||
}
|
}
|
||||||
@@ -40,3 +44,7 @@ export function setWaveCache(key: string, value: unknown): void {
|
|||||||
if (oldest !== undefined) cache.delete(oldest)
|
if (oldest !== undefined) cache.delete(oldest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function clearWaveCache(): void {
|
||||||
|
cache.clear()
|
||||||
|
}
|
||||||
|
|||||||
59
src/utils/waveDisplayHelper.ts
Normal file
59
src/utils/waveDisplayHelper.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
const EMPTY_SERIES: number[][] = []
|
||||||
|
|
||||||
|
function ds(data: number[][] | undefined): number[][] {
|
||||||
|
if (!data?.length) return EMPTY_SERIES
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Worker 完整计算后,剔除当前未使用的值类型,降低内存占用 */
|
||||||
|
export function compactShuWaveResult(data: any, value: number) {
|
||||||
|
const waveDatas = data.waveDatas.map((wd: any) => {
|
||||||
|
if (value === 1) {
|
||||||
|
return {
|
||||||
|
...wd,
|
||||||
|
shunshiF: {
|
||||||
|
shunshiFA: ds(wd.shunshiF.shunshiFA),
|
||||||
|
shunshiFB: ds(wd.shunshiF.shunshiFB),
|
||||||
|
shunshiFC: ds(wd.shunshiF.shunshiFC)
|
||||||
|
},
|
||||||
|
shunshiS: { shunshiSA: EMPTY_SERIES, shunshiSB: EMPTY_SERIES, shunshiSC: EMPTY_SERIES }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...wd,
|
||||||
|
shunshiF: { shunshiFA: EMPTY_SERIES, shunshiFB: EMPTY_SERIES, shunshiFC: EMPTY_SERIES },
|
||||||
|
shunshiS: {
|
||||||
|
shunshiSA: ds(wd.shunshiS.shunshiSA),
|
||||||
|
shunshiSB: ds(wd.shunshiS.shunshiSB),
|
||||||
|
shunshiSC: ds(wd.shunshiS.shunshiSC)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return { ...data, waveDatas }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function compactRmsWaveResult(data: any, value: number) {
|
||||||
|
const waveDatas = data.waveDatas.map((wd: any) => {
|
||||||
|
if (value === 1) {
|
||||||
|
return {
|
||||||
|
...wd,
|
||||||
|
RMSFWave: {
|
||||||
|
rmsFA: ds(wd.RMSFWave.rmsFA),
|
||||||
|
rmsFB: ds(wd.RMSFWave.rmsFB),
|
||||||
|
rmsFC: ds(wd.RMSFWave.rmsFC)
|
||||||
|
},
|
||||||
|
RMSSWave: { rmsSA: EMPTY_SERIES, rmsSB: EMPTY_SERIES, rmsSC: EMPTY_SERIES }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...wd,
|
||||||
|
RMSFWave: { rmsFA: EMPTY_SERIES, rmsFB: EMPTY_SERIES, rmsFC: EMPTY_SERIES },
|
||||||
|
RMSSWave: {
|
||||||
|
rmsSA: ds(wd.RMSSWave.rmsSA),
|
||||||
|
rmsSB: ds(wd.RMSSWave.rmsSB),
|
||||||
|
rmsSC: ds(wd.RMSSWave.rmsSC)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return { ...data, waveDatas }
|
||||||
|
}
|
||||||
75
src/utils/waveRawStore.ts
Normal file
75
src/utils/waveRawStore.ts
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/** 原始波形数据存放于 Vue 响应式体系之外,避免大数组触发深度代理与重复持有 */
|
||||||
|
|
||||||
|
interface WaveRawEntry {
|
||||||
|
listWaveData?: unknown[][]
|
||||||
|
listRmsData?: unknown[][]
|
||||||
|
waveTimeRange?: { min: number; max: number }
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawStore = new Map<string, WaveRawEntry>()
|
||||||
|
|
||||||
|
function calcTimeRange(data: unknown[][] | undefined): { min: number; max: number } | undefined {
|
||||||
|
if (!data?.length) return undefined
|
||||||
|
const first = data[0] as number[]
|
||||||
|
const last = data[data.length - 1] as number[]
|
||||||
|
return { min: first[0], max: last[0] + 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildWaveStoreKey(boxoList: Record<string, any>): string {
|
||||||
|
const id = boxoList?.eventId ?? boxoList?.id ?? ''
|
||||||
|
return `${id}|${boxoList?.startTime ?? ''}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerWaveRaw(storeKey: string, wp: Record<string, any>): void {
|
||||||
|
if (!storeKey || !wp) return
|
||||||
|
const entry: WaveRawEntry = rawStore.get(storeKey) ?? {}
|
||||||
|
|
||||||
|
if (wp.listWaveData?.length) {
|
||||||
|
entry.listWaveData = wp.listWaveData
|
||||||
|
entry.waveTimeRange = calcTimeRange(wp.listWaveData) ?? entry.waveTimeRange
|
||||||
|
}
|
||||||
|
if (wp.listRmsData?.length) {
|
||||||
|
entry.listRmsData = wp.listRmsData
|
||||||
|
entry.waveTimeRange = calcTimeRange(wp.listRmsData) ?? entry.waveTimeRange
|
||||||
|
}
|
||||||
|
|
||||||
|
rawStore.set(storeKey, entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWaveRawList(type: 'shu' | 'rms', storeKey: string | undefined): unknown[][] | undefined {
|
||||||
|
if (!storeKey) return undefined
|
||||||
|
const entry = rawStore.get(storeKey)
|
||||||
|
return type === 'shu' ? entry?.listWaveData : entry?.listRmsData
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWaveTimeRange(storeKey: string | undefined): { min: number; max: number } | undefined {
|
||||||
|
if (!storeKey) return undefined
|
||||||
|
return rawStore.get(storeKey)?.waveTimeRange
|
||||||
|
}
|
||||||
|
|
||||||
|
export function releaseWaveRaw(storeKey: string | undefined, type: 'shu' | 'rms' | 'all' = 'all'): void {
|
||||||
|
if (!storeKey) return
|
||||||
|
if (type === 'all') {
|
||||||
|
rawStore.delete(storeKey)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const entry = rawStore.get(storeKey)
|
||||||
|
if (!entry) return
|
||||||
|
if (type === 'shu') delete entry.listWaveData
|
||||||
|
if (type === 'rms') delete entry.listRmsData
|
||||||
|
if (!entry.listWaveData && !entry.listRmsData) {
|
||||||
|
rawStore.delete(storeKey)
|
||||||
|
} else {
|
||||||
|
rawStore.set(storeKey, entry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 构建不含大数组的 wp 对象,供子组件 props 使用 */
|
||||||
|
export function buildSlimWp(wp: Record<string, any>, storeKey: string): Record<string, any> {
|
||||||
|
const { listWaveData: _w, listRmsData: _r, ...rest } = wp
|
||||||
|
return {
|
||||||
|
...rest,
|
||||||
|
waveStoreKey: storeKey,
|
||||||
|
waveTimeRange: getWaveTimeRange(storeKey) ?? calcTimeRange(_w) ?? calcTimeRange(_r)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { toRaw } from 'vue'
|
import { toRaw } from 'vue'
|
||||||
|
import { getWaveRawList } from './waveRawStore'
|
||||||
|
|
||||||
type WorkerMessageHandler = (data: any) => void
|
type WorkerMessageHandler = (data: any) => void
|
||||||
|
|
||||||
@@ -53,10 +54,11 @@ export function buildWorkerPayload(
|
|||||||
waveType: plainWp.waveType,
|
waveType: plainWp.waveType,
|
||||||
yzd: plainWp.yzd
|
yzd: plainWp.yzd
|
||||||
}
|
}
|
||||||
|
const storeKey = plainWp.waveStoreKey as string | undefined
|
||||||
if (type === 'shu') {
|
if (type === 'shu') {
|
||||||
wpPayload.listWaveData = plainWp.listWaveData
|
wpPayload.listWaveData = getWaveRawList('shu', storeKey) ?? plainWp.listWaveData
|
||||||
} else {
|
} else {
|
||||||
wpPayload.listRmsData = plainWp.listRmsData
|
wpPayload.listRmsData = getWaveRawList('rms', storeKey) ?? plainWp.listRmsData
|
||||||
}
|
}
|
||||||
|
|
||||||
const plainBoxo: Record<string, unknown> = {}
|
const plainBoxo: Record<string, unknown> = {}
|
||||||
|
|||||||
@@ -212,12 +212,21 @@
|
|||||||
})?.name
|
})?.name
|
||||||
}}
|
}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="敏感电能质量指标" v-if="detailData.userType == 6">
|
<el-descriptions-item :span="2" label="电能质量设备检测报告">
|
||||||
{{
|
<el-icon class="elView" v-if="detailData?.checkUrl">
|
||||||
energyQualityIndexList.find(item => {
|
<View @click="openFile(detailData?.checkUrl)" />
|
||||||
return item.id == proviteData.energyQualityIndex
|
</el-icon>
|
||||||
})?.name
|
<span class="aLoad" @click="download(detailData.checkUrl)" target="_blank">
|
||||||
}}
|
{{ detailData.checkUrl?.replace(/^.*?\/(.*?)\//, '') || '' }}
|
||||||
|
</span>
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item :span="2" label="电能质量评估报告">
|
||||||
|
<el-icon class="elView" v-if="detailData?.assessUrl">
|
||||||
|
<View @click="openFile(detailData?.assessUrl)" />
|
||||||
|
</el-icon>
|
||||||
|
<span class="aLoad" @click="download(detailData.assessUrl)" target="_blank">
|
||||||
|
{{ detailData.assessUrl?.replace(/^.*?\/(.*?)\//, '') || '' }}
|
||||||
|
</span>
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
@@ -233,7 +242,7 @@ import { getDictTreeById } from '@/api/system-boot/dictTree'
|
|||||||
import { useDictData } from '@/stores/dictData'
|
import { useDictData } from '@/stores/dictData'
|
||||||
import { getFileNameAndFilePath } from '@/api/system-boot/file'
|
import { getFileNameAndFilePath } from '@/api/system-boot/file'
|
||||||
import { Link, View } from '@element-plus/icons-vue'
|
import { Link, View } from '@element-plus/icons-vue'
|
||||||
import PreviewFile from '@/components/PreviewFile/index.vue'
|
import { download } from '@/utils/fileDownLoad'
|
||||||
// import { addOrUpdateFile, getFileById } from '@/api/supervision-boot/interfere/index'
|
// import { addOrUpdateFile, getFileById } from '@/api/supervision-boot/interfere/index'
|
||||||
defineOptions({ name: 'BpmUserReportDetail' })
|
defineOptions({ name: 'BpmUserReportDetail' })
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="default-main">
|
<div class="default-main">
|
||||||
<TableHeader ref="TableHeaderRef">
|
<TableHeader ref="TableHeaderRef" showExport>
|
||||||
<template #select>
|
<template #select>
|
||||||
<el-form-item label="项目名称">
|
<el-form-item label="项目名称">
|
||||||
<el-input
|
<el-input
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
<el-button icon="el-icon-Upload" type="primary" @click="importUserData">批量导入</el-button> -->
|
<el-button icon="el-icon-Upload" type="primary" @click="importUserData">批量导入</el-button> -->
|
||||||
</template>
|
</template>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<Table ref="tableRef" />
|
<Table ref="tableRef" @cell-click="cellClickEvent" />
|
||||||
|
|
||||||
<el-dialog title="详情" width="1000px" v-model="dialogShow" v-if="dialogShow">
|
<el-dialog title="详情" width="1000px" v-model="dialogShow" v-if="dialogShow">
|
||||||
<DetailInfo :id="userId" :openType="'sourcesOfInterference'"></DetailInfo>
|
<DetailInfo :id="userId" :openType="'sourcesOfInterference'"></DetailInfo>
|
||||||
@@ -58,6 +58,7 @@ import { downloadSensitiveReportTemplate } from '@/api/supervision-boot/userRepo
|
|||||||
import DetailInfo from './components/detail.vue'
|
import DetailInfo from './components/detail.vue'
|
||||||
import { cancelFormData, getUserReportById } from '@/api/supervision-boot/interfere/index'
|
import { cancelFormData, getUserReportById } from '@/api/supervision-boot/interfere/index'
|
||||||
import { deleteUserReport } from '@/api/device-boot/sensitiveLoadMange'
|
import { deleteUserReport } from '@/api/device-boot/sensitiveLoadMange'
|
||||||
|
import { download } from '@/utils/fileDownLoad'
|
||||||
const addForms = ref()
|
const addForms = ref()
|
||||||
const dictData = useDictData()
|
const dictData = useDictData()
|
||||||
const sensitiveUserPopup = ref()
|
const sensitiveUserPopup = ref()
|
||||||
@@ -104,8 +105,26 @@ const tableStore = new TableStore({
|
|||||||
// { field: 'responsibleDepartment', title: '归口管理部门', minWidth: 130 },
|
// { field: 'responsibleDepartment', title: '归口管理部门', minWidth: 130 },
|
||||||
{ field: 'ratePower', title: '装机容量(MW)', minWidth: 80 },
|
{ field: 'ratePower', title: '装机容量(MW)', minWidth: 80 },
|
||||||
{ field: 'stationId', title: '所属电站', minWidth: 100 },
|
{ field: 'stationId', title: '所属电站', minWidth: 100 },
|
||||||
{ field: 'checkUrl', title: '电能质量设备检测报告', minWidth: 170 },
|
{
|
||||||
{ field: 'assessUrl', title: '电能质量评估报告', minWidth: 170 },
|
field: 'checkUrl',
|
||||||
|
title: '电能质量设备检测报告',
|
||||||
|
minWidth: 170,
|
||||||
|
render: 'customRender',
|
||||||
|
customRender: props => {
|
||||||
|
const val = props.renderValue?.replace(/^.*?\/(.*?)\//, '') || ''
|
||||||
|
return val ? h('span', { style: { color: 'var(--el-color-primary)', cursor: 'pointer' } }, val) : '/'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'assessUrl',
|
||||||
|
title: '电能质量评估报告',
|
||||||
|
minWidth: 170,
|
||||||
|
render: 'customRender',
|
||||||
|
customRender: props => {
|
||||||
|
const val = props.renderValue?.replace(/^.*?\/(.*?)\//, '') || ''
|
||||||
|
return val ? h('span', { style: { color: 'var(--el-color-primary)', cursor: 'pointer' } }, val) : '/'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/* {
|
/* {
|
||||||
field: 'createBy',
|
field: 'createBy',
|
||||||
@@ -116,7 +135,8 @@ const tableStore = new TableStore({
|
|||||||
}
|
}
|
||||||
},*/
|
},*/
|
||||||
{
|
{
|
||||||
title: '操作',fixed: 'right',
|
title: '操作',
|
||||||
|
fixed: 'right',
|
||||||
minWidth: 150,
|
minWidth: 150,
|
||||||
|
|
||||||
render: 'buttons',
|
render: 'buttons',
|
||||||
@@ -142,7 +162,6 @@ const tableStore = new TableStore({
|
|||||||
return !(row.status == 0)
|
return !(row.status == 0)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
click: row => {
|
click: row => {
|
||||||
addForms.value.filterUsers([6])
|
addForms.value.filterUsers([6])
|
||||||
|
|
||||||
@@ -151,9 +170,7 @@ const tableStore = new TableStore({
|
|||||||
row: row
|
row: row
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -212,27 +229,13 @@ const deleteEven = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**取消流程操作*/
|
// 点击行
|
||||||
const cancelLeave = async (row: any) => {
|
const cellClickEvent = ({ row, column }: any) => {
|
||||||
// 二次确认
|
if (column.field == 'checkUrl') {
|
||||||
const { value } = await ElMessageBox.prompt('请输入取消原因', '取消流程', {
|
row.checkUrl ? download(row.checkUrl) : ''
|
||||||
confirmButtonText: '确定',
|
} else if (column.field == 'assessUrl') {
|
||||||
cancelButtonText: '取消',
|
row.assessUrl ? download(row.assessUrl) : ''
|
||||||
inputType: 'textarea',
|
|
||||||
inputPattern: /^[\s\S]*.*\S[\s\S]*$/, // 判断非空,且非空格
|
|
||||||
inputErrorMessage: '取消原因不能为空'
|
|
||||||
})
|
|
||||||
// 发起取消
|
|
||||||
let data = {
|
|
||||||
id: row.id,
|
|
||||||
processInstanceId: row.processInstanceId,
|
|
||||||
dataType: 1,
|
|
||||||
reason: value
|
|
||||||
}
|
}
|
||||||
await cancelFormData(data)
|
|
||||||
ElMessage.success('取消成功')
|
|
||||||
// 加载数据
|
|
||||||
tableStore.index()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增
|
// 新增
|
||||||
|
|||||||
Reference in New Issue
Block a user