From 4ade32744e791b3b5f8bc55eed46e4e4b9a8a4f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=B7=E6=88=90=E4=BC=9F?= Date: Thu, 28 Nov 2024 13:44:24 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E5=80=BC=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../calc/functions/FunctionGetCacheValue.java | 65 +++++++++++++++++++ .../com/das/modules/calc/service/CalcJob.java | 2 + .../das/modules/calc/service/CalcService.java | 4 ++ 3 files changed, 71 insertions(+) create mode 100644 das/src/main/java/com/das/modules/calc/functions/FunctionGetCacheValue.java diff --git a/das/src/main/java/com/das/modules/calc/functions/FunctionGetCacheValue.java b/das/src/main/java/com/das/modules/calc/functions/FunctionGetCacheValue.java new file mode 100644 index 00000000..149a517e --- /dev/null +++ b/das/src/main/java/com/das/modules/calc/functions/FunctionGetCacheValue.java @@ -0,0 +1,65 @@ +package com.das.modules.calc.functions; + +import com.das.common.utils.AdminRedisTemplate; +import com.das.modules.cache.domain.DeviceInfoCache; +import com.das.modules.cache.service.CacheService; +import com.das.modules.data.domain.SnapshotValueQueryParam; +import com.das.modules.data.service.DataService; +import com.googlecode.aviator.exception.StandardError; +import com.googlecode.aviator.runtime.function.AbstractFunction; +import com.googlecode.aviator.runtime.type.AviatorNil; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorRuntimeJavaType; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Aviator扩展函数 - 获取设备实时数据 + * 函数格式: cacheValue(key, value) 设置缓存值 + * 函数格式: cacheValue(key) 读取缓存值 + */ +@Slf4j +public class FunctionGetCacheValue extends AbstractFunction { + private ConcurrentHashMap cacheValues = new ConcurrentHashMap<>(); + public FunctionGetCacheValue( ) { + } + + @Override + public String getName() { + return "cacheValue"; + } + + @SneakyThrows + @Override + public AviatorObject call(Map env, AviatorObject keyData, AviatorObject valData) { + //设备Code + String key = (String)keyData.getValue(env); + Double value = (Double) valData.getValue(env); + String scriptName = (String)env.get("G_SCRIPTNAME"); + + String cacheKey = String.format("%s_%s", scriptName, key); + cacheValues.put(cacheKey, value); + + return AviatorRuntimeJavaType.valueOf(0); + } + + @Override + public AviatorObject call(Map env, AviatorObject keyData) { + //设备Code + String key = (String)keyData.getValue(env); + String scriptName = (String)env.get("G_SCRIPTNAME"); + + String cacheKey = String.format("%s_%s", scriptName, key); + Double value = cacheValues.get(cacheKey); + if (value == null) { + return AviatorNil.NIL; + } + + return AviatorRuntimeJavaType.valueOf(value); + } +} diff --git a/das/src/main/java/com/das/modules/calc/service/CalcJob.java b/das/src/main/java/com/das/modules/calc/service/CalcJob.java index bb7ace25..2596592d 100644 --- a/das/src/main/java/com/das/modules/calc/service/CalcJob.java +++ b/das/src/main/java/com/das/modules/calc/service/CalcJob.java @@ -38,6 +38,8 @@ public class CalcJob implements Job { } //准备全局变量 Map envs = expression.newEnv(); + //脚本名称 + envs.put("G_SCRIPTNAME", calcModule.getName()); //风场信息 envs.put("G_WF", cacheService.getEquipmentCache().getDevicesCache().stream().filter(c->c.getObjectType().equals(10001)).findFirst().get()); //风机信息 diff --git a/das/src/main/java/com/das/modules/calc/service/CalcService.java b/das/src/main/java/com/das/modules/calc/service/CalcService.java index 377aab03..395c68c5 100644 --- a/das/src/main/java/com/das/modules/calc/service/CalcService.java +++ b/das/src/main/java/com/das/modules/calc/service/CalcService.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.das.modules.cache.service.CacheService; import com.das.modules.calc.domain.entity.CalcModule; import com.das.modules.calc.domain.vo.CalcModuleVo; +import com.das.modules.calc.functions.FunctionGetCacheValue; import com.das.modules.calc.functions.FunctionRealData; import com.das.modules.calc.functions.FunctionSaveCalcData; import com.das.modules.calc.mapper.CalcModuleMapper; @@ -110,6 +111,9 @@ public class CalcService { // FunctionSaveCalcData save = new FunctionSaveCalcData(dataService, cacheService); aviator.addFunction(save); + + FunctionGetCacheValue cache = new FunctionGetCacheValue(); + aviator.addFunction(cache); } /** From 53dd7333d585012f5cfbf27218f443d03557c326 Mon Sep 17 00:00:00 2001 From: geting <13585118195@163.com> Date: Thu, 28 Nov 2024 14:09:36 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E5=88=86=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/statAnalysis/trendAnalysis.vue | 42 +- .../backend/statAnalysis/trendComparison.vue | 415 ++++++++++-------- 2 files changed, 269 insertions(+), 188 deletions(-) diff --git a/ui/dasadmin/src/views/backend/statAnalysis/trendAnalysis.vue b/ui/dasadmin/src/views/backend/statAnalysis/trendAnalysis.vue index ccd2e7c8..680641b9 100644 --- a/ui/dasadmin/src/views/backend/statAnalysis/trendAnalysis.vue +++ b/ui/dasadmin/src/views/backend/statAnalysis/trendAnalysis.vue @@ -111,6 +111,7 @@ const statAnalysisSelect = reactive({ attributeCode: '', interval: '', time: '', + unit: '', }) const getFormattedDate = (offset: number) => { const date = new Date() @@ -123,7 +124,7 @@ const getFormattedDate = (offset: number) => { const times: any = reactive([[getFormattedDate(0) + ' 00:00:00', getFormattedDate(0) + ' 23:59:59']]) const addTime = () => { if (times.length < 4) { - times.push([getFormattedDate(times.length) + ' 00:00:00', getFormattedDate(times.length) + ' 23:59:59']) + times.push([getFormattedDate(-times.length) + ' 00:00:00', getFormattedDate(-times.length) + ' 23:59:59']) customName.push(statAnalysisSelect.attributes + String(times.length)) } else { ElMessage.info('最多可添加四条查询曲线!') @@ -161,21 +162,27 @@ const attributesChange = () => { const deviceIdChange = () => { statAnalysisSelect.attributes = '' statAnalysisSelect.attributeCode = '' + statAnalysisSelect.unit = '' } const showMeasure = ref(false) const selectedAttrRow: any = ref({ attributeCode: '', attributeName: '', + unit: '', }) const handleRadioChange = (value: any) => { - const { attributeCode, attributeName } = { ...value } + console.log('🚀 ~ handleRadioChange ~ value:', value) + const { attributeCode, attributeName, unit } = { ...value } selectedAttrRow.attributeCode = attributeCode selectedAttrRow.attributeName = attributeName + selectedAttrRow.unit = unit } const selectstatAnalysisAttributes = () => { statAnalysisSelect.attributes = selectedAttrRow.attributeName + console.log('🚀 ~ selectstatAnalysisAttributes ~ selectedAttrRow:', selectedAttrRow) statAnalysisSelect.attributeCode = selectedAttrRow.attributeCode + statAnalysisSelect.unit = selectedAttrRow.unit showMeasure.value = false customName.forEach((item: any, index: number, arr: any) => { arr[index] = statAnalysisSelect.attributes + String(index + 1) @@ -343,6 +350,8 @@ const calculate: any = ref([{ max: '', min: '', average: '' }]) var xDatas: any = [] const isLoading = ref(false) const statAnalysisOperate = () => { + console.log('🚀 ~ findTime ~ times:', times) + const findTime = times.filter((item: any) => { return Array.isArray(item) }) @@ -355,6 +364,9 @@ const statAnalysisOperate = () => { } else if (!findTime.length) { ElMessage.info('请选择查询时间!') return + } else if (hasDuplicateArrays(times)) { + ElMessage.info('存在相同的查询时间!') + return } isLoading.value = true option.series = [] @@ -363,8 +375,10 @@ const statAnalysisOperate = () => { calculate.value = [] chart.value.setOption(option, { notMerge: true }) const promises: any = [] + times.forEach((time: any, index: number) => { - if (time[0] && time[1]) { + console.log('🚀 ~ times.forEach ~ time:', time) + if (time && time[0] && time[1]) { const requestData = { devices: [ { @@ -415,7 +429,6 @@ const historyDataReq = (promises: any) => { const fillData = fillMissingData(alltimes, resData) const xData = fillData['times'] const yData = fillData['values'] - // calculate.value[index] = calculateStats(resData['values']) xDatas.push({ series: String(customName[index]), data: xData, @@ -428,7 +441,7 @@ const historyDataReq = (promises: any) => { .map((item: any) => { const matchData = xDatas.filter((x: any) => x.series == item.seriesName) const x = timestampToTime(matchData[0]['data'][item.dataIndex]) - return `${item.marker}${item.seriesName} (${x}): ${item.data}` + return `${item.marker}${item.seriesName} (${x}): ${item.data}${statAnalysisSelect.unit}` }) .join('
') }, @@ -484,17 +497,16 @@ const statAnalysisExport = () => { }) } -function calculateStats(numbers: any) { - const max = Math.max(...numbers) - const min = Math.min(...numbers) - const sum = numbers.reduce((acc: number, current: number) => acc + current, 0) - const average = sum / numbers.length - - return { - max: max.toFixed(2), - min: min.toFixed(2), - average: average.toFixed(2), +const hasDuplicateArrays = (arr: any) => { + const seen = new Set() + for (let subArray of arr) { + const subArrayStr = JSON.stringify(subArray) + if (seen.has(subArrayStr)) { + return true + } + seen.add(subArrayStr) } + return false } const getTimestamps = (start: any, end: any, interval: any) => { diff --git a/ui/dasadmin/src/views/backend/statAnalysis/trendComparison.vue b/ui/dasadmin/src/views/backend/statAnalysis/trendComparison.vue index c26dadfd..27f3457b 100644 --- a/ui/dasadmin/src/views/backend/statAnalysis/trendComparison.vue +++ b/ui/dasadmin/src/views/backend/statAnalysis/trendComparison.vue @@ -20,7 +20,7 @@ - 增加 + 测点选择
{{ t('statAnalysis.search') }} @@ -28,69 +28,82 @@
-
-
-
-
-
- - - -
- 名称 - - {{ t('statAnalysis.deviceId') }} - - - -
-
- {{ t('statAnalysis.attributes') }} - -
-
-
-
-
-
-
-
-
+
- - +
- + + +
+
+ 风机列表 +
+
+ + + + + + + + +
+
+
+ +
+
+ 可添加的测点 + + 模拟量 + 计算量 + 状态量 + +
+
+ + + + + + +
+
+ +
+
+
+