package com.zsElectric.boot.business.service.impl; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.zsElectric.boot.business.mapper.PolicyFeeMapper; import com.zsElectric.boot.business.mapper.ThirdPartyEquipmentInfoMapper; import com.zsElectric.boot.business.mapper.ThirdPartyStationInfoMapper; import com.zsElectric.boot.business.model.dto.AddPolicyFeeDTO; import com.zsElectric.boot.business.model.entity.PolicyFee; import com.zsElectric.boot.business.model.vo.TimePeriodPriceVO; import com.zsElectric.boot.business.service.PolicyFeeService; import com.zsElectric.boot.charging.entity.*; 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.system.model.entity.DictItem; import com.zsElectric.boot.system.service.DictItemService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * 策略费用服务实现 * * @author system * @since 2025-12-15 */ @Slf4j @Service @RequiredArgsConstructor public class PolicyFeeServiceImpl implements PolicyFeeService { /** * 时段标志映射:1-尖, 2-峰, 3-平, 4-谷(固定常量,避免重复创建) */ private static final Map PERIOD_FLAG_LABEL_MAP = Map.of( 1, "尖", 2, "峰", 3, "平", 4, "谷" ); private final PolicyFeeMapper policyFeeMapper; private final ThirdPartyPolicyInfoMapper thirdPartyPolicyInfoMapper; private final ThirdPartyEquipmentPricePolicyMapper thirdPartyEquipmentPricePolicyMapper; private final DictItemService dictItemService; private final ThirdPartyStationInfoMapper stationInfoMapper; private final ThirdPartyConnectorInfoMapper thirdPartyConnectorInfoMapper; @Override public List getPolicyFee(long stationId, int salesType, Long firmId, Long thirdPartyId) { List timePeriodPriceVOS = new ArrayList<>(); // 查询价格策略 ThirdPartyEquipmentPricePolicy pricePolicy = thirdPartyEquipmentPricePolicyMapper.selectOne(Wrappers.lambdaQuery() .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, thirdPartyConnectorInfoMapper.selectOne(Wrappers.lambdaQuery() .eq(ThirdPartyConnectorInfo::getStationId,stationInfoMapper.selectById(stationId).getStationId()).last("limit 1")).getConnectorId()) .eq(ThirdPartyEquipmentPricePolicy::getIsDeleted, 0) .last("limit 1")); if (pricePolicy == null) { return timePeriodPriceVOS; } // 互联互通成本价 List thirdPartyPolicyInfos = thirdPartyPolicyInfoMapper.selectList(Wrappers.lambdaQuery() .eq(ThirdPartyPolicyInfo::getPricePolicyId, pricePolicy.getId()) .eq(ThirdPartyPolicyInfo::getIsDeleted, 0)); // 运营费(按时段配置) Map policyFeeMap = policyFeeMapper.selectList(Wrappers.lambdaQuery() .eq(PolicyFee::getStationInfoId, stationId) .eq(PolicyFee::getIsDeleted, 0) .eq(PolicyFee::getSalesType, salesType) .eq(salesType == 1, PolicyFee::getFirmId, firmId) .eq(salesType == 2, PolicyFee::getThirdPartyId, thirdPartyId)) .stream() .collect(Collectors.toMap( PolicyFee::getStartTime, policyFee -> policyFee, (v1, v2) -> v1 )); // 查询时段标志字典,获取增值服务费价格(label对应中文,value对应价格) Map labelPriceMap = dictItemService.list( Wrappers.lambdaQuery() .eq(DictItem::getDictCode, "time_period_flag") .eq(DictItem::getStatus, 1) ).stream() .collect(Collectors.toMap( DictItem::getLabel, item -> new BigDecimal(item.getValue()), (v1, v2) -> v1 )); // 计算综合价格 for (ThirdPartyPolicyInfo policyInfo : thirdPartyPolicyInfos) { // 获取增值服务费 BigDecimal valueAddedFees = labelPriceMap.getOrDefault( PERIOD_FLAG_LABEL_MAP.get(policyInfo.getPeriodFlag()), BigDecimal.ZERO ); // 根据时段获取对应的运营费配置 PolicyFee policyFee = policyFeeMap.get(policyInfo.getStartTime()); TimePeriodPriceVO timePeriodPriceVO = new TimePeriodPriceVO(); timePeriodPriceVO.setTimePeriod(policyInfo.getStartTime()) .setPeriodFlag(policyInfo.getPeriodFlag()) .setElectricityPrice(policyInfo.getElecPrice()) .setSettlementServiceFee(policyInfo.getServicePrice()) .setSettlementTotalPrice(policyInfo.getElecPrice().add(policyInfo.getServicePrice())) .setOperationServiceFee(BigDecimal.ZERO) .setSaleTotalPrice(BigDecimal.ZERO) .setValueAddedFees(valueAddedFees); // 只有配置了该时段的运营费才计算销售价并返回 if (policyFee != null) { timePeriodPriceVO.setOperationServiceFee(policyFee.getOpFee()) .setSaleTotalPrice(policyInfo.getElecPrice() .add(policyInfo.getServicePrice()) .add(policyFee.getOpFee()) .add(valueAddedFees)); } timePeriodPriceVOS.add(timePeriodPriceVO); } return timePeriodPriceVOS; } @Override public boolean addPolicyFee(AddPolicyFeeDTO addPolicyFeeDTO) { // 根据站点+时段+销售类型+企业/渠道方查询是否已存在 PolicyFee existPolicyFee = policyFeeMapper.selectOne(Wrappers.lambdaQuery() .eq(PolicyFee::getStationInfoId, addPolicyFeeDTO.getStationInfoId()) .eq(PolicyFee::getStartTime, addPolicyFeeDTO.getTimePeriod()) .eq(PolicyFee::getSalesType, addPolicyFeeDTO.getSalesType()) .eq(addPolicyFeeDTO.getSalesType() == 1, PolicyFee::getFirmId, addPolicyFeeDTO.getFirmId()) .eq(addPolicyFeeDTO.getSalesType() == 2, PolicyFee::getThirdPartyId, addPolicyFeeDTO.getThirdPartyId()) .eq(PolicyFee::getIsDeleted, 0) .last("limit 1")); if (existPolicyFee != null) { // 已存在,执行更新 existPolicyFee.setOpFee(addPolicyFeeDTO.getOperationServiceFee()); return policyFeeMapper.updateById(existPolicyFee) > 0; } else { // 不存在,执行新增 PolicyFee policyFee = new PolicyFee(); policyFee.setStationInfoId(addPolicyFeeDTO.getStationInfoId()); policyFee.setStartTime(addPolicyFeeDTO.getTimePeriod()); policyFee.setOpFee(addPolicyFeeDTO.getOperationServiceFee()); policyFee.setSalesType(addPolicyFeeDTO.getSalesType()); policyFee.setFirmId(addPolicyFeeDTO.getFirmId()); policyFee.setThirdPartyId(addPolicyFeeDTO.getThirdPartyId()); boolean inserted = policyFeeMapper.insert(policyFee) > 0; // 新增成功后,更新站点的配置状态为已配置 if (inserted) { stationInfoMapper.update(null, Wrappers.lambdaUpdate() .eq(ThirdPartyStationInfo::getId, addPolicyFeeDTO.getStationInfoId()) .set(ThirdPartyStationInfo::getPolicyConfigured, 1)); } return inserted; } } @Override @Transactional(rollbackFor = Exception.class) public boolean batchAddPolicyFee(List addPolicyFeeDTOList) { if (addPolicyFeeDTOList == null || addPolicyFeeDTOList.isEmpty()) { return false; } for (AddPolicyFeeDTO dto : addPolicyFeeDTOList) { addPolicyFee(dto); } return true; } }