package com.cyksj.service.mange.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alipay.api.AlipayClient; import com.alipay.api.domain.AlipayTradeRefundModel; import com.alipay.api.request.AlipayTradeRefundRequest; import com.alipay.api.response.AlipayTradeRefundResponse; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.cyksj.common.constant.Constant; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.common.task.GlobalThreadPoolTaskExecutor; import com.cyksj.common.util.Codec; import com.cyksj.common.util.Jsons; import com.cyksj.common.util.StringUtil; import com.cyksj.common.util.Xmls; import com.cyksj.config.WeChatConfig; import com.cyksj.config.zfb.AliPayClientFactory; import com.cyksj.dto.RedisKey; import com.cyksj.mapper.*; import com.cyksj.mapper.channel.ShopConfigMapper; import com.cyksj.mapper.channel.UserPayEquipmentAvailableBenefitsMapper; import com.cyksj.mapper.channel.UserPayEquipmentReceiveBenefitsRecordMapper; import com.cyksj.mapper.manage.cms.CmsUserMapper; import com.cyksj.mapper.manage.distribute.DistributeWaitingSendPointsMapper; import com.cyksj.mapper.manage.distribute.UserDistributeBusinessOrderDonRecordMapper; import com.cyksj.mapper.manage.distribute.UserDistributeMapper; import com.cyksj.mapper.manage.distribute.equipment.EquipmentUserDistributeTransportBenefitsMapper; import com.cyksj.mapper.manage.distribute.sub.UserDistributeSubMapper; import com.cyksj.mapper.manage.distribute.sub.UserDistributeSubRewardsMapper; import com.cyksj.mapper.manage.distribute.sub.UserDistributeSubWaitingMapper; import com.cyksj.mapper.manage.sys.WorkOrderMapper; import com.cyksj.mapper.mirrorshop.UserMirrorShopDistributeWaitingSendPointsMapper; import com.cyksj.mapper.mirrorshop.UserMirrorShopMapper; import com.cyksj.mapper.shop.YhShopUserDistributeBusinessOrderDonRecordMapper; import com.cyksj.mapper.stock.GoodsSkuStockRelateMapper; import com.cyksj.model.entity.*; import com.cyksj.model.excel.ExcelOrderDonInfo; import com.cyksj.model.manage.request.ReqSetLogisticsPost; import com.cyksj.model.manage.views.GroupsRelationView; import com.cyksj.model.request.ChangeRelationReq; import com.cyksj.model.request.ClickOutReq; import com.cyksj.model.request.OrderBalanceRefundReq; import com.cyksj.model.request.OrderRefundReq; import com.cyksj.redis.RedisService; import com.cyksj.service.coin.UserGalaxyCoinService; import com.cyksj.service.coupon.CouponFontService; import com.cyksj.service.distribute.equipment.EquipmentDistributeService; import com.cyksj.service.giftcard.GiftCardOrderUseRecordService; import com.cyksj.service.mange.CmsOrderDonService; import com.cyksj.service.mange.MirrorUserCleatService; import com.cyksj.service.mange.stock.GoodsDonStockService; import com.cyksj.service.market.MarketFrontService; import com.cyksj.service.order.OrderCommonService; import com.cyksj.service.order.OrderRefundService; import com.cyksj.service.order.UserRealOrderBenefitsService; import com.cyksj.service.relation.GroupRelationClearService; import com.cyksj.service.relation.GroupRelationFrontService; import com.cyksj.service.relation.GroupsRelationExpiryRecordService; import com.cyksj.service.relation.GroupsRelationNetflixService; import com.cyksj.service.shop.YhShopDistributeService; import com.cyksj.service.user.UserBenefitsService; import com.cyksj.service.user.UserBindRelationService; import com.cyksj.service.wechat.WeChatService; import com.ejlchina.searcher.BeanSearcher; import com.ejlchina.searcher.util.MapUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.dao.DuplicateKeyException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; /** * @author chan * @date 2021/10/25 下午10:14 */ @Service @Slf4j @RequiredArgsConstructor public class CmsOrderDonServiceImpl extends ServiceImpl implements CmsOrderDonService { private final OrderDonTransportMapper transportMapper; private final OrderDonWaybillMapper orderDonWaybillMapper; private final GoodsSkuStockRelateMapper skuStockRelateMapper; private final GoodsDonStockService goodsDonStockService; private final GoodsDonSkuMapper goodsDonSkuMapper; private final UserRealOrderBenefitsService userRealOrderBenefitsService; private final UserRelationKickOutRecordMapper kickOutRecordMapper; private final CmsUserMapper cmsUserMapper; private final OrderCommonService orderCommonService; private final GoodsDonMapper goodsDonMapper; private final RedisService redisService; private final UserBenefitsService userBenefitsService; private final DistributeWaitingSendPointsMapper distributeWaitingSendPointsMapper; private final RefundOrderDonMapper refundOrderDonMapper; private final UserDistributeMapper userDistributeMapper; private final OrderDonMapper orderDonMapper; private final MarketFrontService marketFrontService; private final EquipmentDistributeService equipmentDistributeService; private final CouponFontService couponFontService; private final WeChatService weChatService; private final WeChatConfig weChatConfig; private final ShopConfigMapper shopConfigMapper; private final GroupRelationClearService relationClearService; private final GroupsRelationMapper relationMapper; private final GroupsMapper groupsMapper; private final GoodsDonSkuMapper skuMapper; private final UserDistributeBusinessOrderDonRecordMapper businessOrderDonRecordMapper; private final WorkOrderMapper workOrderMapper; private final OrderRefundService orderRefundService; private final OrderDiscountPlusPurchaseSkuRelationMapper orderDiscountPlusPurchaseSkuRelationMapper; private final EquipmentUserDistributeTransportBenefitsMapper transportBenefitsMapper; private final BeanSearcher beanSearcher; private final UserPayEquipmentReceiveBenefitsRecordMapper receiveBenefitsRecordMapper; private final GroupsRelationExpiryRecordService groupsRelationExpiryRecordService; private final GiftCardOrderUseRecordService giftCardOrderUseRecordService; private final GiftCardUserRecordMapper giftCardUserRecordMapper; private final YhShopDistributeService yhShopDistributeService; private final YhShopUserDistributeBusinessOrderDonRecordMapper yhShopBusinessOrderDonRecordMapper; private final UserPayEquipmentAvailableBenefitsMapper availableBenefitsMapper; private final GroupRelationFrontService groupRelationFrontService; private final UserMapper userMapper; private final ChatgptUserMapper chatgptUserMapper; private final UserDistributeSubMapper userDistributeSubMapper; private final UserDistributeSubWaitingMapper subWaitingMapper; private final UserDistributeSubRewardsMapper userDistributeSubRewardsMapper; private final UpgradeOrderDonMapper upgradeOrderDonMapper; private final UpgradePackageMapper upgradePackageMapper; private final MidjourneyUserMapper midjourneyUserMapper; private final GroupsRelationMapper groupsRelationMapper; private final UserBindRelationService userBindRelationService; private final GroupsRelationNetflixService groupsRelationNetflixService; private final AccountMapper accountMapper; private final MirrorUserCleatService mirrorUserCleatService; private final OrderDonRenewRecordMapper orderDonRenewRecordMapper; private final OrderDonUpgradeRenewRecordMapper orderDonUpgradeRenewRecordMapper; private final LumaUserMapper lumaUserMapper; private final UserBenefitsOrderRecordMapper userBenefitsOrderRecordMapper; private final UserBenefitsComboRelationRecordMapper userBenefitsComboRelationRecordMapper; private final UserMirrorShopMapper userMirrorShopMapper; private final UserMirrorShopDistributeWaitingSendPointsMapper userMirrorShopDistributeWaitingSendPointsMapper; private final ClaudeUserMapper claudeUserMapper; private final UserTicketClearedRecordMapper userTicketClearedRecordMapper; private final NetflixUserAccountSubmitRecoverRecordMapper netflixUserAccountSubmitRecoverRecordMapper; private final NetflixUserChangeOtherTicketRecordMapper netflixUserChangeOtherTicketRecordMapper; private final OrderDonGalaxyCoinRecordMapper orderDonGalaxyCoinRecordMapper; private final UserGalaxyCoinService userGalaxyCoinService; private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance(); @Override public List exportOrderInfo(Long promotionId, String start, String end) { return this.getBaseMapper().exportOrderInfo(promotionId,start,end); } @Override public OrderDonTransport getTransport(Long orderId) { return transportMapper.selectOne(Wrappers.lambdaQuery(OrderDonTransport.class).eq(OrderDonTransport::getOrderId, orderId)); } @Transactional(rollbackFor = Throwable.class) @Override public OrderDonWaybill setWaybill(ReqSetLogisticsPost reqSetLogisticsPost) { OrderDonWaybill orderDonWaybill = Optional.ofNullable(orderDonWaybillMapper.selectOne(Wrappers.lambdaQuery(OrderDonWaybill.class).eq(OrderDonWaybill::getOrderId, reqSetLogisticsPost.getOrderId()))).orElse(new OrderDonWaybill()); orderDonWaybill.setCodeCn(reqSetLogisticsPost.getCodeCn()); orderDonWaybill.setTrackingNumber(reqSetLogisticsPost.getTrackingNumber()); orderDonWaybill.setOrderId(reqSetLogisticsPost.getOrderId()); orderDonWaybill.setRemark(reqSetLogisticsPost.getRemark()); OrderDon orderDon = getById(orderDonWaybill.getOrderId()); Integer type = Optional.ofNullable(reqSetLogisticsPost.getType()).orElse(0); //实物发货 if (type == 0 || type == 1) { if (orderDonWaybill.getId() == null) { try { orderDonWaybillMapper.insert(orderDonWaybill); } catch (DuplicateKeyException e) { return orderDonWaybill; } orderDon.setStatus(OrderDon.Status.transport); updateById(orderDon); //库存扣减逻辑 List relateList = skuStockRelateMapper.selectList(Wrappers.lambdaQuery(GoodsSkuStockRelate.class).eq(GoodsSkuStockRelate::getSkuId, orderDon.getSkuId())); if (!relateList.isEmpty()) { relateList.forEach((relate) -> { goodsDonStockService.upStockRelate(relate.getStockId(), orderDon.getId(), "transport"); }); } } else { if (orderDon.getStatus() == OrderDon.Status.hasPayment) { orderDon.setStatus(OrderDon.Status.transport); updateById(orderDon); } orderDonWaybillMapper.updateById(orderDonWaybill); } //实物分销订单是否存在 DistributeWaitingSendPoints waitingSendPoints = distributeWaitingSendPointsMapper.selectOne(Wrappers.lambdaQuery(DistributeWaitingSendPoints.class) .eq(DistributeWaitingSendPoints::getOrderId, orderDon.getId()) .eq(DistributeWaitingSendPoints::getIsDelivery, false) .last("limit 1")); if (waitingSendPoints != null) { //实物分销订单发货后再 进行提成结算期 waitingSendPoints.setIsDelivery(true); distributeWaitingSendPointsMapper.updateById(waitingSendPoints); } //分销有礼 分销实物是否有发货后用户权益 EquipmentUserDistributeTransportBenefits transportBenefits = transportBenefitsMapper.selectOne(Wrappers.lambdaQuery(EquipmentUserDistributeTransportBenefits.class) .eq(EquipmentUserDistributeTransportBenefits::getOrderId, orderDon.getId()) .eq(EquipmentUserDistributeTransportBenefits::getStatus, EquipmentUserDistributeTransportBenefits.Status.hasPayment).last("limit 1")); if (transportBenefits != null) { if (transportBenefits.getBalance().compareTo(BigDecimal.ZERO) > 0) { //7天后余额到账 transportBenefitsMapper.update(null, Wrappers.lambdaUpdate(EquipmentUserDistributeTransportBenefits.class) .set(EquipmentUserDistributeTransportBenefits::getStatus, EquipmentUserDistributeTransportBenefits.Status.transport) .set(EquipmentUserDistributeTransportBenefits::getSendTime, DateUtil.offsetDay(DateTime.now(), 7)) .eq(EquipmentUserDistributeTransportBenefits::getOrderId, orderDon.getId()) .eq(EquipmentUserDistributeTransportBenefits::getStatus, EquipmentUserDistributeTransportBenefits.Status.hasPayment)); } } } //权益发货 if (type == 0 || type == 2) { GoodsDonSku sku = goodsDonSkuMapper.selectById(orderDon.getSkuId()); if (sku != null && sku.getIsBenefits()) { //是否实物权益已发放 Integer count = receiveBenefitsRecordMapper.selectCount(Wrappers.lambdaQuery(UserPayEquipmentReceiveBenefitsRecord.class) .eq(UserPayEquipmentReceiveBenefitsRecord::getRealOrderId, orderDon.getId())); if (count == 0) { count = availableBenefitsMapper.selectCount(Wrappers.lambdaQuery(UserPayEquipmentAvailableBenefits.class) .eq(UserPayEquipmentAvailableBenefits::getRealOrderId, orderDon.getId())); } if (count == 0) { //实物权益未发 String benefitsKey = RedisService.key.REAL_GOODS_BENEFITS_KEY.getNameFormat(orderDon.getId()); if (redisService.setNx(benefitsKey, orderDon.getId(), RedisService.key.REAL_GOODS_BENEFITS_KEY.getTimeout())) { //发放实物购买权益 if (StrUtil.isNotEmpty(sku.getBenefitsList())) { try { List goodsDonSkus = Jsons.parseList(sku.getBenefitsList(), GoodsDonSku.class); //自购实物 获取权益 userRealOrderBenefitsService.getPayRealGoodsBenefits(orderDon.getUserId(), orderDon.getId(), orderDon.getYhsId(), goodsDonSkus); //清除多余的车票 clearExtraRelation(orderDon); } catch (Exception e) { redisService.del(benefitsKey); } } } } } } return orderDonWaybill; } @Override public void kickOutRelationId(long adminId, ClickOutReq req) { Long orderId = req.getOrderId(); OrderDon orderDon = getById(orderId); if (orderDon != null && !orderDon.getIsKickOut()) { try { UserRelationKickOutRecord kickOutRecord = new UserRelationKickOutRecord(); kickOutRecord.setUserId(orderDon.getUserId()); kickOutRecord.setRelationId(orderDon.getRelationId()); kickOutRecord.setGoodsId(orderDon.getGoodsId()); kickOutRecord.setSkuId(orderDon.getSkuId()); kickOutRecord.setReason(req.getReason()); kickOutRecord.setImg(req.getImg()); kickOutRecord.setRemark(req.getRemark()); kickOutRecord.setOrderId(orderDon.getId()); kickOutRecord.setOrderNo(orderDon.getOrderNo()); Optional.ofNullable(cmsUserMapper.selectById(adminId)).ifPresent(cmsUser -> kickOutRecord.setOperator(cmsUser.getNickname())); kickOutRecordMapper.insert(kickOutRecord); orderDon.setIsKickOut(true); updateById(orderDon); GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId()); GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(orderDon.getSkuId()); //清除车票 orderCommonService.clearUnrealGoodsDetail(orderDon, goodsDon.getType(), goodsDonSku); } catch (DuplicateKeyException e) { } } } @Override @Transactional(rollbackFor = Throwable.class) public void unifiedRefund(OrderRefundReq refundReq) throws Exception { OrderDon orderDon = orderDonMapper.selectById(refundReq.getOrderId()); GoodsDonSku sku = null; if (orderDon.getSkuId() != null) { sku = goodsDonSkuMapper.selectById(orderDon.getSkuId()); } GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId()); if (StrUtil.isEmpty(refundReq.getRefundType())) { refundReq.setRefundType("money"); } String refundType = refundReq.getRefundType(); //校验订单是否符合退款 checkOrderRefund(orderDon, goodsDon, sku, refundReq); //空订单关闭 if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0 && orderDon.getBalance().compareTo(BigDecimal.ZERO) == 0 && orderDon.getRelationId() == 0) { orderDon.setStatus(OrderDon.Status.refund); orderDonMapper.updateById(orderDon); if (goodsDon.getType() == 2) { //扣除用户自身实物权益 userRealOrderBenefitsService.deductUserRealGoodsBenefits(orderDon.getId()); } return; } //调用第三方接口退款 String outNo = StrUtil.EMPTY; if (refundReq.getRefundMoney() != null && refundReq.getRefundMoney().compareTo(BigDecimal.ZERO) > 0) { outNo = orderRefundService.centerRefund(refundReq, orderDon); } orderDon.setRefundDesc(refundReq.getRefundDesc()); //记录退款信息 commonRefund(orderDon, refundReq.getRefundMoney(), refundReq.getOperator(), goodsDon, sku, outNo, refundType, refundReq.getIsOnly(), refundReq.getRefundBalance(), refundReq.getChatImg(), refundReq.getDeductBalance(), refundReq.getDpRelationIds()); //修改订单状态 orderDon.setStatus(OrderDon.Status.refund); orderDonMapper.updateById(orderDon); //续费升级订单 if (orderDon.getOrderType() == 2 && sku.getIsMirror()) { mirrorUserCleatService.handleRenewUpgradeOrders(orderDon, sku); } //提交过工单的订单 //将用户异常订单关闭 workOrderMapper.update(null, Wrappers.lambdaUpdate(WorkOrder.class) .set(WorkOrder::getStatus, WorkOrder.Status.close) .eq(WorkOrder::getStatus, WorkOrder.Status.waiting) .eq(WorkOrder::getUserId, orderDon.getUserId()) .eq(WorkOrder::getRelationId, orderDon.getRelationId())); //将GPT规格的车队 下次可停车时间置空 groupRelationFrontService.setGroupsTripsParkingTimeEmpty(sku, orderDon.getRelationId()); } @Override @Transactional(rollbackFor = Throwable.class) public void unifiedUpgradeRefund(OrderRefundReq refundReq) throws Exception { UpgradeOrderDon orderDon = upgradeOrderDonMapper.selectById(refundReq.getOrderId()); UpgradePackage upgradePackage = upgradePackageMapper.selectById(orderDon.getPackageId()); if (StrUtil.isEmpty(refundReq.getRefundType())) { refundReq.setRefundType("money"); } String refundType = refundReq.getRefundType(); //校验订单是否符合退款 checkUpgradeOrderRefund(orderDon, refundReq); //空订单关闭 if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0 && orderDon.getBalance().compareTo(BigDecimal.ZERO) == 0) { orderDon.setStatus(UpgradeOrderDon.Status.refund); upgradeOrderDonMapper.updateById(orderDon); return; } Long userId = orderDon.getUserId(); List userIdList = null; //检验gpt套餐 if (upgradePackage.getGoodsId() == 18) { userIdList = userBindRelationService.getRelationUserIdList(userId, null); //是否有更高级的套餐 UpgradeOrderDon more = upgradeOrderDonMapper.selectOne(Wrappers.lambdaQuery(UpgradeOrderDon.class) .in(UpgradeOrderDon::getUserId, userIdList) .eq(UpgradeOrderDon::getRelationId, orderDon.getRelationId()) .gt(UpgradeOrderDon::getNum, orderDon.getNum()) .eq(UpgradeOrderDon::getStatus, UpgradeOrderDon.Status.complete) .last("limit 1")); if (more != null) { throw BusinessRuntimeException.getInstance("请先退掉其更高级套餐"); } } //调用第三方接口退款 String outNo = orderRefundService.centerUpgradeRefund(refundReq, orderDon); orderDon.setRefundDesc(refundReq.getRefundDesc()); //记录退款信息 commonUpgradeRefund(orderDon, refundReq.getRefundMoney(), refundReq.getOperator(), upgradePackage, outNo, refundType, refundReq.getIsOnly(), refundReq.getRefundBalance(), refundReq.getChatImg()); //修改订单状态 orderDon.setStatus(UpgradeOrderDon.Status.refund); upgradeOrderDonMapper.updateById(orderDon); //扣除套餐次数 if (upgradePackage.getGoodsId() == 26) { MidjourneyUser midjourneyUser = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class).eq(MidjourneyUser::getRelationId, orderDon.getRelationId())); if (midjourneyUser != null) { int update = midjourneyUserMapper.update(null, Wrappers.lambdaUpdate(MidjourneyUser.class) .set(MidjourneyUser::getMjUpgradeNum, midjourneyUser.getMjUpgradeNum() < upgradePackage.getNum() ? 0 : midjourneyUser.getMjUpgradeNum() - upgradePackage.getNum()) .eq(MidjourneyUser::getId, midjourneyUser.getId())); if (update == 0) { log.info("midjourneyUser 套餐包增值失败 id:{},orderId:{}", midjourneyUser.getId(), orderDon.getId()); } Long decr = redisService.decr(RedisService.key.MIDJOURNEY_UPGRADE_LIMIT.getName() + midjourneyUser.getId(), upgradePackage.getNum().longValue()); if (decr < 0) { redisService.set(RedisService.key.MIDJOURNEY_UPGRADE_LIMIT.getName() + midjourneyUser.getId(), 0L); } } } //扣除gpt套餐升级 if (upgradePackage.getGoodsId() == 18) { ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, orderDon.getRelationId())); if (chatgptUser != null) { GroupsRelation relation = groupsRelationMapper.selectById(chatgptUser.getRelationId()); GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId()); GoodsDonSku sku = skuMapper.selectById(groupsTrips.getSkuId()); //原先sku的套餐 Long gptLimitTime = sku.getGptLimitTime(); Integer gptLimitNum = sku.getGptLimitNum(); //次等套餐的规格 UpgradeOrderDon secondUpgrade = upgradeOrderDonMapper.selectOne(Wrappers.lambdaQuery(UpgradeOrderDon.class) .in(UpgradeOrderDon::getUserId, userIdList) .eq(UpgradeOrderDon::getRelationId, orderDon.getRelationId()) .lt(UpgradeOrderDon::getNum, orderDon.getNum()) .eq(UpgradeOrderDon::getStatus, UpgradeOrderDon.Status.complete) .last("limit 1")); Long renewSkuId = chatgptUser.getRenewSkuId(); //续费升级 GoodsDonSku renewSku = null; if (renewSkuId != null) { renewSku = goodsDonSkuMapper.selectById(renewSkuId); gptLimitTime = renewSku.getGptLimitTime(); gptLimitNum = renewSku.getGptLimitNum(); } if (secondUpgrade != null) { gptLimitTime = secondUpgrade.getTime(); gptLimitNum = secondUpgrade.getNum(); if (renewSku != null) { //低级套餐 GoodsDonSku secondSkuUpGrade = goodsDonSkuMapper.selectById(secondUpgrade.getSkuId()); //续费升级套餐更高 if (renewSku.getMonths() >= secondSkuUpGrade.getMonths() && renewSku.getGptLimitNum() >= secondSkuUpGrade.getGptLimitNum() && renewSku.getGptLimitTime() <= secondSkuUpGrade.getGptLimitTime()) { gptLimitTime = renewSku.getGptLimitTime(); gptLimitNum = renewSku.getGptLimitNum(); } } } Long packageId = 0l; //降级套餐 if (secondUpgrade != null) { packageId = secondUpgrade.getPackageId(); } int update = chatgptUserMapper.update(null, Wrappers.lambdaUpdate(ChatgptUser.class) .set(ChatgptUser::getLimitTime, gptLimitTime) .set(ChatgptUser::getLimitNum, gptLimitNum) .set(ChatgptUser::getPackageId, packageId) //无次等套餐 不需要清除套餐时间 .set(secondUpgrade == null, ChatgptUser::getClearPackageTime, null) .eq(ChatgptUser::getId, chatgptUser.getId())); if (update == 0) { log.info("chatgptUser 升级套餐包增值失败 id:{},orderId:{}", chatgptUser.getId(), orderDon.getId()); } } } //扣除luma套餐次数 if (upgradePackage.getGoodsId() == Constant.LUMA_GOODS_ID) { LumaUser lumaUser = lumaUserMapper.selectOne(Wrappers.lambdaQuery(LumaUser.class).eq(LumaUser::getRelationId, orderDon.getRelationId())); if (lumaUser != null) { int update = lumaUserMapper.update(null, Wrappers.lambdaUpdate(LumaUser.class) .set(LumaUser::getNum, lumaUser.getNum() < upgradePackage.getNum() ? 0 : lumaUser.getNum() - upgradePackage.getNum()) .eq(LumaUser::getId, lumaUser.getId())); if (update == 0) { log.info("lumaUser 套餐包增值失败 id:{},orderId:{}", lumaUser.getId(), orderDon.getId()); } Long decr = redisService.decr(RedisService.key.LUMA_NUM_LIMIT.getName() + lumaUser.getId(), upgradePackage.getNum().longValue()); if (decr < 0) { redisService.set(RedisService.key.LUMA_NUM_LIMIT.getName() + lumaUser.getId(), 0L); } } } } /** * 退款后 处理关联 */ public void commonUpgradeRefund(UpgradeOrderDon orderDon, BigDecimal refundMoney, String operator, UpgradePackage upgradePackage, String outNo, String refundType, Boolean isOnly, BigDecimal refundBalance, String chatImg) { TASK_POOL.execute(() -> { orderRefundService.refundUpgradeRecord(orderDon, refundMoney,upgradePackage, operator, outNo, refundType, chatImg); //退等比例 if (isOnly != null && isOnly) { userBenefitsService.addUserBalance(orderDon.getUserId(), refundBalance, UserBalanceSourceRecord.Source.refund, 0L, orderDon.getId(), upgradePackage.getName()+ UserBalanceSourceRecord.Source.refund.getDesc(), true); BigDecimal orderDonRefundBalance = Optional.ofNullable(orderDon.getRefundBalance()).orElse(BigDecimal.ZERO); orderDon.setRefundBalance(orderDonRefundBalance.add(refundBalance)); } //若存在余额支付,退还余额 if (isOnly == null && orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) { userBenefitsService.addUserBalance(orderDon.getUserId(), orderDon.getBalance(), UserBalanceSourceRecord.Source.refund, 0L, orderDon.getId(), upgradePackage.getName() + UserBalanceSourceRecord.Source.refund.getDesc(), true); } if (UpgradeOrderDon.Type.BALANCE.getType().equals(refundType)) { if (isOnly == null && orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) { userBenefitsService.addUserBalance(orderDon.getUserId(), orderDon.getRefundBalance(), UserBalanceSourceRecord.Source.refund, 0L, orderDon.getId(), upgradePackage.getName() + UserBalanceSourceRecord.Source.refund.getDesc(), true); } } }); } /** * 校验订单是否符合退款操作 */ private void checkUpgradeOrderRefund(UpgradeOrderDon orderDon, OrderRefundReq refundReq) { if (orderDon == null) { throw BusinessRuntimeException.getInstance("订单不存在"); } BigDecimal orderDonRefundMoney = Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO); BigDecimal orderDonRefundBalance = Optional.ofNullable(orderDon.getRefundBalance()).orElse(BigDecimal.ZERO); String refundType = refundReq.getRefundType(); if (orderDon.getType() == UpgradeOrderDon.Type.BALANCE && !UpgradeOrderDon.Type.BALANCE.getType().equals(refundType)) { throw BusinessRuntimeException.getInstance("余额支付的订单不支持金额退款"); } if (UpgradeOrderDon.Status.refund == orderDon.getStatus()) { throw BusinessRuntimeException.getInstance("该订单已退款"); } if (UpgradeOrderDon.Status.noPayment == orderDon.getStatus() || UpgradeOrderDon.Status.close == orderDon.getStatus()) { throw BusinessRuntimeException.getInstance("订单{0}状态不支持退款", orderDon.getStatus()); } BigDecimal refundMoney = refundReq.getRefundMoney(); BigDecimal money = orderDon.getMoney(); //余额退款 if (UpgradeOrderDon.Type.BALANCE.getType().equals(refundType)) { BigDecimal balance = orderDon.getBalance(); refundMoney = orderDonRefundBalance.add(refundMoney); if (UpgradeOrderDon.Type.BALANCE == orderDon.getType() && refundMoney.compareTo(balance) > 0) { throw BusinessRuntimeException.getInstance("退款余额大于订单支付余额"); } if (UpgradeOrderDon.Type.BALANCE != orderDon.getType() && refundMoney.compareTo(money) > 0) { throw BusinessRuntimeException.getInstance("退款余额大于订单支付金额"); } orderDon.setRefundBalance(refundMoney); orderDon.setRefundMoney(BigDecimal.ZERO); } else { //退金额 refundMoney = orderDonRefundMoney.add(refundMoney); if (refundMoney.compareTo(money) > 0) { throw BusinessRuntimeException.getInstance("退款金额大于订单支付金额"); } orderDon.setRefundMoney(refundMoney); } if (!redisService.setNx(String.format("%s", refundReq.getOrderId()), refundReq.getOrderId(), 10l)) { throw BusinessRuntimeException.getInstance("请勿重复点击,正在退款中.."); } } public String wxRefund(OrderRefundReq refundReq, OrderDon orderDon) throws Exception { if (orderDon.getMoney().compareTo(BigDecimal.ZERO) <=0){ return StrUtil.EMPTY; } long time = System.currentTimeMillis(); //退款订单号 String outRefundNo = Codec.DoDigest.custom() .setAlgorithm(Codec.DoDigest.Algorithm.MD5) .setStringData(time + String.valueOf(orderDon.getId())) .toHexString(); weChatService.refundWxOrder(weChatConfig.getAppid(), Optional.ofNullable(orderDon.getShopId()).orElse(ShopConfig.WX_DEFAULT_APP_ID), orderDon.getTransactionId(), outRefundNo, orderDon.getMoney(), refundReq.getRefundMoney(), weChatConfig.getNotifyDomain() + "manage/order/wx/refund/notify"); //记录退款信息 return outRefundNo; } @Override public void wxRefundNotify(Map map) throws Exception { // 对退款数据 解密 String md5Key = Codec.DoDigest.custom().setAlgorithm(Codec.DoDigest.Algorithm.MD5).setStringData(shopConfigMapper.getByAppId(map.get("mch_id")).getSecret()).toHexString(); String reqInfoXml = Codec.DoCipher.custom().setAlgorithm(Codec.DoCipher.Trans.AES_ECB_PKCS7Padding).setBase64Data(map.get("req_info")).setStringKey(md5Key).ofDecrypt().toText(); log.info("=== 退款数据解密: \n {}", reqInfoXml); Map reqInfoMap = Xmls.toMap(reqInfoXml); // 退款失败 if (StrUtil.equals("CHANGE", reqInfoMap.get("refund_status"))) { throw BusinessRuntimeException.getInstance("退款异常."); } else if (StrUtil.equals("REFUNDCLOSE", reqInfoMap.get("refund_status"))) { throw BusinessRuntimeException.getInstance("退款关闭."); } /* 此处处理业务逻辑 */ String outRefundNo = reqInfoMap.get("out_refund_no"); String transactionId = reqInfoMap.get("transaction_id"); String refundFee = reqInfoMap.get("refund_fee"); OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getTransactionId, transactionId).last("limit 1")); if (orderDon == null) { log.error("退款回调,transactionId:{}订单不存在", transactionId); return; } log.info("微信退款: 退款单号[{}] 退款成功.", outRefundNo); } @Override @Transactional(rollbackFor = Throwable.class) public void changeRelation(ChangeRelationReq req) throws Exception { Long relationId = req.getRelationId(); Long groupId = req.getGroupsId(); UserTicketClearedRecord.Source source = req.getSource(); if (source == null) source = UserTicketClearedRecord.Source.change_ticket; GroupsRelation relation = relationMapper.selectById(relationId); Long yhsId = relation.getYhsId(); Assert.notNull(relation, "车票已不存在"); if (relation.getRechargeStatus() != null) { throw BusinessRuntimeException.getInstance("代充账号车票无法更换车票"); } String key = RedisService.key.NETFLIX_CHANGE_TICKET_KEY.getName() + relationId; if (!redisService.setNx(key, relationId, RedisService.key.NETFLIX_CHANGE_TICKET_KEY.getTimeout())) { throw BusinessRuntimeException.getInstance("正在更换车票中.."); } Long userId = relation.getUserId(); log.info("用户userId:{}更换车票relationId:{}", userId, relationId); OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class) .eq(OrderDon::getUserId, userId) .eq(OrderDon::getRelationId, relationId) .notIn(OrderDon::getStatus, Constant.noOrderAllStatus) .orderByDesc(OrderDon::getId) .last("limit 1")); OrderDiscountPlusPurchaseSkuRelation plusPurchaseSkuRelation = null; List plus_relationList = null; if (orderDon == null) { List plusPurchaseSkuRelations = orderDiscountPlusPurchaseSkuRelationMapper.selectPlusRelationByIdAndUserId(relation.getId(), relation.getUserId()); for (OrderDiscountPlusPurchaseSkuRelation data : plusPurchaseSkuRelations) { String relationIds = data.getRelationIds(); if (StrUtil.isEmpty(relationIds)) { return; } List relationList = Jsons.parseList(relationIds, Long.class); if (relationList.contains(relationId)) { plusPurchaseSkuRelation = data; break; } } if (plusPurchaseSkuRelation != null) { String relationIds = plusPurchaseSkuRelation.getRelationIds(); if (StrUtil.isNotEmpty(relationIds)) { plus_relationList = Jsons.parseList(relationIds, Long.class); if (plus_relationList.contains(relationId)) { orderDon = new OrderDon(); GroupsRelationView groupsRelationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getId, relationId).build()); Assert.notNull(groupsRelationView, "车票已不存在"); orderDon.setUserId(groupsRelationView.getUserId()); orderDon.setSkuId(groupsRelationView.getSkuId()); orderDon.setGoodsId(groupsRelationView.getGoodsId()); orderDon.setStatus(OrderDon.Status.complete); orderDon.setOrderType(1); } } } } Assert.notNull(orderDon, "订单不存在"); if (orderDon.getStatus() == OrderDon.Status.refund) { throw BusinessRuntimeException.getInstance("订单已退款"); } //获取新车队 LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(GroupsTrips.class) .eq(GroupsTrips::getSkuId, orderDon.getSkuId()) .eq(GroupsTrips::getId, groupId) .ne(GroupsTrips::getId, relation.getGroupsId()) .ne(GroupsTrips::getStatus, GroupsTrips.Status.down) .last("limit 1"); GroupsTrips groups = groupsMapper.selectOne(queryWrapper); if (groups == null) throw BusinessRuntimeException.getInstance("车队不存在或已下架"); if (!Constant.AI_goodsIds.contains(orderDon.getGoodsId()) && groups.getAvailableNum() <= 0) { throw BusinessRuntimeException.getInstance("该新车位人员已满"); } Integer relationNum = groups.getNum(); //获取新车队车位 GroupsRelation newRelation; Boolean isOutside = req.getIsOutside(); if (Constant.AI_goodsIds.contains(orderDon.getGoodsId()) && ((isOutside != null && isOutside) || groups.getAvailableNum() == 0) && groups.getNum() > 1) { //Ai车队 额外增加车位 并不让上车 newRelation = getChatGPTOutsideRelation(orderDon.getUserId(), groupId, relationNum, 1); } else { newRelation = getRelationThisTrips(orderDon.getUserId(), groupId, 1); } newRelation.setUserId(userId); newRelation.setStartTime(relation.getStartTime()); newRelation.setExpiryTime(relation.getExpiryTime()); newRelation.setYhsId(yhsId); newRelation.setCmt(relation.getCmt()); newRelation.setCustomerService(relation.getCustomerService()); if (newRelation.getStatus() != GroupsRelation.Status.outside) { newRelation.setStatus(GroupsRelation.Status.validity); } //清除原先车票 relation.setNewRelationId(newRelation.getId()); relationClearService.clearTicket(relation, source); //兜底处理 多余车票 clearOtherChangeTicket(userId, relationId, newRelation, orderDon.getSkuId()); //奈飞车票 if (orderDon.getGoodsId() == 1) { User user = userMapper.selectById(newRelation.getUserId()); GroupsTrips groupsTrips = groupsMapper.selectById(newRelation.getGroupsId()); Account account = accountMapper.selectById(groupsTrips.getAccountId()); AtomicInteger start = new AtomicInteger(1); groupsRelationNetflixService.timingSetNetflix(newRelation.getNum(), user.getNickname(), account.getAccount(), account.getPassword(), newRelation.getExpiryTime(), start); } if (plusPurchaseSkuRelation != null && plus_relationList != null) { plus_relationList.remove(relationId); plus_relationList.add(newRelation.getId()); plusPurchaseSkuRelation.setRelationIds(plus_relationList.toString()); orderDiscountPlusPurchaseSkuRelationMapper.updateById(plusPurchaseSkuRelation); } if (source != null && source == UserTicketClearedRecord.Source.abnormal) { //将用户异常订单关闭 workOrderMapper.update(null, Wrappers.lambdaUpdate(WorkOrder.class) .set(WorkOrder::getStatus, WorkOrder.Status.close) .eq(WorkOrder::getStatus, WorkOrder.Status.waiting) .eq(WorkOrder::getUserId, userId) .eq(WorkOrder::getRelationId, relationId)); } if (orderDon.getMoney() != null && orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) { //是否是实物权益车票 UserPayEquipmentReceiveBenefitsRecord receiveBenefitsRecord = receiveBenefitsRecordMapper.selectOne(Wrappers.lambdaQuery(UserPayEquipmentReceiveBenefitsRecord.class) .eq(UserPayEquipmentReceiveBenefitsRecord::getTicketOrderId, orderDon.getId()) .eq(UserPayEquipmentReceiveBenefitsRecord::getRelationId, relationId).last("limit 1")); if (receiveBenefitsRecord != null) { receiveBenefitsRecord.setRelationId(newRelation.getId()); receiveBenefitsRecordMapper.updateById(receiveBenefitsRecord); } } if ((newRelation.getStartTime() == null || newRelation.getExpiryTime() == null)) { List orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getUserId, userId).eq(OrderDon::getRelationId, relationId).eq(OrderDon::getStatus, OrderDon.Status.hasPayment)); if (orderDonList.isEmpty()) { orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class) .eq(OrderDon::getUserId, userId) .eq(OrderDon::getRelationId, relationId) .eq(OrderDon::getStatus, OrderDon.Status.complete) .orderByDesc(OrderDon::getId) .last("limit 1")); } if (groups.getStatus() == GroupsTrips.Status.waiting) { orderDonList.forEach(hasPaymentOrder -> { hasPaymentOrder.setRelationId(newRelation.getId()); orderDonMapper.updateById(hasPaymentOrder); }); relationMapper.updateById(newRelation); return; } orderDonList.forEach((hasPaymentOrder) -> { //如果续费增加时间,如果首次则设置当前时间为初始时间 Date expiryTime = Optional.ofNullable(newRelation.getExpiryTime()).orElse(new Date()); GoodsDonSku donSku = skuMapper.selectById(hasPaymentOrder.getSkuId()); Date newDate; if (donSku.getDays() != null && donSku.getDays() > 0) { newDate = DateUtil.offsetDay(expiryTime, donSku.getDays() * hasPaymentOrder.getNum()); } else { newDate = DateUtil.offset(expiryTime, DateField.MONTH, donSku.getMonths() * hasPaymentOrder.getNum()); } newRelation.setExpiryTime(newDate); newRelation.setStartTime(newRelation.getStartTime() == null ? new Date() : null); relationMapper.updateById(newRelation); hasPaymentOrder.setStatus(OrderDon.Status.complete); hasPaymentOrder.setRelationId(newRelation.getId()); orderDonMapper.updateById(hasPaymentOrder); }); return; } List orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getUserId, userId).eq(OrderDon::getRelationId, relationId).eq(OrderDon::getStatus, OrderDon.Status.complete)); orderDonList.forEach(completeOrder->{ completeOrder.setRelationId(newRelation.getId()); orderDonMapper.updateById(completeOrder); }); log.info("userId:{}更换车票,原座位号relationId:{}======>新座位号newRelationId:{}", newRelation.getUserId(), relationId, newRelation.getId()); relationMapper.updateById(newRelation); //更换车票 调整GPT相关规格新车队 上车数 GoodsDonSku sku = goodsDonSkuMapper.selectById(groups.getSkuId()); groupRelationFrontService.adjustGroupsParkingTime(newRelation.getId(), sku); //关闭正在恢复的车票 if (orderDon.getGoodsId() == Constant.NETFLIX_GID) { List userIdList = userBindRelationService.getRelationUserIdList(orderDon.getUserId(), null); NetflixUserAccountSubmitRecoverRecord recoverRecord = netflixUserAccountSubmitRecoverRecordMapper.selectOne(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class) .eq(NetflixUserAccountSubmitRecoverRecord::getRelationId, orderDon.getRelationId()) .in(NetflixUserAccountSubmitRecoverRecord::getUserId, userIdList) .eq(NetflixUserAccountSubmitRecoverRecord::getStatus, 0) .last("limit 1")); if (recoverRecord != null) { recoverRecord.setStatus(3); netflixUserAccountSubmitRecoverRecordMapper.updateById(recoverRecord); } } } public String zfbRefund(OrderRefundReq refundReq, OrderDon orderDon) throws Exception { if (orderDon.getMoney().compareTo(BigDecimal.ZERO) <=0){ return StrUtil.EMPTY; } AlipayTradeRefundResponse response; //支付宝退款 AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(Optional.ofNullable(orderDon.getShopId()).orElse(ShopConfig.ZFB_DEFAULT_APP_ID)); AlipayTradeRefundRequest request = new AlipayTradeRefundRequest(); AlipayTradeRefundModel model = new AlipayTradeRefundModel(); //支付宝交易号 model.setTradeNo(orderDon.getTransactionId()); model.setRefundAmount(refundReq.getRefundMoney().divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_EVEN).toString()); model.setQueryOptions(List.of("gmt_refund_pay")); long time = System.currentTimeMillis(); //退款订单号 String outRefundNo = Codec.DoDigest.custom() .setAlgorithm(Codec.DoDigest.Algorithm.MD5) .setStringData(time + String.valueOf(orderDon.getId())) .toHexString(); //退款请求号 model.setOutRequestNo(outRefundNo); request.setBizModel(model); String shopId = orderDon.getShopId(); ShopConfig shopConfig = shopConfigMapper.selectOne(Wrappers.lambdaQuery(ShopConfig.class).eq(ShopConfig::getAppId, orderDon.getShopId())); if (shopId != null && shopConfig != null && shopConfig.getIsCert()) { response = alipayClient.certificateExecute(request); } else { response = alipayClient.execute(request); } if (!response.isSuccess()) throw BusinessRuntimeException.getInstance("退款失败,e:{0}", response.getSubMsg()); // AliPayRefundRep aliPayRefundRep = Jsons.parseObject(response.getBody(), AliPayRefundRep.class); // AliPayRefundRep.AlipayTradeRefundResponse res = aliPayRefundRep.getResponse(); // orderDon.setRefundMoney(res.getRefundFee().multiply(BigDecimal.valueOf(100))); return outRefundNo; } /** * 校验订单是否符合退款操作 */ private void checkOrderRefund(OrderDon orderDon, GoodsDon goodsDon, GoodsDonSku sku, OrderRefundReq refundReq) { if (orderDon == null) { throw BusinessRuntimeException.getInstance("订单不存在"); } BigDecimal orderDonRefundMoney = Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO); BigDecimal orderDonRefundBalance = Optional.ofNullable(orderDon.getRefundBalance()).orElse(BigDecimal.ZERO); String refundType = refundReq.getRefundType(); if (orderDon.getType() == OrderDon.Type.BALANCE && !OrderDon.Type.BALANCE.getType().equals(refundType)) { throw BusinessRuntimeException.getInstance("余额支付的订单不支持金额退款"); } if (OrderDon.Status.refund == orderDon.getStatus()) { throw BusinessRuntimeException.getInstance("该订单已退款"); } if (OrderDon.Status.noPayment == orderDon.getStatus() || OrderDon.Status.close == orderDon.getStatus()) { throw BusinessRuntimeException.getInstance("订单{0}状态不支持退款", orderDon.getStatus()); } if (goodsDon.getId() == Constant.NETFLIX_GID) { Integer selectCount = netflixUserChangeOtherTicketRecordMapper.selectCount(Wrappers.lambdaQuery(NetflixUserChangeOtherTicketRecord.class) .eq(NetflixUserChangeOtherTicketRecord::getOrderId, orderDon.getId())); if (selectCount > 0) { throw BusinessRuntimeException.getInstance("该奈飞车票已替换其他车票,无法退款"); } } if (goodsDon.getType() == 1 && sku != null) { //虚拟原订单是否已过期 Integer months = sku.getMonths(); Integer days = sku.getDays(); Integer num = orderDon.getNum(); DateTime now = DateTime.now(); DateTime endTime; if (days != null && days > 0) { endTime = DateUtil.offsetDay(orderDon.getCreatedTime(), days * num); } else { endTime = DateUtil.offsetMonth(orderDon.getCreatedTime(), months * num); } if (now.isAfter(endTime)) { throw BusinessRuntimeException.getInstance("该订单车票已过期"); } if (orderDon.getOrderType() == 1) { //是否有其他付款订单是否过期 OrderDon otherOrder = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class) .eq(OrderDon::getRelationId, orderDon.getRelationId()) .eq(OrderDon::getUserId, orderDon.getUserId()) .ne(OrderDon::getId, orderDon.getId()) .notIn(OrderDon::getStatus, Constant.noOrderAllStatus) .eq(OrderDon::getOrderType, 2) .orderByDesc(OrderDon::getId) .last("limit 1")); if (otherOrder != null) { throw BusinessRuntimeException.getInstance("该笔订单存在续费订单,请先退掉续费订单"); } } } BigDecimal refundMoney = refundReq.getRefundMoney(); BigDecimal money = orderDon.getMoney(); //余额退款 if (OrderDon.Type.BALANCE.getType().equals(refundType)) { BigDecimal balance = orderDon.getBalance(); refundMoney = orderDonRefundBalance.add(refundMoney); if (OrderDon.Type.BALANCE == orderDon.getType() && refundMoney.compareTo(balance) > 0) { throw BusinessRuntimeException.getInstance("退款余额大于订单支付余额"); } if (OrderDon.Type.BALANCE != orderDon.getType() && refundMoney.compareTo(money) > 0) { throw BusinessRuntimeException.getInstance("退款余额大于订单支付金额"); } orderDon.setRefundBalance(refundMoney); orderDon.setRefundMoney(BigDecimal.ZERO); } else { //退金额 refundMoney = orderDonRefundMoney.add(refundMoney); if (refundMoney.compareTo(money) > 0) { throw BusinessRuntimeException.getInstance("退款金额大于订单支付金额"); } orderDon.setRefundMoney(refundMoney); } //礼品卡是否已使用 GiftCardUserRecord giftCardUserRecord = null; if (goodsDon.getSpecialType() != null && goodsDon.getSpecialType() == GoodsDon.SpecialType.giftCard) { Integer count = giftCardUserRecordMapper.selectCount(Wrappers.lambdaQuery(GiftCardUserRecord.class) .eq(GiftCardUserRecord::getIsUsed, 1) .eq(GiftCardUserRecord::getOrderId, orderDon.getId())); if (count > 0) { throw BusinessRuntimeException.getInstance("该礼品卡已使用无法退款"); } } if (!redisService.setNx(String.format("%s", refundReq.getOrderId()), refundReq.getOrderId(), 10l)) { throw BusinessRuntimeException.getInstance("请勿重复点击,正在退款中.."); } //礼品卡购买状态 if (giftCardUserRecord != null) { giftCardUserRecord.setIsPay(false); giftCardUserRecordMapper.updateById(giftCardUserRecord); } //校验续费升级规格 checkMirrorRenewSku(orderDon); } /** * 退款后 处理关联 */ public void commonRefund(OrderDon orderDon, BigDecimal refundMoney, String operator, GoodsDon goodsDon, GoodsDonSku sku, String outNo, String refundType, Boolean isOnly, BigDecimal refundBalance, String chatImg, BigDecimal deductBalance, List dpRelationIds) { orderRefundService.refundRecord(orderDon, refundMoney, operator, goodsDon, sku, outNo, refundType, chatImg); //退款一次 goodsDonStockService.upStockRelate(null, orderDon.getId(), "refund"); try { if (!orderDon.getIsDp()) { //虚物订单退款,清出车队,车票变为已过期 orderCommonService.clearUnrealGoodsDetail(orderDon, goodsDon.getType(), sku); } } catch (Exception e) { log.error("清除车票错误:{}", StringUtil.getErrorText(e)); } //若存在优惠券使用,退还优惠券 if (orderDon.getCouponUserId() != 0) { couponFontService.updateOrderDonCouponStatus(orderDon); } //退等比例 if (isOnly != null && isOnly) { userBenefitsService.addUserBalance(orderDon.getUserId(), refundBalance, UserBalanceSourceRecord.Source.refund, orderDon.getYhsId(), orderDon.getId(), goodsDon.getTitle() + UserBalanceSourceRecord.Source.refund.getDesc(), true); BigDecimal orderDonRefundBalance = Optional.ofNullable(orderDon.getRefundBalance()).orElse(BigDecimal.ZERO); orderDon.setRefundBalance(orderDonRefundBalance.add(refundBalance)); } //若存在余额支付,退还余额 if (isOnly == null && orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) { BigDecimal addBalance = orderDon.getBalance(); //需额外扣除余额 if (deductBalance != null && deductBalance.compareTo(BigDecimal.ZERO) > 0) { addBalance = addBalance.subtract(deductBalance); } userBenefitsService.addUserBalance(orderDon.getUserId(), addBalance, UserBalanceSourceRecord.Source.refund, orderDon.getYhsId(), orderDon.getId(), goodsDon.getTitle() + UserBalanceSourceRecord.Source.refund.getDesc(), true); } //是否全额退款 if (refundMoney.compareTo(orderDon.getMoney()) == 0) { //是否使用银河币支付 OrderDonGalaxyCoinRecord orderDonGalaxyCoinRecord = orderDonGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonGalaxyCoinRecord.class) .eq(OrderDonGalaxyCoinRecord::getOrderId, orderDon.getId()) .last("limit 1")); if (orderDonGalaxyCoinRecord != null) { //有效时,返还银河币 并记录 userGalaxyCoinService.recordOrderRefundGalaxyCoinIfValid(orderDon.getId(), orderDonGalaxyCoinRecord.getUserId(), orderDonGalaxyCoinRecord.getGalaxyCoin()); //扣除 该笔订单产生的返现银河币 if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) { userGalaxyCoinService.subOrderGenerateGalaxyCoin(orderDon.getId()); } } } try { marketFrontService.subSpecificChanceNum(orderDon.getUserId(), orderDon.getId(), orderDon.getGoodsId(), orderDon.getUpdateTime()); if (goodsDon.getType() == 2 && !orderDon.getIsDistribute()) { equipmentDistributeService.subDistributeBenefitsChance(orderDon.getUserId(), orderDon.getId()); //扣除用户自身实物权益 userRealOrderBenefitsService.deductUserRealGoodsBenefits(orderDon.getId()); } } catch (Exception e) { log.error("wx减少抽奖机会错误,orderId:{},error:{}", orderDon.getId(), e); } if (OrderDon.Type.BALANCE.getType().equals(refundType)) { if (isOnly == null && orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) { userBenefitsService.addUserBalance(orderDon.getUserId(), orderDon.getRefundBalance(), UserBalanceSourceRecord.Source.refund, orderDon.getYhsId(), orderDon.getId(), goodsDon.getTitle() + UserBalanceSourceRecord.Source.refund.getDesc(), true); } } else { //余额退款不需要扣除积分 //分销提成积分扣除 deductDsPoints(orderDon); //店铺 分销提成金额扣除 yhShopDistributeService.deductDsMoney(orderDon); //镜像店铺 分销提成金额扣除 deductUserMirrorShopMoney(orderDon); } if (orderDon.getIsFixedDistribute()) { //商务提成 因订单退款去掉 UserDistributeBusinessOrderDonRecord record = businessOrderDonRecordMapper.selectOne(Wrappers.lambdaQuery(UserDistributeBusinessOrderDonRecord.class) .eq(UserDistributeBusinessOrderDonRecord::getOrderId, orderDon.getId()) .eq(UserDistributeBusinessOrderDonRecord::getStatus, UserDistributeBusinessOrderDonRecord.Status.success) .last("limit 1")); if (record != null) { record.setStatus(UserDistributeBusinessOrderDonRecord.Status.refund); businessOrderDonRecordMapper.updateById(record); } } //店铺商务提成 if (orderDon.getYhsId() != null && orderDon.getYhsId() > 0) { YhShopUserDistributeBusinessOrderDonRecord shop_record = yhShopBusinessOrderDonRecordMapper.selectOne(Wrappers.lambdaQuery(YhShopUserDistributeBusinessOrderDonRecord.class) .eq(YhShopUserDistributeBusinessOrderDonRecord::getOrderId, orderDon.getId()) .eq(YhShopUserDistributeBusinessOrderDonRecord::getStatus, YhShopUserDistributeBusinessOrderDonRecord.Status.success) .last("limit 1")); if (shop_record != null) { shop_record.setStatus(YhShopUserDistributeBusinessOrderDonRecord.Status.refund); yhShopBusinessOrderDonRecordMapper.updateById(shop_record); } } //是否是优惠加购关联订单 if (orderDon.getIsDp()) { OrderDiscountPlusPurchaseSkuRelation discountPlusPurchaseSkuRelation = orderDiscountPlusPurchaseSkuRelationMapper.selectOne(Wrappers.lambdaQuery(OrderDiscountPlusPurchaseSkuRelation.class) .eq(OrderDiscountPlusPurchaseSkuRelation::getOrderId, orderDon.getId()).last("limit 1")); if (discountPlusPurchaseSkuRelation != null) { //选择清除加购车票 if (CollUtil.isNotEmpty(dpRelationIds)) { try { List groupsRelations = relationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class) .eq(GroupsRelation::getUserId, orderDon.getUserId()) .in(GroupsRelation::getId, dpRelationIds)); log.info("优惠加购订单orderId:{}退款,清除相关车票relation_ids:{}", orderDon.getId(), dpRelationIds); groupsRelations.forEach(relation -> relationClearService.clearTicket(relation, UserTicketClearedRecord.Source.dp)); } catch (Exception e) { } } String plusOrderIds = discountPlusPurchaseSkuRelation.getPlusOrderIds(); if (StrUtil.isNotBlank(plusOrderIds)) { try { log.info("关闭优惠加购orderId:{}关联实物订单", orderDon.getId()); List plusOrderIdList = Jsons.parseList(plusOrderIds, Long.class); List relate_orderDons = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class) .in(OrderDon::getId, plusOrderIdList) .notIn(OrderDon::getStatus, Constant.noOrderStatus)); relate_orderDons.forEach(relate_o -> { //扣除用户自身实物权益 userRealOrderBenefitsService.deductUserRealGoodsBenefits(relate_o.getId()); }); orderDonMapper.update(null, Wrappers.lambdaUpdate(OrderDon.class) .set(OrderDon::getStatus, OrderDon.Status.refund) .in(OrderDon::getId, plusOrderIdList) .ne(OrderDon::getStatus, OrderDon.Status.refund)); } catch (Exception e) { } } } } //同步车票退款 重购记录 TASK_POOL.execute(() -> { GroupsRelationExpiryRecord groupsRelationExpiryRecord = groupsRelationExpiryRecordService.getOne(Wrappers.lambdaQuery(GroupsRelationExpiryRecord.class) .in(GroupsRelationExpiryRecord::getReBuyOrderId, orderDon.getId()) .eq(GroupsRelationExpiryRecord::getRelationId, orderDon.getRelationId()).last("limit 1")); if (groupsRelationExpiryRecord == null) { log.info("订单orderId:{}退款,同步是否有重购记录不是直接续费车票", orderDon.getId()); List groupsRelationExpiryRecords = groupsRelationExpiryRecordService.list(Wrappers.lambdaQuery(GroupsRelationExpiryRecord.class) .in(GroupsRelationExpiryRecord::getReBuyOrderId, orderDon.getId())); log.info("订单orderId:{}退款,重购记录不是直接续费车票大小:{}", groupsRelationExpiryRecords.size()); if (CollUtil.isNotEmpty(groupsRelationExpiryRecords)) { groupsRelationExpiryRecords.forEach(data -> { data.setIsReBuy(false); }); groupsRelationExpiryRecordService.saveOrUpdateBatch(groupsRelationExpiryRecords); } } if (groupsRelationExpiryRecord != null) { groupsRelationExpiryRecord.setIsReBuy(false); groupsRelationExpiryRecordService.saveOrUpdate(groupsRelationExpiryRecord); } }); //是否是礼品卡 现金支付订单 BigDecimal gcCash = orderDon.getGcCash(); if (gcCash != null && gcCash.compareTo(BigDecimal.ZERO) > 0) { giftCardOrderUseRecordService.returnGiftCardCash(orderDon.getId()); } //清除礼品卡 if (goodsDon.getSpecialType() != null && goodsDon.getSpecialType() == GoodsDon.SpecialType.giftCard) { giftCardUserRecordMapper.update(null, Wrappers.lambdaUpdate(GiftCardUserRecord.class) .set(GiftCardUserRecord::getIsPay, 0) .eq(GiftCardUserRecord::getOrderId, orderDon.getId())); } //是否是分销订单 //处理下级渠道分销提成 handleSubRewards(orderDon); //是否是用户套餐优惠权益订单 if (orderDon.getGoodsId() == 15) { UserBenefitsComboRelationRecord userBenefitsComboRelationRecord = userBenefitsComboRelationRecordMapper.selectOne(Wrappers.lambdaQuery(UserBenefitsComboRelationRecord.class) .eq(UserBenefitsComboRelationRecord::getOrderId, orderDon.getId()).last("limit 1")); if (userBenefitsComboRelationRecord != null) { try { String relationIds = userBenefitsComboRelationRecord.getRelationIds(); List relationIdList = Jsons.parseList(relationIds, Long.class); //清空车票或减少车票时间 relationIdList.forEach(relationId -> { orderCommonService.clearUserTicketTime(relationId); }); } catch (Exception e) { } } } //HBO GO退款,车队上架 setUpIfEmpty(orderDon.getGoodsId(), orderDon.getRelationId()); if (orderDon.getGoodsId() == Constant.NETFLIX_GID) { List userIdList = userBindRelationService.getRelationUserIdList(orderDon.getUserId(), null); NetflixUserAccountSubmitRecoverRecord recoverRecord = netflixUserAccountSubmitRecoverRecordMapper.selectOne(Wrappers.lambdaQuery(NetflixUserAccountSubmitRecoverRecord.class) .eq(NetflixUserAccountSubmitRecoverRecord::getRelationId, orderDon.getRelationId()) .in(NetflixUserAccountSubmitRecoverRecord::getUserId, userIdList) .eq(NetflixUserAccountSubmitRecoverRecord::getStatus, 0) .last("limit 1")); if (recoverRecord != null) { recoverRecord.setStatus(3); netflixUserAccountSubmitRecoverRecordMapper.updateById(recoverRecord); } } } //处理下级渠道分销提成 public void handleSubRewards(OrderDon orderDon) { //是否是分销订单 //处理下级渠道分销提成 if (orderDon.getIsDistribute()) { UserDistributeSub subRelate = userDistributeSubMapper.getSubRelate(orderDon.getUserId()); if (subRelate != null) { List subWaitings = subWaitingMapper.selectList(Wrappers.lambdaQuery(UserDistributeSubWaiting.class) .eq(UserDistributeSubWaiting::getSubUserId, subRelate.getSubUserId()) .eq(UserDistributeSubWaiting::getSendStatus, UserDistributeSubWaiting.Status.waiting)); if (CollUtil.isNotEmpty(subWaitings)) { List userDistributeSubRewards = userDistributeSubRewardsMapper.selectList(null); Map> rewardLevelMap = userDistributeSubRewards.stream().collect(Collectors.groupingBy(UserDistributeSubRewards::getLevel)); subWaitings.forEach(wait -> { List thisLevelList = rewardLevelMap.get(wait.getLevel()); if (thisLevelList == null) { return; } UserDistributeSubRewards thisLevel = thisLevelList.get(0); Integer months = thisLevel.getMonths(); BigDecimal subOrderMoney = Optional.ofNullable(orderDonMapper.selectSubChannelOrderMoney(wait.getSubUserId(), subRelate.getCreatedTime(), DateUtil.offsetMonth(subRelate.getCreatedTime(), months))).orElse(BigDecimal.ZERO); if (subOrderMoney.compareTo(thisLevel.getTargetAmount()) < 0) { subWaitingMapper.update(null, Wrappers.lambdaUpdate(UserDistributeSubWaiting.class) .set(UserDistributeSubWaiting::getSendStatus, UserDistributeSubWaiting.Status.close) .eq(UserDistributeSubWaiting::getSendStatus, UserDistributeSubWaiting.Status.waiting) .eq(UserDistributeSubWaiting::getId, wait.getId())); } }); } } } } /** * 退款 分销提成积分扣除 */ public void deductDsPoints(OrderDon orderDon) { if (orderDon.getIsDistribute()) { DistributeWaitingSendPoints distributeWaitingSendPoints = distributeWaitingSendPointsMapper.selectOne(Wrappers.lambdaQuery(DistributeWaitingSendPoints.class).eq(DistributeWaitingSendPoints::getOrderId, orderDon.getId()).eq(DistributeWaitingSendPoints::getIsVip,Boolean.FALSE).last("limit 1")); if (distributeWaitingSendPoints != null) { BigDecimal money = orderDon.getMoney(); BigDecimal refundMoney = orderDon.getRefundMoney(); //已发送 发送中 部分 全额退款 DistributeWaitingSendPoints.Status sendStatus = distributeWaitingSendPoints.getSendStatus(); BigDecimal points = distributeWaitingSendPoints.getPoints(); if (sendStatus == DistributeWaitingSendPoints.Status.waiting) { //实物设备退款就清0 if (refundMoney.compareTo(money) == 0 || orderDon.getGoodsId() == 15) { //待发送状态 全额退款 distributeWaitingSendPoints.setSendStatus(DistributeWaitingSendPoints.Status.close); distributeWaitingSendPoints.setRefundPoints(points); distributeWaitingSendPoints.setPoints(BigDecimal.ZERO); distributeWaitingSendPointsMapper.updateById(distributeWaitingSendPoints); return; } Integer thisGoodsRate = distributeWaitingSendPoints.getRate(); if (thisGoodsRate == null || thisGoodsRate == 0) { thisGoodsRate = Optional.ofNullable(userDistributeMapper.getDistributeGoodsRateByUidAndGid(orderDon.getUserId(), orderDon.getGoodsId())).orElse(0); } if (thisGoodsRate > 0) { BigDecimal refundRate = refundMoney.divide(money, 2, RoundingMode.DOWN); //退掉比例的提成 BigDecimal needSubPoints = points.multiply(refundRate); distributeWaitingSendPoints.setRefundPoints(needSubPoints); //剩余积分 BigDecimal remainPoints = points.subtract(needSubPoints); distributeWaitingSendPoints.setPoints(remainPoints); //原先获取积分也扣除 if (distributeWaitingSendPoints.getOriPoints().compareTo(BigDecimal.ZERO) > 0) { BigDecimal oriNeedSubPoints = distributeWaitingSendPoints.getOriPoints().multiply(refundRate); distributeWaitingSendPoints.setOriPoints(distributeWaitingSendPoints.getOriPoints().subtract(oriNeedSubPoints)); } distributeWaitingSendPointsMapper.updateById(distributeWaitingSendPoints); } } else if (sendStatus == DistributeWaitingSendPoints.Status.success) { //已发送的提成 部分退款 全额退款 需要扣除用户积分 //扣除固定推广者积分 //实物设备退款就清0 if (refundMoney.compareTo(money) == 0 || orderDon.getGoodsId() == 15) { userBenefitsService.deductDistributePoints(orderDon.getId(), distributeWaitingSendPoints.getSharedId(), points); distributeWaitingSendPoints.setRefundPoints(points); distributeWaitingSendPoints.setPoints(BigDecimal.ZERO); distributeWaitingSendPoints.setSendStatus(DistributeWaitingSendPoints.Status.close); distributeWaitingSendPointsMapper.updateById(distributeWaitingSendPoints); return; } Integer thisGoodsRate = distributeWaitingSendPoints.getRate(); if (thisGoodsRate == null || thisGoodsRate == 0) { thisGoodsRate = Optional.ofNullable(userDistributeMapper.getDistributeGoodsRateByUidAndGid(orderDon.getUserId(), orderDon.getGoodsId())).orElse(0); } if (thisGoodsRate > 0) { BigDecimal refundRate = refundMoney.divide(money, 2, RoundingMode.DOWN); //退掉比例的提成 BigDecimal needSubPoints = points.multiply(refundRate); userBenefitsService.deductDistributePoints(orderDon.getId(), distributeWaitingSendPoints.getSharedId(), needSubPoints); //部分退款 distributeWaitingSendPoints.setRefundPoints(needSubPoints); distributeWaitingSendPoints.setPoints(points.subtract(needSubPoints)); //原先获取积分也扣除 if (distributeWaitingSendPoints.getOriPoints().compareTo(BigDecimal.ZERO) > 0) { BigDecimal oriNeedSubPoints = distributeWaitingSendPoints.getOriPoints().multiply(refundRate); distributeWaitingSendPoints.setOriPoints(distributeWaitingSendPoints.getOriPoints().subtract(oriNeedSubPoints)); } distributeWaitingSendPointsMapper.updateById(distributeWaitingSendPoints); } } } } } @Override public void refundPriceDiffer(OrderRefundReq orderRefundReq) throws Exception { Long orderId = orderRefundReq.getOrderId(); OrderDon orderDon = orderDonMapper.selectById(orderId); if (orderDon == null) { throw BusinessRuntimeException.getInstance("订单不存在"); } if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) { throw BusinessRuntimeException.getInstance("该订单是0元订单,无法补差价"); } if (Constant.noOrderAllStatus.contains(orderDon.getStatus().name())) { throw BusinessRuntimeException.getInstance("订单不是已支付状态"); } //默认补差价余额 String refundType = Optional.ofNullable(orderRefundReq.getRefundType()).orElse("balance"); BigDecimal refundMoney = orderRefundReq.getRefundMoney(); BigDecimal orderRefundMoney = Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO); BigDecimal orderDonRefundBalance = Optional.ofNullable(orderDon.getRefundBalance()).orElse(BigDecimal.ZERO); if (refundMoney.add(orderRefundMoney).add(orderDonRefundBalance).compareTo(orderDon.getRealMoney()) >= 0) { throw BusinessRuntimeException.getInstance("补差价已达到该订单付款金额"); } GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId()); GoodsDonSku sku = null; if (orderDon.getSkuId() != null) { sku = skuMapper.selectById(orderDon.getSkuId()); } orderDon.setRefundDesc("补差价"); String outNo = StrUtil.EMPTY; if ("money".equals(refundType)) { if (refundMoney == null || refundMoney.compareTo(BigDecimal.ZERO) <= 0) { throw BusinessRuntimeException.getInstance("请输入正确的差价金额"); } if (refundMoney.compareTo(orderDon.getMoney()) >= 0) { throw BusinessRuntimeException.getInstance("补差价金额应不大于订单金额"); } //退款 orderRefundReq.setIsDiffer(true); outNo = orderRefundService.centerRefund(orderRefundReq, orderDon); orderDon.setRefundMoney(orderRefundMoney.add(refundMoney)); orderDonMapper.updateById(orderDon); //补差价金额 扣除对应分销提成金额 orderDon.setRefundMoney(refundMoney); deductDsPoints(orderDon); //店铺分销提成金额扣除 yhShopDistributeService.deductDsMoney(orderDon); } else { BigDecimal refundBalance = refundMoney; if (refundBalance == null || refundBalance.compareTo(BigDecimal.ZERO) <= 0 || refundBalance.compareTo(orderDon.getMoney()) > 0) { throw BusinessRuntimeException.getInstance("请输入正确的差价金额"); } userBenefitsService.addUserBalance(orderDon.getUserId(), refundBalance, UserBalanceSourceRecord.Source.price_differ, orderDon.getYhsId(), orderDon.getId(), goodsDon.getTitle() + UserBalanceSourceRecord.Source.price_differ.getDesc(), true); orderDon.setRefundBalance(orderDonRefundBalance.add(refundBalance)); orderDonMapper.updateById(orderDon); } orderRefundService.refundRecord(orderDon, refundMoney, orderRefundReq.getOperator(), goodsDon, sku, outNo, refundType, null); } @Override @Transactional(rollbackFor = Throwable.class) public void clearBalanceToRefundMoney(OrderBalanceRefundReq refundReq) throws Exception { Long refundOrderId = refundReq.getRefundOrderId(); BigDecimal refundMoney = refundReq.getRefundMoney(); RefundOrderDon refundOrderDon = refundOrderDonMapper.selectById(refundOrderId); if (!"balance".equals(refundOrderDon.getRefundMethod())) { throw BusinessRuntimeException.getInstance("该记录不是余额退款类型"); } Long orderId = refundOrderDon.getOrderId(); OrderDon orderDon = orderDonMapper.selectById(orderId); if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) { throw BusinessRuntimeException.getInstance("该记录对应的订单无实际支付金额"); } if (refundOrderDon.getIsClearBalance()) { throw BusinessRuntimeException.getInstance("该笔退款余额记录已退款"); } BigDecimal refundFee = refundOrderDon.getRefundFee(); //默认退全部余额 if (refundMoney != null) { refundFee = refundMoney; } BigDecimal money = orderDon.getMoney(); //若退款余额 大于退款金额 将退款余额至为 退款金额 if (refundFee.compareTo(money) > 0) { refundFee = money; } User user = userMapper.selectById(orderDon.getUserId()); if (user.getBalance().compareTo(refundFee) < 0) { throw BusinessRuntimeException.getInstance("用户余额不足,无法扣除对应退款余额"); } int update = userMapper.update(null, Wrappers.lambdaUpdate(User.class) .set(User::getBalance, user.getBalance().subtract(refundFee)) .eq(User::getId, user.getId()) .eq(User::getBalance, user.getBalance())); if (update == 0) { throw BusinessRuntimeException.getInstance("扣除用户退款余额失败,请重试..."); } OrderRefundReq orderRefundReq = new OrderRefundReq(); orderRefundReq.setOrderId(orderId); orderRefundReq.setRefundMoney(refundFee); orderRefundReq.setRefundType("money"); String outNo = orderRefundService.centerRefund(orderRefundReq, orderDon); orderDon.setRefundBalance(orderDon.getRefundBalance().subtract(refundFee)); BigDecimal orderRefundMoney = Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO); orderDon.setRefundMoney(orderRefundMoney.add(refundFee)); orderDonMapper.updateById(orderDon); refundOrderDon.setOutRefundNo(outNo); refundOrderDon.setIsClearBalance(true); refundOrderDonMapper.updateById(refundOrderDon); } /** * 寻找该车队空余车位 */ public GroupsRelation getRelationThisTrips(Long userId, Long groupsId, Integer retryNum) { //寻找快满编车队进行占座 GroupsRelation relation = relationMapper.selectRandomOneRelationByGroupsId(groupsId); if (relation == null) { throw BusinessRuntimeException.getInstance("该车队人员已满,请选择另一车队"); } Long relationId = relation.getId(); if (!redisService.setNx(RedisKey.GROUPS_RELATION_NUM_KEY + relationId, userId, 60 * 5L)) { if (retryNum == 7) throw BusinessRuntimeException.getInstance("该车队人员已满,请选择另一车队"); retryNum++; return getRelationThisTrips(userId, groupsId, retryNum); } int count = groupsMapper.decrAvailableNum(relation.getGroupsId()); if (count == 0) { log.error("车位异常 groupId:{}", groupsId); groupsMapper.updateAvailableNum(groupsId); throw new BusinessRuntimeException("车位异常"); } return relation; } private GroupsRelation getChatGPTOutsideRelation(Long userId, Long groupsId, Integer relationNum, Integer retryNum) { //寻找快满编车队额外座位 GroupsRelation relation = relationMapper.selectOutsideRelationByGroupsId(groupsId, relationNum); if (relation == null) { relation = new GroupsRelation(); relation.setStatus(GroupsRelation.Status.outside); relation.setUserId(userId); relation.setGroupsId(groupsId); GroupsRelation maxNumRelation = relationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class).eq(GroupsRelation::getGroupsId, groupsId).orderByDesc(GroupsRelation::getNum).last("limit 1")); relation.setNum(maxNumRelation.getNum() + 1); relationMapper.insert(relation); return relation; } Long relationId = relation.getId(); if (!redisService.setNx(RedisKey.GROUPS_RELATION_NUM_KEY + relationId, userId, 60 * 5L)) { if (retryNum == 7) throw BusinessRuntimeException.getInstance("该车队人员已满,请选择另一车队"); retryNum++; return getChatGPTOutsideRelation(userId, groupsId, relationNum, retryNum); } return relation; } private void checkMirrorRenewSku(OrderDon orderDon) { Long skuId = orderDon.getSkuId(); Long orderId = orderDon.getId(); OrderDonRenewRecord orderDonRenewRecord = orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class) .eq(OrderDonRenewRecord::getOrderId, orderId) .last("limit 1")); if (orderDonRenewRecord != null) { //gpt if (orderDon.getGoodsId() == 18) { ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class) .eq(ChatgptUser::getRelationId, orderDon.getRelationId()) .last("limit 1")); Long presentRenewSkuId = chatgptUser.getRenewSkuId(); if (presentRenewSkuId != null) { //存在不同升级套餐 GoodsDonSku presentRenewSku = skuMapper.selectById(presentRenewSkuId); if (!ObjectUtil.equal(presentRenewSkuId, skuId)) { throw BusinessRuntimeException.getInstance("请先退掉用户目前续费升级的{0}规格", presentRenewSku.getSpecVal()); } } } //claude pro if (orderDon.getGoodsId() == 75) { ClaudeUser claudeUser = claudeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeUser.class) .eq(ClaudeUser::getRelationId, orderDon.getRelationId()) .last("limit 1")); Long presentRenewSkuId = claudeUser.getRenewSkuId(); if (presentRenewSkuId != null) { //存在不同升级套餐 GoodsDonSku presentRenewSku = skuMapper.selectById(presentRenewSkuId); if (!ObjectUtil.equal(presentRenewSkuId, skuId)) { throw BusinessRuntimeException.getInstance("请先退掉用户目前续费升级的{0}规格", presentRenewSku.getSpecVal()); } } } } } private void clearExtraRelation(OrderDon orderDon) { List userPayEquipmentReceiveBenefitsRecords = receiveBenefitsRecordMapper.selectList(Wrappers.lambdaQuery(UserPayEquipmentReceiveBenefitsRecord.class) .eq(UserPayEquipmentReceiveBenefitsRecord::getRealOrderId, orderDon.getId())); userPayEquipmentReceiveBenefitsRecords.forEach(record -> { Long skuId = record.getSkuId(); List relations = relationMapper.selectExtraRelation(orderDon.getUserId(), skuId, record.getRelationId()); relations.forEach(relation -> { //不是优惠加购 Integer count = orderDiscountPlusPurchaseSkuRelationMapper.selectCount(Wrappers.lambdaQuery(OrderDiscountPlusPurchaseSkuRelation.class) .eq(OrderDiscountPlusPurchaseSkuRelation::getUserId, relation.getUserId()) .apply("JSON_CONTAINS(relation_ids,'" + relation.getId() + "')")); if (count == 0) { log.info("非优惠加购订单,直接清除userId:{}车票:{}", relation.getUserId(), relation.getId()); relationClearService.clearTicket(relation, UserTicketClearedRecord.Source.manual); } }); }); } /** * 扣除用户镜像店铺提成 */ private void deductUserMirrorShopMoney(OrderDon orderDon) { UserMirrorShopDistributeWaitingSendPoints distributeWaitingSendPoints = userMirrorShopDistributeWaitingSendPointsMapper.selectOne(Wrappers.lambdaQuery(UserMirrorShopDistributeWaitingSendPoints.class) .eq(UserMirrorShopDistributeWaitingSendPoints::getOrderId, orderDon.getId()) .last("limit 1")); if (distributeWaitingSendPoints != null) { BigDecimal money = orderDon.getMoney(); BigDecimal refundMoney = orderDon.getRefundMoney(); //已发送 发送中 部分 全额退款 UserMirrorShopDistributeWaitingSendPoints.Status sendStatus = distributeWaitingSendPoints.getSendStatus(); BigDecimal take_money = distributeWaitingSendPoints.getMoney(); if (sendStatus == UserMirrorShopDistributeWaitingSendPoints.Status.waiting) { if (refundMoney.compareTo(money) == 0) { //待发送状态 全额退款 distributeWaitingSendPoints.setSendStatus(UserMirrorShopDistributeWaitingSendPoints.Status.close); distributeWaitingSendPoints.setRefundMoney(take_money); distributeWaitingSendPoints.setMoney(BigDecimal.ZERO); userMirrorShopDistributeWaitingSendPointsMapper.updateById(distributeWaitingSendPoints); return; } Integer rate = distributeWaitingSendPoints.getRate(); if (rate > 0) { BigDecimal needDeductMoney = refundMoney.multiply(BigDecimal.valueOf(rate).divide(BigDecimal.valueOf(100))); distributeWaitingSendPoints.setRefundMoney(needDeductMoney); //剩余积分 distributeWaitingSendPoints.setMoney(take_money.subtract(needDeductMoney)); userMirrorShopDistributeWaitingSendPointsMapper.updateById(distributeWaitingSendPoints); } } else if (sendStatus == UserMirrorShopDistributeWaitingSendPoints.Status.success) { //已发送的提成 部分退款 全额退款 需要扣除用户积分 //扣除固定推广者积分 if (refundMoney.compareTo(money) == 0) { //扣除店铺主 已有的提成金额 userBenefitsService.deductUserMirrorShopTakeMoney(orderDon.getId(), distributeWaitingSendPoints.getShopUserId(), take_money); distributeWaitingSendPoints.setRefundMoney(take_money); distributeWaitingSendPoints.setMoney(BigDecimal.ZERO); distributeWaitingSendPoints.setSendStatus(UserMirrorShopDistributeWaitingSendPoints.Status.close); userMirrorShopDistributeWaitingSendPointsMapper.updateById(distributeWaitingSendPoints); return; } Integer rate = distributeWaitingSendPoints.getRate(); if (rate > 0) { BigDecimal needDeductMoney = refundMoney.multiply(BigDecimal.valueOf(rate).divide(BigDecimal.valueOf(100))); //扣除店铺主 已有的提成金额 userBenefitsService.deductUserMirrorShopTakeMoney(orderDon.getId(), distributeWaitingSendPoints.getShopUserId(), needDeductMoney); //部分退款 distributeWaitingSendPoints.setRefundMoney(needDeductMoney); distributeWaitingSendPoints.setMoney(take_money.subtract(needDeductMoney)); userMirrorShopDistributeWaitingSendPointsMapper.updateById(distributeWaitingSendPoints); } } } } /** * 清除多余车票 */ private void clearOtherChangeTicket(Long userId, Long relationId, GroupsRelation newRelation, Long skuId) { UserTicketClearedRecord userTicketClearedRecord = userTicketClearedRecordMapper.selectOne(Wrappers.lambdaQuery(UserTicketClearedRecord.class) .eq(UserTicketClearedRecord::getUserId, userId) .eq(UserTicketClearedRecord::getRelationId, relationId) .eq(UserTicketClearedRecord::getSource, UserTicketClearedRecord.Source.change_ticket) .orderByDesc(UserTicketClearedRecord::getId) .last("limit 1")); if (userTicketClearedRecord != null) { Long newRelationId = userTicketClearedRecord.getNewRelationId(); List others = relationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class) .ne(GroupsRelation::getId, newRelationId) .eq(GroupsRelation::getUserId, userId) .eq(GroupsRelation::getStartTime, newRelation.getStartTime()) .eq(GroupsRelation::getExpiryTime, newRelation.getExpiryTime())); others.forEach(r -> { Long groupsId = r.getGroupsId(); GroupsTrips groupsTrips = groupsMapper.selectById(groupsId); //排除 非同规格车票 if (!skuId.equals(groupsTrips.getSkuId())) { return; } Long rid = r.getId(); Integer selectCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class) .eq(OrderDon::getUserId, userId) .eq(OrderDon::getRelationId, rid) .notIn(OrderDon::getStatus, Constant.noOrderAllStatus)); if (selectCount == 0) { //不是优惠加购 Integer count = orderDiscountPlusPurchaseSkuRelationMapper.selectCount(Wrappers.lambdaQuery(OrderDiscountPlusPurchaseSkuRelation.class) .eq(OrderDiscountPlusPurchaseSkuRelation::getUserId, userId) .apply("JSON_CONTAINS(relation_ids,'" + rid + "')")); if (count == 0) { log.info("清除用户:{}多余车票", userId); relationClearService.clearTicket(r, UserTicketClearedRecord.Source.manual); } } }); } } /** * 车队退款 自动上架 */ private void setUpIfEmpty(Long goodsId, Long relationId) { if (goodsId == Constant.HBO_GO_GOODS_ID) { GroupsRelation relation = relationMapper.selectById(relationId); if (relation == null) { return; } GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId()); if (groupsTrips == null) { return; } if (groupsTrips.getStatus() == GroupsTrips.Status.down) { log.info("HBO GO车队:{}存在退款,自动上架", groupsTrips.getId()); groupsMapper.update(null, Wrappers.lambdaUpdate(GroupsTrips.class) .set(GroupsTrips::getStatus, GroupsTrips.Status.validity) .eq(GroupsTrips::getId, groupsTrips.getId())); } } } }