优化算法分类信号/点位折线图和其他逻辑

This commit is contained in:
weitang 2025-05-16 13:24:36 +08:00
parent 9fabff6be9
commit 14e10b9a59
10 changed files with 199 additions and 41 deletions

View File

@ -95,17 +95,4 @@ public class AlgorithmClassController {
} }
} }
@PostMapping("/callAlgorithmAnalyse")
@ApiOperation("调用算法分析")
public ResponseResult callAlgorithmAnalyse(String id) {
if (StrUtil.isBlank(id)) {
return ResponseResult.error("算法分类id为空");
}
boolean isOK = algorithmClassService.deleteAlgorithmClass(id);
if (isOK) {
return ResponseResult.success();
} else {
return ResponseResult.error();
}
}
} }

View File

@ -1,5 +1,7 @@
package com.yfd.platform.modules.algorithm.controller; package com.yfd.platform.modules.algorithm.controller;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.config.ResponseResult; import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.algorithm.domain.AlgorithmClass; import com.yfd.platform.modules.algorithm.domain.AlgorithmClass;
@ -37,11 +39,11 @@ public class AlgorithmParamsController {
return ResponseResult.successData(algorithmClassList); return ResponseResult.successData(algorithmClassList);
} }
@GetMapping("/getAlgorithmParamsNameList") @GetMapping("/getAlgorithmParamsNameList")
@ApiOperation("根据算法id过去参数名称") @ApiOperation("获取参数名称")
public ResponseResult getAlgorithmParamsNameList(String algorithmId) { public ResponseResult getAlgorithmParamsNameList(String algorithmId, String componentId) {
List<Map<String, Object>> algorithmClassList = algorithmParamsService.getAlgorithmParamsNameList(algorithmId); List<Map<String, Object>> algorithmClassList = algorithmParamsService.getAlgorithmParamsNameList(algorithmId,
componentId);
return ResponseResult.successData(algorithmClassList); return ResponseResult.successData(algorithmClassList);
} }
@ -88,4 +90,14 @@ public class AlgorithmParamsController {
return ResponseResult.error(); return ResponseResult.error();
} }
} }
@PostMapping("/callAlgorithmAnalyse")
@ApiOperation("调用算法分析")
public ResponseResult callAlgorithmAnalyse(String id,String componentId) {
if (StrUtil.isBlank(id)) {
return ResponseResult.error("算法分类id为空");
}
JSONObject data = algorithmParamsService.callAlgorithmAnalyse(id, componentId);
return ResponseResult.successData(data);
}
} }

View File

@ -18,5 +18,5 @@ public interface AlgorithmParamsMapper extends BaseMapper<AlgorithmParams> {
List<Map<String, Object>> getAlgorithmParamsList(String algorithmId,String componentId); List<Map<String, Object>> getAlgorithmParamsList(String algorithmId,String componentId);
List<Map<String, Object>> getAlgorithmParamsNameList(String algorithmId); List<Map<String, Object>> getAlgorithmParamsNameList(String algorithmId,String componentId);
} }

View File

@ -1,5 +1,6 @@
package com.yfd.platform.modules.algorithm.service; package com.yfd.platform.modules.algorithm.service;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.modules.algorithm.domain.AlgorithmParams; import com.yfd.platform.modules.algorithm.domain.AlgorithmParams;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
@ -27,5 +28,8 @@ public interface IAlgorithmParamsService extends IService<AlgorithmParams> {
boolean deleteAlgorithmParams(String id); boolean deleteAlgorithmParams(String id);
List<Map<String, Object>> getAlgorithmParamsNameList(String algorithmId); List<Map<String, Object>> getAlgorithmParamsNameList(String algorithmId,String componentId);
JSONObject callAlgorithmAnalyse(String id, String componentId);
} }

View File

@ -1,5 +1,6 @@
package com.yfd.platform.modules.algorithm.service.impl; package com.yfd.platform.modules.algorithm.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -11,17 +12,20 @@ import com.yfd.platform.modules.auxcontrol.domain.DeviceSignal;
import com.yfd.platform.modules.auxcontrol.domain.DeviceWorkData; import com.yfd.platform.modules.auxcontrol.domain.DeviceWorkData;
import com.yfd.platform.modules.auxcontrol.mapper.DeviceSignalMapper; import com.yfd.platform.modules.auxcontrol.mapper.DeviceSignalMapper;
import com.yfd.platform.modules.auxcontrol.service.IDeviceWorkDataService; import com.yfd.platform.modules.auxcontrol.service.IDeviceWorkDataService;
import com.yfd.platform.modules.basedata.domain.SubstationDevice;
import com.yfd.platform.modules.basedata.mapper.SubstationDeviceMapper;
import com.yfd.platform.modules.patroltask.domain.TaskResult;
import com.yfd.platform.modules.patroltask.mapper.TaskResultMapper;
import com.yfd.platform.utils.SecurityUtils; import com.yfd.platform.utils.SecurityUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -41,6 +45,10 @@ public class AlgorithmDeviceServiceImpl extends ServiceImpl<AlgorithmDeviceMappe
private DeviceSignalMapper deviceSignalMapper; private DeviceSignalMapper deviceSignalMapper;
@Resource @Resource
private IDeviceWorkDataService deviceWorkDataService; private IDeviceWorkDataService deviceWorkDataService;
@Resource
private TaskResultMapper taskResultMapper;
@Resource
private SubstationDeviceMapper substationDeviceMapper;
/********************************** /**********************************
* 用途说明: 批量新增算法分类部件点位关联数据 * 用途说明: 批量新增算法分类部件点位关联数据
@ -79,15 +87,23 @@ public class AlgorithmDeviceServiceImpl extends ServiceImpl<AlgorithmDeviceMappe
List<String> deviceIdList = groupedDevices.get("1"); List<String> deviceIdList = groupedDevices.get("1");
List<String> signalIdList = groupedDevices.get("2"); List<String> signalIdList = groupedDevices.get("2");
if (deviceIdList != null && deviceIdList.size() > 0) { if (deviceIdList != null && deviceIdList.size() > 0) {
List<TaskResult> deviceWorkDataList = taskResultMapper.getResultCurveData(deviceIdList);
Map<String, List<TaskResult>> collect =
deviceWorkDataList.stream().collect(Collectors.groupingBy(TaskResult::getDeviceId));
for (String deviceId : collect.keySet()) {
List<TaskResult> taskResults = collect.get(deviceId);
Map<String, Object> map = processDeviceData(taskResults, deviceId);
deviceDataList.add(map);
}
} }
if (signalIdList != null && signalIdList.size() > 0) { if (signalIdList != null && signalIdList.size() > 0) {
List<DeviceWorkData> deviceWorkDataList = deviceWorkDataService.getHistoricalCurveList(signalIdList); List<DeviceWorkData> deviceWorkDataList = deviceWorkDataService.getHistoricalCurveList(signalIdList);
Map<String, List<DeviceWorkData>> collect = Map<String, List<DeviceWorkData>> collect =
deviceWorkDataList.stream().collect(Collectors.groupingBy(DeviceWorkData::getSignalId)); deviceWorkDataList.stream().collect(Collectors.groupingBy(DeviceWorkData::getSignalId));
for (String signalId : collect.keySet()) { for (String signalId : collect.keySet()) {
List<DeviceWorkData> deviceWorkDataGroup = collect.get(signalId); List<DeviceWorkData> deviceWorkDataGroup = collect.get(signalId);
Map<String, Object> map = processDeviceData(deviceWorkDataGroup, signalId); Map<String, Object> map = processSignalData(deviceWorkDataGroup, signalId);
deviceDataList.add(map); deviceDataList.add(map);
} }
@ -96,7 +112,13 @@ public class AlgorithmDeviceServiceImpl extends ServiceImpl<AlgorithmDeviceMappe
return deviceDataList; return deviceDataList;
} }
public Map<String, Object> processDeviceData(List<DeviceWorkData> deviceWorkDataList, String signalId) { /**********************************
* 用途说明: 绘制信号ECharts折线图
* 参数说明 deviceWorkDataList 信号数据
* 参数说明 signalId 信号id
* 返回值说明: java.util.Map<java.lang.String,java.lang.Object>
***********************************/
public Map<String, Object> processSignalData(List<DeviceWorkData> deviceWorkDataList, String signalId) {
// 生成过去60分钟的分钟时间槽 // 生成过去60分钟的分钟时间槽
LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES); LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES);
LocalDateTime startTime = now.minusMinutes(59); LocalDateTime startTime = now.minusMinutes(59);
@ -153,4 +175,96 @@ public class AlgorithmDeviceServiceImpl extends ServiceImpl<AlgorithmDeviceMappe
return result; return result;
} }
/**********************************
* 用途说明: 绘制点位ECharts折线图
* 参数说明 taskResults 点位数据
* 参数说明 deviceId 点位id
* 返回值说明: java.util.Map<java.lang.String,java.lang.Object>
***********************************/
public Map<String, Object> processDeviceData(List<TaskResult> taskResults, String deviceId) {
// 定义时间格式解析器
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 预处理过滤无效数据并解析时间
List<ProcessedData> processedList = new ArrayList<>();
for (TaskResult result : taskResults) {
try {
// 解析时间字符串为LocalDateTime仅用于排序
LocalDateTime dateTime = LocalDateTime.parse(result.getPatroldeviceDate(), formatter);
// 解析数值
double value;
try {
value = NumberUtil.parseDouble(result.getValue());
} catch (Exception e) {
// 非数值处理为0
value = 0.0;
}
processedList.add(new ProcessedData(
result.getPatroldeviceDate(),
value,
dateTime
));
} catch (DateTimeParseException e) {
// 时间解析失败时跳过此条记录
System.err.println("Invalid date format: " + result.getPatroldeviceDate());
}
}
// 按时间排序基于解析后的LocalDateTime
processedList.sort(Comparator.comparing(ProcessedData::getDateTime));
// 构建ECharts数据结构
Map<String, Object> result = new LinkedHashMap<>();
Map<String, Object> xAxis = new LinkedHashMap<>();
xAxis.put("type", "category"); // 关键变化点
xAxis.put("data", processedList.stream()
.map(ProcessedData::getOriginalDate) // 直接使用原始字符串
.collect(Collectors.toList()));
result.put("xAxis", xAxis);
Map<String, Object> yAxis = new HashMap<>();
yAxis.put("type", "value");
result.put("yAxis", yAxis);
List<Double> seriesData = processedList.stream()
.map(ProcessedData::getValue)
.collect(Collectors.toList());
SubstationDevice substationDevice = substationDeviceMapper.selectById(deviceId);
String name = substationDevice == null ? "" : substationDevice.getDeviceName();
Map<String, Object> series = new LinkedHashMap<>();
series.put("name", name);
series.put("type", "line");
series.put("data", seriesData); // 直接对应xAxis.data的顺序
result.put("series", Collections.singletonList(series));
return result;
}
private static class ProcessedData {
// 原始时间字符串用于最终展示
private final String originalDate;
private final double value;
// 仅用于排序
private final LocalDateTime dateTime;
public ProcessedData(String originalDate, double value, LocalDateTime dateTime) {
this.originalDate = originalDate;
this.value = value;
this.dateTime = dateTime;
}
public String getOriginalDate() { return originalDate; }
public double getValue() { return value; }
public LocalDateTime getDateTime() { return dateTime; }
}
} }

View File

@ -1,7 +1,9 @@
package com.yfd.platform.modules.algorithm.service.impl; package com.yfd.platform.modules.algorithm.service.impl;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.modules.algorithm.domain.AlgorithmParams; import com.yfd.platform.modules.algorithm.domain.AlgorithmParams;
import com.yfd.platform.modules.algorithm.mapper.AlgorithmDeviceMapper;
import com.yfd.platform.modules.algorithm.mapper.AlgorithmParamsMapper; import com.yfd.platform.modules.algorithm.mapper.AlgorithmParamsMapper;
import com.yfd.platform.modules.algorithm.service.IAlgorithmParamsService; import com.yfd.platform.modules.algorithm.service.IAlgorithmParamsService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -23,6 +25,8 @@ public class AlgorithmParamsServiceImpl extends ServiceImpl<AlgorithmParamsMappe
@Resource @Resource
private AlgorithmParamsMapper algorithmParamsMapper; private AlgorithmParamsMapper algorithmParamsMapper;
@Resource
private AlgorithmDeviceMapper algorithmDeviceMapper;
@Override @Override
public List<Map<String, Object>> getAlgorithmParamsList(String algorithmId, String componentId) { public List<Map<String, Object>> getAlgorithmParamsList(String algorithmId, String componentId) {
@ -50,7 +54,13 @@ public class AlgorithmParamsServiceImpl extends ServiceImpl<AlgorithmParamsMappe
} }
@Override @Override
public List<Map<String, Object>> getAlgorithmParamsNameList(String algorithmId) { public List<Map<String, Object>> getAlgorithmParamsNameList(String algorithmId, String componentId) {
return algorithmParamsMapper.getAlgorithmParamsNameList(algorithmId); return algorithmParamsMapper.getAlgorithmParamsNameList(algorithmId, componentId);
}
@Override
public JSONObject callAlgorithmAnalyse(String id, String componentId) {
return null;
} }
} }

View File

@ -210,4 +210,6 @@ public interface TaskResultMapper extends BaseMapper<TaskResult> {
List<TaskResult> getNonCoherentResult(String areaId,String bayId,String mainDeviceId,String componentId,String recognitionTypeList,String meterType,String resultId,String taskTodoId,String phase); List<TaskResult> getNonCoherentResult(String areaId,String bayId,String mainDeviceId,String componentId,String recognitionTypeList,String meterType,String resultId,String taskTodoId,String phase);
Page<Map<String, Object>> getHistoryDevice(Page<Map<String, Object>> page, String startDate, String endDate, String deviceId); Page<Map<String, Object>> getHistoryDevice(Page<Map<String, Object>> page, String startDate, String endDate, String deviceId);
List<TaskResult> getResultCurveData(List<String> deviceIdList);
} }

View File

@ -14,10 +14,10 @@
WHERE WHERE
ap.param_fixed = '1' ap.param_fixed = '1'
<if test="algorithmId != null and algorithmId != ''"> <if test="algorithmId != null and algorithmId != ''">
AND ad.algorithm_id LIKE CONCAT('%',#{algorithmId},'%') AND ad.algorithm_id = #{algorithmId}
</if> </if>
<if test="componentId != null and componentId != ''"> <if test="componentId != null and componentId != ''">
AND ad.component_id LIKE CONCAT('%',#{componentId},'%') AND ad.component_id =#{componentId}
</if> </if>
</select> </select>
<select id="getAlgorithmDeviceType" resultType="java.util.Map"> <select id="getAlgorithmDeviceType" resultType="java.util.Map">
@ -30,10 +30,10 @@
WHERE WHERE
ap.param_fixed = '0' ap.param_fixed = '0'
<if test="algorithmId != null and algorithmId != ''"> <if test="algorithmId != null and algorithmId != ''">
AND ad.algorithm_id LIKE CONCAT('%',#{algorithmId},'%') AND ad.algorithm_id =#{algorithmId}
</if> </if>
<if test="componentId != null and componentId != ''"> <if test="componentId != null and componentId != ''">
AND ad.component_id LIKE CONCAT('%',#{componentId},'%') AND ad.component_id =#{componentId}
</if> </if>
</select> </select>
</mapper> </mapper>

View File

@ -34,15 +34,20 @@
</select> </select>
<select id="getAlgorithmParamsNameList" resultType="java.util.Map"> <select id="getAlgorithmParamsNameList" resultType="java.util.Map">
SELECT SELECT
id, ap.param_unit,
param_name, ap.param_name,
param_type, ap.id
param_unit
FROM FROM
iis_algorithm_params iis_algorithm_params ap
WHERE 1=1 LEFT JOIN iis_algorithm_device ad
ON ap.id = ad.param_id
<!-- 动态添加 component_id 匹配条件 -->
<if test="componentId != null and componentId != ''">
AND ad.component_id = #{componentId}
</if>
WHERE 1=1 AND ap.param_fixed='0'
<if test="algorithmId != null and algorithmId != ''"> <if test="algorithmId != null and algorithmId != ''">
AND algorithm_id = #{algorithmId} AND ap.algorithm_id = #{algorithmId}
</if> </if>
</select> </select>
</mapper> </mapper>

View File

@ -911,4 +911,28 @@ ORDER BY
AND t.patroldevice_date &lt;= #{endDate} AND t.patroldevice_date &lt;= #{endDate}
</if> </if>
</select> </select>
<select id="getResultCurveData" resultType="com.yfd.platform.modules.patroltask.domain.TaskResult">
SELECT
device_id,
value,
patroldevice_date
FROM (
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY device_id
ORDER BY patroldevice_date DESC
) AS row_num
FROM iis_task_result
WHERE flag='2' AND device_id IN
<foreach collection="deviceIdList" item="deviceId" open="(" separator=","
close=")">
#{deviceId}
</foreach>
) AS ranked
WHERE row_num &lt;= 60
ORDER BY device_id, patroldevice_date DESC;
</select>
</mapper> </mapper>