dev #2

Merged
dashixiong merged 349 commits from dev into main 2026-02-11 01:55:46 +00:00
238 changed files with 26750 additions and 1003 deletions
Showing only changes of commit 8954329ccc - Show all commits

View File

@ -9,6 +9,7 @@ import com.xzzn.common.utils.file.MimeTypeUtils;
import com.xzzn.ems.domain.EmsDevicesSetting;
import com.xzzn.ems.domain.EmsPointMatch;
import com.xzzn.ems.domain.EmsSiteSetting;
import com.xzzn.ems.domain.vo.PointQueryResponse;
import com.xzzn.ems.domain.vo.SiteDeviceListVo;
import com.xzzn.ems.mapper.EmsPointMatchMapper;
import com.xzzn.ems.service.IEmsDeviceSettingService;
@ -145,10 +146,9 @@ public class EmsSiteConfigController extends BaseController{
* 单个站点单个设备点位查询
*/
@GetMapping("/getDevicePointList")
public TableDataInfo getDevicePointList(@RequestParam String siteId,@RequestParam String deviceCategory)
public TableDataInfo getDevicePointList(@RequestParam String siteId,@RequestParam String deviceId,@RequestParam String deviceCategory)
{
startPage();
List<EmsPointMatch> pointList = emsPointMatchMapper.getSingleSiteDevicePoints(siteId,deviceCategory);
return getDataTable(pointList);
List<PointQueryResponse> result = iEmsDeviceSettingService.getSingleSiteDevicePoints(siteId,deviceId,deviceCategory);
return getDataTable2(result);
}
}

View File

@ -51,4 +51,9 @@ public class RedisKeyConstants
* BMSD原始数据 redis key
*/
public static final String ORIGINAL_BMSD = "BMSD_";
/**
* 存放单个设备同步过来的原始数据
*/
public static final String ORIGINAL_MQTT_DATA = "MQTT_";
}

View File

@ -208,28 +208,42 @@ public class BaseController
@SuppressWarnings({ "rawtypes", "unchecked" })
protected TableDataInfo getDataTable2(List<?> list)
{
List<?> subList = new ArrayList<>();
// 分页梳理
// 1. 处理原列表为null的情况避免空指针
List<?> targetList = (list == null) ? Collections.emptyList() : list;
List<?> subList;
// 2. 获取分页参数
PageDomain pageDomain = TableSupport.buildPageRequest();
int pageNum = pageDomain.getPageNum();
int pageSize = pageDomain.getPageSize();
// 3. 判断分页参数是否有效pageNum和pageSize均为正数时才分页
if (pageNum > 0 && pageSize > 0) {
// 计算分页起始和结束索引
int startIndex = (pageNum - 1) * pageSize;
int endIndex = Math.min(startIndex + pageSize, list.size());
// 防止越界
if (startIndex >= list.size()) {
subList = Collections.emptyList();
// 计算起始索引确保不小于0
int startIndex = Math.max((pageNum - 1) * pageSize, 0);
// 关键修复:若起始索引已超出列表大小,直接返回空列表
if (startIndex >= targetList.size()) {
subList = Collections.emptyList();
} else {
// 计算结束索引(不超过列表大小,且不小于起始索引)
int endIndex = Math.min(startIndex + pageSize, targetList.size());
endIndex = Math.max(endIndex, startIndex); // 防止endIndex < startIndex
// 截取子列表转换为新ArrayList避免视图依赖
subList = new ArrayList<>(targetList.subList(startIndex, endIndex));
}
// 截取当前页数据
subList = list.subList(startIndex, endIndex);
} else {
// 分页参数无效时,返回全部数据
subList = new ArrayList<>(targetList);
}
// 4. 封装返回结果
TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS);
rspData.setMsg("查询成功");
rspData.setRows(subList);
rspData.setTotal(list.size());
rspData.setTotal(targetList.size());
return rspData;
}

View File

@ -0,0 +1,96 @@
package com.xzzn.ems.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xzzn.common.annotation.Excel;
import java.util.Date;
/**
* 设备列表-点位详情返回
*/
public class PointQueryResponse
{
/** 点位名称 */
@Excel(name = "点位名称")
private String pointName;
/** 数据点位 */
@Excel(name = "数据点位")
private String dataPoint;
/** 数据点位名称 */
@Excel(name = "数据点位名称")
private String dataPointName;
/** 数据点位来源设备 */
@Excel(name = "数据点位来源设备")
private String dataDevice;
/** 数据点位来源设备 */
@Excel(name = "点位最新数据")
private Object pointValue;
/** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/** 点位是否需要匹配多设备 */
@Excel(name = "点位最新数据")
private int isNeedDeviceId;
public int getIsNeedDeviceId() {
return isNeedDeviceId;
}
public void setIsNeedDeviceId(int isNeedDeviceId) {
this.isNeedDeviceId = isNeedDeviceId;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Object getPointValue() {
return pointValue;
}
public void setPointValue(Object pointValue) {
this.pointValue = pointValue;
}
public String getDataDevice() {
return dataDevice;
}
public void setDataDevice(String dataDevice) {
this.dataDevice = dataDevice;
}
public String getDataPointName() {
return dataPointName;
}
public void setDataPointName(String dataPointName) {
this.dataPointName = dataPointName;
}
public String getDataPoint() {
return dataPoint;
}
public void setDataPoint(String dataPoint) {
this.dataPoint = dataPoint;
}
public String getPointName() {
return pointName;
}
public void setPointName(String pointName) {
this.pointName = pointName;
}
}

View File

@ -6,6 +6,7 @@ import java.util.Map;
import com.xzzn.ems.domain.EmsPointMatch;
import com.xzzn.ems.domain.vo.GeneralQueryDataVo;
import com.xzzn.ems.domain.vo.PointQueryResponse;
import org.apache.ibatis.annotations.Param;
/**
@ -118,5 +119,5 @@ public interface EmsPointMatchMapper
@Param("deviceId")String deviceId);
// 单个站点单个设备点位查询
public List<EmsPointMatch> getSingleSiteDevicePoints(@Param("siteId")String siteId, @Param("deviceCategory")String deviceCategory);
public List<PointQueryResponse> getSingleSiteDevicePoints(@Param("siteId")String siteId, @Param("deviceCategory")String deviceCategory);
}

View File

@ -2,6 +2,8 @@ package com.xzzn.ems.service;
import com.xzzn.common.enums.DeviceCategory;
import com.xzzn.ems.domain.EmsDevicesSetting;
import com.xzzn.ems.domain.EmsPointMatch;
import com.xzzn.ems.domain.vo.PointQueryResponse;
import java.util.List;
@ -21,4 +23,6 @@ public interface IEmsDeviceSettingService
public int deleteEmsDevicesSettingById(Long id);
public List<DeviceCategory> getDeviceCategory();
public List<PointQueryResponse> getSingleSiteDevicePoints(String siteId, String deviceId, String deviceCategory);
}

View File

@ -92,6 +92,9 @@ public class DDSDataProcessServiceImpl extends AbstractBatteryDataProcessor impl
return;
}
// 存放mqtt原始每个设备数据便于后面点位获取数据
redisCache.setCacheObject(RedisKeyConstants.ORIGINAL_MQTT_DATA + SITE_ID + "_" + deviceId, obj);
// 处理相关数据
if (deviceId.contains("BMSD")) {
batteryStackDataProcess(deviceId, jsonData);

View File

@ -1,16 +1,22 @@
package com.xzzn.ems.service.impl;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.xzzn.common.constant.RedisKeyConstants;
import com.xzzn.common.core.redis.RedisCache;
import com.xzzn.common.enums.DeviceCategory;
import com.xzzn.common.utils.DateUtils;
import com.xzzn.common.utils.StringUtils;
import com.xzzn.ems.domain.EmsDevicesSetting;
import com.xzzn.ems.domain.vo.PointQueryResponse;
import com.xzzn.ems.mapper.EmsDevicesSettingMapper;
import com.xzzn.ems.mapper.EmsPointMatchMapper;
import com.xzzn.ems.service.IEmsDeviceSettingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
import java.util.*;
/**
* 站点信息 服务层实现
@ -19,9 +25,14 @@ import java.util.List;
@Service
public class EmsDeviceSettingServiceImpl implements IEmsDeviceSettingService
{
private static final String DDS_SITE_ID = "021_DDS_01";
@Autowired
private EmsDevicesSettingMapper emsDevicesMapper;
@Autowired
private EmsPointMatchMapper emsPointMatchMapper;
@Autowired
private RedisCache redisCache;
/**
* 获取设备详细信息
* @param id
@ -106,4 +117,100 @@ public class EmsDeviceSettingServiceImpl implements IEmsDeviceSettingService
List<DeviceCategory> deviceList = Arrays.asList(DeviceCategory.values());
return deviceList;
}
@Override
public List<PointQueryResponse> getSingleSiteDevicePoints(String siteId, String deviceId, String deviceCategory) {
List<PointQueryResponse> response = emsPointMatchMapper.getSingleSiteDevicePoints(siteId,deviceCategory);
// 电动所的电池簇特殊处理-来源pcs+bmsd
if (siteId.equals(DDS_SITE_ID) && DeviceCategory.CLUSTER.getCode().equals(deviceCategory)) {
response = specialDealWithDDSCluster(response,siteId,deviceId);
return response;
}
// 从redis取最新数据
//String test = redisCache.getCacheObject(RedisKeyConstants.ORIGINAL_MQTT_DATA + siteId + "_" + deviceId);
JSONObject mqttJson = redisCache.getCacheObject(RedisKeyConstants.ORIGINAL_MQTT_DATA + siteId + "_" + deviceId);
if(mqttJson == null){
return response;
}
String deviceFromMqtt = mqttJson.get("Device").toString();
String jsonData = mqttJson.get("Data").toString();
if (StringUtils.isEmpty(jsonData) || !deviceId.equals(deviceFromMqtt)) {
return response;
}
Map<String, Object> obj = JSON.parseObject(jsonData, new TypeReference<Map<String, Object>>() {});
for (PointQueryResponse pointInfo : response) {
String dataKey = pointInfo.getDataPoint();
int isNeedDeviceId = pointInfo.getIsNeedDeviceId();
if (isNeedDeviceId == 1) {// 需要根据deviceId拼接point
dataKey = deviceId + dataKey;
pointInfo.setDataPoint(dataKey);
}
pointInfo.setPointValue(obj.get(dataKey));
Long updateTime = Long.valueOf(mqttJson.get("timestamp").toString());
Date latestUpdateTime = convertUpdateTime(updateTime);
pointInfo.setUpdateTime(latestUpdateTime);
}
return response;
}
// 对于dds的电池簇点位最新数据获取特殊处理
private List<PointQueryResponse> specialDealWithDDSCluster(List<PointQueryResponse> response, String siteId, String deviceId) {
JSONObject mergedData = new JSONObject();
// 数据来源pcs
JSONObject pcsJson = redisCache.getCacheObject(RedisKeyConstants.ORIGINAL_MQTT_DATA + siteId + "_PCS");
if (pcsJson != null) {
JSONObject data = pcsJson.getJSONObject("Data");
mergedData.putAll(data);
}
// 根据deviceId获取父类bmsd
String bmsdDeviceId = deviceId.replace("BMSC","BMSD");
JSONObject bmsdJson = redisCache.getCacheObject(RedisKeyConstants.ORIGINAL_MQTT_DATA + siteId + "_" + bmsdDeviceId);
if (bmsdJson != null) {
JSONObject data = bmsdJson.getJSONObject("Data");
mergedData.putAll(data);
}
String jsonData = mergedData.toString();
Map<String, Object> obj = JSON.parseObject(jsonData, new TypeReference<Map<String, Object>>() {});
for (PointQueryResponse pointInfo : response) {
String dataKey = pointInfo.getDataPoint();
Long updateTime = Long.valueOf(bmsdJson.get("timestamp").toString());
int isNeedDeviceId = pointInfo.getIsNeedDeviceId();
if (isNeedDeviceId == 1 && "PCS".equals(pointInfo.getDataDevice())) {// 需要根据deviceId拼接point
dataKey = deviceId + dataKey;
updateTime = Long.valueOf(pcsJson.get("timestamp").toString());
} else if (isNeedDeviceId == 1 && "BMSD".equals(pointInfo.getDataDevice())){
dataKey = bmsdDeviceId + dataKey;
}
pointInfo.setDataPoint(dataKey);
pointInfo.setPointValue(obj.get(dataKey));
Date latestUpdateTime = convertUpdateTime(updateTime);
pointInfo.setUpdateTime(latestUpdateTime);
}
return response;
}
private Date convertUpdateTime(Long updateTime) {
if (updateTime == null) {
return null;
}
// 兼容10位秒级和13位毫秒级
int length = String.valueOf(updateTime).length();
if (length == 10) { // 10位秒级 -> 转换为毫秒级
updateTime *= 1000;
} else if (length != 13) { // 既不是10位也不是13位视为非法
System.err.println("时间戳格式错误必须是10位(秒)或13位(毫秒)");
return null;
}
// 3. 转换为Date
return new Date(updateTime);
}
}

View File

@ -85,6 +85,9 @@ public class FXXDataProcessServiceImpl extends AbstractBatteryDataProcessor impl
return;
}
// 存放mqtt原始每个设备数据便于后面点位获取数据
redisCache.setCacheObject(RedisKeyConstants.ORIGINAL_MQTT_DATA + SITE_ID + "_" + deviceId, obj);
if (deviceId.contains("BMSD")) {
batteryStackDataProcess(deviceId, jsonData);

View File

@ -318,8 +318,13 @@
ORDER BY t.site_id, t.device_id, valueDate ASC
</select>
<select id="getSingleSiteDevicePoints" resultMap="EmsPointMatchResult">
<include refid="selectEmsPointMatchVo"/>
<select id="getSingleSiteDevicePoints" resultType="com.xzzn.ems.domain.vo.PointQueryResponse">
select t.point_name as pointName,
t.data_point as dataPoint,
t.data_point_name as dataPointName,
t.data_device as dataDevice,
t.need_diff_device_id as isNeedDeviceId
from ems_point_match t
where 1=1
<if test="siteId != null and siteId != ''">
and site_id = #{siteId}