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.account.api.feignClient.AppUserVipDetailClient;
import com.ruoyi.account.api.model.TAppUser;
import com.ruoyi.account.api.model.TAppUserVipDetail;
import com.ruoyi.account.api.vo.GetAppUserVipDetail;
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 com.ruoyi.other.api.domain.TVip;
import com.ruoyi.other.api.feignClient.VipClient;
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;
/**
*
* 计费策略明细 服务实现类
*
*
* @author xiaochen
* @since 2024-08-06
*/
@Service
public class TAccountingStrategyDetailServiceImpl extends ServiceImpl implements TAccountingStrategyDetailService {
@Autowired
private TAccountingStrategyMapper accountingStrategyMapper;
@Autowired
private VipClient vipClient;
@Autowired
private TokenService tokenService;
@Autowired
private ISiteService siteService;
@Autowired
private TChargingGunService chargingGunService;
@Autowired
private AppUserClient appUserClient;
@Resource
private AppUserVipDetailClient vipDetailClient;
@Override
public List queryAccountingStrategyDetailByStrategyId(Integer strategyId) {
List tAccountingStrategyDetailVOS = this.baseMapper.queryAccountingStrategyDetailByStrategyId(strategyId);
Long userId = tokenService.getLoginUserApplet().getUserId();
TAppUser appUser = appUserClient.getUserById(userId).getData();
for (TAccountingStrategyDetailVO tAccountingStrategyDetailVO : tAccountingStrategyDetailVOS) {
GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
getAppUserVipDetail.setAppUserId(userId);
getAppUserVipDetail.setVipId(appUser.getVipId());
R appUserVipDetail = vipDetailClient.getAppUserVipDetail(getAppUserVipDetail);
TAppUserVipDetail data1 = appUserVipDetail.getData();
if(Objects.nonNull(data1)){
String vipJson = data1.getVipJson();
TVip vip = JSON.parseObject(vipJson, TVip.class);
if(Objects.nonNull(vip) && vip.getType() == 2){
tAccountingStrategyDetailVO.setDiscount(vip.getDiscount().divide(new BigDecimal(10)));
}
}
}
return tAccountingStrategyDetailVOS;
}
@Override
public List queryMangementAccountingStrategyDetailByStrategyId(Integer strategyId) {
return this.baseMapper.queryAccountingStrategyDetailByStrategyId(strategyId);
}
@Override
public List queryStrategyBySiteIdAndTime(Integer siteId) {
Site site = siteService.getById(siteId);
TAccountingStrategy accountingStrategy = accountingStrategyMapper.selectById(site.getAccountingStrategyId());
if(Objects.isNull(accountingStrategy)){
throw new ServiceException("未查询到计费策略");
}
List list = this.queryAccountingStrategyDetailByStrategyId(accountingStrategy.getId());
list.stream().filter(item -> "00:00".equals(item.getEndTime())).forEach(item -> item.setEndTime("23:59:59"));
// 获取当前登录用户id
Long userId = tokenService.getLoginUserApplet().getUserId();
// 根据id查询用户信息
TAppUser appUser = appUserClient.getUserById(userId).getData();
TVip vip = null;
if(Objects.nonNull(appUser)){
// 查询会员信息
GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
getAppUserVipDetail.setAppUserId(userId);
getAppUserVipDetail.setVipId(appUser.getVipId());
R appUserVipDetail = vipDetailClient.getAppUserVipDetail(getAppUserVipDetail);
TAppUserVipDetail data1 = appUserVipDetail.getData();
if(Objects.nonNull(data1)){
String vipJson = data1.getVipJson();
vip = JSON.parseObject(vipJson, TVip.class);
}
}
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("未查询到下一时间段的计费策略明细"));
if(Objects.nonNull(vip)) {
if (vip.getType() == 2) {
accountingStrategyDetailVO.setTotalPrice(accountingStrategyDetailVO.getElectrovalence().add(accountingStrategyDetailVO.getServiceCharge().multiply(vip.getDiscount())));
accountingStrategyDetailVO.setDiscount(vip.getDiscount().divide(new BigDecimal(10)));
accountingStrategyDetailNext.setTotalPrice(accountingStrategyDetailNext.getElectrovalence().add(accountingStrategyDetailNext.getServiceCharge().multiply(vip.getDiscount())));
} else {
if(Objects.isNull(accountingStrategy.getDiscount())){
accountingStrategyDetailVO.setTotalPrice(accountingStrategyDetailVO.getElectrovalence().add(accountingStrategyDetailVO.getServiceCharge().multiply(new BigDecimal(1))));
accountingStrategyDetailNext.setTotalPrice(accountingStrategyDetailNext.getElectrovalence().add(accountingStrategyDetailNext.getServiceCharge().multiply(new BigDecimal(1))));
}else {
accountingStrategyDetailVO.setTotalPrice(accountingStrategyDetailVO.getElectrovalence().add(accountingStrategyDetailVO.getServiceCharge().multiply(accountingStrategy.getDiscount())));
accountingStrategyDetailNext.setTotalPrice(accountingStrategyDetailNext.getElectrovalence().add(accountingStrategyDetailNext.getServiceCharge().multiply(accountingStrategy.getDiscount())));
}
}
}else {
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 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));
}
// 查询最高折扣的会员
TVip monthlyCardDiscount = vipClient.getVipInfoByType(3).getData();
strategyPriceVO.setServiceFeeDiscount(null == monthlyCardDiscount ? new BigDecimal(10) : monthlyCardDiscount.getMonthlyCardDiscount());
// 查询最高优惠的会员
TVip maximumDeduction = vipClient.getVipInfoByType(1).getData();
strategyPriceVO.setMaxDiscountAmount(null == maximumDeduction ? new BigDecimal(10) : maximumDeduction.getMaximumDeduction());
// 查询最低起步价会员
TVip monthlyCard = vipClient.getVipInfoByType(2).getData();
strategyPriceVO.setVipStartPrice(null == monthlyCard ? new BigDecimal(10) : monthlyCard.getMonthlyCard());
// 模板折扣
strategyPriceVO.setDiscount(accountingStrategy.getDiscount());
return strategyPriceVO;
}
@Override
public Boolean isStrategy24Hour(List accountingStrategyDetails) {
List 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());
boolean isTimeContinuous = sortedDetails.stream()
.skip(1)
.allMatch(detail -> detail.getStartTime().equals(sortedDetails.get(sortedDetails.indexOf(detail) - 1).getEndTime()));
return isFirstElementValid || !isTimeContinuous;
}
@Override
public Boolean isStrategyPriceConsistent(List accountingStrategyDetails) {
Map phaseToElectrovalence = new HashMap<>();
Map phaseToServiceFee = new HashMap<>();
Map phaseToCostServiceFee = new HashMap<>();
for (TAccountingStrategyDetail detail : accountingStrategyDetails) {
Integer type = detail.getType();
BigDecimal electrovalence = detail.getElectrovalence();
BigDecimal serviceFee = detail.getServiceCharge();
BigDecimal costServiceCharge = detail.getCostServiceCharge();
if (phaseToServiceFee.containsKey(type)) {
BigDecimal existingElectrovalence = phaseToElectrovalence.get(type);
BigDecimal existingFee = phaseToServiceFee.get(type);
BigDecimal existingCostServiceCharge = phaseToCostServiceFee.get(type);
if (existingElectrovalence.compareTo(electrovalence) != 0) {
return false; // 发现不一致的电价
}
if (existingFee.compareTo(serviceFee) != 0) {
return false; // 发现不一致的服务费
}
if (existingCostServiceCharge.compareTo(costServiceCharge) != 0) {
return false; // 发现不一致的原价服务费
}
} else {
phaseToElectrovalence.put(type, electrovalence);
phaseToServiceFee.put(type, serviceFee);
phaseToCostServiceFee.put(type, costServiceCharge);
}
}
return true; // 所有相同阶段的电价、服务费均一致
}
@Override
public List 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 list = this.queryAccountingStrategyDetailByStrategyId(accountingStrategy.getId());
list.stream().filter(item -> "00:00".equals(item.getEndTime())).forEach(item -> item.setEndTime("23:59:59"));
// 获取当前登录用户id
Long userId = tokenService.getLoginUserApplet().getUserId();
// 根据id查询用户信息
TAppUser appUser = appUserClient.getUserById(userId).getData();
TVip vip = null;
if(Objects.nonNull(appUser)){
// 查询会员信息
GetAppUserVipDetail getAppUserVipDetail = new GetAppUserVipDetail();
getAppUserVipDetail.setAppUserId(userId);
getAppUserVipDetail.setVipId(appUser.getVipId());
R appUserVipDetail = vipDetailClient.getAppUserVipDetail(getAppUserVipDetail);
TAppUserVipDetail data1 = appUserVipDetail.getData();
if(Objects.nonNull(data1)){
String vipJson = data1.getVipJson();
vip = JSON.parseObject(vipJson, TVip.class);
}
}
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("未查询到下一时间段的计费策略明细"));
if(Objects.nonNull(vip)) {
if (vip.getType() == 2) {
accountingStrategyDetailVO.setTotalPrice(accountingStrategyDetailVO.getElectrovalence().add(accountingStrategyDetailVO.getServiceCharge().multiply(vip.getDiscount())));
accountingStrategyDetailNext.setTotalPrice(accountingStrategyDetailNext.getElectrovalence().add(accountingStrategyDetailNext.getServiceCharge().multiply(vip.getDiscount())));
} else {
BigDecimal discount = accountingStrategy.getDiscount();
if(Objects.isNull(discount)){
discount = BigDecimal.ONE;
}
accountingStrategyDetailVO.setTotalPrice(accountingStrategyDetailVO.getElectrovalence().add(accountingStrategyDetailVO.getServiceCharge().multiply(discount)));
accountingStrategyDetailNext.setTotalPrice(accountingStrategyDetailNext.getElectrovalence().add(accountingStrategyDetailNext.getServiceCharge().multiply(discount)));
}
}else {
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;
}
}