| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890 |
- package com.zsElectric.boot.business.service.impl;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.baomidou.mybatisplus.core.metadata.IPage;
- import com.baomidou.mybatisplus.core.toolkit.Wrappers;
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.core.type.TypeReference;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.zsElectric.boot.charging.entity.*;
- import com.zsElectric.boot.business.mapper.FirmInfoMapper;
- import com.zsElectric.boot.business.mapper.PolicyFeeMapper;
- import com.zsElectric.boot.business.mapper.ThirdPartyEquipmentInfoMapper;
- import com.zsElectric.boot.business.mapper.ThirdPartyInfoMapper;
- import com.zsElectric.boot.business.mapper.ThirdPartyStationInfoMapper;
- import com.zsElectric.boot.charging.mapper.ThirdPartyConnectorInfoMapper;
- import com.zsElectric.boot.charging.mapper.ThirdPartyEquipmentPricePolicyMapper;
- import com.zsElectric.boot.charging.mapper.ThirdPartyPolicyInfoMapper;
- import com.zsElectric.boot.business.model.entity.FirmInfo;
- import com.zsElectric.boot.business.model.entity.PolicyFee;
- import com.zsElectric.boot.business.model.entity.ThirdPartyInfo;
- import com.zsElectric.boot.business.model.query.ThirdPartyEquipmentInfoQuery;
- import com.zsElectric.boot.business.model.query.ThirdPartyStationInfoQuery;
- import com.zsElectric.boot.business.model.vo.PartyStationInfoVO;
- import com.zsElectric.boot.business.model.vo.ThirdPartyEquipmentInfoVO;
- import com.zsElectric.boot.business.model.vo.ThirdPartyStationInfoVO;
- import com.zsElectric.boot.business.model.vo.StationDetailVO;
- import com.zsElectric.boot.business.model.dto.StationDetailDTO;
- import com.zsElectric.boot.business.service.ThirdPartyChargingService;
- import com.zsElectric.boot.charging.vo.ChargingPricePolicyVO;
- import com.zsElectric.boot.charging.vo.QueryStationsInfoVO;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import org.springframework.util.CollectionUtils;
- import java.math.BigDecimal;
- import java.time.LocalDateTime;
- import java.util.Comparator;
- import java.util.List;
- import java.util.Map;
- import java.util.Objects;
- import java.util.stream.Collectors;
- /**
- * 第三方充电站/充电桩/价格策略统一服务实现
- *
- * @author system
- * @since 2025-12-15
- */
- @Slf4j
- @Service
- @RequiredArgsConstructor
- public class ThirdPartyChargingServiceImpl implements ThirdPartyChargingService {
- private final ThirdPartyStationInfoMapper stationInfoMapper;
- private final ThirdPartyEquipmentInfoMapper equipmentInfoMapper;
- private final ThirdPartyConnectorInfoMapper connectorInfoMapper;
- private final ThirdPartyEquipmentPricePolicyMapper pricePolicyMapper;
- private final ThirdPartyPolicyInfoMapper policyInfoMapper;
- private final FirmInfoMapper firmInfoMapper;
- private final ThirdPartyInfoMapper thirdPartyInfoMapper;
- private final PolicyFeeMapper policyFeeMapper;
- private final ObjectMapper objectMapper;
- // ==================== 充电站信息查询 ====================
- @Override
- public IPage<ThirdPartyStationInfoVO> getStationInfoPage(ThirdPartyStationInfoQuery queryParams) {
- // 构建分页
- Page<ThirdPartyStationInfoVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
- // 调用Mapper联表查询
- return stationInfoMapper.selectStationInfoPage(page, queryParams);
- }
- // ==================== 充电桩信息查询 ====================
- @Override
- public IPage<ThirdPartyEquipmentInfoVO> getEquipmentInfoPage(ThirdPartyEquipmentInfoQuery queryParams) {
- // 构建分页
- Page<ThirdPartyEquipmentInfoVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
- // 调用Mapper联表查询
- return equipmentInfoMapper.selectEquipmentInfoPage(page, queryParams);
- }
- @Override
- public List<PartyStationInfoVO> getPartyStationInfo() {
- // 查询所有设备信息
- List<ThirdPartyEquipmentInfo> equipmentInfos = equipmentInfoMapper.selectList(null);
- // 获取所有不重复的充电站ID
- List<String> stationIds = equipmentInfos.stream()
- .map(ThirdPartyEquipmentInfo::getStationId)
- .distinct()
- .collect(Collectors.toList());
- if (stationIds.isEmpty()) {
- return List.of();
- }
- // 查询充电站信息
- List<ThirdPartyStationInfo> stationInfos = stationInfoMapper.selectList(
- new LambdaQueryWrapper<ThirdPartyStationInfo>()
- .in(ThirdPartyStationInfo::getStationId, stationIds)
- );
- // 转换为VO
- return stationInfos.stream()
- .map(station -> {
- PartyStationInfoVO vo = new PartyStationInfoVO();
- vo.setId(station.getId());
- vo.setStationName(station.getStationName());
- return vo;
- })
- .collect(Collectors.toList());
- }
- // ==================== 充电站数据保存 ====================
- @Override
- @Transactional(rollbackFor = Exception.class)
- public void saveStationsInfo(QueryStationsInfoVO queryStationsInfoVO) {
- if (queryStationsInfoVO == null || CollectionUtils.isEmpty(queryStationsInfoVO.getStationInfos())) {
- log.warn("充电站信息为空,跳过存储");
- return;
- }
- List<StationInfo> stationInfos = queryStationsInfoVO.getStationInfos();
- log.info("开始保存充电站信息,总数: {}", stationInfos.size());
- for (StationInfo stationInfo : stationInfos) {
- try {
- // 保存充电站信息
- saveStationInfo(stationInfo);
- // 保存设备信息
- if (!CollectionUtils.isEmpty(stationInfo.getEquipmentInfos())) {
- for (EquipmentInfo equipmentInfo : stationInfo.getEquipmentInfos()) {
- saveEquipmentInfo(equipmentInfo, stationInfo.getStationID());
- // 保存接口信息
- if (!CollectionUtils.isEmpty(equipmentInfo.getConnectorInfos())) {
- for (ConnectorInfo connectorInfo : equipmentInfo.getConnectorInfos()) {
- saveConnectorInfo(connectorInfo, equipmentInfo.getEquipmentID(), stationInfo.getStationID());
- }
- }
- }
- }
- } catch (Exception e) {
- log.error("保存充电站信息失败, stationId: {}", stationInfo.getStationID(), e);
- throw new RuntimeException("保存充电站信息失败: " + stationInfo.getStationID(), e);
- }
- }
- log.info("充电站信息保存完成");
- }
- /**
- * 保存充电站信息
- */
- private void saveStationInfo(StationInfo stationInfo) {
- // 查询是否已存在
- ThirdPartyStationInfo existingStation = stationInfoMapper.selectOne(
- new LambdaQueryWrapper<ThirdPartyStationInfo>()
- .eq(ThirdPartyStationInfo::getStationId, stationInfo.getStationID())
- );
- ThirdPartyStationInfo entity = buildStationEntity(stationInfo, existingStation);
- if (existingStation == null) {
- // 不存在,执行新增
- stationInfoMapper.insert(entity);
- log.debug("充电站信息新增成功 - stationId: {}", stationInfo.getStationID());
- } else if (!isStationSame(existingStation, entity)) {
- // 存在且数据变化,执行更新
- stationInfoMapper.updateById(entity);
- log.debug("充电站信息更新成功 - stationId: {}", stationInfo.getStationID());
- } else {
- log.debug("充电站信息未变化,跳过保存 - stationId: {}", stationInfo.getStationID());
- }
- }
- /**
- * 构建充电站实体
- */
- private ThirdPartyStationInfo buildStationEntity(StationInfo stationInfo, ThirdPartyStationInfo existingStation) {
- ThirdPartyStationInfo entity = new ThirdPartyStationInfo();
- if (existingStation != null) {
- entity.setId(existingStation.getId());
- // 保留原有的自有字段(不会被第三方接口覆盖)
- entity.setPolicyConfigured(existingStation.getPolicyConfigured());
- entity.setStationTips(existingStation.getStationTips());
- entity.setOwnBusinessHours(existingStation.getOwnBusinessHours());
- entity.setCustomerServiceHotline(existingStation.getCustomerServiceHotline());
- entity.setBannerPictures(existingStation.getBannerPictures());
- }
- // 设置字段值
- entity.setStationId(stationInfo.getStationID());
- entity.setOperatorId(stationInfo.getOperatorID());
- entity.setEquipmentOwnerId(stationInfo.getEquipmentOwnerID());
- entity.setStationName(stationInfo.getStationName());
- entity.setCountryCode(stationInfo.getCountryCode());
- entity.setAreaCode(stationInfo.getAreaCode());
- entity.setAddress(stationInfo.getAddress());
- entity.setStationTel(stationInfo.getStationTel());
- entity.setServiceTel(stationInfo.getServiceTel());
- entity.setStationType(stationInfo.getStationType());
- entity.setStationStatus(stationInfo.getStationStatus());
- entity.setParkNums(stationInfo.getParkNums());
- // 处理经纬度
- if (stationInfo.getStationLng() != null) {
- entity.setStationLng(BigDecimal.valueOf(stationInfo.getStationLng()));
- }
- if (stationInfo.getStationLat() != null) {
- entity.setStationLat(BigDecimal.valueOf(stationInfo.getStationLat()));
- }
- entity.setSiteGuide(stationInfo.getSiteGuide());
- entity.setConstruction(stationInfo.getConstruction());
- // 处理图片列表(转JSON)
- if (!CollectionUtils.isEmpty(stationInfo.getPictures())) {
- try {
- entity.setPictures(objectMapper.writeValueAsString(stationInfo.getPictures()));
- } catch (JsonProcessingException e) {
- log.warn("图片列表转JSON失败", e);
- }
- }
- entity.setBusineHours(stationInfo.getBusineHours());
- // 处理费用(字符串转BigDecimal)
- if (stationInfo.getElectricityFee() != null) {
- try {
- entity.setElectricityFee(new BigDecimal(stationInfo.getElectricityFee()));
- } catch (NumberFormatException e) {
- log.warn("电费转换失败: {}", stationInfo.getElectricityFee(), e);
- }
- }
- if (stationInfo.getServiceFee() != null) {
- try {
- entity.setServiceFee(new BigDecimal(stationInfo.getServiceFee()));
- } catch (NumberFormatException e) {
- log.warn("服务费转换失败: {}", stationInfo.getServiceFee(), e);
- }
- }
- entity.setParkFee(stationInfo.getParkFee());
- entity.setPayment(stationInfo.getPayment());
- entity.setSupportOrder(stationInfo.getSupportOrder());
- entity.setRemark(stationInfo.getRemark());
- return entity;
- }
- /**
- * 判断充电站信息是否相同
- */
- private boolean isStationSame(ThirdPartyStationInfo existing, ThirdPartyStationInfo newEntity) {
- return Objects.equals(existing.getOperatorId(), newEntity.getOperatorId()) &&
- Objects.equals(existing.getEquipmentOwnerId(), newEntity.getEquipmentOwnerId()) &&
- Objects.equals(existing.getStationName(), newEntity.getStationName()) &&
- Objects.equals(existing.getCountryCode(), newEntity.getCountryCode()) &&
- Objects.equals(existing.getAreaCode(), newEntity.getAreaCode()) &&
- Objects.equals(existing.getAddress(), newEntity.getAddress()) &&
- Objects.equals(existing.getStationTel(), newEntity.getStationTel()) &&
- Objects.equals(existing.getServiceTel(), newEntity.getServiceTel()) &&
- Objects.equals(existing.getStationType(), newEntity.getStationType()) &&
- Objects.equals(existing.getStationStatus(), newEntity.getStationStatus()) &&
- Objects.equals(existing.getParkNums(), newEntity.getParkNums()) &&
- isBigDecimalEqual(existing.getStationLng(), newEntity.getStationLng()) &&
- isBigDecimalEqual(existing.getStationLat(), newEntity.getStationLat()) &&
- Objects.equals(existing.getSiteGuide(), newEntity.getSiteGuide()) &&
- Objects.equals(existing.getConstruction(), newEntity.getConstruction()) &&
- Objects.equals(existing.getPictures(), newEntity.getPictures()) &&
- Objects.equals(existing.getBusineHours(), newEntity.getBusineHours()) &&
- isBigDecimalEqual(existing.getElectricityFee(), newEntity.getElectricityFee()) &&
- isBigDecimalEqual(existing.getServiceFee(), newEntity.getServiceFee()) &&
- Objects.equals(existing.getParkFee(), newEntity.getParkFee()) &&
- Objects.equals(existing.getPayment(), newEntity.getPayment()) &&
- Objects.equals(existing.getSupportOrder(), newEntity.getSupportOrder()) &&
- Objects.equals(existing.getRemark(), newEntity.getRemark());
- }
- /**
- * 保存充电设备信息
- */
- private void saveEquipmentInfo(EquipmentInfo equipmentInfo, String stationId) {
- // 查询是否已存在
- ThirdPartyEquipmentInfo existingEquipment = equipmentInfoMapper.selectOne(
- new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
- .eq(ThirdPartyEquipmentInfo::getEquipmentId, equipmentInfo.getEquipmentID())
- );
- ThirdPartyEquipmentInfo entity = buildEquipmentEntity(equipmentInfo, stationId, existingEquipment);
- if (existingEquipment == null) {
- // 不存在,执行新增
- equipmentInfoMapper.insert(entity);
- log.debug("充电设备信息新增成功 - equipmentId: {}", equipmentInfo.getEquipmentID());
- } else if (!isEquipmentSame(existingEquipment, entity)) {
- // 存在且数据变化,执行更新
- equipmentInfoMapper.updateById(entity);
- log.debug("充电设备信息更新成功 - equipmentId: {}", equipmentInfo.getEquipmentID());
- } else {
- log.debug("充电设备信息未变化,跳过保存 - equipmentId: {}", equipmentInfo.getEquipmentID());
- }
- }
- /**
- * 构建充电设备实体
- */
- private ThirdPartyEquipmentInfo buildEquipmentEntity(EquipmentInfo equipmentInfo, String stationId, ThirdPartyEquipmentInfo existingEquipment) {
- ThirdPartyEquipmentInfo entity = new ThirdPartyEquipmentInfo();
- if (existingEquipment != null) {
- entity.setId(existingEquipment.getId());
- }
- // 设置字段值
- entity.setEquipmentId(equipmentInfo.getEquipmentID());
- entity.setStationId(stationId);
- entity.setManufacturerId(equipmentInfo.getManufacturerID());
- entity.setManufacturerName(equipmentInfo.getManufacturerName());
- entity.setEquipmentModel(equipmentInfo.getEquipmentModel());
- entity.setProductionDate(equipmentInfo.getProductionDate());
- entity.setEquipmentType(equipmentInfo.getEquipmentType());
- // 处理经纬度
- if (equipmentInfo.getEquipmentLng() != null) {
- entity.setEquipmentLng(BigDecimal.valueOf(equipmentInfo.getEquipmentLng()));
- }
- if (equipmentInfo.getEquipmentLat() != null) {
- entity.setEquipmentLat(BigDecimal.valueOf(equipmentInfo.getEquipmentLat()));
- }
- // 处理功率
- if (equipmentInfo.getPower() != null) {
- entity.setPower(BigDecimal.valueOf(equipmentInfo.getPower()));
- }
- entity.setEquipmentName(equipmentInfo.getEquipmentName());
- return entity;
- }
- /**
- * 判断充电设备信息是否相同
- */
- private boolean isEquipmentSame(ThirdPartyEquipmentInfo existing, ThirdPartyEquipmentInfo newEntity) {
- return Objects.equals(existing.getStationId(), newEntity.getStationId()) &&
- Objects.equals(existing.getManufacturerId(), newEntity.getManufacturerId()) &&
- Objects.equals(existing.getManufacturerName(), newEntity.getManufacturerName()) &&
- Objects.equals(existing.getEquipmentModel(), newEntity.getEquipmentModel()) &&
- Objects.equals(existing.getProductionDate(), newEntity.getProductionDate()) &&
- Objects.equals(existing.getEquipmentType(), newEntity.getEquipmentType()) &&
- isBigDecimalEqual(existing.getEquipmentLng(), newEntity.getEquipmentLng()) &&
- isBigDecimalEqual(existing.getEquipmentLat(), newEntity.getEquipmentLat()) &&
- isBigDecimalEqual(existing.getPower(), newEntity.getPower()) &&
- Objects.equals(existing.getEquipmentName(), newEntity.getEquipmentName());
- }
- /**
- * 保存充电接口信息
- */
- private void saveConnectorInfo(ConnectorInfo connectorInfo, String equipmentId, String stationId) {
- // 查询是否已存在
- ThirdPartyConnectorInfo existingConnector = connectorInfoMapper.selectOne(
- new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
- .eq(ThirdPartyConnectorInfo::getConnectorId, connectorInfo.getConnectorID())
- );
- ThirdPartyConnectorInfo entity = buildConnectorEntity(connectorInfo, equipmentId, stationId, existingConnector);
- if (existingConnector == null) {
- // 不存在,执行新增
- connectorInfoMapper.insert(entity);
- log.debug("充电接口信息新增成功 - connectorId: {}", connectorInfo.getConnectorID());
- } else if (!isConnectorSame(existingConnector, entity)) {
- // 存在且数据变化,执行更新
- connectorInfoMapper.updateById(entity);
- log.debug("充电接口信息更新成功 - connectorId: {}", connectorInfo.getConnectorID());
- } else {
- log.debug("充电接口信息未变化,跳过保存 - connectorId: {}", connectorInfo.getConnectorID());
- }
- }
- /**
- * 构建充电接口实体
- */
- private ThirdPartyConnectorInfo buildConnectorEntity(ConnectorInfo connectorInfo, String equipmentId, String stationId, ThirdPartyConnectorInfo existingConnector) {
- ThirdPartyConnectorInfo entity = new ThirdPartyConnectorInfo();
- if (existingConnector != null) {
- entity.setId(existingConnector.getId());
- // 保留原有的status字段,该字段由设备状态推送接口单独维护
- entity.setStatus(existingConnector.getStatus());
- }
- // 设置字段值
- entity.setConnectorId(connectorInfo.getConnectorID());
- entity.setEquipmentId(equipmentId);
- entity.setStationId(stationId);
- entity.setConnectorName(connectorInfo.getConnectorName());
- entity.setConnectorType(connectorInfo.getConnectorType());
- entity.setVoltageUpperLimits(connectorInfo.getVoltageUpperLimits());
- entity.setVoltageLowerLimits(connectorInfo.getVoltageLowerLimits());
- entity.setCurrent(connectorInfo.getCurrent());
- // 处理功率
- if (connectorInfo.getPower() != null) {
- entity.setPower(BigDecimal.valueOf(connectorInfo.getPower()));
- }
- entity.setParkNo(connectorInfo.getParkNo());
- entity.setNationalStandard(connectorInfo.getNationalStandard());
- return entity;
- }
- /**
- * 判断充电接口信息是否相同
- */
- private boolean isConnectorSame(ThirdPartyConnectorInfo existing, ThirdPartyConnectorInfo newEntity) {
- return Objects.equals(existing.getEquipmentId(), newEntity.getEquipmentId()) &&
- Objects.equals(existing.getStationId(), newEntity.getStationId()) &&
- Objects.equals(existing.getConnectorName(), newEntity.getConnectorName()) &&
- Objects.equals(existing.getConnectorType(), newEntity.getConnectorType()) &&
- Objects.equals(existing.getVoltageUpperLimits(), newEntity.getVoltageUpperLimits()) &&
- Objects.equals(existing.getVoltageLowerLimits(), newEntity.getVoltageLowerLimits()) &&
- Objects.equals(existing.getCurrent(), newEntity.getCurrent()) &&
- isBigDecimalEqual(existing.getPower(), newEntity.getPower()) &&
- Objects.equals(existing.getParkNo(), newEntity.getParkNo()) &&
- Objects.equals(existing.getNationalStandard(), newEntity.getNationalStandard());
- }
- // ==================== 价格策略数据保存 ====================
- @Override
- @Transactional(rollbackFor = Exception.class)
- public void savePricePolicyInfo(ChargingPricePolicyVO pricePolicyVO) {
- if (pricePolicyVO == null) {
- log.warn("价格策略信息为空,跳过存储");
- return;
- }
- try {
- // 查询最新的价格策略记录
- ThirdPartyEquipmentPricePolicy latestPolicy = getLatestPricePolicy(
- pricePolicyVO.getEquipBizSeq(),
- pricePolicyVO.getConnectorID()
- );
- // 如果数据完全相同,仅更新同步时间
- if (latestPolicy != null && isPolicySame(latestPolicy, pricePolicyVO)) {
- log.info("价格策略数据未发生变化,仅更新同步时间 - equipBizSeq: {}, connectorId: {}",
- pricePolicyVO.getEquipBizSeq(), pricePolicyVO.getConnectorID());
- // 更新所有明细的同步时间
- updateAllDetailSyncTime(latestPolicy.getId());
- return;
- }
- // 数据发生变化
- Long policyId;
- if (latestPolicy != null) {
- // 已存在记录,执行更新
- policyId = updatePricePolicy(latestPolicy, pricePolicyVO);
- log.info("价格策略信息保存成功(更新记录) - equipBizSeq: {}, connectorId: {}, policyId: {}",
- pricePolicyVO.getEquipBizSeq(), pricePolicyVO.getConnectorID(), policyId);
- } else {
- // 不存在记录,执行新增
- policyId = insertNewPricePolicy(pricePolicyVO);
- log.info("价格策略信息保存成功(新增记录) - equipBizSeq: {}, connectorId: {}, policyId: {}",
- pricePolicyVO.getEquipBizSeq(), pricePolicyVO.getConnectorID(), policyId);
- }
- // 保存价格策略明细(对比后更新或新增,不做删除操作)
- if (!CollectionUtils.isEmpty(pricePolicyVO.getPolicyInfos())) {
- savePolicyInfoDetails(pricePolicyVO.getPolicyInfos(), policyId);
- }
- } catch (Exception e) {
- log.error("保存价格策略信息失败 - equipBizSeq: {}, connectorId: {}",
- pricePolicyVO.getEquipBizSeq(), pricePolicyVO.getConnectorID(), e);
- throw new RuntimeException("保存价格策略信息失败", e);
- }
- }
- @Override
- public IPage<ThirdPartyStationInfoVO> getStationInfoPageByEquipment(ThirdPartyStationInfoQuery queryParams) {
- // 构建分页
- Page<ThirdPartyStationInfoVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
- // 调用Mapper联表查询(固定设备所属方MA6DP6BE7)
- IPage<ThirdPartyStationInfoVO> resultPage = stationInfoMapper.selectStationInfoPageByEquipment(page, queryParams);
-
- // 填充单位名称
- for (ThirdPartyStationInfoVO vo : resultPage.getRecords()) {
- if (vo.getSalesType() != null) {
- if (vo.getSalesType() == 1 && vo.getFirmId() != null) {
- // 企业类型,查询企业名称
- FirmInfo firmInfo = firmInfoMapper.selectById(vo.getFirmId());
- if (firmInfo != null) {
- vo.setUnitName(firmInfo.getName());
- }
- } else if (vo.getSalesType() == 2 && vo.getThirdPartyId() != null) {
- // 渠道方类型,查询渠道方名称
- ThirdPartyInfo thirdPartyInfo = thirdPartyInfoMapper.selectById(vo.getThirdPartyId());
- if (thirdPartyInfo != null) {
- vo.setUnitName(thirdPartyInfo.getEcName());
- }
- }
- }
- }
-
- return resultPage;
- }
- /**
- * 获取最新的价格策略记录
- */
- private ThirdPartyEquipmentPricePolicy getLatestPricePolicy(String equipBizSeq, String connectorId) {
- List<ThirdPartyEquipmentPricePolicy> policies = pricePolicyMapper.selectList(
- Wrappers.<ThirdPartyEquipmentPricePolicy>lambdaQuery()
- .eq(ThirdPartyEquipmentPricePolicy::getEquipBizSeq, equipBizSeq)
- .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, connectorId)
- .orderByDesc(ThirdPartyEquipmentPricePolicy::getCreateTime)
- .last("LIMIT 1")
- );
- return CollectionUtils.isEmpty(policies) ? null : policies.get(0);
- }
- /**
- * 判断价格策略是否相同(比较主表和明细表)
- */
- private boolean isPolicySame(ThirdPartyEquipmentPricePolicy latestPolicy, ChargingPricePolicyVO newPolicy) {
- // 比较主表字段
- if (!Objects.equals(latestPolicy.getSuccStat(), newPolicy.getSuccStat()) ||
- !Objects.equals(latestPolicy.getFailReason(), newPolicy.getFailReason()) ||
- !Objects.equals(latestPolicy.getSumPeriod(), newPolicy.getSumPeriod())) {
- return false;
- }
- // 查询明细表数据
- List<ThirdPartyPolicyInfo> existingDetails = policyInfoMapper.selectList(
- Wrappers.<ThirdPartyPolicyInfo>lambdaQuery()
- .eq(ThirdPartyPolicyInfo::getPricePolicyId, latestPolicy.getId())
- .orderBy(true, true, ThirdPartyPolicyInfo::getStartTime)
- );
- // 比较明细表
- return isPolicyDetailsSame(existingDetails, newPolicy.getPolicyInfos());
- }
- /**
- * 比较价格策略明细是否相同
- */
- private boolean isPolicyDetailsSame(List<ThirdPartyPolicyInfo> existingDetails,
- List<ChargingPricePolicyVO.PolicyInfo> newDetails) {
- if (CollectionUtils.isEmpty(existingDetails) && CollectionUtils.isEmpty(newDetails)) {
- return true;
- }
- if (CollectionUtils.isEmpty(existingDetails) || CollectionUtils.isEmpty(newDetails)) {
- return false;
- }
- if (existingDetails.size() != newDetails.size()) {
- return false;
- }
- // 按 StartTime 排序后比较
- List<ChargingPricePolicyVO.PolicyInfo> sortedNewDetails = newDetails.stream()
- .sorted(Comparator.comparing(ChargingPricePolicyVO.PolicyInfo::getStartTime))
- .collect(Collectors.toList());
- for (int i = 0; i < existingDetails.size(); i++) {
- ThirdPartyPolicyInfo existing = existingDetails.get(i);
- ChargingPricePolicyVO.PolicyInfo newDetail = sortedNewDetails.get(i);
- if (!Objects.equals(existing.getStartTime(), newDetail.getStartTime()) ||
- !isBigDecimalEqual(existing.getElecPrice(), newDetail.getElecPrice()) ||
- !isBigDecimalEqual(existing.getServicePrice(), newDetail.getServicePrice()) ||
- !Objects.equals(existing.getPeriodFlag(), newDetail.getPeriodFlag())) {
- return false;
- }
- }
- return true;
- }
- /**
- * 比较 BigDecimal 是否相等(处理 null 情况)
- */
- private boolean isBigDecimalEqual(BigDecimal a, BigDecimal b) {
- if (a == null && b == null) {
- return true;
- }
- if (a == null || b == null) {
- return false;
- }
- return a.compareTo(b) == 0;
- }
- /**
- * 插入新的价格策略记录
- */
- private Long insertNewPricePolicy(ChargingPricePolicyVO pricePolicyVO) {
- ThirdPartyEquipmentPricePolicy entity = new ThirdPartyEquipmentPricePolicy();
- // 设置字段值
- entity.setEquipBizSeq(pricePolicyVO.getEquipBizSeq());
- entity.setConnectorId(pricePolicyVO.getConnectorID());
- entity.setSuccStat(pricePolicyVO.getSuccStat());
- entity.setFailReason(pricePolicyVO.getFailReason());
- entity.setSumPeriod(pricePolicyVO.getSumPeriod());
- entity.setCreateTime(LocalDateTime.now());
- // 插入新记录
- pricePolicyMapper.insert(entity);
- return entity.getId();
- }
- /**
- * 更新价格策略记录
- */
- private Long updatePricePolicy(ThirdPartyEquipmentPricePolicy existingPolicy, ChargingPricePolicyVO pricePolicyVO) {
- existingPolicy.setSuccStat(pricePolicyVO.getSuccStat());
- existingPolicy.setFailReason(pricePolicyVO.getFailReason());
- existingPolicy.setSumPeriod(pricePolicyVO.getSumPeriod());
- pricePolicyMapper.updateById(existingPolicy);
- return existingPolicy.getId();
- }
- /**
- * 保存价格策略明细(对比后更新或新增)
- */
- private void savePolicyInfoDetails(List<ChargingPricePolicyVO.PolicyInfo> policyInfos, Long policyId) {
- // 查询已存在的明细记录,以 startTime 为 key
- Map<String, ThirdPartyPolicyInfo> existingMap = policyInfoMapper.selectList(
- Wrappers.<ThirdPartyPolicyInfo>lambdaQuery()
- .eq(ThirdPartyPolicyInfo::getPricePolicyId, policyId))
- .stream()
- .collect(Collectors.toMap(ThirdPartyPolicyInfo::getStartTime, info -> info, (v1, v2) -> v1));
- for (ChargingPricePolicyVO.PolicyInfo policyInfo : policyInfos) {
- ThirdPartyPolicyInfo existing = existingMap.get(policyInfo.getStartTime());
-
- if (existing == null) {
- // 不存在,执行新增
- savePolicyInfoDetail(policyInfo, policyId);
- log.debug("价格策略明细新增成功 - policyId: {}, startTime: {}", policyId, policyInfo.getStartTime());
- } else if (!isPolicyInfoSame(existing, policyInfo)) {
- // 检查上次更新时间,如果低于1小时,跳过本次更新
- if (existing.getUpdateTime() != null) {
- LocalDateTime oneHourAgo = LocalDateTime.now().minusHours(1);
- if (existing.getUpdateTime().isAfter(oneHourAgo)) {
- log.info("价格策略明细上次更新时间不足1小时,跳过更新 - policyId: {}, startTime: {}, lastUpdateTime: {}",
- policyId, policyInfo.getStartTime(), existing.getUpdateTime());
- continue; // 跳过本次更新
- }
- }
-
- // 存在且数据变化,且距离上次更新超过1小时,执行更新
- updatePolicyInfoDetail(existing, policyInfo);
- log.debug("价格策略明细更新成功 - policyId: {}, startTime: {}", policyId, policyInfo.getStartTime());
-
- // 价格变化后,同步更新 c_policy_fee 表中的 comp_sales_fee
- updateRelatedPolicyFeeCompSalesFee(policyId, policyInfo.getPeriodFlag());
- } else {
- // 数据未变化,但仍更新同步时间
- updateSyncTime(existing);
- log.debug("价格策略明细未变化,更新同步时间 - policyId: {}, startTime: {}", policyId, policyInfo.getStartTime());
- }
- }
- }
-
- /**
- * 更新同步时间(数据未变化时仅更新update_time)
- */
- private void updateSyncTime(ThirdPartyPolicyInfo existing) {
- existing.setUpdateTime(LocalDateTime.now());
- policyInfoMapper.updateById(existing);
- }
-
- /**
- * 更新所有明细的同步时间
- */
- private void updateAllDetailSyncTime(Long policyId) {
- policyInfoMapper.update(null, Wrappers.<ThirdPartyPolicyInfo>lambdaUpdate()
- .eq(ThirdPartyPolicyInfo::getPricePolicyId, policyId)
- .set(ThirdPartyPolicyInfo::getUpdateTime, LocalDateTime.now()));
- log.debug("批量更新价格策略明细同步时间完成 - policyId: {}", policyId);
- }
- /**
- * 判断价格策略明细是否相同
- */
- private boolean isPolicyInfoSame(ThirdPartyPolicyInfo existing, ChargingPricePolicyVO.PolicyInfo newInfo) {
- return isBigDecimalEqual(existing.getElecPrice(), newInfo.getElecPrice()) &&
- isBigDecimalEqual(existing.getServicePrice(), newInfo.getServicePrice()) &&
- Objects.equals(existing.getPeriodFlag(), newInfo.getPeriodFlag());
- }
- /**
- * 更新价格策略明细
- */
- private void updatePolicyInfoDetail(ThirdPartyPolicyInfo existing, ChargingPricePolicyVO.PolicyInfo policyInfo) {
- existing.setElecPrice(policyInfo.getElecPrice());
- existing.setServicePrice(policyInfo.getServicePrice());
- existing.setPeriodFlag(policyInfo.getPeriodFlag());
- existing.setUpdateTime(LocalDateTime.now());
- policyInfoMapper.updateById(existing);
- }
-
- /**
- * 价格策略变化后,同步更新 c_policy_fee 表中的 comp_sales_fee
- * 根据 pricePolicyId 查询对应的 stationInfoId,然后更新相关的 policy_fee 记录
- *
- * @param policyId 价格策略ID
- * @param periodFlag 时段标志(1-尖,2-峰,3-平,4-谷)
- */
- private void updateRelatedPolicyFeeCompSalesFee(Long policyId, Integer periodFlag) {
- try {
- // 1. 通过 policyId 查询 connectorId
- ThirdPartyEquipmentPricePolicy pricePolicy = pricePolicyMapper.selectById(policyId);
- if (pricePolicy == null) {
- log.warn("未找到价格策略记录,policyId: {}", policyId);
- return;
- }
-
- // 2. 通过 connectorId 查询 stationId
- ThirdPartyConnectorInfo connector = connectorInfoMapper.selectOne(
- Wrappers.<ThirdPartyConnectorInfo>lambdaQuery()
- .eq(ThirdPartyConnectorInfo::getConnectorId, pricePolicy.getConnectorId())
- .last("LIMIT 1")
- );
-
- if (connector == null) {
- log.warn("未找到充电接口记录,connectorId: {}", pricePolicy.getConnectorId());
- return;
- }
-
- // 3. 通过 stationId 查询 stationInfoId
- ThirdPartyStationInfo station = stationInfoMapper.selectOne(
- Wrappers.<ThirdPartyStationInfo>lambdaQuery()
- .eq(ThirdPartyStationInfo::getStationId, connector.getStationId())
- .last("LIMIT 1")
- );
-
- if (station == null) {
- log.warn("未找到站点记录,stationId: {}", connector.getStationId());
- return;
- }
-
- // 4. 查询该站点、该时段标志的所有 policy_fee 记录
- List<PolicyFee> policyFees = policyFeeMapper.selectList(
- Wrappers.<PolicyFee>lambdaQuery()
- .eq(PolicyFee::getStationInfoId, station.getId())
- .eq(PolicyFee::getPeriodFlag, periodFlag)
- .eq(PolicyFee::getIsDeleted, 0)
- );
-
- if (policyFees.isEmpty()) {
- log.debug("该站点该时段标志没有 policy_fee 记录,stationInfoId: {}, periodFlag: {}", station.getId(), periodFlag);
- return;
- }
-
- // 5. 重新计算并更新每条记录的 comp_sales_fee
- for (PolicyFee policyFee : policyFees) {
- BigDecimal newCompSalesFee = calculateCompSalesFeeForPolicyFee(
- station.getId(),
- periodFlag,
- policyFee.getOpFee()
- );
-
- policyFee.setCompSalesFee(newCompSalesFee);
- policyFeeMapper.updateById(policyFee);
-
- log.info("更新 policy_fee 的 comp_sales_fee - id: {}, stationInfoId: {}, periodFlag: {}, salesType: {}, 新值: {}",
- policyFee.getId(), station.getId(), periodFlag, policyFee.getSalesType(), newCompSalesFee);
- }
-
- } catch (Exception e) {
- log.error("更新 policy_fee 的 comp_sales_fee 失败 - policyId: {}, periodFlag: {}", policyId, periodFlag, e);
- // 不抛出异常,避免影响主流程
- }
- }
-
- /**
- * 计算 comp_sales_fee
- * 公式:compSalesFee = elec_price + service_price + op_fee
- * 注意:这里不加字典值,与 PolicyFeeServiceImpl 中的计算逻辑保持一致
- */
- private BigDecimal calculateCompSalesFeeForPolicyFee(Long stationInfoId, Integer periodFlag, BigDecimal opFee) {
- BigDecimal elecPrice = BigDecimal.ZERO;
- BigDecimal servicePrice = BigDecimal.ZERO;
-
- // 查询电价和服务费
- ThirdPartyPolicyInfo policyInfo = policyInfoMapper.selectElecAndServicePriceByStationAndPeriodFlag(stationInfoId, periodFlag);
-
- if (policyInfo != null) {
- elecPrice = policyInfo.getElecPrice() != null ? policyInfo.getElecPrice() : BigDecimal.ZERO;
- servicePrice = policyInfo.getServicePrice() != null ? policyInfo.getServicePrice() : BigDecimal.ZERO;
- }
-
- BigDecimal opFeeValue = opFee != null ? opFee : BigDecimal.ZERO;
- return elecPrice.add(servicePrice).add(opFeeValue);
- }
- /**
- * 保存价格策略明细
- */
- private void savePolicyInfoDetail(ChargingPricePolicyVO.PolicyInfo policyInfo, Long policyId) {
- ThirdPartyPolicyInfo entity = new ThirdPartyPolicyInfo();
- entity.setPricePolicyId(policyId);
- entity.setStartTime(policyInfo.getStartTime());
- entity.setElecPrice(policyInfo.getElecPrice());
- entity.setServicePrice(policyInfo.getServicePrice());
- entity.setPeriodFlag(policyInfo.getPeriodFlag());
- entity.setCreateTime(LocalDateTime.now());
- policyInfoMapper.insert(entity);
- }
- @Override
- public boolean updateStationTips(Long stationId, String stationTips) {
- return stationInfoMapper.update(null, Wrappers.<ThirdPartyStationInfo>lambdaUpdate()
- .eq(ThirdPartyStationInfo::getId, stationId)
- .set(ThirdPartyStationInfo::getStationTips, stationTips)) > 0;
- }
- @Override
- public StationDetailVO getStationDetail(Long stationId) {
- ThirdPartyStationInfo station = stationInfoMapper.selectById(stationId);
- if (station == null) {
- return null;
- }
- StationDetailVO vo = new StationDetailVO();
- vo.setId(station.getId());
- vo.setStationName(station.getStationName());
- vo.setStationTips(station.getStationTips());
- vo.setOwnBusinessHours(station.getOwnBusinessHours());
- vo.setCustomerServiceHotline(station.getCustomerServiceHotline());
- // 解析banner图片JSON
- if (station.getBannerPictures() != null) {
- try {
- vo.setBannerPictures(objectMapper.readValue(station.getBannerPictures(), new TypeReference<List<String>>() {}));
- } catch (JsonProcessingException e) {
- log.warn("解析banner图片失败", e);
- }
- }
- return vo;
- }
- @Override
- @Transactional(rollbackFor = Exception.class)
- public boolean updateStationDetail(StationDetailDTO dto) {
- ThirdPartyStationInfo station = stationInfoMapper.selectById(dto.getId());
- if (station == null) {
- return false;
- }
- // 转banner图片为JSON
- String bannerJson = null;
- if (dto.getBannerPictures() != null) {
- try {
- bannerJson = objectMapper.writeValueAsString(dto.getBannerPictures());
- } catch (JsonProcessingException e) {
- log.warn("banner图片转JSON失败", e);
- }
- }
- return stationInfoMapper.update(null, Wrappers.<ThirdPartyStationInfo>lambdaUpdate()
- .eq(ThirdPartyStationInfo::getId, dto.getId())
- .set(ThirdPartyStationInfo::getStationTips, dto.getStationTips())
- .set(ThirdPartyStationInfo::getOwnBusinessHours, dto.getOwnBusinessHours())
- .set(ThirdPartyStationInfo::getCustomerServiceHotline, dto.getCustomerServiceHotline())
- .set(bannerJson != null, ThirdPartyStationInfo::getBannerPictures, bannerJson)) > 0;
- }
- }
|