package com.cyksj.service.vip.impl; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.cyksj.common.constant.Constant; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.mapper.*; import com.cyksj.mapper.sys.SysConfigMapper; import com.cyksj.mapper.vip.VipGoodsSkuMapper; import com.cyksj.model.dto.VipDeductDto; import com.cyksj.model.entity.*; import com.cyksj.model.manage.views.GroupsRelationView; import com.cyksj.model.response.VipUserPageResp; import com.cyksj.service.user.UserBindRelationService; import com.cyksj.service.vip.VipFrontService; import com.ejlchina.searcher.BeanSearcher; import com.ejlchina.searcher.param.Operator; import com.ejlchina.searcher.util.MapUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; /** * 项目名: yhlxj2 * 文件名: VipFrontServiceImpl * 创建者: JavaZou * 创建时间:2025/5/15 16:00 */ @Service @RequiredArgsConstructor @Slf4j public class VipFrontServiceImpl implements VipFrontService { private final SysConfigMapper sysConfigMapper; private final VipGoodsSkuMapper vipGoodsSkuMapper; private final UserBindRelationService userBindRelationService; private final BeanSearcher beanSearcher; private final GoodsDonSkuMapper skuMapper; private final ChatgptUserMapper chatgptUserMapper; private final OrderDonRenewRecordMapper orderDonRenewRecordMapper; private final ClaudeUserMapper claudeUserMapper; private final OrderDonMapper orderDonMapper; private final GoodsDonSkuMapper goodsDonSkuMapper; @Override public void fillVipInfo(Long userId, VipUserPageResp vipUserPageResp) { SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.VIP_FEE_KEY).last("limit 1")); if (sysConfig != null && StrUtil.isNotBlank(sysConfig.getSysValue())) { vipUserPageResp.setVipFee(BigDecimal.valueOf(Integer.parseInt(sysConfig.getSysValue()))); } if (userId == null) { return; } //可抵扣价格 BigDecimal deductMoney = BigDecimal.ZERO; List userIdList = userBindRelationService.getRelationUserIdList(userId, null); List vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList()); //可有抵扣车票 DateTime now = DateTime.now(); //会员规格 Set goodsIds = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class) .in(GoodsDonSku::getId, vipSkuIds)).stream().map(GoodsDonSku::getGoodsId).collect(Collectors.toSet()); Number count = beanSearcher.searchCount(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getUserId, userIdList).op(Operator.InList).field(GroupsRelationView::getGoodsId, goodsIds).op(Operator.InList).field(GroupsRelationView::getExpiryTime, now).op(Operator.GreaterThan).build()); //可抵扣车票 if (count.intValue() > 0) { //处理vip抵扣金额 VipDeductDto vipDeductDto = commonHandleVipDeductMoney(userIdList, goodsIds, 12); deductMoney = vipDeductDto.getDeductMoney(); vipUserPageResp.setRelationUserViews(vipDeductDto.getRelationUserViews()); } vipUserPageResp.setDeductMoney(deductMoney); } /** * 检查用户并获取订单抵扣金额 */ @Override public VipDeductDto checkAndGetOrderDeductMoney(Long userId, Integer months) { List userIdList = userBindRelationService.getRelationUserIdList(userId, null); List vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList()); //会员规格 Set goodsIds = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class) .in(GoodsDonSku::getId, vipSkuIds)).stream().map(GoodsDonSku::getGoodsId).collect(Collectors.toSet()); Number count = beanSearcher.searchCount(GroupsRelationView.class, MapUtils.builder() .field(GroupsRelationView::getUserId, userIdList).op(Operator.InList) .field(GroupsRelationView::getGoodsId, goodsIds).op(Operator.InList) .field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan) .field(GroupsRelationView::getIsVip, false) .build()); if (count.intValue() == 0) { throw BusinessRuntimeException.getInstance("暂无可抵扣AI车票"); } VipDeductDto vipDeductDto = commonHandleVipDeductMoney(userIdList, goodsIds, months); return vipDeductDto; } private BigDecimal getVipMoney(Integer months) { SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.VIP_FEE_KEY).last("limit 1")); if (sysConfig == null || StrUtil.isEmpty(sysConfig.getSysValue())) { throw BusinessRuntimeException.getInstance("系统异常"); } BigDecimal vipFee = BigDecimal.valueOf(Long.valueOf(sysConfig.getSysValue())); return vipFee.multiply(BigDecimal.valueOf(months)); } /** * 统一处理vip抵扣金额 */ public VipDeductDto commonHandleVipDeductMoney(List userIdList, Set goodsIds, Integer months) { VipDeductDto vipDeductDto = new VipDeductDto(); DateTime now = DateTime.now(); List deductRelationIds = new ArrayList<>(); BigDecimal deductMoney = BigDecimal.ZERO; BigDecimal vipMoney = getVipMoney(months); List relations = beanSearcher.searchAll(GroupsRelationView.class, MapUtils.builder() .field(GroupsRelationView::getGoodsId, goodsIds).op(Operator.InList) .field(GroupsRelationView::getUserId, userIdList).op(Operator.InList) .field(GroupsRelationView::getIsVip, false) .field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan) .orderBy(GroupsRelationView::getExpiryTime).desc() .build()); Set deductGoodsIds = null; List deductRelations = null; for (GroupsRelationView relation : relations) { if (deductGoodsIds == null) { deductGoodsIds = new HashSet<>(); } if (deductRelations == null) { deductRelations = new ArrayList<>(); } Long goodsId = relation.getGoodsId(); if (deductGoodsIds.contains(goodsId)) { continue; } Long skuId = relation.getSkuId(); deductGoodsIds.add(goodsId); Long relationId = relation.getId(); Date relationExpiryTime = relation.getExpiryTime(); //GPT // if (goodsId == Constant.GPT_PLUS_GID) { // ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, relationId).last("limit 1")); // if (chatgptUser != null) { // //获取抵扣金额 // deductMoney = deductMoney.add(getFinalDeductMoney(relationId, relation.getSkuId(), chatgptUser.getRenewSkuId(), chatgptUser.getRenewOrderId(), chatgptUser.getRenewExpiryTime(), relation.getStartTime(), relationExpiryTime, now, userIdList)); // } // } else if (goodsId == Constant.CLAUDE_PRO_GID) { // ClaudeUser claudeUser = claudeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeUser.class).eq(ClaudeUser::getRelationId, relationId).last("limit 1")); // if (claudeUser != null) { // //获取抵扣金额 // deductMoney = deductMoney.add(getFinalDeductMoney(relationId, relation.getSkuId(), claudeUser.getRenewSkuId(), claudeUser.getRenewOrderId(), claudeUser.getRenewExpiryTime(), relation.getStartTime(), relationExpiryTime, now, userIdList)); // } // } else { // //该车票抵扣金额 // deductMoney = deductMoney.add(getDeductMoneyFromTicket(skuId, now, relation.getId(), relation.getStartTime(), relationExpiryTime)); // } //该车票抵扣金额 deductMoney = deductMoney.add(getDeductMoneyFromTicket(skuId, now, relation.getId(), relation.getStartTime(), relationExpiryTime)); deductRelationIds.add(relationId); //可抵扣车票 deductRelations.add(relation); //超出可抵扣的金额 直接返回 if (deductMoney.compareTo(vipMoney) >= 0) { deductMoney = vipMoney; break; } } vipDeductDto.setDeductMoney(deductMoney); vipDeductDto.setDeductRelationIds(deductRelationIds); vipDeductDto.setRelationUserViews(deductRelations); return vipDeductDto; } /** * 获取最终抵扣金额 */ public BigDecimal getFinalDeductMoney(Long relationId, Long relationSkuId, Long renewSkuId, Long renewOrderId, Date renewExpiryTime, Date relationStartTime, Date relationExpiryTime, DateTime now, List userIdList) { BigDecimal deductMoney = BigDecimal.ZERO; //一个月当30天算单价 往上取整 //续费规格 if (renewSkuId != null) { OrderDon renewOrderDon = orderDonMapper.selectById(renewOrderId); GoodsDonSku sku = skuMapper.selectById(renewSkuId); Long betweenDay = DateUtil.betweenDay(now, renewExpiryTime, false) + 1; //当天购买的按规格原价抵扣 if (now.toDateStr().equals(DateUtil.format(renewOrderDon.getCreatedTime(), "yyyy-MM-dd"))) { deductMoney = deductMoney.add(sku.getPrice()); } else { BigDecimal single = sku.getPrice().divide(BigDecimal.valueOf(sku.getMonths()).multiply(BigDecimal.valueOf(30)), 0, RoundingMode.UP); //该车票抵扣金额 BigDecimal renewDeductMoney = single.multiply(BigDecimal.valueOf(betweenDay)); log.info("车票id:{}目前续费升级规格可抵扣的金额为:{}", relationId, renewDeductMoney); deductMoney = deductMoney.add(renewDeductMoney); } relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -betweenDay.intValue()); //上一个续费升级规格 List orderDOns = orderDonRenewRecordMapper.getOtherRenewSkus(renewOrderId, relationId, userIdList); for (OrderDon orderDOn : orderDOns) { Long skuId = orderDOn.getSkuId(); sku = skuMapper.selectById(skuId); BigDecimal upDeductMoney = sku.getPrice(); log.info("车票id:{}目前次一级规格:{}可抵扣的金额为:{}", relationId, sku.getSpecVal(), upDeductMoney); deductMoney = deductMoney.add(upDeductMoney); if (sku.getDays() != null) { relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -sku.getDays()); } else { relationExpiryTime = DateUtil.offsetMonth(relationExpiryTime, -sku.getMonths()); } } } if (relationExpiryTime.after(DateTime.now())) { //该车票抵扣金额 BigDecimal deductMoneyFromTicket = getDeductMoneyFromTicket(relationSkuId, now, relationId, relationStartTime, relationExpiryTime); deductMoney = deductMoney.add(deductMoneyFromTicket); } log.info("车票id:{}最终到期时间为:{}车票可返回 抵扣金额:{}", relationId, DateUtil.format(relationExpiryTime, "yyyy-MM-dd HH:mm:ss"), deductMoney); return deductMoney; } /** * 获取车票可抵扣金额 */ public BigDecimal getDeductMoneyFromTicket(Long skuId, DateTime now, Long relationId, Date relationStartTime, Date relationExpiryTime) { GoodsDonSku sku = skuMapper.selectById(skuId); BigDecimal single = sku.getPrice().divide(BigDecimal.valueOf(sku.getMonths()).multiply(BigDecimal.valueOf(30)), 0, RoundingMode.UP); Long betweenDay = DateUtil.betweenDay(now, relationExpiryTime, false) + 1; //当天购买的按规格原价抵扣 if (now.toDateStr().equals(DateUtil.format(relationStartTime, "yyyy-MM-dd"))) { //并且没有续费 且未扣时长 if (DateUtil.betweenDay(DateUtil.offsetMonth(relationStartTime, 1), relationExpiryTime, true) == 0) { return sku.getPrice(); } } //该车票抵扣金额 BigDecimal deductMoney = single.multiply(BigDecimal.valueOf(betweenDay)); return deductMoney; } }