|
|
@@ -1,420 +0,0 @@
|
|
|
-package com.zsElectric.boot.business.service.impl;
|
|
|
-
|
|
|
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
-import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
-import com.zsElectric.boot.business.model.dto.UpdatePricePolicyDTO;
|
|
|
-import com.zsElectric.boot.business.model.query.PricePolicyPageQuery;
|
|
|
-import com.zsElectric.boot.business.model.vo.PricePolicyPageVO;
|
|
|
-import com.zsElectric.boot.business.service.PricePolicyManagementService;
|
|
|
-import com.zsElectric.boot.charging.entity.ThirdPartyConnectorInfo;
|
|
|
-import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentPricePolicy;
|
|
|
-import com.zsElectric.boot.charging.entity.ThirdPartyPolicyInfo;
|
|
|
-import com.zsElectric.boot.charging.entity.ThirdPartyStationInfo;
|
|
|
-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.charging.mapper.ThirdPartyStationInfoMapper;
|
|
|
-import com.zsElectric.boot.system.model.vo.DictItemOptionVO;
|
|
|
-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 org.springframework.util.CollectionUtils;
|
|
|
-import org.springframework.util.StringUtils;
|
|
|
-
|
|
|
-import java.math.BigDecimal;
|
|
|
-import java.time.LocalDateTime;
|
|
|
-import java.time.format.DateTimeFormatter;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
-import java.util.stream.Collectors;
|
|
|
-
|
|
|
-/**
|
|
|
- * 价格策略管理服务实现
|
|
|
- *
|
|
|
- * @author system
|
|
|
- * @since 2025-12-12
|
|
|
- */
|
|
|
-@Slf4j
|
|
|
-@Service
|
|
|
-@RequiredArgsConstructor
|
|
|
-public class PricePolicyManagementServiceImpl implements PricePolicyManagementService {
|
|
|
-
|
|
|
- private final ThirdPartyStationInfoMapper stationInfoMapper;
|
|
|
- private final ThirdPartyConnectorInfoMapper connectorInfoMapper;
|
|
|
- private final ThirdPartyEquipmentPricePolicyMapper pricePolicyMapper;
|
|
|
- private final ThirdPartyPolicyInfoMapper policyInfoMapper;
|
|
|
- private final DictItemService dictItemService;
|
|
|
-
|
|
|
- private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
|
|
|
-
|
|
|
- // 字典缓存
|
|
|
- private Map<String, String> constructionTypeMap;
|
|
|
- private Map<String, String> stationStatusMap;
|
|
|
- private Map<String, String> stationTypeMap;
|
|
|
- private Map<String, String> connectorTypeMap;
|
|
|
-
|
|
|
- @Override
|
|
|
- public Page<PricePolicyPageVO> queryPricePolicyPage(PricePolicyPageQuery query) {
|
|
|
- // 查询充电站列表
|
|
|
- LambdaQueryWrapper<ThirdPartyStationInfo> queryWrapper = Wrappers.lambdaQuery();
|
|
|
-
|
|
|
- if (StringUtils.hasText(query.getStationId())) {
|
|
|
- queryWrapper.eq(ThirdPartyStationInfo::getStationId, query.getStationId());
|
|
|
- }
|
|
|
- if (StringUtils.hasText(query.getStationName())) {
|
|
|
- queryWrapper.like(ThirdPartyStationInfo::getStationName, query.getStationName());
|
|
|
- }
|
|
|
- if (query.getStationStatus() != null) {
|
|
|
- queryWrapper.eq(ThirdPartyStationInfo::getStationStatus, query.getStationStatus());
|
|
|
- }
|
|
|
-
|
|
|
- Page<ThirdPartyStationInfo> stationPage = stationInfoMapper.selectPage(
|
|
|
- new Page<>(query.getPageNum(), query.getPageSize()),
|
|
|
- queryWrapper
|
|
|
- );
|
|
|
-
|
|
|
- // 转换为VO
|
|
|
- Page<PricePolicyPageVO> resultPage = new Page<>(stationPage.getCurrent(), stationPage.getSize(), stationPage.getTotal());
|
|
|
- List<PricePolicyPageVO> voList = stationPage.getRecords().stream()
|
|
|
- .map(this::convertToVO)
|
|
|
- .collect(Collectors.toList());
|
|
|
-
|
|
|
- resultPage.setRecords(voList);
|
|
|
- return resultPage;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 转换为VO对象
|
|
|
- */
|
|
|
- private PricePolicyPageVO convertToVO(ThirdPartyStationInfo station) {
|
|
|
- PricePolicyPageVO vo = new PricePolicyPageVO();
|
|
|
- vo.setStationId(station.getStationId());
|
|
|
- vo.setStationName(station.getStationName());
|
|
|
- vo.setCity(getCity(station.getAreaCode()));
|
|
|
- vo.setEquipmentOwner(station.getEquipmentOwnerId());
|
|
|
- vo.setAddress(station.getAddress());
|
|
|
- vo.setLocationType(getLocationType(station.getConstruction()));
|
|
|
- vo.setStationType(getStationType(station.getStationType()));
|
|
|
- vo.setTerminalCount(getTerminalCount(station.getStationId()));
|
|
|
- vo.setStationStatus(getStationStatusText(station.getStationStatus()));
|
|
|
- vo.setServiceTel(station.getServiceTel());
|
|
|
- vo.setUpdateTime(station.getUpdateTime());
|
|
|
-
|
|
|
- // 查询价格策略明细
|
|
|
- vo.setPolicyDetails(queryPolicyDetails(station.getStationId()));
|
|
|
-
|
|
|
- return vo;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 查询价格策略明细
|
|
|
- */
|
|
|
- private List<PricePolicyPageVO.PricePolicyDetail> queryPolicyDetails(String stationId) {
|
|
|
- // 查询该充电站的所有充电桩接口
|
|
|
- List<ThirdPartyConnectorInfo> connectors = connectorInfoMapper.selectList(
|
|
|
- Wrappers.<ThirdPartyConnectorInfo>lambdaQuery()
|
|
|
- .eq(ThirdPartyConnectorInfo::getStationId, stationId)
|
|
|
- .last("LIMIT 1") // 取第一个充电桩的价格策略
|
|
|
- );
|
|
|
-
|
|
|
- if (CollectionUtils.isEmpty(connectors)) {
|
|
|
- return new ArrayList<>();
|
|
|
- }
|
|
|
-
|
|
|
- String connectorId = connectors.get(0).getConnectorId();
|
|
|
-
|
|
|
- // 查询最新的价格策略
|
|
|
- List<ThirdPartyEquipmentPricePolicy> policies = pricePolicyMapper.selectList(
|
|
|
- Wrappers.<ThirdPartyEquipmentPricePolicy>lambdaQuery()
|
|
|
- .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, connectorId)
|
|
|
- .orderByDesc(ThirdPartyEquipmentPricePolicy::getCreateTime)
|
|
|
- .last("LIMIT 1")
|
|
|
- );
|
|
|
-
|
|
|
- if (CollectionUtils.isEmpty(policies)) {
|
|
|
- return new ArrayList<>();
|
|
|
- }
|
|
|
-
|
|
|
- Long policyId = policies.get(0).getId();
|
|
|
-
|
|
|
- // 查询价格策略明细
|
|
|
- List<ThirdPartyPolicyInfo> policyInfos = policyInfoMapper.selectList(
|
|
|
- Wrappers.<ThirdPartyPolicyInfo>lambdaQuery()
|
|
|
- .eq(ThirdPartyPolicyInfo::getPricePolicyId, policyId)
|
|
|
- .orderBy(true, true, ThirdPartyPolicyInfo::getStartTime)
|
|
|
- );
|
|
|
-
|
|
|
- return convertToPolicyDetails(policyInfos);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 转换价格策略明细
|
|
|
- */
|
|
|
- private List<PricePolicyPageVO.PricePolicyDetail> convertToPolicyDetails(List<ThirdPartyPolicyInfo> policyInfos) {
|
|
|
- List<PricePolicyPageVO.PricePolicyDetail> details = new ArrayList<>();
|
|
|
-
|
|
|
- for (int i = 0; i < policyInfos.size(); i++) {
|
|
|
- ThirdPartyPolicyInfo info = policyInfos.get(i);
|
|
|
- PricePolicyPageVO.PricePolicyDetail detail = new PricePolicyPageVO.PricePolicyDetail();
|
|
|
-
|
|
|
- // 时间段处理
|
|
|
- String startTime = formatTime(info.getStartTime());
|
|
|
- String endTime;
|
|
|
- if (i < policyInfos.size() - 1) {
|
|
|
- endTime = formatTime(policyInfos.get(i + 1).getStartTime());
|
|
|
- } else {
|
|
|
- endTime = formatTime(policyInfos.get(0).getStartTime());
|
|
|
- }
|
|
|
- detail.setTimePeriod(startTime + "-" + endTime);
|
|
|
-
|
|
|
- detail.setElecPrice(info.getElecPrice());
|
|
|
- detail.setServicePrice(info.getServicePrice());
|
|
|
-
|
|
|
- // 结算费合计 = 电价 + 结算服务费
|
|
|
- BigDecimal settlementTotal = BigDecimal.ZERO;
|
|
|
- if (info.getElecPrice() != null) {
|
|
|
- settlementTotal = settlementTotal.add(info.getElecPrice());
|
|
|
- }
|
|
|
- if (info.getServicePrice() != null) {
|
|
|
- settlementTotal = settlementTotal.add(info.getServicePrice());
|
|
|
- }
|
|
|
- detail.setSettlementTotal(settlementTotal);
|
|
|
-
|
|
|
- detail.setOperationServiceFee(info.getOperationServiceFee());
|
|
|
- detail.setTotalSalesPrice(info.getTotalSalesPrice());
|
|
|
-
|
|
|
- details.add(detail);
|
|
|
- }
|
|
|
-
|
|
|
- return details;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- @Transactional(rollbackFor = Exception.class)
|
|
|
- public boolean updatePricePolicy(UpdatePricePolicyDTO dto) {
|
|
|
- // 查询该充电站的所有充电桩接口
|
|
|
- List<ThirdPartyConnectorInfo> connectors = connectorInfoMapper.selectList(
|
|
|
- Wrappers.<ThirdPartyConnectorInfo>lambdaQuery()
|
|
|
- .eq(ThirdPartyConnectorInfo::getStationId, dto.getStationId())
|
|
|
- );
|
|
|
-
|
|
|
- if (CollectionUtils.isEmpty(connectors)) {
|
|
|
- log.warn("未找到充电站的充电桩接口信息, stationId: {}", dto.getStationId());
|
|
|
- return Boolean.FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- BigDecimal operationServiceFee = dto.getHasContractServiceFee() && dto.getContractServiceFee() != null
|
|
|
- ? dto.getContractServiceFee()
|
|
|
- : BigDecimal.ZERO;
|
|
|
-
|
|
|
- // 更新所有充电桩的价格策略
|
|
|
- for (ThirdPartyConnectorInfo connector : connectors) {
|
|
|
- updateConnectorPricePolicy(connector.getConnectorId(), operationServiceFee);
|
|
|
- }
|
|
|
-
|
|
|
- log.info("更新充电站价格策略成功, stationId: {}, operationServiceFee: {}", dto.getStationId(), operationServiceFee);
|
|
|
- return Boolean.TRUE;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新单个充电桩的价格策略
|
|
|
- */
|
|
|
- private void updateConnectorPricePolicy(String connectorId, BigDecimal operationServiceFee) {
|
|
|
- // 查询最新的价格策略
|
|
|
- List<ThirdPartyEquipmentPricePolicy> policies = pricePolicyMapper.selectList(
|
|
|
- Wrappers.<ThirdPartyEquipmentPricePolicy>lambdaQuery()
|
|
|
- .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, connectorId)
|
|
|
- .orderByDesc(ThirdPartyEquipmentPricePolicy::getCreateTime)
|
|
|
- .last("LIMIT 1")
|
|
|
- );
|
|
|
-
|
|
|
- if (CollectionUtils.isEmpty(policies)) {
|
|
|
- log.warn("未找到充电桩的价格策略, connectorId: {}", connectorId);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- Long policyId = policies.get(0).getId();
|
|
|
-
|
|
|
- // 查询所有价格策略明细
|
|
|
- List<ThirdPartyPolicyInfo> policyInfos = policyInfoMapper.selectList(
|
|
|
- Wrappers.<ThirdPartyPolicyInfo>lambdaQuery()
|
|
|
- .eq(ThirdPartyPolicyInfo::getPricePolicyId, policyId)
|
|
|
- );
|
|
|
-
|
|
|
- // 更新每条明细的运营服务费和销售合计价格
|
|
|
- for (ThirdPartyPolicyInfo info : policyInfos) {
|
|
|
- info.setOperationServiceFee(operationServiceFee);
|
|
|
-
|
|
|
- // 重新计算销售合计价格
|
|
|
- BigDecimal totalSalesPrice = calculateTotalSalesPrice(
|
|
|
- info.getElecPrice(),
|
|
|
- info.getServicePrice(),
|
|
|
- operationServiceFee
|
|
|
- );
|
|
|
- info.setTotalSalesPrice(totalSalesPrice);
|
|
|
-
|
|
|
- policyInfoMapper.updateById(info);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 计算销售合计价格 = 电价 + 结算服务费 + 运营服务费
|
|
|
- */
|
|
|
- private BigDecimal calculateTotalSalesPrice(BigDecimal elecPrice, BigDecimal servicePrice, BigDecimal operationServiceFee) {
|
|
|
- BigDecimal total = BigDecimal.ZERO;
|
|
|
-
|
|
|
- if (elecPrice != null) {
|
|
|
- total = total.add(elecPrice);
|
|
|
- }
|
|
|
- if (servicePrice != null) {
|
|
|
- total = total.add(servicePrice);
|
|
|
- }
|
|
|
- if (operationServiceFee != null) {
|
|
|
- total = total.add(operationServiceFee);
|
|
|
- }
|
|
|
-
|
|
|
- return total;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 格式化时间 HHmmss -> HH:mm
|
|
|
- */
|
|
|
- private String formatTime(String timeStr) {
|
|
|
- if (timeStr == null || timeStr.length() < 4) {
|
|
|
- return timeStr;
|
|
|
- }
|
|
|
- return timeStr.substring(0, 2) + ":" + timeStr.substring(2, 4);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取城市名称(简化处理)
|
|
|
- */
|
|
|
- private String getCity(String areaCode) {
|
|
|
- // TODO: 根据区域码查询城市名称
|
|
|
- return "贵阳市";
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取场所类型文本
|
|
|
- */
|
|
|
- private String getLocationType(Integer construction) {
|
|
|
- if (construction == null) {
|
|
|
- return "其他";
|
|
|
- }
|
|
|
-
|
|
|
- // 懒加载字典数据
|
|
|
- if (constructionTypeMap == null) {
|
|
|
- loadConstructionTypeDict();
|
|
|
- }
|
|
|
-
|
|
|
- return constructionTypeMap.getOrDefault(String.valueOf(construction), "其他");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 加载建设场所类型字典
|
|
|
- */
|
|
|
- private void loadConstructionTypeDict() {
|
|
|
- constructionTypeMap = new HashMap<>();
|
|
|
- List<DictItemOptionVO> dictItems = dictItemService.getDictItems("charging_construction_type");
|
|
|
- for (DictItemOptionVO item : dictItems) {
|
|
|
- constructionTypeMap.put(item.getValue(), item.getLabel());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取站点类型文本
|
|
|
- */
|
|
|
- private String getStationType(Integer stationType) {
|
|
|
- if (stationType == null) {
|
|
|
- return "其他";
|
|
|
- }
|
|
|
-
|
|
|
- // 懒加载字典数据
|
|
|
- if (stationTypeMap == null) {
|
|
|
- loadStationTypeDict();
|
|
|
- }
|
|
|
-
|
|
|
- return stationTypeMap.getOrDefault(String.valueOf(stationType), "其他");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 加载站点类型字典
|
|
|
- */
|
|
|
- private void loadStationTypeDict() {
|
|
|
- stationTypeMap = new HashMap<>();
|
|
|
- List<DictItemOptionVO> dictItems = dictItemService.getDictItems("charging_station_type");
|
|
|
- for (DictItemOptionVO item : dictItems) {
|
|
|
- stationTypeMap.put(item.getValue(), item.getLabel());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取充电设备接口类型文本
|
|
|
- */
|
|
|
- public String getConnectorType(Integer connectorType) {
|
|
|
- if (connectorType == null) {
|
|
|
- return "其他";
|
|
|
- }
|
|
|
-
|
|
|
- // 懒加载字典数据
|
|
|
- if (connectorTypeMap == null) {
|
|
|
- loadConnectorTypeDict();
|
|
|
- }
|
|
|
-
|
|
|
- return connectorTypeMap.getOrDefault(String.valueOf(connectorType), "其他");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 加载充电设备接口类型字典
|
|
|
- */
|
|
|
- private void loadConnectorTypeDict() {
|
|
|
- connectorTypeMap = new HashMap<>();
|
|
|
- List<DictItemOptionVO> dictItems = dictItemService.getDictItems("charging_connector_type");
|
|
|
- for (DictItemOptionVO item : dictItems) {
|
|
|
- connectorTypeMap.put(item.getValue(), item.getLabel());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取充电终端数量
|
|
|
- */
|
|
|
- private Integer getTerminalCount(String stationId) {
|
|
|
- Long count = connectorInfoMapper.selectCount(
|
|
|
- Wrappers.<ThirdPartyConnectorInfo>lambdaQuery()
|
|
|
- .eq(ThirdPartyConnectorInfo::getStationId, stationId)
|
|
|
- );
|
|
|
- return count != null ? count.intValue() : 0;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取站点状态文本
|
|
|
- */
|
|
|
- private String getStationStatusText(Integer status) {
|
|
|
- if (status == null) {
|
|
|
- return "未知";
|
|
|
- }
|
|
|
-
|
|
|
- // 懒加载字典数据
|
|
|
- if (stationStatusMap == null) {
|
|
|
- loadStationStatusDict();
|
|
|
- }
|
|
|
-
|
|
|
- return stationStatusMap.getOrDefault(String.valueOf(status), "未知");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 加载站点状态字典
|
|
|
- */
|
|
|
- private void loadStationStatusDict() {
|
|
|
- stationStatusMap = new HashMap<>();
|
|
|
- List<DictItemOptionVO> dictItems = dictItemService.getDictItems("charging_station_status");
|
|
|
- for (DictItemOptionVO item : dictItems) {
|
|
|
- stationStatusMap.put(item.getValue(), item.getLabel());
|
|
|
- }
|
|
|
- }
|
|
|
-}
|