package com.ruoyi.other.service.impl; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.common.core.exception.ServiceException; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.other.api.domain.TStationCollect; import com.ruoyi.other.api.domain.TStationInfo; import com.ruoyi.other.mapper.TStationCollectMapper; import com.ruoyi.other.mapper.TStationInfoMapper; import com.ruoyi.other.query.StationCollectQuery; import com.ruoyi.other.service.TStationCollectService; import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; /** * 电站逆变器服务实现。 */ @Service public class TStationCollectServiceImpl extends ServiceImpl implements TStationCollectService { @Resource private TStationInfoMapper stationInfoMapper; @Override @Transactional(rollbackFor = Exception.class) public boolean addStationCollect(TStationCollect stationCollect) { validate(stationCollect); stationCollect.setCollectId("1"+System.currentTimeMillis()); stationCollect.setDataSource(1); fillDefaults(stationCollect); stationCollect.setId(null); stationCollect.setCreateTime(LocalDateTime.now()); stationCollect.setUpdateTime(LocalDateTime.now()); return save(stationCollect); } @Override public PageInfo pageList(StationCollectQuery query) { if (query == null) query = new StationCollectQuery(); PageInfo page = new PageInfo<>(query.getPageCurr(), query.getPageSize()); lambdaQuery() .eq(query.getPlatformId() != null, TStationCollect::getPlatformId, query.getPlatformId()) .like(StringUtils.isNotBlank(query.getStationName()), TStationCollect::getStationName, query.getStationName()) .like(StringUtils.isNotBlank(query.getCollectName()), TStationCollect::getCollectName, query.getCollectName()) .like(StringUtils.isNotBlank(query.getDeviceModel()), TStationCollect::getDeviceModel, query.getDeviceModel()) .like(StringUtils.isNotBlank(query.getInverterId()), TStationCollect::getInverterId, query.getInverterId()) .eq(StringUtils.isNotBlank(query.getStatus()), TStationCollect::getStatus, query.getStatus()) .in(StringUtils.isBlank(query.getStatus()) && Boolean.TRUE.equals(query.getAbnormalOnly()), TStationCollect::getStatus, "2", "3") .orderByAsc(TStationCollect::getSortOrder).orderByDesc(TStationCollect::getCreateTime).page(page); fillStationAddress(page.getRecords()); return page; } @Override public TStationCollect getStationCollectDetail(Long id) { if (id == null) { return null; } TStationCollect stationCollect = getById(id); if (stationCollect != null) { List stationCollectList = new ArrayList<>(1); stationCollectList.add(stationCollect); fillStationAddress(stationCollectList); } return stationCollect; } private void fillStationAddress(List stationCollectList) { if (stationCollectList == null || stationCollectList.isEmpty()) { return; } Set stationIds = stationCollectList.stream() .map(TStationCollect::getStationId) .filter(StringUtils::isNotBlank) .collect(Collectors.toSet()); if (stationIds.isEmpty()) { return; } List stationInfoList = stationInfoMapper.selectList( new LambdaQueryWrapper() .select(TStationInfo::getStationId, TStationInfo::getProvinceName, TStationInfo::getCityName, TStationInfo::getAreaName, TStationInfo::getAddress) .in(TStationInfo::getStationId, stationIds)); Map stationInfoMap = stationInfoList.stream() .filter(item -> StringUtils.isNotBlank(item.getStationId())) .collect(Collectors.toMap(TStationInfo::getStationId, Function.identity(), (first, ignored) -> first)); for (TStationCollect stationCollect : stationCollectList) { TStationInfo stationInfo = stationInfoMap.get(stationCollect.getStationId()); if (stationInfo != null) { stationCollect.setProvinceName(stationInfo.getProvinceName()); stationCollect.setCityName(stationInfo.getCityName()); stationCollect.setAreaName(stationInfo.getAreaName()); stationCollect.setAddress(stationInfo.getAddress()); } } } @Override @Transactional(rollbackFor = Exception.class) public boolean updateStationCollect(TStationCollect stationCollect) { if (stationCollect == null || stationCollect.getId() == null) { throw new ServiceException("逆变器记录ID不能为空"); } if (getById(stationCollect.getId()) == null) { throw new ServiceException("逆变器记录不存在"); } validate(stationCollect); if (lambdaQuery().eq(TStationCollect::getCollectId, stationCollect.getCollectId()) .ne(TStationCollect::getId, stationCollect.getId()).count() > 0) { throw new ServiceException("逆变器ID已存在"); } stationCollect.setCreateBy(null); stationCollect.setCreateTime(null); stationCollect.setDelFlag(null); stationCollect.setUpdateTime(LocalDateTime.now()); return updateById(stationCollect); } /** * 将第三方逆变器基础数据转换为实体并批量保存。 */ @Override @Transactional(rollbackFor = Exception.class) public boolean saveCollectBaseList(JSONArray collectBaseList) { if (collectBaseList == null || collectBaseList.isEmpty()) { return false; } Set existingKeys = getExistingCollectKeys(); // 数据库中存在的所有逆变器ID List stationCollectList = new ArrayList<>(collectBaseList.size()); for (Object item : collectBaseList) { JSONObject jsonObject = JSONObject.parseObject(item.toString()); TStationCollect stationCollect = buildStationCollect(jsonObject); if (existingKeys.contains(stationCollect.getCollectId())) { continue; } stationCollectList.add(stationCollect); } return !stationCollectList.isEmpty() && saveBatch(stationCollectList); } private TStationCollect buildStationCollect(JSONObject jsonObject) { String stationId = jsonObject.getString("stationId"); String stationName = jsonObject.getString("stationName"); String collectName = jsonObject.getString("collectName"); TStationCollect stationCollect = new TStationCollect(); stationCollect.setPlatformId(0L); stationCollect.setStationId(stationId); stationCollect.setStationName(stationName); stationCollect.setCollectId(jsonObject.getString("collectId")); stationCollect.setCollectName(collectName); stationCollect.setDeviceModel(jsonObject.getString("deviceModel")); stationCollect.setInverterId(jsonObject.getString("inverterId")); stationCollect.setInstalledCapacity(jsonObject.getString("capacity")); stationCollect.setPowerNum(parsePowerNum(jsonObject.getString("powerNum"))); stationCollect.setProvinceName(jsonObject.getString("province")); stationCollect.setCityName(jsonObject.getString("city")); stationCollect.setAreaName(jsonObject.getString("district")); stationCollect.setAddress(jsonObject.getString("address")); stationCollect.setLatitude(jsonObject.getString("lat")); stationCollect.setLongitude(jsonObject.getString("lon")); stationCollect.setDataSource(2); stationCollect.setSyncTime(LocalDateTime.now()); stationCollect.setCreateTime(parseDateTime(jsonObject.getString("saveTime"))); stationCollect.setUpdateTime(LocalDateTime.now()); fillDefaults(stationCollect); return stationCollect; } private Set getExistingCollectKeys() { List existingList = lambdaQuery().select(TStationCollect::getCollectId).list(); Set existingKeys = new HashSet<>(); for (TStationCollect stationCollect : existingList) { existingKeys.add(stationCollect.getCollectId()); } return existingKeys; } private void validate(TStationCollect stationCollect) { if (stationCollect == null) { throw new ServiceException("电站逆变器参数不能为空"); } if (stationCollect.getStationId() == null) { throw new ServiceException("电站ID不能为空"); } if (StringUtils.isBlank(stationCollect.getStationName())) { throw new ServiceException("电站名称不能为空"); } if (StringUtils.isBlank(stationCollect.getCollectName())) { throw new ServiceException("逆变器名称不能为空"); } } private void fillDefaults(TStationCollect stationCollect) { stationCollect.setPlatformId(stationCollect.getPlatformId() == null ? 0L : stationCollect.getPlatformId()); stationCollect.setPowerNum(stationCollect.getPowerNum() == null ? 0 : stationCollect.getPowerNum()); stationCollect.setStatus(StringUtils.isBlank(stationCollect.getStatus()) ? "0" : stationCollect.getStatus()); stationCollect.setSortOrder(stationCollect.getSortOrder() == null ? 0 : stationCollect.getSortOrder()); stationCollect.setCreateBy(StringUtils.defaultString(stationCollect.getCreateBy())); stationCollect.setUpdateBy(StringUtils.defaultString(stationCollect.getUpdateBy())); stationCollect.setDelFlag("0"); } private Long parseLong(String value) { if (StringUtils.isBlank(value)) { return null; } try { return Long.valueOf(value); } catch (NumberFormatException exception) { return null; } } private BigDecimal parseBigDecimal(String value) { if (StringUtils.isBlank(value)) { return BigDecimal.ZERO; } try { return new BigDecimal(value); } catch (NumberFormatException exception) { return BigDecimal.ZERO; } } private Integer parsePowerNum(String value) { if (StringUtils.isBlank(value)) { return 0; } String number = value.replaceAll("[^0-9.]", ""); if (StringUtils.isBlank(number)) { return 0; } try { return new BigDecimal(number).intValue(); } catch (NumberFormatException exception) { return 0; } } private Integer parseInteger(String value) { if (StringUtils.isBlank(value)) { return 0; } try { return Integer.valueOf(value); } catch (NumberFormatException exception) { return parsePowerNum(value); } } private LocalDateTime parseDateTime(String value) { if (StringUtils.isBlank(value)) { return null; } try { return LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } catch (DateTimeParseException exception) { return null; } } private String firstNotBlank(String preferred, String fallback) { return StringUtils.isNotBlank(preferred) ? preferred : fallback; } /** * 根据ids删除数据时,校验示范存在第三方同步的数据,第三方同步的数据不允许删除 * @param ids 数据id * @return true可以删除,false不可以删除 */ public Boolean validateDelete(Long[] ids) { if(ids != null && ids.length > 0) { List idList = Arrays.stream(ids).collect(Collectors.toList()); List infoList = lambdaQuery().eq(TStationCollect::getDataSource, 2).in(TStationCollect::getId, idList).list(); if(CollectionUtils.isNotEmpty(infoList) && !infoList.isEmpty()) { return false; } } return true; } /** * 将华为 FusionSolar 设备列表转换为逆变器记录并批量保存。 * devDn 作为设备唯一标识(接口未提供时使用 esnCode)。 */ @Override @Transactional(rollbackFor = Exception.class) public boolean saveCollectHuaWeiList(JSONArray devList) { if (devList == null || devList.isEmpty()) { return false; } Set existingKeys = getExistingCollectKeys(); Set pendingKeys = new HashSet<>(); List insertList = new ArrayList<>(devList.size()); for (Object item : devList) { if (item == null) { continue; } JSONObject json = JSONObject.parseObject(item.toString()); String collectId = firstNotBlank(json.getString("devDn"), json.getString("esnCode")); String stationId = json.getString("stationCode"); Integer devTypeId = json.getInteger("devTypeId"); if (StringUtils.isBlank(collectId) || StringUtils.isBlank(stationId) || existingKeys.contains(collectId) || !pendingKeys.add(collectId) || devTypeId != 1) { continue; } TStationCollect collect = new TStationCollect(); collect.setPlatformId(1L); collect.setStationId(stationId); collect.setStationName(firstNotBlank(json.getString("stationName"), "")); collect.setCollectId(collectId); collect.setCollectName(firstNotBlank(json.getString("devName"), collectId)); collect.setDeviceModel(firstNotBlank(json.getString("invType"), json.getString("model"))); collect.setInverterId(json.getString("esnCode")); collect.setInstalledCapacity(firstNotBlank(json.getString("capacity"), "0")); collect.setPowerNum(parseInteger(json.getString("optimizerNumber"))); collect.setLatitude(json.getString("latitude")); collect.setLongitude(json.getString("longitude")); collect.setStatus("1"); collect.setDataSource(2); collect.setSyncTime(LocalDateTime.now()); collect.setCreateTime(LocalDateTime.now()); collect.setUpdateTime(LocalDateTime.now()); fillDefaults(collect); insertList.add(collect); } // 设置电站名称 List infoList = stationInfoMapper.selectList(new LambdaQueryWrapper<>()); insertList.forEach(s -> infoList.forEach(info -> { if(StringUtils.isNotEmpty(s.getStationId()) && s.getStationId().equals(info.getStationId())) { s.setStationName(info.getStationName()); } })); return CollectionUtils.isNotEmpty(insertList) && saveBatch(insertList); } }