diff --git a/ems-admin/src/main/java/com/xzzn/web/controller/ems/EmsGeneralQueryController.java b/ems-admin/src/main/java/com/xzzn/web/controller/ems/EmsGeneralQueryController.java new file mode 100644 index 0000000..a0f7a76 --- /dev/null +++ b/ems-admin/src/main/java/com/xzzn/web/controller/ems/EmsGeneralQueryController.java @@ -0,0 +1,72 @@ +package com.xzzn.web.controller.ems; + +import com.xzzn.common.core.controller.BaseController; +import com.xzzn.common.core.domain.AjaxResult; +import com.xzzn.common.enums.DeviceCategory; +import com.xzzn.ems.domain.vo.*; +import com.xzzn.ems.service.IGeneralQueryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * 综合查询 + * + */ +@RestController +@RequestMapping("/ems/generalQuery") +public class EmsGeneralQueryController extends BaseController{ + + @Autowired + private IGeneralQueryService iGeneralQueryService; + + /** + * 获取设备枚举 + */ + @GetMapping("/getAllDeviceCategory") + public AjaxResult getDeviceCategory() + { + // 获取所有枚举的中文信息 + List deviceCategoryName = new ArrayList<>(); + for (DeviceCategory category : DeviceCategory.values()) { + deviceCategoryName.add(category.getInfo()); + } + return success(deviceCategoryName); + } + + /** + * 点位模糊查询 + */ + @PostMapping("/pointFuzzyQuery") + public AjaxResult pointFuzzyQuery(@RequestBody PointNameRequest request) + { + return success(iGeneralQueryService.getPointNameList(request)); + } + + /** + * 根据点位查询点位数据变化 + */ + @PostMapping("/getPointValueList") + public AjaxResult getPointValueList(@RequestBody PointNameRequest request) + { + List result = new ArrayList<>(); + try { + result = iGeneralQueryService.getPointValueList(request); + } catch (Exception e) { + return error("报错请重试!"); + } + return success(result); + } + + /** + * 获取设备枚举 + */ + @GetMapping("/getAllBatteryIdsBySites/{siteIds}") + public AjaxResult getAllBatteryIdsBySites(@PathVariable String[] siteIds) + { + return success(iGeneralQueryService.getAllBatteryIdsBySites(siteIds)); + } +} diff --git a/ems-common/src/main/java/com/xzzn/common/enums/DeviceCategory.java b/ems-common/src/main/java/com/xzzn/common/enums/DeviceCategory.java index 3b48820..6a23611 100644 --- a/ems-common/src/main/java/com/xzzn/common/enums/DeviceCategory.java +++ b/ems-common/src/main/java/com/xzzn/common/enums/DeviceCategory.java @@ -1,5 +1,8 @@ package com.xzzn.common.enums; +import java.util.HashMap; +import java.util.Map; + /** * device-设备类别 * @@ -13,7 +16,10 @@ public enum DeviceCategory CLUSTER("CLUSTER", "电池簇"), BATTERY("BATTERY", "单体电池"), AMMETER("AMMETER", "电表"), - COOLING("COOLING", "冷液体"); + COOLING("COOLING", "冷却"), + DH("DH", "动环"), + XF("XF", "消防"), + BATTERY_GROUP("BATTERY_GROUP", "电池组"); private final String code; private final String info; @@ -33,4 +39,19 @@ public enum DeviceCategory { return info; } + + // 缓存info与code的映射(优化查询效率) + private static final Map INFO_CODE_MAP = new HashMap<>(); + + // 静态块初始化缓存 + static { + for (DeviceCategory category : DeviceCategory.values()) { + INFO_CODE_MAP.put(category.info, category.code); + } + } + + // 通过info获取code的方法 + public static String getCodeByInfo(String info) { + return INFO_CODE_MAP.get(info); // 从缓存中直接获取,效率高 + } } diff --git a/ems-common/src/main/java/com/xzzn/common/utils/DateUtils.java b/ems-common/src/main/java/com/xzzn/common/utils/DateUtils.java index 61d94a2..12c8167 100644 --- a/ems-common/src/main/java/com/xzzn/common/utils/DateUtils.java +++ b/ems-common/src/main/java/com/xzzn/common/utils/DateUtils.java @@ -32,6 +32,8 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils public static String YYYYMMDD = "yyyyMMdd"; + public static String YYYY_MM_DD_HH_MM_00 = "yyyy-MM-dd HH:mm:00"; + private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", @@ -252,4 +254,39 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils return time.format(DateTimeFormatter.ofPattern("yyyy-MM")); } + /** + * 增加 LocalDateTime ==> String + */ + public static String convertToString(LocalDateTime time) { + return time.format(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS)); + } + + /** + * 将输入时间调整到下一分钟的整点(秒数强制为00) + * 例如:2026-09-03 18:34:49 -> 2026-09-03 18:35:00 + * @param timeStr 输入时间字符串(支持yyyy-MM-dd HH:mm:ss格式) + * @return 调整后的时间字符串(yyyy-MM-dd HH:mm:00) + * @throws ParseException 时间格式错误时抛出 + */ + public static String adjustToNextMinute(String timeStr) throws ParseException { + // 1. 解析原始时间(使用包含秒数的格式) + SimpleDateFormat fullFormat = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS); + Date originalDate = fullFormat.parse(timeStr); + + // 2. 使用Calendar调整时间 + Calendar cal = Calendar.getInstance(); + cal.setTime(originalDate); + + // 3. 如果当前秒数大于0,自动进1分钟(否则保持当前分钟) + if (cal.get(Calendar.SECOND) > 0) { + cal.add(Calendar.MINUTE, 1); // 分钟+1 + } + + // 4. 强制设置秒数和毫秒为0 + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + + // 5. 格式化为目标字符串 + return new SimpleDateFormat(YYYY_MM_DD_HH_MM_00).format(cal.getTime()); + } } diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/EmsPointMatch.java b/ems-system/src/main/java/com/xzzn/ems/domain/EmsPointMatch.java new file mode 100644 index 0000000..afe534b --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/domain/EmsPointMatch.java @@ -0,0 +1,117 @@ +package com.xzzn.ems.domain; + +import com.xzzn.common.core.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.xzzn.common.annotation.Excel; + +/** + * 点位匹配对象 ems_point_match + * + * @author xzzn + * @date 2025-09-02 + */ +public class EmsPointMatch extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 设备ID,主键自增长 */ + private Long id; + + /** 点位名称 */ + @Excel(name = "点位名称") + private String pointName; + + /** 点位所在表 */ + @Excel(name = "点位所在表") + private String matchTable; + + /** 点位匹配字段 */ + @Excel(name = "点位匹配字段") + private String matchField; + + /** 站点id */ + @Excel(name = "站点id") + private String siteId; + + /** 设备类别,例如“STACK/CLUSTER/PCS等” */ + @Excel(name = "设备类别,例如“STACK/CLUSTER/PCS等”") + private String deviceCategory; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + + public void setPointName(String pointName) + { + this.pointName = pointName; + } + + public String getPointName() + { + return pointName; + } + + public void setMatchTable(String matchTable) + { + this.matchTable = matchTable; + } + + public String getMatchTable() + { + return matchTable; + } + + public void setMatchField(String matchField) + { + this.matchField = matchField; + } + + public String getMatchField() + { + return matchField; + } + + public void setSiteId(String siteId) + { + this.siteId = siteId; + } + + public String getSiteId() + { + return siteId; + } + + public void setDeviceCategory(String deviceCategory) + { + this.deviceCategory = deviceCategory; + } + + public String getDeviceCategory() + { + return deviceCategory; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("pointName", getPointName()) + .append("matchTable", getMatchTable()) + .append("matchField", getMatchField()) + .append("siteId", getSiteId()) + .append("deviceCategory", getDeviceCategory()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/DevicePointDataList.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/DevicePointDataList.java new file mode 100644 index 0000000..d5230b1 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/DevicePointDataList.java @@ -0,0 +1,36 @@ +package com.xzzn.ems.domain.vo; + +import java.util.List; + +/** + * 综合查询返回-设备数据list + */ +public class DevicePointDataList +{ + // 设备id + private String deviceId; + + // 该设备点位数据list + private List pointValueList; + + public DevicePointDataList(String deviceId, List pointValueList) { + this.deviceId = deviceId; + this.pointValueList = pointValueList; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public List getPointValueList() { + return pointValueList; + } + + public void setPointValueList(List pointValueList) { + this.pointValueList = pointValueList; + } +} diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/GeneralQueryDataVo.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/GeneralQueryDataVo.java new file mode 100644 index 0000000..50c0468 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/GeneralQueryDataVo.java @@ -0,0 +1,47 @@ +package com.xzzn.ems.domain.vo; + +import java.math.BigDecimal; + +/** + * 综合查询-数据库返回结果 + */ +public class GeneralQueryDataVo { + + // 站点 + private String siteId; + private String deviceId; + private String valueDate; + private Object pointValue; + + public String getSiteId() { + return siteId; + } + + public void setSiteId(String siteId) { + this.siteId = siteId; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public String getValueDate() { + return valueDate; + } + + public void setValueDate(String valueDate) { + this.valueDate = valueDate; + } + + public Object getPointValue() { + return pointValue; + } + + public void setPointValue(Object pointValue) { + this.pointValue = pointValue; + } +} diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/GeneralQueryResponse.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/GeneralQueryResponse.java new file mode 100644 index 0000000..0569696 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/GeneralQueryResponse.java @@ -0,0 +1,37 @@ +package com.xzzn.ems.domain.vo; + +import java.util.List; + +/** + * 综合查询结果 + * + */ +public class GeneralQueryResponse { + + // 站点 + private String siteId; + + // 设备数据 + private List deviceList; + + public GeneralQueryResponse(String siteId, List deviceList) { + this.siteId = siteId; + this.deviceList = deviceList; + } + + public String getSiteId() { + return siteId; + } + + public void setSiteId(String siteId) { + this.siteId = siteId; + } + + public List getDeviceList() { + return deviceList; + } + + public void setDeviceList(List deviceList) { + this.deviceList = deviceList; + } +} diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/MonthlyTimeRange.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/MonthlyTimeRange.java new file mode 100644 index 0000000..675b410 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/MonthlyTimeRange.java @@ -0,0 +1,49 @@ +package com.xzzn.ems.domain.vo; + +import java.time.LocalDateTime; + +/** + * 每月时间范围实体 + */ +public class MonthlyTimeRange { + // 站点ID + private String siteId; + // 月份(YYYY-MM) + private String month; + // 当月最早时间 + private LocalDateTime firstDataTime; + // 当月最晚时间 + private LocalDateTime lastDataTime; + + public String getSiteId() { + return siteId; + } + + public void setSiteId(String siteId) { + this.siteId = siteId; + } + + public String getMonth() { + return month; + } + + public void setMonth(String month) { + this.month = month; + } + + public LocalDateTime getFirstDataTime() { + return firstDataTime; + } + + public void setFirstDataTime(LocalDateTime firstDataTime) { + this.firstDataTime = firstDataTime; + } + + public LocalDateTime getLastDataTime() { + return lastDataTime; + } + + public void setLastDataTime(LocalDateTime lastDataTime) { + this.lastDataTime = lastDataTime; + } +} diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/PointNameRequest.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/PointNameRequest.java new file mode 100644 index 0000000..f7b7470 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/PointNameRequest.java @@ -0,0 +1,82 @@ +package com.xzzn.ems.domain.vo; + +import java.util.List; +import java.util.Map; + +/** + * 点位模糊查询入参 + * + */ +public class PointNameRequest { + + private List siteIds; + + private String categoryName; + + private String pointName; + + /** 数据分组 1-分钟 2-小时 3-天 */ + private int dataUnit; + + private String startDate; + + private String endDate; + + private Map> siteDeviceMap; + + public List getSiteIds() { + return siteIds; + } + + public void setSiteIds(List siteIds) { + this.siteIds = siteIds; + } + + public String getCategoryName() { + return categoryName; + } + + public void setCategoryName(String categoryName) { + this.categoryName = categoryName; + } + + public String getPointName() { + return pointName; + } + + public void setPointName(String pointName) { + this.pointName = pointName; + } + + public int getDataUnit() { + return dataUnit; + } + + public void setDataUnit(int dataUnit) { + this.dataUnit = dataUnit; + } + + public String getStartDate() { + return startDate; + } + + public void setStartDate(String startDate) { + this.startDate = startDate; + } + + public String getEndDate() { + return endDate; + } + + public void setEndDate(String endDate) { + this.endDate = endDate; + } + + public Map> getSiteDeviceMap() { + return siteDeviceMap; + } + + public void setSiteDeviceMap(Map> siteDeviceMap) { + this.siteDeviceMap = siteDeviceMap; + } +} diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/SiteBatteryListVo.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/SiteBatteryListVo.java new file mode 100644 index 0000000..94eb5dc --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/SiteBatteryListVo.java @@ -0,0 +1,27 @@ +package com.xzzn.ems.domain.vo; + +/** + * 综合查询-站点下单体电池实际数据 + * + */ +public class SiteBatteryListVo { + /** 站点id */ + private String siteId; + private String deviceId; + + public String getSiteId() { + return siteId; + } + + public void setSiteId(String siteId) { + this.siteId = siteId; + } + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } +} diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/TimePointQuery.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/TimePointQuery.java new file mode 100644 index 0000000..207d291 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/TimePointQuery.java @@ -0,0 +1,33 @@ +package com.xzzn.ems.domain.vo; + +import java.time.LocalDateTime; + +/** + * 时间点参数实体 + */ +public class TimePointQuery { + private String siteId; + // 要查询的时间点 + private LocalDateTime dataTime; + + public TimePointQuery(String siteId, LocalDateTime dataTime) { + this.siteId = siteId; + this.dataTime = dataTime; + } + + public String getSiteId() { + return siteId; + } + + public void setSiteId(String siteId) { + this.siteId = siteId; + } + + public LocalDateTime getDataTime() { + return dataTime; + } + + public void setDataTime(LocalDateTime dataTime) { + this.dataTime = dataTime; + } +} diff --git a/ems-system/src/main/java/com/xzzn/ems/domain/vo/TimePointValue.java b/ems-system/src/main/java/com/xzzn/ems/domain/vo/TimePointValue.java new file mode 100644 index 0000000..95c75f5 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/domain/vo/TimePointValue.java @@ -0,0 +1,48 @@ +package com.xzzn.ems.domain.vo; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 时间点-总充放电数据 + */ +public class TimePointValue { + private String siteId; + private LocalDateTime dataUpdateTime; + // 总充电量 + private BigDecimal totalChargeData; + // 总放电量 + private BigDecimal totalDischargeData; + + public String getSiteId() { + return siteId; + } + + public void setSiteId(String siteId) { + this.siteId = siteId; + } + + public LocalDateTime getDataUpdateTime() { + return dataUpdateTime; + } + + public void setDataUpdateTime(LocalDateTime dataUpdateTime) { + this.dataUpdateTime = dataUpdateTime; + } + + public BigDecimal getTotalChargeData() { + return totalChargeData; + } + + public void setTotalChargeData(BigDecimal totalChargeData) { + this.totalChargeData = totalChargeData; + } + + public BigDecimal getTotalDischargeData() { + return totalDischargeData; + } + + public void setTotalDischargeData(BigDecimal totalDischargeData) { + this.totalDischargeData = totalDischargeData; + } +} diff --git a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryDataMonthMapper.java b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryDataMonthMapper.java index cc5784e..56cf737 100644 --- a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryDataMonthMapper.java +++ b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsBatteryDataMonthMapper.java @@ -4,6 +4,7 @@ import java.time.LocalDateTime; import java.util.List; import com.xzzn.ems.domain.EmsBatteryDataMonth; +import com.xzzn.ems.domain.vo.SiteBatteryListVo; import org.apache.ibatis.annotations.Param; /** @@ -69,4 +70,7 @@ public interface EmsBatteryDataMonthMapper * 批量插入或更新月级数据(存在则更新,不存在则插入) */ void batchInsertOrUpdate(@Param("list") List monthDataList); + + // 查找siteId下面所有的单体电池编码 + public List getAllBatteryIdsBySites(@Param("siteIds")String[] siteIds); } diff --git a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsDevicesSettingMapper.java b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsDevicesSettingMapper.java index 1f451de..29e851e 100644 --- a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsDevicesSettingMapper.java +++ b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsDevicesSettingMapper.java @@ -87,4 +87,6 @@ public interface EmsDevicesSettingMapper public List> getClusterIdsByFuzzyQuery(@Param("siteId")String siteId, @Param("deviceCategory")String deviceCategory, @Param("parentId")String parentId); + + public List getDeviceIdsBySiteIdAndCategory(@Param("siteId")String siteId,@Param("deviceCategory")String deviceCategory); } diff --git a/ems-system/src/main/java/com/xzzn/ems/mapper/EmsPointMatchMapper.java b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsPointMatchMapper.java new file mode 100644 index 0000000..01ee073 --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/mapper/EmsPointMatchMapper.java @@ -0,0 +1,97 @@ +package com.xzzn.ems.mapper; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +import com.xzzn.ems.domain.EmsPointMatch; +import com.xzzn.ems.domain.vo.GeneralQueryDataVo; +import org.apache.ibatis.annotations.Param; + +/** + * 点位匹配Mapper接口 + * + * @author xzzn + * @date 2025-09-02 + */ +public interface EmsPointMatchMapper +{ + /** + * 查询点位匹配 + * + * @param id 点位匹配主键 + * @return 点位匹配 + */ + public EmsPointMatch selectEmsPointMatchById(Long id); + + /** + * 查询点位匹配列表 + * + * @param emsPointMatch 点位匹配 + * @return 点位匹配集合 + */ + public List selectEmsPointMatchList(EmsPointMatch emsPointMatch); + + /** + * 新增点位匹配 + * + * @param emsPointMatch 点位匹配 + * @return 结果 + */ + public int insertEmsPointMatch(EmsPointMatch emsPointMatch); + + /** + * 修改点位匹配 + * + * @param emsPointMatch 点位匹配 + * @return 结果 + */ + public int updateEmsPointMatch(EmsPointMatch emsPointMatch); + + /** + * 删除点位匹配 + * + * @param id 点位匹配主键 + * @return 结果 + */ + public int deleteEmsPointMatchById(Long id); + + /** + * 批量删除点位匹配 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteEmsPointMatchByIds(Long[] ids); + + // 模糊查询所有点位 + public List getPointNameList(@Param("siteIds") List siteIds, + @Param("deviceCategory")String deviceCategory, + @Param("pointName") String pointName); + + // 获取匹配信息 + public List getMatchInfo(@Param("siteIds") List siteIds, + @Param("deviceCategory")String deviceCategory, + @Param("pointName") String pointName); + // 根据条件查询数据-按分钟 + public List getPointDataListByMinutes(@Param("siteIds")List siteIds, + @Param("tableName")String tableName, + @Param("tableField")String tableField, + @Param("startDate")Date startDate, + @Param("endDate")Date endDate, + @Param("params") Map> params); + // 根据条件查询数据-按小时 + public List getPointDataListByHours(@Param("siteIds")List siteIds, + @Param("tableName")String tableName, + @Param("tableField")String tableField, + @Param("startDate") Date startDate, + @Param("endDate")Date endDate, + @Param("params") Map> params); + // 根据条件查询数据-按天 + public List getPointDataListByDays(@Param("siteIds")List siteIds, + @Param("tableName")String tableName, + @Param("tableField")String tableField, + @Param("startDate")Date startDate, + @Param("endDate")Date endDate, + @Param("params") Map> params); +} diff --git a/ems-system/src/main/java/com/xzzn/ems/service/IGeneralQueryService.java b/ems-system/src/main/java/com/xzzn/ems/service/IGeneralQueryService.java new file mode 100644 index 0000000..325993f --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/service/IGeneralQueryService.java @@ -0,0 +1,23 @@ +package com.xzzn.ems.service; + +import com.xzzn.ems.domain.vo.*; + +import java.util.List; +import java.util.Map; + +/** + * 综合查询 服务层 + * + */ +public interface IGeneralQueryService +{ + + // 模糊查询获取点位名称List + public List getPointNameList(PointNameRequest request); + + // 根据条件获取点位数据变化 + public List getPointValueList(PointNameRequest request); + + // 根据siteId获取下面对应的单体电池编号 + public Map> getAllBatteryIdsBySites(String[] siteIds); +} diff --git a/ems-system/src/main/java/com/xzzn/ems/service/impl/DDSDataProcessServiceImpl.java b/ems-system/src/main/java/com/xzzn/ems/service/impl/DDSDataProcessServiceImpl.java index 97c31cd..05cf43a 100644 --- a/ems-system/src/main/java/com/xzzn/ems/service/impl/DDSDataProcessServiceImpl.java +++ b/ems-system/src/main/java/com/xzzn/ems/service/impl/DDSDataProcessServiceImpl.java @@ -112,11 +112,11 @@ public class DDSDataProcessServiceImpl extends AbstractBatteryDataProcessor impl } else if (deviceId.contains("XF")) { meteXFProcess(deviceId, jsonData); } else if (deviceId.contains("DH")) { - meteDHProcess(deviceId, jsonData); + dhDataProcess(deviceId, jsonData); } } - private void meteDHProcess(String deviceId, String dataJson) { + private void dhDataProcess(String deviceId, String dataJson) { //动环 Map obj = JSON.parseObject(dataJson, new TypeReference>() { }); diff --git a/ems-system/src/main/java/com/xzzn/ems/service/impl/FXXDataProcessServiceImpl.java b/ems-system/src/main/java/com/xzzn/ems/service/impl/FXXDataProcessServiceImpl.java index 12aad12..e988941 100644 --- a/ems-system/src/main/java/com/xzzn/ems/service/impl/FXXDataProcessServiceImpl.java +++ b/ems-system/src/main/java/com/xzzn/ems/service/impl/FXXDataProcessServiceImpl.java @@ -64,6 +64,8 @@ public class FXXDataProcessServiceImpl extends AbstractBatteryDataProcessor impl private EmsBatteryDataMinutesMapper emsBatteryDataMinutesMapper; @Autowired private EmsDailyChargeDataMapper emsDailyChargeDataMapper; + @Autowired + private EmsDhDataMapper emsDhDataMapper; // 构造方法(调用父类构造) public FXXDataProcessServiceImpl(ObjectMapper objectMapper) { @@ -99,12 +101,36 @@ public class FXXDataProcessServiceImpl extends AbstractBatteryDataProcessor impl pcsBranchDataProcess(deviceId, jsonData); } else if (deviceId.contains("LOAD")) { loadDataProcess(deviceId, jsonData); - } else if (deviceId.contains("METE")) { + } else if (deviceId.contains("METE")) { meteDataProcess(deviceId, jsonData); + } else if (deviceId.contains("donghuan")) { + dhDataProcess(deviceId, jsonData); } } } + private void dhDataProcess(String deviceId, String dataJson) { + //动环 + Map obj = JSON.parseObject(dataJson, new TypeReference>() { + }); + + //DH + EmsDhData dhData = new EmsDhData(); + + dhData.setHumidity(StringUtils.getBigDecimal(obj.get("SD3"))); + dhData.setTemperature(StringUtils.getBigDecimal(obj.get("WD3"))); + + dhData.setCreateBy("system"); + dhData.setCreateTime(DateUtils.getNowDate()); + dhData.setUpdateBy("system"); + dhData.setUpdateTime(DateUtils.getNowDate()); + dhData.setSiteId(SITE_ID); + dhData.setDeviceId(deviceId); + emsDhDataMapper.insertEmsDhData(dhData); + + redisCache.setCacheObject(RedisKeyConstants.DH + SITE_ID + "_" +deviceId, dhData); + } + private void batteryStackDataProcess(String deviceId, String dataJson) { //电池堆 @@ -433,6 +459,7 @@ public class FXXDataProcessServiceImpl extends AbstractBatteryDataProcessor impl EmsPcsBranchData data = new EmsPcsBranchData(); data.setDeviceId(deviceId); + data.setSiteId(SITE_ID); data.setGridStatus(GridStatus.GRID.getCode()); data.setDcPower(StringUtils.getBigDecimal(fields.get("ZLGL"))); data.setDcVoltage(StringUtils.getBigDecimal(fields.get("ZLDY"))); @@ -457,6 +484,10 @@ public class FXXDataProcessServiceImpl extends AbstractBatteryDataProcessor impl data.setAcLeakageCurrent(StringUtils.getBigDecimal(fields.get("JLLDL"))); data.setInsulationResistance(StringUtils.getBigDecimal(fields.get("JYZK"))); data.setBranchId(recordId); + data.setCreateBy("system"); + data.setCreateTime(DateUtils.getNowDate()); + data.setUpdateBy("system"); + data.setUpdateTime(DateUtils.getNowDate()); list.add(data); } if (list.size() > 0 ) { diff --git a/ems-system/src/main/java/com/xzzn/ems/service/impl/GeneralQueryServiceImpl.java b/ems-system/src/main/java/com/xzzn/ems/service/impl/GeneralQueryServiceImpl.java new file mode 100644 index 0000000..5d4d46d --- /dev/null +++ b/ems-system/src/main/java/com/xzzn/ems/service/impl/GeneralQueryServiceImpl.java @@ -0,0 +1,284 @@ +package com.xzzn.ems.service.impl; + +import com.xzzn.common.enums.DeviceCategory; +import com.xzzn.common.utils.DateUtils; +import com.xzzn.ems.domain.EmsPointMatch; +import com.xzzn.ems.domain.vo.*; +import com.xzzn.ems.mapper.EmsBatteryDataMonthMapper; +import com.xzzn.ems.mapper.EmsDevicesSettingMapper; +import com.xzzn.ems.mapper.EmsPointMatchMapper; +import com.xzzn.ems.service.IGeneralQueryService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.temporal.TemporalAdjusters; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 综合查询 服务层实现 + * + */ +@Service +public class GeneralQueryServiceImpl implements IGeneralQueryService +{ + private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:00"); + + @Autowired + private EmsPointMatchMapper emsPointMatchMapper; + @Autowired + private EmsDevicesSettingMapper emsDevicesSettingMapper; + @Autowired + private EmsBatteryDataMonthMapper emsBatteryDataMonthMapper; + + @Override + public List getPointNameList(PointNameRequest request) { + List siteIds = request.getSiteIds(); + if (siteIds == null || siteIds.isEmpty()) { + return Collections.emptyList(); + } + + String categoryName = request.getCategoryName(); + String deviceCategory = DeviceCategory.getCodeByInfo(categoryName); + if (deviceCategory == null) { + return Collections.emptyList(); + } + + return emsPointMatchMapper.getPointNameList(siteIds,deviceCategory,request.getPointName()); + } + + @Override + public Map> getAllBatteryIdsBySites(String[] siteIds) { + Map> resultMap = new HashMap<>(); + if (siteIds == null || siteIds.length == 0) { + return resultMap; + } + List siteBatteryListVos = emsBatteryDataMonthMapper.getAllBatteryIdsBySites(siteIds); + resultMap = convertToMap(siteBatteryListVos); + return resultMap; + } + + public static Map> convertToMap(List siteDeviceList) { + Map> resultMap = new HashMap<>(); + + for (SiteBatteryListVo item : siteDeviceList) { + String siteId = item.getSiteId (); + String deviceId = item.getDeviceId (); + if (!resultMap.containsKey (siteId)) { + resultMap.put (siteId, new ArrayList<>()); + } + resultMap.get (siteId).add (deviceId); + } + + return resultMap; + } + + @Override + public List getPointValueList(PointNameRequest request){ + List result = new ArrayList<>(); + List querySiteIds = new ArrayList<>(); + + List siteIds = request.getSiteIds(); + String categoryName = request.getCategoryName(); + String deviceCategory = DeviceCategory.getCodeByInfo(categoryName); + // 根据入参获取点位对应的表和字段 + List matchInfo = emsPointMatchMapper.getMatchInfo(siteIds,deviceCategory,request.getPointName()); + if (matchInfo == null || matchInfo.size() == 0) { + return result; + } else { + for (EmsPointMatch emsPointMatch : matchInfo) { + querySiteIds.add(emsPointMatch.getSiteId()); + } + } + + Map> siteDeviceMap = request.getSiteDeviceMap(); + if (DeviceCategory.BATTERY.getCode().equals(deviceCategory) && (siteDeviceMap == null || siteDeviceMap.size() == 0)) { + return result; + } + + // 处理时间范围,如果未传根据单位设默认值 + dealDataTime(request); + + int dataUnit = request.getDataUnit(); + Date startDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS,request.getStartDate()); + Date endDate = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS,request.getEndDate()); + try { + // 不同的site_id根据设备类型和字段,默认取第一个匹配到的表和表字段只会有一个, + String tableName = matchInfo.get(0).getMatchTable(); + String tableField = matchInfo.get(0).getMatchField(); + List dataVoList = new ArrayList<>(); + if (dataUnit == 1) { // 分钟 + dataVoList = emsPointMatchMapper.getPointDataListByMinutes(querySiteIds,tableName,tableField,startDate,endDate,siteDeviceMap); + if (dataVoList != null && dataVoList.size() > 0) { + dataVoList = dealWithMinutesData(querySiteIds,dataVoList,deviceCategory, + request.getStartDate(),request.getEndDate(),siteDeviceMap); + } + } else if (dataUnit == 2) { // 小时 + if (DeviceCategory.BATTERY.getCode().equals(deviceCategory)) { + // 单体电池特殊处理,已经提前按小时分表 + tableName = "ems_battery_data_hour"; + } + dataVoList = emsPointMatchMapper.getPointDataListByHours(querySiteIds,tableName,tableField,startDate,endDate,siteDeviceMap); + } else if (dataUnit == 3) { // 天 + if (DeviceCategory.BATTERY.getCode().equals(deviceCategory)) { + tableName = "ems_battery_data_day"; + } + dataVoList = emsPointMatchMapper.getPointDataListByDays(querySiteIds,tableName,tableField,startDate,endDate,siteDeviceMap); + } + + // 数据转换: 先按siteId分组,再按deviceId分组 + result = dataVoList.stream() + // 第一层分组:按siteId分组,得到 + .collect(Collectors.groupingBy(GeneralQueryDataVo::getSiteId)) + .entrySet().stream() + .map(siteEntry -> { + String siteId = siteEntry.getKey(); + List siteAllData = siteEntry.getValue(); + + // 第二层分组:在当前站点下,按deviceId分组,得到 + List deviceList = siteAllData.stream() + .collect(Collectors.groupingBy(GeneralQueryDataVo::getDeviceId)) + .entrySet().stream() + .map(deviceEntry -> new DevicePointDataList( + deviceEntry.getKey(), + deviceEntry.getValue() + )) + .collect(Collectors.toList()); + + return new GeneralQueryResponse(siteId, deviceList); + }) + .collect(Collectors.toList()); + } catch (ParseException e) { + throw new RuntimeException(e); + } + return result; + } + + private void dealDataTime(PointNameRequest request) { + String startDate = request.getStartDate(); + String endDate = request.getEndDate(); + int dataUnit = request.getDataUnit(); + if (startDate == null || endDate == null) { + // 前端未传递时,根据dataunit设置默认时间范围 + LocalDateTime now = LocalDateTime.now(); + LocalDateTime start; + LocalDateTime end; + switch (dataUnit) { + case 1: // 按分钟 - 前一小时 + end = now; + start = now.minusHours(1); + break; + case 2: // 按小时 - 当天 + end = now.with(LocalTime.MAX); + start = now.with(LocalTime.MIN); + break; + case 3: // 按天 - 当月 + end = now.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX); + start = now.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN); + break; + default: + throw new IllegalArgumentException("无效的dataunit值: " + dataUnit); + } + // 格式化为字符串(与前端传递的格式一致) + startDate = DateUtils.convertToString(start); + endDate = DateUtils.convertToString(end); + } + request.setStartDate(startDate); + request.setEndDate(endDate); + } + + private List dealWithMinutesData(List querySiteIds, List dataVoList, + String deviceCategory, String startDate, String endDate, Map> siteDeviceMap) throws ParseException { + List fullData = new ArrayList<>(); + Map dataMap = new HashMap<>(); + for (GeneralQueryDataVo data : dataVoList) { + String key = data.getSiteId() + "_" + data.getDeviceId() + "_" + data.getValueDate(); + dataMap.put(key, data); + } + // 生成分钟序列 + Set minuteSeries = generateMinuteSeries(startDate, endDate); + // 遍历每个站点,动态获取该站点下的所有设备 + for (String siteId : querySiteIds) { + List deviceIds = new ArrayList<>(); + // 单体电池deviceId特殊处理 + if (DeviceCategory.BATTERY.getCode().equals(deviceCategory) && (siteDeviceMap != null || siteDeviceMap.size() > 0)) { + deviceIds = siteDeviceMap.get(siteId); + } else { + deviceIds = emsDevicesSettingMapper.getDeviceIdsBySiteIdAndCategory(siteId,deviceCategory); + } + if (deviceIds.isEmpty()) { + continue; // 跳过无设备的站点 + } + + // 处理该站点下的所有设备 + for (String deviceId : deviceIds) { + Object lastValue = null; + + for (String minute : minuteSeries) { + String dataKey = siteId + "_" + deviceId + "_" + minute; + GeneralQueryDataVo data = dataMap.get(dataKey); + + // 空值填充逻辑 + if (data == null) { + data = new GeneralQueryDataVo(); + data.setValueDate(minute); + data.setSiteId(siteId); + data.setDeviceId(deviceId); + data.setPointValue(lastValue); // 用上一分钟值填充 + } else { + lastValue = data.getPointValue(); // 更新最新值 + } + + fullData.add(data); + } + } + } + + fullData.sort(Comparator.comparing(GeneralQueryDataVo::getValueDate) + .thenComparing(GeneralQueryDataVo::getSiteId) + .thenComparing(GeneralQueryDataVo::getDeviceId)); + + return fullData; + } + + /** + * 根据前端传递的startDate和endDate生成所有分钟点的序列 + * @param startDate 起始时间(格式:yyyy-MM-dd HH:mm:00) + * @param endDate 结束时间(格式:yyyy-MM-dd HH:mm:00) + * @return 包含所有分钟点的有序集合 + * @throws ParseException 时间格式解析失败时抛出 + */ + private Set generateMinuteSeries(String startDate, String endDate) throws ParseException { + Set minutes = new TreeSet<>(); // TreeSet保证时间有序 + + // 解析起止时间 + startDate = DateUtils.adjustToNextMinute(startDate); + Date startTime = TIME_FORMAT.parse(startDate.substring(0, 16) + ":00"); + Date endTime = TIME_FORMAT.parse(endDate.substring(0, 16) + ":00"); + + // 验证时间有效性 + if (startTime.after(endTime)) { + throw new IllegalArgumentException("起始时间不能晚于结束时间"); + } + + // 初始化日历对象,从起始时间开始 + Calendar cal = Calendar.getInstance(); + cal.setTime(startTime); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + + // 循环生成从startDate到endDate的所有分钟点 + while (!cal.getTime().after(endTime)) { + // 添加当前分钟(格式:yyyy-MM-dd HH:mm:00) + minutes.add(TIME_FORMAT.format(cal.getTime())); + // 递增1分钟 + cal.add(Calendar.MINUTE, 1); + } + + return minutes; + } +} diff --git a/ems-system/src/main/java/com/xzzn/ems/service/impl/SingleSiteServiceImpl.java b/ems-system/src/main/java/com/xzzn/ems/service/impl/SingleSiteServiceImpl.java index e518c70..3084a11 100644 --- a/ems-system/src/main/java/com/xzzn/ems/service/impl/SingleSiteServiceImpl.java +++ b/ems-system/src/main/java/com/xzzn/ems/service/impl/SingleSiteServiceImpl.java @@ -17,6 +17,8 @@ import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.*; import java.util.stream.Collectors; @@ -75,7 +77,7 @@ public class SingleSiteServiceImpl implements ISingleSiteService { if (dataMap != null) { siteMonitorHomeVo.setTotalChargedCap(dataMap.get("totalChargedCap")); siteMonitorHomeVo.setTotalDischargedCap(dataMap.get("totalDischargedCap")); - siteMonitorHomeVo.setGridNrtPower(dataMap.get("gridNrtPower")); + //siteMonitorHomeVo.setGridNrtPower(dataMap.get("gridNrtPower")); } // 实时告警数据 名称+状态+告警内容 List siteMonitorHomeAlarmVo = emsAlarmRecordsMapper.getAlarmRecordsBySiteId(siteId); @@ -121,9 +123,20 @@ public class SingleSiteServiceImpl implements ISingleSiteService { SiteMonitorRunningHeadInfoVo siteMonitorRunningHeadInfoVo = new SiteMonitorRunningHeadInfoVo(); if (!StringUtils.isEmpty(siteId)) { - // 实时有功功率/实时无功功率/今日充电量/今日放电量 + // 实时有功功率/实时无功功率 SiteMonitorRunningHeadInfoVo tempVo = emsPcsDataMapper.getSiteRunningHeadInfo(siteId); - siteMonitorRunningHeadInfoVo = tempVo != null ? tempVo : siteMonitorRunningHeadInfoVo; + siteMonitorRunningHeadInfoVo.setTotalActivePower(tempVo.getTotalActivePower()); + siteMonitorRunningHeadInfoVo.setTotalReactivePower(tempVo.getTotalReactivePower()); + // 今日充放电 + LocalDateTime now = LocalDateTime.now(); + LocalDateTime startOfDay = now.with(LocalTime.MIN); + Date startDate = DateUtils.toDate(startOfDay); + Date endDate = new Date(); + List siteMonitorDataVoList = emsDailyChargeDataMapper.getSingleSiteChargeData(siteId,startDate,endDate); + if (siteMonitorDataVoList != null && siteMonitorDataVoList.size() > 0) { + siteMonitorRunningHeadInfoVo.setDayChargedCap(siteMonitorDataVoList.get(0).getChargedCap()); + siteMonitorRunningHeadInfoVo.setDayDisChargedCap(siteMonitorDataVoList.get(0).getDisChargedCap()); + } // 电池堆SOC + 电池堆SOH EmsBatteryStack emsBatteryStack = emsBatteryStackMapper.getSiteSumStackInfo(siteId); if (emsBatteryStack != null) { diff --git a/ems-system/src/main/resources/mapper/ems/EmsBatteryDataMonthMapper.xml b/ems-system/src/main/resources/mapper/ems/EmsBatteryDataMonthMapper.xml index 4d066dd..0ef37df 100644 --- a/ems-system/src/main/resources/mapper/ems/EmsBatteryDataMonthMapper.xml +++ b/ems-system/src/main/resources/mapper/ems/EmsBatteryDataMonthMapper.xml @@ -199,4 +199,13 @@ update_by = IF(VALUES(temperature) > temperature, VALUES(update_by), update_by), temperature = IF(VALUES(temperature) > temperature, VALUES(temperature), temperature) + + \ No newline at end of file diff --git a/ems-system/src/main/resources/mapper/ems/EmsDevicesSettingMapper.xml b/ems-system/src/main/resources/mapper/ems/EmsDevicesSettingMapper.xml index fd7bb73..38cb326 100644 --- a/ems-system/src/main/resources/mapper/ems/EmsDevicesSettingMapper.xml +++ b/ems-system/src/main/resources/mapper/ems/EmsDevicesSettingMapper.xml @@ -210,4 +210,8 @@ and device_category = #{deviceCategory} + + \ No newline at end of file diff --git a/ems-system/src/main/resources/mapper/ems/EmsPointMatchMapper.xml b/ems-system/src/main/resources/mapper/ems/EmsPointMatchMapper.xml new file mode 100644 index 0000000..2f21263 --- /dev/null +++ b/ems-system/src/main/resources/mapper/ems/EmsPointMatchMapper.xml @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + select id, point_name, match_table, match_field, site_id, device_category, create_by, create_time, update_by, update_time, remark from ems_point_match + + + + + + + + insert into ems_point_match + + point_name, + match_table, + match_field, + site_id, + device_category, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{pointName}, + #{matchTable}, + #{matchField}, + #{siteId}, + #{deviceCategory}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update ems_point_match + + point_name = #{pointName}, + match_table = #{matchTable}, + match_field = #{matchField}, + site_id = #{siteId}, + device_category = #{deviceCategory}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where id = #{id} + + + + delete from ems_point_match where id = #{id} + + + + delete from ems_point_match where id in + + #{id} + + + + + + + + + + + AND ( + + ( site_id = #{siteId} + AND device_id IN + + #{deviceId} + + ) + + + ) + + + AND site_id IN + + #{siteId} + + + + + + + + + + + \ No newline at end of file