package com.ruoyi.other.service.impl;
|
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson2.JSONObject;
|
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.TStationInfo;
|
import com.ruoyi.other.mapper.TStationInfoMapper;
|
import com.ruoyi.other.service.TStationCollectService;
|
import com.ruoyi.other.service.TStationEarnService;
|
import com.ruoyi.other.service.TStationInfoService;
|
import com.ruoyi.other.query.StationInfoQuery;
|
import com.ruoyi.other.util.KsolarUtils;
|
import com.ruoyi.other.vo.StationInfoStatusVO;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.collections4.CollectionUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeParseException;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* 电站信息服务实现。
|
*/
|
@Service
|
@Slf4j
|
public class TStationInfoServiceImpl
|
extends ServiceImpl<TStationInfoMapper, TStationInfo>
|
implements TStationInfoService {
|
|
@Autowired
|
private TStationCollectService collectService;
|
@Autowired
|
private TStationEarnService stationEarnService;
|
|
|
/**
|
* 每天同步科士达数据到数据库
|
*/
|
@Transactional(rollbackFor = Exception.class)
|
public void syncKsolarDataTask() {
|
String token = KsolarUtils.token();
|
JSONObject statusJsonObj = KsolarUtils.getListStatus(token);
|
|
log.info("-------1开始同步科士达-电站列表信息----");
|
// 电站列表
|
JSONArray listInfoJsonArray = KsolarUtils.getStationListInfo(1, 1000, token);
|
// 电站基本信息列表
|
JSONArray listBaseJsonArray = KsolarUtils.getStationListBase(1, 1000, token);
|
List<TStationInfo> stationInfoList = build(listInfoJsonArray, listBaseJsonArray);
|
if(CollectionUtils.isNotEmpty(stationInfoList)) {
|
List<TStationInfo> existingStationList = lambdaQuery().select(TStationInfo::getStationId).list();
|
Set<String> existingStationIds = new HashSet<>();
|
for (TStationInfo stationInfo : existingStationList) {
|
if (stationInfo.getStationId() != null) {
|
existingStationIds.add(stationInfo.getStationId());
|
}
|
}
|
Set<String> pendingStationIds = new HashSet<>();
|
stationInfoList.removeIf(stationInfo -> stationInfo.getStationId() == null || existingStationIds.contains(stationInfo.getStationId()) || !pendingStationIds.add(stationInfo.getStationId()));
|
|
if (CollectionUtils.isNotEmpty(stationInfoList)) {
|
saveBatch(stationInfoList);
|
}
|
}
|
log.info("-------1结束同步科士达-电站列表信息----");
|
|
log.info("-------2开始同步科士达-逆变器列表----");
|
// 逆变器列表
|
JSONArray collectBaseList = KsolarUtils.getCollectBaseList(1, 1000, token);
|
collectService.saveCollectBaseList(collectBaseList);
|
log.info("-------2结束同步科士达-逆变器列表----");
|
|
log.info("-------3开始同步科士达-电站的电量和收益统计查询----");
|
LocalDate startDate = stationEarnService.getMaxSaveTime();
|
String startDateStr = "";
|
String endDateStr = "";
|
if(Objects.nonNull(startDate)) {
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
// String dateStr = startDate.plusDays(1).format(formatter);
|
String dateStr = startDate.format(formatter);
|
startDateStr = dateStr + " 00:00:00";
|
endDateStr = LocalDateTime.now().format(formatter);
|
}
|
JSONArray stationEarnList = KsolarUtils.getStationElecList(startDateStr, endDateStr, token);
|
stationEarnService.saveStationEarnList(stationEarnList);
|
log.info("-------3结束同步科士达-电站的电量和收益统计查询----");
|
}
|
|
|
/**
|
* 根据电站列表信息和电站基础信息批量构建电站对象。
|
* 两个数组通过 stationId 进行关联。
|
*/
|
public List<TStationInfo> build(JSONArray listInfoJsonArray, JSONArray listBaseJsonArray) {
|
if (listInfoJsonArray == null || listInfoJsonArray.isEmpty()) {
|
log.error("电站列表信息获取第三方API数据为空!");
|
return null;
|
}
|
Map<String, JSONObject> baseMap = buildBaseMap(listBaseJsonArray);
|
List<TStationInfo> stationInfoList = new ArrayList<>(listInfoJsonArray.size());
|
for (Object item : listInfoJsonArray) {
|
JSONObject info = JSONObject.parseObject(item.toString());
|
String stationId = info.getString("stationId");
|
if (StringUtils.isBlank(stationId)) {
|
log.error("电站列表信息中的stationId不能为空!");
|
continue;
|
}
|
stationInfoList.add(buildStationInfo(info, baseMap.get(stationId)));
|
}
|
return stationInfoList;
|
}
|
|
private TStationInfo buildStationInfo(JSONObject info, JSONObject base) {
|
String stationId = info.getString("stationId");
|
TStationInfo stationInfo = new TStationInfo();
|
stationInfo.setPlatformId(0L);
|
stationInfo.setStationId(stationId);
|
stationInfo.setStationName(info.getString("stationName"));
|
stationInfo.setStationType(info.getString("stationType"));
|
stationInfo.setRunStatus(info.getString("status"));
|
stationInfo.setRealtimePower(toBigDecimal(info, "powerInter"));
|
stationInfo.setInstalledCapacity(toBigDecimal(info, "installCapacity"));
|
stationInfo.setDailyGeneration(toBigDecimal(info, "dayGeneration"));
|
stationInfo.setDeviceCount(info.getInteger("collects"));
|
stationInfo.setAddress(info.getString("address"));
|
stationInfo.setStationImage(info.getString("stationImage"));
|
|
if (base != null) {
|
stationInfo.setStationName(firstNotBlank(base.getString("stationName"), stationInfo.getStationName()));
|
stationInfo.setInstalledCapacity(firstNotNull(
|
toBigDecimal(base, "installCapacity"), stationInfo.getInstalledCapacity()));
|
stationInfo.setAreaName(base.getString("areaName"));
|
stationInfo.setCityName(base.getString("cityName"));
|
stationInfo.setElecPrice(base.getString("elecPrice"));
|
stationInfo.setLatitude(base.getString("latitude"));
|
stationInfo.setLongitude(base.getString("longitude"));
|
stationInfo.setPhone(firstNotBlank(base.getString("Phone"), base.getString("phone")));
|
stationInfo.setProvinceName(base.getString("provinceName"));
|
stationInfo.setAddress(firstNotBlank(
|
base.getString("stationAddressDetail"), stationInfo.getAddress()));
|
stationInfo.setLoanStatus(base.getInteger("loanStatus"));
|
stationInfo.setGridStatus(Objects.equals(stationInfo.getLoanStatus(), 3) ? "1" : "0");
|
stationInfo.setDataTime(parseDataTime(base.getString("saveTime")));
|
}
|
|
stationInfo.setDataSource(2);
|
stationInfo.setSyncTime(LocalDateTime.now());
|
fillDefaults(stationInfo);
|
return stationInfo;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public boolean addStationInfo(TStationInfo stationInfo) {
|
validate(stationInfo);
|
stationInfo.setStationId("1"+System.currentTimeMillis());
|
stationInfo.setDataSource(1);
|
if (lambdaQuery().eq(TStationInfo::getPlatformId,
|
stationInfo.getPlatformId() == null ? 0L : stationInfo.getPlatformId())
|
.eq(TStationInfo::getStationId, stationInfo.getStationId()).count() > 0) {
|
throw new ServiceException("该平台下的电站信息已存在");
|
}
|
fillDefaults(stationInfo);
|
stationInfo.setId(null);
|
stationInfo.setCreateTime(LocalDateTime.now());
|
stationInfo.setUpdateTime(LocalDateTime.now());
|
return save(stationInfo);
|
}
|
|
@Override
|
public PageInfo<TStationInfo> pageList(StationInfoQuery query) {
|
if (query == null) query = new StationInfoQuery();
|
PageInfo<TStationInfo> page = new PageInfo<>(query.getPageCurr(), query.getPageSize());
|
lambdaQuery()
|
.eq(query.getPlatformId() != null, TStationInfo::getPlatformId, query.getPlatformId())
|
.like(StringUtils.isNotBlank(query.getStationName()), TStationInfo::getStationName, query.getStationName())
|
.eq(StringUtils.isNotBlank(query.getStationType()), TStationInfo::getStationType, query.getStationType())
|
.eq(StringUtils.isNotBlank(query.getRunStatus()), TStationInfo::getRunStatus, query.getRunStatus())
|
.eq(StringUtils.isNotBlank(query.getGridStatus()), TStationInfo::getGridStatus, query.getGridStatus())
|
.orderByAsc(TStationInfo::getSortOrder).orderByDesc(TStationInfo::getCreateTime).page(page);
|
return page;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public boolean updateStationInfo(TStationInfo stationInfo) {
|
if (stationInfo == null || stationInfo.getId() == null) throw new ServiceException("电站信息ID不能为空");
|
TStationInfo old = getById(stationInfo.getId());
|
if (old == null) throw new ServiceException("电站信息不存在");
|
if (stationInfo.getStationId() != null && lambdaQuery()
|
.eq(TStationInfo::getPlatformId, stationInfo.getPlatformId() == null ? old.getPlatformId() : stationInfo.getPlatformId())
|
.eq(TStationInfo::getStationId, stationInfo.getStationId()).ne(TStationInfo::getId, stationInfo.getId()).count() > 0) {
|
throw new ServiceException("该平台下的电站信息已存在");
|
}
|
stationInfo.setCreateBy(null); stationInfo.setCreateTime(null); stationInfo.setDelFlag(null);
|
stationInfo.setUpdateTime(LocalDateTime.now());
|
return updateById(stationInfo);
|
}
|
|
private void validate(TStationInfo stationInfo) {
|
if (stationInfo == null) {
|
throw new ServiceException("电站信息参数不能为空");
|
}
|
if (StringUtils.isBlank(stationInfo.getStationName())) {
|
throw new ServiceException("电站名称不能为空");
|
}
|
}
|
|
private void fillDefaults(TStationInfo stationInfo) {
|
stationInfo.setPlatformId(stationInfo.getPlatformId() == null ? 0L : stationInfo.getPlatformId());
|
stationInfo.setStationType(StringUtils.isBlank(stationInfo.getStationType()) ? "1" : stationInfo.getStationType());
|
stationInfo.setRunStatus(StringUtils.isBlank(stationInfo.getRunStatus()) ? "0" : stationInfo.getRunStatus());
|
stationInfo.setInstalledCapacity(stationInfo.getInstalledCapacity() == null
|
? BigDecimal.ZERO : stationInfo.getInstalledCapacity());
|
stationInfo.setRealtimePower(stationInfo.getRealtimePower() == null
|
? BigDecimal.ZERO : stationInfo.getRealtimePower());
|
stationInfo.setDeviceCount(stationInfo.getDeviceCount() == null ? 0 : stationInfo.getDeviceCount());
|
stationInfo.setDailyGeneration(stationInfo.getDailyGeneration() == null
|
? BigDecimal.ZERO : stationInfo.getDailyGeneration());
|
stationInfo.setGridStatus(StringUtils.isBlank(stationInfo.getGridStatus()) ? "0" : stationInfo.getGridStatus());
|
stationInfo.setSortOrder(stationInfo.getSortOrder() == null ? 0 : stationInfo.getSortOrder());
|
stationInfo.setCreateBy(StringUtils.defaultString(stationInfo.getCreateBy()));
|
stationInfo.setUpdateBy(StringUtils.defaultString(stationInfo.getUpdateBy()));
|
stationInfo.setDelFlag("0");
|
}
|
|
private Map<String, JSONObject> buildBaseMap(JSONArray jsonArray) {
|
Map<String, JSONObject> baseMap = new HashMap<>();
|
if (jsonArray != null) {
|
for (Object item : jsonArray) {
|
JSONObject object = JSONObject.parseObject(item.toString());
|
String stationId = object.getString("stationId");
|
if (StringUtils.isNotBlank(stationId)) {
|
baseMap.put(stationId, object);
|
}
|
}
|
}
|
return baseMap;
|
}
|
|
private Long parseStationId(String stationId) {
|
try {
|
return Long.valueOf(stationId);
|
} catch (NumberFormatException exception) {
|
log.error("stationId格式不正确:" + stationId);
|
return null;
|
}
|
}
|
|
private BigDecimal toBigDecimal(JSONObject object, String key) {
|
if (object == null || object.get(key) == null || StringUtils.isBlank(object.getString(key))) {
|
return null;
|
}
|
try {
|
return new BigDecimal(object.getString(key));
|
} catch (NumberFormatException exception) {
|
log.error(key + "格式不正确:" + object.getString(key));
|
return null;
|
}
|
}
|
|
private LocalDateTime parseDataTime(String value) {
|
if (StringUtils.isBlank(value)) {
|
return null;
|
}
|
DateTimeFormatter[] dateTimeFormatters = {
|
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
|
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")
|
};
|
for (DateTimeFormatter formatter : dateTimeFormatters) {
|
try {
|
return LocalDateTime.parse(value, formatter);
|
} catch (DateTimeParseException ignored) {
|
// 尝试下一个时间格式
|
}
|
}
|
try {
|
return LocalDate.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay();
|
} catch (DateTimeParseException exception) {
|
log.error("saveTime格式不正确:" + value);
|
return null;
|
}
|
}
|
|
private String firstNotBlank(String preferred, String fallback) {
|
return StringUtils.isNotBlank(preferred) ? preferred : fallback;
|
}
|
|
private <T> T firstNotNull(T preferred, T fallback) {
|
return preferred != null ? preferred : fallback;
|
}
|
|
/**
|
* 实时获取电站状态
|
*/
|
public StationInfoStatusVO getStationStatus() {
|
StationInfoStatusVO statusVO = new StationInfoStatusVO();
|
String token = KsolarUtils.token();
|
JSONObject statusJsonObj = KsolarUtils.getListStatus(token);
|
JSONObject earnJsonObj = KsolarUtils.getListEarn("", token);
|
if(Objects.nonNull(statusJsonObj)) {
|
statusVO.setAlarm(statusJsonObj.getInteger("alarm"));
|
statusVO.setOffline(statusJsonObj.getInteger("offline"));
|
statusVO.setOnline(statusJsonObj.getInteger("online"));
|
statusVO.setTotal(statusJsonObj.getInteger("total"));
|
}
|
if(Objects.nonNull(earnJsonObj)) {
|
statusVO.setRealPower(earnJsonObj.getDouble("realPower"));
|
statusVO.setDayGeneration(earnJsonObj.getDouble("dayGeneration"));
|
}
|
// 统计电站数量
|
List<TStationInfo> stationInfoList = lambdaQuery().eq(TStationInfo::getDelFlag, "0").list();
|
if(CollectionUtils.isNotEmpty(stationInfoList)) {
|
statusVO.setStationCount(stationInfoList.size());
|
List<TStationInfo> onStatusList = stationInfoList.stream().filter(s -> Objects.nonNull(s.getLoanStatus()) && s.getLoanStatus() == 3).collect(Collectors.toList());
|
statusVO.setOnStatusCount(onStatusList.size());
|
statusVO.setOffStatusCount(stationInfoList.size() - onStatusList.size());
|
}
|
return statusVO;
|
}
|
|
/**
|
* 根据ids删除数据时,校验示范存在第三方同步的数据,第三方同步的数据不允许删除
|
* @param ids 数据id
|
* @return true可以删除,false不可以删除
|
*/
|
public Boolean validateDelete(Long[] ids) {
|
if(ids != null && ids.length > 0) {
|
List<Long> idList = Arrays.stream(ids).collect(Collectors.toList());
|
List<TStationInfo> infoList = lambdaQuery().eq(TStationInfo::getDataSource, 2).in(TStationInfo::getId, idList).list();
|
if(CollectionUtils.isNotEmpty(infoList) && !infoList.isEmpty()) {
|
return false;
|
}
|
}
|
return true;
|
}
|
|
}
|