puzhibing
4 天以前 a7d9fba4c1d0b021e017abd70d1b37ba87ebae1e
ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/service/impl/TStationInfoServiceImpl.java
@@ -13,6 +13,7 @@
import com.ruoyi.other.service.TStationInfoService;
import com.ruoyi.other.query.StationInfoQuery;
import com.ruoyi.other.util.KsolarUtils;
import com.ruoyi.other.util.HuWeiUtils;
import com.ruoyi.other.vo.StationInfoStatusVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
@@ -23,15 +24,12 @@
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -48,6 +46,8 @@
    @Autowired
    private TStationEarnService stationEarnService;
    @Autowired
    private HuWeiUtils huWeiUtils;
    /**
     * 每天同步科士达数据到数据库
@@ -55,7 +55,7 @@
    @Transactional(rollbackFor = Exception.class)
    public void syncKsolarDataTask() {
        String token = KsolarUtils.token();
        JSONObject statusJsonObj = KsolarUtils.getListStatus(token);
        //JSONObject statusJsonObj = KsolarUtils.getListStatus(token);
        log.info("-------1开始同步科士达-电站列表信息----");
        // 电站列表
@@ -63,19 +63,41 @@
        // 电站基本信息列表
        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());
            // 去除stationInfoList中的重复stationId
            Map<String, TStationInfo> stationMap = stationInfoList.stream().filter(item -> StringUtils.isNotEmpty(item.getStationId()))
                    .collect(Collectors.toMap(TStationInfo::getStationId, Function.identity(), (o1, o2) -> o2));
            stationInfoList = new ArrayList<>(stationMap.values());
            // 查询数据库已有数据
            List<TStationInfo> existingStationList = lambdaQuery().in(TStationInfo::getStationId, stationMap.keySet()).list();
            // 转Map,方便查找
            Map<String, TStationInfo> existingMap = existingStationList.stream().collect(Collectors.toMap(TStationInfo::getStationId, Function.identity()));
            List<TStationInfo> insertList = new ArrayList<>();
            List<TStationInfo> updateList = new ArrayList<>();
            for (TStationInfo station : stationInfoList) {
                TStationInfo dbStation = existingMap.get(station.getStationId());
                if (dbStation == null) {
                    // 数据库不存在
                    insertList.add(station);
                } else {
                    // 数据库存在,需要更新;保留数据库主键,否则updateBatchById无法更新
                    station.setId(dbStation.getId());
                    updateList.add(station);
                }
            }
            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);
            // 批量新增
            if (CollectionUtils.isNotEmpty(insertList)) {
                saveBatch(insertList);
            }
            // 批量更新
            if (CollectionUtils.isNotEmpty(updateList)) {
                updateBatchById(updateList);
            }
        }
        log.info("-------1结束同步科士达-电站列表信息----");
@@ -87,16 +109,8 @@
        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);
        }
        String startDateStr = buildSyncStartDate(LocalDate.now());
        String endDateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        JSONArray stationEarnList = KsolarUtils.getStationElecList(startDateStr, endDateStr, token);
        stationEarnService.saveStationEarnList(stationEarnList);
        log.info("-------3结束同步科士达-电站的电量和收益统计查询----");
@@ -254,6 +268,10 @@
        return baseMap;
    }
    static String buildSyncStartDate(LocalDate date) {
        return date.withDayOfYear(1).format(DateTimeFormatter.ISO_LOCAL_DATE) + " 00:00:00";
    }
    private Long parseStationId(String stationId) {
        try {
            return Long.valueOf(stationId);
@@ -298,6 +316,21 @@
        }
    }
    private LocalDateTime parseHuaweiDateTime(String value) {
        if (StringUtils.isBlank(value)) {
            return null;
        }
        try {
            return OffsetDateTime.parse(value).toLocalDateTime();
        } catch (DateTimeParseException ignored) {
            try {
                return ZonedDateTime.parse(value).toLocalDateTime();
            } catch (DateTimeParseException ignoredAgain) {
                return parseDataTime(value);
            }
        }
    }
    private String firstNotBlank(String preferred, String fallback) {
        return StringUtils.isNotBlank(preferred) ? preferred : fallback;
    }
@@ -332,6 +365,104 @@
            statusVO.setOnStatusCount(onStatusList.size());
            statusVO.setOffStatusCount(stationInfoList.size() - onStatusList.size());
        }
        // 电站状态数量加上非科士达的数据
        List<TStationInfo> noKeShiDaList = stationInfoList.stream().filter(s -> s.getPlatformId() != 0).collect(Collectors.toList());
        statusVO.setTotal(statusVO.getTotal() + noKeShiDaList.size());
        statusVO.setOnline(statusVO.getOnline() + noKeShiDaList.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;
    }
    /**
     * 同步华为 FusionSolar 电站数据。
     * 电站编号 plantCode 作为系统中的 stationId,仅插入数据库中不存在的电站。
     */
    @Transactional(rollbackFor = Exception.class)
    public void syncHuaWeiDataTask() {
        log.info("-------1、开始同步华为电站列表信息----");
        String token = huWeiUtils.getXsrfToken();
        JSONArray stationArray = huWeiUtils.getStations(1, token);
        Set<String> stationIds = new HashSet<>();
        if (CollectionUtils.isNotEmpty(stationArray)) {
            List<TStationInfo> insertList = new ArrayList<>();
            huaWeiBuild(stationArray, stationIds, insertList);
            if (CollectionUtils.isNotEmpty(insertList)) {
                List<TStationInfo> existing = lambdaQuery().eq(TStationInfo::getPlatformId, 1L).in(TStationInfo::getStationId, stationIds).list();
                Set<String> existingIds = existing.stream().map(TStationInfo::getStationId).collect(Collectors.toSet());
                insertList.removeIf(item -> existingIds.contains(item.getStationId()));
                if (CollectionUtils.isNotEmpty(insertList)) {
                    saveBatch(insertList);
                }
            }
            log.info("-------1、结束同步华为电站列表信息,本次新增{}条----", insertList.size());
        }
        log.info("-------2、开始同步华为设备列表信息----");
        if(CollectionUtils.isNotEmpty(stationIds)) {
            String codes = String.join(",", stationIds);
            JSONArray devList = huWeiUtils.getDevList(codes, token);
            collectService.saveCollectHuaWeiList(devList);
        }
        log.info("-------3、开始同步华为电站日数据信息----");
        List<TStationInfo> existInfos = lambdaQuery().eq(TStationInfo::getPlatformId, 1L).list();
        Set<String> existIds = existInfos.stream().map(TStationInfo::getStationId).collect(Collectors.toSet());
        if(CollectionUtils.isNotEmpty(existIds)) {
            String codes = String.join(",", existIds);
            JSONArray stationDayList = huWeiUtils.getKpiStationDay(codes, System.currentTimeMillis(), token);
            stationEarnService.saveStationHuaWeiList(stationDayList);
        }
        log.info("-------3、结束同步华为电站日数据信息----");
    }
    public void huaWeiBuild(JSONArray stationArray, Set<String> stationIds, List<TStationInfo> insertList) {
        for (Object item : stationArray) {
            JSONObject json = JSONObject.parseObject(item.toString());
            String stationId = json.getString("plantCode");
            if (StringUtils.isBlank(stationId) || !stationIds.add(stationId)) {
                continue;
            }
            TStationInfo info = new TStationInfo();
            info.setPlatformId(1L);
            info.setStationId(stationId);
            info.setStationName(json.getString("plantName"));
            info.setStationType("1");
            info.setRunStatus("0");
            info.setInstalledCapacity(toBigDecimal(json, "capacity"));
            info.setContactName(json.getString("contactPerson"));
            info.setPhone(json.getString("contactMethod"));
            info.setLatitude(json.getString("latitude"));
            info.setLongitude(json.getString("longitude"));
            info.setAddress(json.getString("plantAddress"));
            LocalDateTime gridTime = parseHuaweiDateTime(json.getString("gridConnectionDate"));
            info.setDataTime(gridTime);
            info.setLoanStatus(gridTime != null && gridTime.isBefore(LocalDateTime.now()) ? 3 : 1);
            info.setGridStatus(info.getLoanStatus() == 3 ? "1" : "0");
            info.setDataSource(2);
            info.setSyncTime(LocalDateTime.now());
            info.setCreateTime(LocalDateTime.now());
            info.setUpdateTime(LocalDateTime.now());
            fillDefaults(info);
            insertList.add(info);
        }
    }
}