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.ChatgptUserMapper; import com.cyksj.mapper.ClaudeUserMapper; import com.cyksj.mapper.GoodsDonSkuMapper; import com.cyksj.mapper.OrderDonRenewRecordMapper; 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.ArrayList; import java.util.Date; import java.util.List; 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; @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()))); } //可抵扣价格 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(); Number count = beanSearcher.searchCount(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getUserId, userIdList).op(Operator.InList).field(GroupsRelationView::getSkuId, vipSkuIds).op(Operator.InList).field(GroupsRelationView::getExpiryTime, now).op(Operator.GreaterThan).build()); //可抵扣车票 if (count.intValue() > 0) { //处理vip抵扣金额 VipDeductDto vipDeductDto = commonHandleVipDeductMoney(userIdList, vipSkuIds); deductMoney = vipDeductDto.getDeductMoney(); } vipUserPageResp.setDeductMoney(deductMoney); } /** * 检查用户并获取订单抵扣金额 */ @Override public VipDeductDto checkAndGetOrderDeductMoney(Long userId) { List userIdList = userBindRelationService.getRelationUserIdList(userId, null); List vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList()); Number count = beanSearcher.searchCount(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getUserId, userIdList).op(Operator.InList).field(GroupsRelationView::getSkuId, vipSkuIds).op(Operator.InList).field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan).build()); if (count.intValue() == 0) { throw BusinessRuntimeException.getInstance("暂无可抵扣AI车票"); } VipDeductDto vipDeductDto = commonHandleVipDeductMoney(userIdList, vipSkuIds); return vipDeductDto; } private BigDecimal getVipMoney() { 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; } /** * 统一处理vip抵扣金额 */ public VipDeductDto commonHandleVipDeductMoney(List userIdList, List vipSkuIds) { VipDeductDto vipDeductDto = new VipDeductDto(); DateTime now = DateTime.now(); List deductRelationIds = new ArrayList<>(); BigDecimal deductMoney = BigDecimal.ZERO; BigDecimal vipMoney = getVipMoney(); for (Long vipSkuId : vipSkuIds) { GroupsRelationView relation = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getSkuId, vipSkuId).field(GroupsRelationView::getUserId, userIdList).op(Operator.InList).orderBy(GroupsRelationView::getExpiryTime).desc().build()); if (relation != null) { Long goodsId = relation.getGoodsId(); 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(), 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(), relationExpiryTime, now, userIdList)); } } else { //该车票抵扣金额 deductMoney = deductMoney.add(getDeductMoneyFromTicket(vipSkuId, now, relationExpiryTime)); } deductRelationIds.add(relationId); //超出可抵扣的金额 直接返回 if (deductMoney.compareTo(vipMoney) >= 0) { deductMoney = vipMoney; break; } } } vipDeductDto.setDeductMoney(deductMoney); vipDeductDto.setDeductRelationIds(deductRelationIds); return vipDeductDto; } /** * 获取最终抵扣金额 */ public BigDecimal getFinalDeductMoney(Long relationId, Long relationSkuId, Long renewSkuId, Long renewOrderId, Date renewExpiryTime, Date relationExpiryTime, DateTime now, List userIdList) { BigDecimal deductMoney = BigDecimal.ZERO; //一个月当30天算单价 往上取整 //续费规格 if (renewSkuId != null) { GoodsDonSku sku = skuMapper.selectById(renewSkuId); BigDecimal single = sku.getPrice().divide(BigDecimal.valueOf(sku.getMonths()).multiply(BigDecimal.valueOf(30)), 0, RoundingMode.UP); Long betweenDay = DateUtil.betweenDay(now, renewExpiryTime, false); //该车票抵扣金额 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 = orderDOn.getMoney().add(orderDOn.getBalance()); 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, relationExpiryTime); log.info("车票id:{}最终到期时间为:{}车票可返回 抵扣金额:{}", relationId, relationExpiryTime, deductMoney); deductMoney = deductMoney.add(deductMoneyFromTicket); } return deductMoney; } /** * 获取车票可抵扣金额 */ public BigDecimal getDeductMoneyFromTicket(Long skuId, DateTime now, 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); //该车票抵扣金额 BigDecimal deductMoney = single.multiply(BigDecimal.valueOf(betweenDay)); return deductMoney; } }