package com.ruoyi.chargingPile.service.impl;
|
|
import com.alibaba.fastjson2.JSON;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.ruoyi.account.api.feignClient.AppUserClient;
|
import com.ruoyi.chargingPile.api.model.Site;
|
import com.ruoyi.chargingPile.api.model.TAccountingStrategy;
|
import com.ruoyi.chargingPile.api.model.TAccountingStrategyDetail;
|
import com.ruoyi.chargingPile.api.model.TChargingGun;
|
import com.ruoyi.chargingPile.api.vo.StrategyPriceVO;
|
import com.ruoyi.chargingPile.api.vo.TAccountingStrategyDetailVO;
|
import com.ruoyi.chargingPile.mapper.TAccountingStrategyDetailMapper;
|
import com.ruoyi.chargingPile.mapper.TAccountingStrategyMapper;
|
import com.ruoyi.chargingPile.service.ISiteService;
|
import com.ruoyi.chargingPile.service.TAccountingStrategyDetailService;
|
import com.ruoyi.chargingPile.service.TChargingGunService;
|
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.exception.ServiceException;
|
import com.ruoyi.common.core.utils.DateUtils;
|
import com.ruoyi.common.security.service.TokenService;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.math.BigDecimal;
|
import java.time.LocalTime;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* <p>
|
* 计费策略明细 服务实现类
|
* </p>
|
*
|
* @author xiaochen
|
* @since 2024-08-06
|
*/
|
@Service
|
public class TAccountingStrategyDetailServiceImpl extends ServiceImpl<TAccountingStrategyDetailMapper, TAccountingStrategyDetail> implements TAccountingStrategyDetailService {
|
|
@Autowired
|
private TAccountingStrategyMapper accountingStrategyMapper;
|
@Autowired
|
private TokenService tokenService;
|
@Autowired
|
private ISiteService siteService;
|
@Autowired
|
private TChargingGunService chargingGunService;
|
@Override
|
public List<TAccountingStrategyDetailVO> queryAccountingStrategyDetailByStrategyId(Integer strategyId) {
|
List<TAccountingStrategyDetailVO> tAccountingStrategyDetailVOS = this.baseMapper.queryAccountingStrategyDetailByStrategyId(strategyId);
|
return tAccountingStrategyDetailVOS;
|
}
|
|
@Override
|
public List<TAccountingStrategyDetailVO> queryMangementAccountingStrategyDetailByStrategyId(Integer strategyId) {
|
return this.baseMapper.queryAccountingStrategyDetailByStrategyId(strategyId);
|
}
|
|
@Override
|
public List<TAccountingStrategyDetailVO> queryStrategyBySiteIdAndTime(Integer siteId) {
|
Site site = siteService.getById(siteId);
|
TAccountingStrategy accountingStrategy = accountingStrategyMapper.selectById(site.getAccountingStrategyId());
|
if(Objects.isNull(accountingStrategy)){
|
throw new ServiceException("未查询到计费策略");
|
}
|
List<TAccountingStrategyDetailVO> list = this.queryAccountingStrategyDetailByStrategyId(accountingStrategy.getId());
|
list.stream().filter(item -> "00:00".equals(item.getEndTime())).forEach(item -> item.setEndTime("23:59:59"));
|
TAccountingStrategyDetailVO accountingStrategyDetailVO;
|
TAccountingStrategyDetailVO accountingStrategyDetailNext;
|
// 获取当前时间段的计费策略明细
|
accountingStrategyDetailVO = list.stream().filter(detail -> DateUtils.string2LocalTime(detail.getStartTime() + ":00").compareTo(LocalTime.now()) <= 0
|
&& DateUtils.string2LocalTime(detail.getEndTime() + ("23:59:59".equals(detail.getEndTime())?"":":00")).compareTo(LocalTime.now()) > 0)
|
.findFirst().orElseThrow(() -> new ServiceException("当前时间段未查询到计费策略明细"));
|
// 获取后一次的计费策略明细
|
accountingStrategyDetailVO.setEndTime("23:59:59".equals(accountingStrategyDetailVO.getEndTime())? "00:00":accountingStrategyDetailVO.getEndTime());
|
accountingStrategyDetailNext = list.stream().filter(detail -> detail.getStartTime().compareTo(accountingStrategyDetailVO.getEndTime()) == 0)
|
.findFirst().orElseThrow(() -> new ServiceException("未查询到下一时间段的计费策略明细"));
|
accountingStrategyDetailVO.setTotalPrice(accountingStrategyDetailVO.getElectrovalence().add(accountingStrategyDetailVO.getServiceCharge()));
|
accountingStrategyDetailNext.setTotalPrice(accountingStrategyDetailNext.getElectrovalence().add(accountingStrategyDetailNext.getServiceCharge()));
|
list = new ArrayList<>();
|
list.add(accountingStrategyDetailVO);
|
list.add(accountingStrategyDetailNext);
|
return list;
|
}
|
|
@Override
|
public StrategyPriceVO queryPrice(Integer siteId) {
|
Site site = siteService.getById(siteId);
|
TAccountingStrategy accountingStrategy = accountingStrategyMapper.selectById(site.getAccountingStrategyId());
|
if(Objects.isNull(accountingStrategy)){
|
throw new ServiceException("未查询到计费策略");
|
}
|
|
StrategyPriceVO strategyPriceVO = new StrategyPriceVO();
|
|
List<TAccountingStrategyDetailVO> list = this.queryAccountingStrategyDetailByStrategyId(accountingStrategy.getId());
|
list.stream().filter(item -> "24:00".equals(item.getEndTime())).forEach(item -> item.setEndTime("23:59:59"));
|
// 获取当前时间段的计费策略明细
|
TAccountingStrategyDetailVO accountingStrategyDetailVO = list.stream().filter(detail -> DateUtils.string2LocalTime(detail.getStartTime() + ":00").compareTo(LocalTime.now()) <= 0
|
&& DateUtils.string2LocalTime(detail.getEndTime() + ("23:59:59".equals(detail.getEndTime())?"":":00")).compareTo(LocalTime.now()) > 0)
|
.findFirst().orElseThrow(() -> new ServiceException("当前时间段未查询到计费策略明细"));
|
// strategyPriceVO.setDiscountAmount(accountingStrategyDetailVO.getElectrovalence().add(accountingStrategyDetailVO.getServiceCharge())
|
// .subtract(accountingStrategyDetailVO.getServiceCharge().multiply(accountingStrategy.getDiscount())).setScale(2, BigDecimal.ROUND_HALF_UP));
|
if(Objects.isNull(accountingStrategy.getDiscount())){
|
strategyPriceVO.setDiscountAmount(BigDecimal.ZERO);
|
}else {
|
strategyPriceVO.setDiscountAmount(accountingStrategyDetailVO.getServiceCharge()
|
.subtract(accountingStrategyDetailVO.getServiceCharge().multiply(accountingStrategy.getDiscount())).setScale(2, BigDecimal.ROUND_HALF_UP));
|
}
|
// 模板折扣
|
strategyPriceVO.setDiscount(accountingStrategy.getDiscount());
|
return strategyPriceVO;
|
}
|
|
@Override
|
public Boolean isStrategy24Hour(List<TAccountingStrategyDetail> accountingStrategyDetails) {
|
// List<TAccountingStrategyDetail> sortedDetails = accountingStrategyDetails.stream()
|
// .sorted(Comparator.comparing(TAccountingStrategyDetail::getStartTime))
|
// .collect(Collectors.toList());
|
//
|
// boolean isFirstElementValid = sortedDetails.isEmpty() || !sortedDetails.get(0).getStartTime().equals(sortedDetails.get(sortedDetails.size() - 1).getEndTime());
|
// if(isFirstElementValid){
|
// return true;
|
// }
|
//
|
// boolean eqTime = sortedDetails.stream().allMatch(detail -> detail.getStartTime().equals(detail.getEndTime()));
|
// if(eqTime){
|
// return true;
|
// }
|
//
|
// boolean isTimeContinuous = sortedDetails.stream()
|
// .skip(1)
|
// .allMatch(detail -> detail.getStartTime().equals(sortedDetails.get(sortedDetails.indexOf(detail) - 1).getEndTime()));
|
//
|
// return !isTimeContinuous;
|
|
// 处理空列表情况
|
if (accountingStrategyDetails == null || accountingStrategyDetails.isEmpty()) {
|
return false;
|
}
|
|
// 按开始时间排序
|
List<TAccountingStrategyDetail> sortedDetails = accountingStrategyDetails.stream()
|
.sorted(Comparator.comparing(TAccountingStrategyDetail::getStartTime))
|
.collect(Collectors.toList());
|
|
// 检查是否形成完整的24小时循环
|
// 第一个时间段的开始时间应该等于最后一个时间段的结束时间(形成闭环)
|
TAccountingStrategyDetail firstDetail = sortedDetails.get(0);
|
TAccountingStrategyDetail lastDetail = sortedDetails.get(sortedDetails.size() - 1);
|
|
// 首尾时间不匹配,不能构成24小时周期
|
if (!firstDetail.getStartTime().equals(lastDetail.getEndTime())) {
|
return false;
|
}
|
|
// 检查中间时间段是否连续
|
for (int i = 1; i < sortedDetails.size(); i++) {
|
TAccountingStrategyDetail current = sortedDetails.get(i);
|
TAccountingStrategyDetail previous = sortedDetails.get(i - 1);
|
|
// 当前时间段的开始时间必须等于前一个时间段的结束时间
|
if (!current.getStartTime().equals(previous.getEndTime())) {
|
return false;
|
}
|
}
|
|
return true;
|
}
|
|
@Override
|
public Boolean isStrategyPriceConsistent(List<TAccountingStrategyDetail> accountingStrategyDetails) {
|
Map<Integer, BigDecimal> phaseToServiceFee = new HashMap<>();
|
Map<Integer, BigDecimal> phaseToCostServiceFee = new HashMap<>();
|
for (TAccountingStrategyDetail detail : accountingStrategyDetails) {
|
Integer type = detail.getType();
|
BigDecimal serviceFee = detail.getServiceCharge();
|
BigDecimal costServiceCharge = detail.getCostServiceCharge();
|
|
if (phaseToServiceFee.containsKey(type)) {
|
BigDecimal existingFee = phaseToServiceFee.get(type);
|
BigDecimal existingCostServiceCharge = phaseToCostServiceFee.get(type);
|
if (existingFee.compareTo(serviceFee) != 0) {
|
return false; // 发现不一致的服务费
|
}
|
if (existingCostServiceCharge.compareTo(costServiceCharge) != 0) {
|
return false; // 发现不一致的原价服务费
|
}
|
} else {
|
phaseToServiceFee.put(type, serviceFee);
|
phaseToCostServiceFee.put(type, costServiceCharge);
|
}
|
}
|
return true; // 所有相同阶段的服务费一致
|
}
|
|
@Override
|
public List<TAccountingStrategyDetailVO> queryStrategyByGunIdAndTime(Integer gunId) {
|
TChargingGun chargingGun = chargingGunService.getById(gunId);
|
TAccountingStrategy accountingStrategy = accountingStrategyMapper.selectById(chargingGun.getAccountingStrategyId());
|
if(Objects.isNull(accountingStrategy)){
|
Site site = siteService.getById(chargingGun.getSiteId());
|
accountingStrategy = accountingStrategyMapper.selectById(site.getAccountingStrategyId());
|
if(Objects.isNull(accountingStrategy)){
|
throw new ServiceException("未查询到计费策略");
|
}
|
}
|
List<TAccountingStrategyDetailVO> list = this.queryAccountingStrategyDetailByStrategyId(accountingStrategy.getId());
|
list.stream().filter(item -> "00:00".equals(item.getEndTime())).forEach(item -> item.setEndTime("23:59:59"));
|
TAccountingStrategyDetailVO accountingStrategyDetailVO;
|
TAccountingStrategyDetailVO accountingStrategyDetailNext;
|
// 获取当前时间段的计费策略明细
|
accountingStrategyDetailVO = list.stream().filter(detail -> DateUtils.string2LocalTime(detail.getStartTime() + ":00").compareTo(LocalTime.now()) <= 0
|
&& DateUtils.string2LocalTime(detail.getEndTime() + ("23:59:59".equals(detail.getEndTime())?"":":00")).compareTo(LocalTime.now()) > 0)
|
.findFirst().orElseThrow(() -> new ServiceException("当前时间段未查询到计费策略明细"));
|
// 获取后一次的计费策略明细
|
accountingStrategyDetailVO.setEndTime("23:59:59".equals(accountingStrategyDetailVO.getEndTime())? "00:00":accountingStrategyDetailVO.getEndTime());
|
accountingStrategyDetailNext = list.stream().filter(detail -> detail.getStartTime().compareTo(accountingStrategyDetailVO.getEndTime()) == 0)
|
.findFirst().orElseThrow(() -> new ServiceException("未查询到下一时间段的计费策略明细"));
|
accountingStrategyDetailVO.setTotalPrice(accountingStrategyDetailVO.getElectrovalence().add(accountingStrategyDetailVO.getServiceCharge()));
|
accountingStrategyDetailNext.setTotalPrice(accountingStrategyDetailNext.getElectrovalence().add(accountingStrategyDetailNext.getServiceCharge()));
|
list = new ArrayList<>();
|
list.add(accountingStrategyDetailVO);
|
list.add(accountingStrategyDetailNext);
|
return list;
|
}
|
}
|