package com.cyksj.service.order.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayFundTransCommonQueryModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransCommonQueryRequest;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayFundTransCommonQueryResponse;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cyksj.common.EnvCommonService;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.constant.PointsRecordConst;
import com.cyksj.common.constant.TaskTypeEnum;
import com.cyksj.common.constant.TransferConstant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.snowflake.Sequence;
import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
import com.cyksj.common.util.Codec;
import com.cyksj.common.util.Jsons;
import com.cyksj.common.util.SmsUtil;
import com.cyksj.common.util.StringUtil;
import com.cyksj.config.WeChatConfig;
import com.cyksj.config.zfb.AliPayClientFactory;
import com.cyksj.config.zfb.BaseZfbConfig;
import com.cyksj.config.zfb.ZfbProductCode;
import com.cyksj.dto.RedisKey;
import com.cyksj.enums.GatewayApiCode;
import com.cyksj.mapper.*;
import com.cyksj.mapper.channel.ChannelPopularizeMapper;
import com.cyksj.mapper.channel.ShopConfigMapper;
import com.cyksj.mapper.channel.UserPayEquipmentAvailableBenefitsMapper;
import com.cyksj.mapper.codex.CodexDeductRecordMapper;
import com.cyksj.mapper.corp.CorpInteractiveUserOrderRelationMapper;
import com.cyksj.mapper.corp.CorpUserMapper;
import com.cyksj.mapper.corp.CorpUserTagMapper;
import com.cyksj.mapper.fission.UserMirrorFissionInvertRecordMapper;
import com.cyksj.mapper.fission.UserMirrorFissionReceiveRecordMapper;
import com.cyksj.mapper.manage.coupon.CouponDistributePopularizeMapper;
import com.cyksj.mapper.manage.coupon.CouponMapper;
import com.cyksj.mapper.manage.coupon.CouponSkuMapper;
import com.cyksj.mapper.manage.coupon.CouponUserMapper;
import com.cyksj.mapper.manage.distribute.*;
import com.cyksj.mapper.manage.distribute.equipment.UserDistributeEquipmentMapper;
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.market.task.TaskTypeMapper;
import com.cyksj.mapper.market.task.UserBindDetailMapper;
import com.cyksj.mapper.mirrorshop.UserMirrorShopDistributeWaitingSendPointsMapper;
import com.cyksj.mapper.mirrorshop.UserMirrorShopMapper;
import com.cyksj.mapper.mirrorshop.UserMirrorShopOrderRelateMapper;
import com.cyksj.mapper.mirrorshop.UserMirrorShopUserDistributeSharedMapper;
import com.cyksj.mapper.renew.RenewUpgradePackageMapper;
import com.cyksj.mapper.shop.YhShopGoodsSkuMapper;
import com.cyksj.model.dto.*;
import com.cyksj.model.entity.*;
import com.cyksj.model.manage.dto.ChannelBaiDuDiscountDto;
import com.cyksj.model.manage.dto.GiftCardDto;
import com.cyksj.model.manage.request.ReqGoodsSkuSpec;
import com.cyksj.model.manage.views.GroupsRelationView;
import com.cyksj.model.manage.views.OrderDonView;
import com.cyksj.model.manage.views.UpgradeOrderDetailView;
import com.cyksj.model.request.*;
import com.cyksj.model.views.*;
import com.cyksj.redis.RedisService;
import com.cyksj.service.chatgpt.GptUserRechargeRecordService;
import com.cyksj.service.claude.ClaudeCodeService;
import com.cyksj.service.codex.CodexService;
import com.cyksj.service.coin.UserGalaxyCoinService;
import com.cyksj.service.corp.WxCorpOps;
import com.cyksj.service.coupon.CouponFontService;
import com.cyksj.service.distribute.UserBusinessFrontService;
import com.cyksj.service.distribute.equipment.EquipmentDistributeService;
import com.cyksj.service.exchange.ExchangeCodeService;
import com.cyksj.service.giftcard.GiftCardOrderUseRecordService;
import com.cyksj.service.giftcard.GiftCardUserRecordService;
import com.cyksj.service.groups.GroupsFuncService;
import com.cyksj.service.mange.coupon.CouponCommonService;
import com.cyksj.service.market.MarketFrontService;
import com.cyksj.service.market.task.TaskService;
import com.cyksj.service.order.*;
import com.cyksj.service.pay.AliPayCommonService;
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.shop.YhShopFrontService;
import com.cyksj.service.sys.SysConfigService;
import com.cyksj.service.telegram.TelegramService;
import com.cyksj.service.template.TemplateCommonService;
import com.cyksj.service.user.UserBenefitsService;
import com.cyksj.service.user.UserBindRelationService;
import com.cyksj.service.user.UserCommonService;
import com.cyksj.service.wechat.WeChatService;
import com.cyksj.task.JobManager;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.param.Operator;
import com.ejlchina.searcher.util.MapBuilder;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author chan
 * @date 2021/10/11 下午4:08
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> implements OrderDonService {

	private static final Long EXPIRY_TIME = 1000 * 60 * 5L;

	private static final Sequence SEQUENCE = new Sequence(0);

	private final WeChatConfig weChatConfig;

	private final UserMapper userMapper;

	private final UserCommonService userCommonService;

	private final WeChatService weChatService;

	private final RedisService redisService;

	private final GoodsDonSkuMapper goodsDonSkuMapper;

	private final GoodsDonMapper goodsDonMapper;

	private final GoodsDonSpecMapper goodsDonSpecMapper;

	private final GroupsRelationMapper groupsRelationMapper;

	private final BeanSearcher beanSearcher;

	private final GroupsMapper groupsMapper;

	private final JobManager jobManager;

	private final OrderDonTransportMapper orderDonTransportMapper;

	private final AddressMapper addressMapper;

	private final OrderDonTransportMapper transportMapper;

	private final OrderDonWaybillMapper waybillMapper;

	private final OrderDonMapper orderDonMapper;

	private final EnvCommonService envCommonService;

	private static final GlobalThreadPoolTaskExecutor TASK_POOL = GlobalThreadPoolTaskExecutor.getInstance();

	private final UserDistributeSharedMapper userDistributeSharedMapper;

	private final DistributeWaitingSendPointsMapper distributeWaitingSendPointsMapper;

	private final DistributePointsExchangeMoneyMapper distributePointsExchangeMoneyMapper;

	private final UserDistributeMapper userDistributeMapper;

	private final UserDistributeEquipmentMapper userDistributeEquipmentMapper;

	private final UserPlatDistributeRateMapper userPlatDistributeRateMapper;

	private final BusinessDistributeDefaultSkuRateConfigMapper businessDistributeDefaultSkuRateConfigMapper;

	private final BusinessDistributeDefaultRateConfigMapper businessDistributeDefaultRateConfigMapper;

	private final CouponMapper couponMapper;

	private final CouponFontService couponFontService;

	private final CouponUserMapper couponUserMapper;

	private final CouponSkuMapper couponSkuMapper;

	private final ShopConfigMapper shopConfigMapper;

	private final TaskService taskService;

	private final TaskTypeMapper taskTypeMapper;

	private final CustomerServiceRenewOrderRecordMapper customerServiceRenewOrderRecordMapper;

	private final ExchangeCodeService exchangeCodeService;

	private final TemplateCommonService templateCommonService;

	private final MarketFrontService marketFrontService;

	private final EquipmentDistributeService equipmentDistributeService;

	private final CouponDistributePopularizeMapper couponDistributePopularizeMapper;

	private final GroupRelationFrontService groupRelationFrontService;

	private final GroupRelationClearService groupRelationClearService;

	private final UserRenewChangeTicketRecordMapper userRenewChangeTicketRecordMapper;

	private final SysConfigService sysConfigService;

	private final UserBusinessFrontService userBusinessFrontService;

	private final UserBindDetailMapper userBindDetailMapper;

	private final OrderCommonService orderCommonService;

	private final UserBenefitsService userBenefitsService;

	private final GroupsFuncService groupsFuncService;

	private final AliPayCommonService aliPayCommonService;

	private final OrderDonPostService orderDonPostService;

	private final CorpInteractiveUserOrderRelationMapper corpInteractiveUserOrderRelationMapper;

	private final GoodsDiscountPlusPurchaseRelationMapper discountPlusPurchaseRelationMapper;

	private final OrderDiscountPlusPurchaseSkuRelationMapper orderDiscountPlusPurchaseSkuRelationMapper;

	private final UserBindRelationService userBindRelationService;

	private final ChannelPopularizeMapper channelPopularizeMapper;

	private final GroupsRelationExpiryRecordService groupsRelationExpiryRecordService;

	private final UserPhoneSendRecordMapper userPhoneSendRecordMapper;

	private final TelegramService telegramService;

	private final GiftCardUserRecordService giftCardUserRecordService;

	private final GiftCardOrderUseRecordService giftCardOrderUseRecordService;

	private final GiftCardOrderRelateMapper giftCardOrderRelateMapper;

	private final YhShopFrontService yhShopFrontService;

	private final YhShopDistributeService yhShopDistributeService;

	private final YhShopGoodsSkuMapper yhShopGoodsSkuMapper;

	private final AccountMapper accountMapper;

	private final CouponCommonService couponCommonService;

	private final UserPlatSkuDistributeRateMapper userPlatSkuDistributeRateMapper;

	private final OrderRefundService orderRefundService;

	private final UserPayOrderBlockMapper userPayOrderBlockMapper;

	private final UserDistributeSharedWhiteMapper userDistributeSharedWhiteMapper;

	private final UserDistributeSharedRelateUnbindMapper userDistributeSharedRelateUnbindMapper;

	private final EquipmentActivityReduceMapper equipmentActivityReduceMapper;

	private final InformationClickUserRecordMapper informationClickUserRecordMapper;

	private final UserCertRecordMapper userCertRecordMapper;

	private final UserDistributeSubMapper userDistributeSubMapper;

	private final UserDistributeSubRewardsMapper userDistributeSubRewardsMapper;

	private final UserDistributeSubWaitingMapper userDistributeSubWaitingMapper;

	private final OrderDonLocationRelateMapper orderDonLocationRelateMapper;

	private final GoodsDonSkuSubsidyMapper goodsDonSkuSubsidyMapper;

	private final OrderDonSubsidyRelateMapper orderDonSubsidyRelateMapper;

	private final CorpUserTagMapper corpUserTagMapper;

	private final CorpUserMapper corpUserMapper;

	private final WxCorpOps wxCorpOps;

	private final UpgradePackageMapper upgradePackageMapper;

	private final UpgradeOrderDonMapper upgradeOrderDonMapper;

	private final MidjourneyUserMapper midjourneyUserMapper;

	private final ChatgptUserMapper chatgptUserMapper;

	private final LumaUserMapper lumaUserMapper;

	private final UserTrialTicketJumpPayRecordMapper userTrialTicketJumpPayRecordMapper;

	private final GroupsRelationNetflixService groupsRelationNetflixService;

	private final OrderDonExceptionUserRecordMapper orderDonExceptionUserRecordMapper;

	private final DistributeGeneralSkuRateMapper distributeGeneralSkuRateMapper;

	private final RenewUpgradePackageMapper renewUpgradePackageMapper;

	private final OrderDonRenewRecordMapper orderDonRenewRecordMapper;

	private final OrderDonPosterRelateMapper orderDonPosterRelateMapper;

	private final OrderDonUpgradeRenewRecordMapper orderDonUpgradeRenewRecordMapper;

	private final UserIpRecordMapper userIpRecordMapper;

	private final OrderDonUserDiscountPopularizeRecordMapper orderDonUserDiscountPopularizeRecordMapper;

	private final OrderDonIndependentRenewRecordMapper independentRenewRecordMapper;

	private final UserBenefitsMapper userBenefitsMapper;

	private final UserBenefitsOrderRecordMapper userBenefitsOrderRecordMapper;

	private final UserRealOrderBenefitsService userRealOrderBenefitsService;

	private final UserPayEquipmentAvailableBenefitsMapper userPayEquipmentAvailableBenefitsMapper;

	private final UserMirrorShopMapper userMirrorShopMapper;

	private final UserMirrorShopUserDistributeSharedMapper userMirrorShopUserDistributeSharedMapper;

	private final UserMirrorShopOrderRelateMapper userMirrorShopOrderRelateMapper;

	private final UserMirrorShopDistributeWaitingSendPointsMapper userMirrorShopDistributeWaitingSendPointsMapper;

	private final UserMirrorFissionReceiveRecordMapper userMirrorFissionReceiveRecordMapper;

	private final UserMirrorFissionInvertRecordMapper userMirrorFissionInvertRecordMapper;

	private final ZfbShopOrderDayLimitMapper zfbShopOrderDayLimitMapper;

	private final ClaudeUserMapper claudeUserMapper;

	private final MirrorExpiryRenewOrderRelateMapper mirrorExpiryRenewOrderRelateMapper;

	private final SpotifyUserUpgradeOrderMapper spotifyUserUpgradeOrderMapper;

	private final GptMirrorDayCardGiveawayActivityMapper gptMirrorDayCardGiveawayActivityMapper;

	private final GptMirrorDayCardActivityRecordMapper gptMirrorDayCardActivityRecordMapper;

	private final GoodsClickUserOrderRecordMapper goodsClickUserOrderRecordMapper;

	private final UserGalaxyCoinService userGalaxyCoinService;

	private final OrderDonGalaxyCoinRecordMapper orderDonGalaxyCoinRecordMapper;

	private final UserGalaxyCoinRecordMapper userGalaxyCoinRecordMapper;

	private final OrderDonGalaxyCoinRenewRelateMapper orderDonGalaxyCoinRenewRelateMapper;

	private final GptUserRechargeRecordService gptUserRechargeRecordService;

	private final UserBalanceSourceRecordMapper userBalanceSourceRecordMapper;

	private final ClaudeCodeService claudeCodeService;

	private final ClaudeCodeUserMapper claudeCodeUserMapper;

	private final NanoUserQuotaMapper nanoUserQuotaMapper;

	private final UserTicketClearedRecordMapper userTicketClearedRecordMapper;

	private final CodexService codexService;

	private final CodexDeductRecordMapper codexDeductRecordMapper;

	private final CodexUserMapper codexUserMapper;

	private final List<String> noChekGoodsTemp = List.of("Apple One", "Youtube", "Spotify");

	@Transactional(rollbackFor = Throwable.class)
	@Override
	public OrderDon submit(OrderPayRequest payRequest) throws Exception {
		GoodsDonSku sku = null;
		Long goodsId;
		List<GiftCardPayReq> giftCards = null;
		GiftCardDto gcPayInfo = payRequest.getGcPayInfo();
		if (gcPayInfo != null && gcPayInfo.getGiftCards() != null) {
			giftCards = gcPayInfo.getGiftCards();
		}
		AtomicBoolean isGiftCardPay = new AtomicBoolean(false);
		//若存在店铺id,校验店铺状态
		String customId = payRequest.getCustomId();
		UserMirrorShop userMirrorShop = null;
		Long yhsId = 0l;
		if (payRequest.getCmt() == 1) {
			yhsId = yhShopFrontService.checkShopCustomIdAndReturnShopId(customId);
		} else if (payRequest.getCmt() == 2) {
			if (StrUtil.isNotEmpty(customId)) {
				userMirrorShop = userMirrorShopMapper.selectOne(Wrappers.lambdaQuery(UserMirrorShop.class).eq(UserMirrorShop::getCustomId, customId).last("limit 1"));
				if (userMirrorShop == null || !userMirrorShop.getStatus()) {
					throw BusinessRuntimeException.getInstance("店铺已关闭");
				}
			}
		}
		if (CollUtil.isNotEmpty(giftCards)) {
			goodsId = payRequest.getGoodsId();
			isGiftCardPay.set(true);
		} else {
			if (payRequest.getSkuId() == null) {
				throw BusinessRuntimeException.getInstance("请指定对应平台规格下单");
			}
			sku = adjustGoodsDonSku(yhsId, payRequest.getIsPayReal(), payRequest.getSkuId());
			Assert.notNull(sku, "规格不存在");
			goodsId = sku.getGoodsId();
		}
		GoodsDon goodsDon = goodsDonMapper.selectById(goodsId);
		//是否是补差价订单
		if (goodsDon.getType() != null && goodsDon.getType() == 5) {
			return generateDifferOrderDon(payRequest, goodsDon, sku);
		}
		if (goodsDon == null || !goodsDon.getStatus()) {
			throw new BusinessRuntimeException("商品已下架");
		}
		//是否参与店铺分销
		if (yhsId > 0 && !goodsDon.getIsDistribute()) {
			throw new BusinessRuntimeException("系统异常,请刷新页面重试");
		}
		if (isGiftCardPay.get() && (goodsDon.getSpecialType() == null || goodsDon.getSpecialType() != GoodsDon.SpecialType.giftCard)) {
			throw BusinessRuntimeException.getInstance("非礼品卡类型商品");
		}
		CouponUser couponUser = null;
		if (StrUtil.isNotBlank(payRequest.getCouponExCode()) || payRequest.getCouponId() != null) {
			CouponPopularizeDto couponPopularizeDto = checkCouponStatus(payRequest.getSkuId(), payRequest.getCouponExCode(), payRequest.getCouponId(), payRequest.getUserId(), false);
			//记录优惠券使用状态
			couponUser = couponStatusRecord(payRequest.getCouponExCode(), payRequest.getCouponId(), payRequest.getUserId(), couponPopularizeDto);
		}
		Boolean isNoLogin = payRequest.getIsNoLogin();
		User user = null;
		String payOpenId = null;
		Long relationId = 0L;
		Boolean isNeedTicket = checkIsNeedGroupsRelation(goodsDon);
		Long userId = payRequest.getUserId();
		if (userId != null && payRequest.getCmt() == 1) {
			int noPayCount = count(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getUserId, userId).eq(OrderDon::getGoodsId, goodsId)
					.eq(OrderDon::getYhsId, yhsId)
					.eq(OrderDon::getStatus, OrderDon.Status.noPayment.toString()));
			if (noPayCount > 0) {
				throw new BusinessRuntimeException("您有未支付订单.");
			}
		}
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		//claude code限购
		if (goodsId == Constant.CLAUDE_CODE_GOODS_ID) {
			//是否拥有这张车票
			Integer selectCount = groupsRelationMapper.selectCountByGoodsId(userIdList, Constant.CLAUDE_CODE_GOODS_ID, DateTime.now());
			if (selectCount > 0) {
				throw BusinessRuntimeException.getInstance("claude code车票限购一次");
			}
			//购买cc体验卡 仅可体检一次
			if (sku != null && ObjectUtil.equal(sku.getId(), Constant.DISTRIBUTE_CLAUDE_CODE_TRIAL_SKU_ID)) {
				checkCCTrialCardNum(userIdList);
			}
//			//是否是赠送codex sku
//			if (sku.getIsCodex()) {
//				//是否存在codex
//				CodexUser codexUser = codexUserMapper.selectOne(Wrappers.lambdaQuery(CodexUser.class).in(CodexUser::getUserId, userIdList).last("limit 1"));
//				if (codexUser != null) {
//					throw BusinessRuntimeException.getInstance("您已购买了codex套餐，如需claude可用codex抵扣升级，不可重复购买");
//				}
//			}
		}
		//codex 限购
		if (goodsId == Constant.CODEX_GOODS_ID) {
			Integer selectCount = groupsRelationMapper.selectCountByGoodsId(userIdList, Constant.CODEX_GOODS_ID, DateTime.now());
			if (selectCount > 0) {
				throw BusinessRuntimeException.getInstance("codex车票限购一次");
			}
			//是否拥有cc赠送codex
			CodexUser codexUser = codexUserMapper.selectOne(Wrappers.lambdaQuery(CodexUser.class).in(CodexUser::getUserId, userIdList).last("limit 1"));
			if (codexUser != null) {
				throw BusinessRuntimeException.getInstance("codex车票限购一次");
			}
		}

		//校验奈飞限购信息
		checkNfPayLimit(goodsId, userId);
		GroupsRelation relation = null;
		String orderPhone = payRequest.getPhone();
		if (StrUtil.isNotBlank(orderPhone)) {
			user = saveOrGetOrderPhoneUser(payRequest);
			userId = user.getId();
			payRequest.setUserId(userId);
			isNoLogin = false;
		}
		if (userId == null) {
			user = new User();
			user.setId(0l);
			isNoLogin = true;
		} else {
			user = userMapper.selectById(userId);
			if (user == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
			if (user.getIsBlack()) throw BusinessRuntimeException.getInstance("系统检测操作异常，请稍后再试");
			payOpenId = user.getOpenId();
			if (sku != null) {
				//ChatGPT Plus账号限购校验
				checkChatGPTPlusPurchaseLimit(user.getId(), goodsDon.getId(), goodsDon.getTitle(), sku.getId(), sku.getSpecVal());
			}
			if (goodsDon.getType() == 1 && isNeedTicket) {
				//获取座位
				relation = getRelation(payRequest, sku, yhsId);
				relationId = relation.getId();
			} else {

			}
		}

		/* 生成订单 */
		String donNo = SEQUENCE.nextId().toString();
		OrderDon orderDon = new OrderDon();

		orderDon.setIsDp(false);
		if (isNoLogin != null && isNoLogin) {
			orderDon.setIsNoLogin(true);
		}
		orderDon.setOrderNo(donNo);
		orderDon.setOpenId(payOpenId);
		if (sku != null) {
			if (sku.getPrice() == null || sku.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
				throw BusinessRuntimeException.getInstance("下单商品价格异常");
			}
		}

		//是否是特定价格 且是否满足
		Boolean isSpecificPrice = Optional.ofNullable(payRequest.getIsSpecificPrice()).orElse(false);
		String specificGoodsIds = null;
		BigDecimal specificPrice = BigDecimal.ZERO;
		if (isSpecificPrice) {
			specificGoodsIds = sku.getSpecificGoodsIds();
			if (StrUtil.isEmpty(specificGoodsIds)) {
				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重试");
			}
			if (payRequest.getDonMoney().compareTo(sku.getSpecificPrice()) <= 0) {
				payRequest.setDonMoney(sku.getSpecificPrice());
			}
			List<Long> specificGoodsList = Jsons.parseList(specificGoodsIds, Long.class);
			if (CollUtil.isEmpty(specificGoodsList)) {
				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重试");
			}
			if (user.getId() == 0) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
			Number count = beanSearcher.searchCount(OrderDon.class, MapUtils.builder().field(OrderDon::getGoodsId, specificGoodsList).op(Operator.InList)
					.field(OrderDon::getUserId, user.getId())
					.field(OrderDon::getStatus, Constant.noOrderAllStatus).op(Operator.NotIn)
					.build());
			if (count.intValue() <= 0) {
				throw BusinessRuntimeException.getInstance("你不满足该商品特定价格条件");
			}
			specificPrice = sku.getSpecificPrice();
		}

		if (sku != null && payRequest.getDonMoney().compareTo(sku.getPrice()) < 0 && !isSpecificPrice) {
			log.info("规格:{}支付金额:{}异常,调整用户userId:{}支付金额为:{}", sku.getSpecVal(), payRequest.getDonMoney(), user.getId(), sku.getPrice());
			payRequest.setDonMoney(sku.getPrice());
		}

//		//如 mj标准6人月付 价格特殊处理
//		if (Constant.SPECIAL_PRICE_SKU_IDS.contains(sku.getId())) {
//			UserDistributeShared distributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class)
//					.eq(UserDistributeShared::getUserId, userId)
//					.last("limit 1"));
//			if (distributeShared != null) {
//				SysConfig one = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
//						.eq(SysConfig::getSysKey, Constant.MJ_SPECIAL_SKU_PRICE_KEY)
//						.last("limit 1"));
//				if (one != null && StrUtil.isNotBlank(one.getSysValue())) {
//					GoodsDonPriceDto goodsDonPriceDto = Jsons.parseObject(one.getSysValue(), GoodsDonPriceDto.class);
//					payRequest.setDonMoney(goodsDonPriceDto.getPrice());
//				}
//			}
//		}

		//租赁商品
		if (goodsDon.getType() == 4) {
			//是否已实名认证过
			Integer count = userCertRecordMapper.selectCount(Wrappers.lambdaQuery(UserCertRecord.class).in(UserCertRecord::getUserId, userIdList));
			if (count == 0) throw BusinessRuntimeException.getInstance("请您先完成实名认证..");

			//租赁商品押金
			BigDecimal rentGoodsDonDeposit = getRentGoodsDonDeposit(goodsId, sku.getSpecIds());
			if (rentGoodsDonDeposit == null) throw BusinessRuntimeException.getInstance("应付押金异常..");
			BigDecimal sPay = rentGoodsDonDeposit.add(sku.getPrice());
			if (payRequest.getDonMoney().compareTo(sPay) < 0) {
				payRequest.setDonMoney(sPay);
			}
			orderDon.setDeposit(rentGoodsDonDeposit);
		}

		orderDon.setMoney(payRequest.getDonMoney());
		orderDon.setRealMoney(payRequest.getDonMoney());
		orderDon.setOriMoney(sku != null ? sku.getPrice() : orderDon.getMoney());

		List<Long> dpSkuIds = payRequest.getDpSkuIds();
		if (CollUtil.isNotEmpty(dpSkuIds)) {
			//是否满足关联
			List<GoodsDiscountPlusPurchaseRelation> ds_relations = discountPlusPurchaseRelationMapper.selectList(Wrappers.lambdaQuery(GoodsDiscountPlusPurchaseRelation.class)
					.eq(GoodsDiscountPlusPurchaseRelation::getSkuId, sku.getId())
					.in(GoodsDiscountPlusPurchaseRelation::getDisSid, dpSkuIds));
			if (ds_relations.size() != dpSkuIds.size()) {
				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新下单");
			}
			BigDecimal goods_discount_plus_pay = BigDecimal.ZERO;
			List<Long> dsSkuIds = new ArrayList<>();
			for (GoodsDiscountPlusPurchaseRelation re : ds_relations) {
				goods_discount_plus_pay = goods_discount_plus_pay.add(re.getDisPrice());
				dsSkuIds.add(re.getDisSid());
				orderDon.setDpMoney(goods_discount_plus_pay);
			}
			BigDecimal pay_money = sku.getPrice().add(goods_discount_plus_pay);
			if (pay_money.compareTo(orderDon.getMoney()) > 0) {
				orderDon.setMoney(pay_money);
				orderDon.setRealMoney(pay_money);
			}
			orderDon.setIsDp(true);
		}

		//渠道链接id
		if (payRequest.getPopularizeId() != null) {
			orderDon.setPopularizeId(payRequest.getPopularizeId());
		}

		orderDon.setSkuId(payRequest.getSkuId());
		orderDon.setRelationId(relationId);
		orderDon.setNum(payRequest.getNum());
		orderDon.setGoodsId(goodsDon.getId());
		orderDon.setStatus(OrderDon.Status.noPayment);
		orderDon.setUserId(user.getId());
		orderDon.setType(OrderDon.Type.getType(payRequest.getType()));
		orderDon.setIsWebPay(payRequest.getIsWebPay());
		orderDon.setSource(payRequest.getSource());
		orderDon.setCouponExCode(payRequest.getCouponExCode());
		//店铺id
		orderDon.setYhsId(yhsId);
		//规格补贴id
		Long subsidyId = payRequest.getSubsidyId();
		if (subsidyId != null) {
			//校验百亿补贴规格，并设置参数
			setSubsidyOrderDonInfo(subsidyId, user, orderDon);
		}
		if (relation != null && relation.getStatus() == GroupsRelation.Status.outside) {
			orderDon.setIsOt(true);
		}
		if (orderDon.getYhsId() == 0 && subsidyId == null) {
			//虚拟商品订单,是否是分销订单
			setDistributeOrderMark(orderDon, goodsDon.getType(), user.getId());
		}
		if (relationId != 0) {
			Long gtSkuId = groupsRelationMapper.getGroupTripsSkuIdByRelationId(relationId);
			if (!gtSkuId.equals(orderDon.getSkuId())) {
				throw BusinessRuntimeException.getInstance("车位与车队规格不一致");
			}
		}
		if (sku != null) {
			//扣除使用优惠券、余额的订单金额
			deductOrderMoney(orderDon, couponUser, payRequest.getBalance(), user, sku.getPrice(), goodsDon, payRequest.getGcCash(), payRequest.getGcpIds(), payRequest.getIsAcReduce(), subsidyId, sku, payRequest.getGalaxyCoin());
		}

		if (isSpecificPrice && (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0 || orderDon.getMoney().compareTo(specificPrice) != 0)) {
			throw BusinessRuntimeException.getInstance("专属价格不支持使用其他优惠");
		}
		orderDon.setPayDesc(goodsDon.getPayDesc());
		//设置订单支付商品信息
		setOrderDonPayTile(isGiftCardPay, gcPayInfo, giftCards, orderDon, goodsDon, sku, dpSkuIds);
		//下单手机号
		orderDon.setPhone(orderPhone);
		//镜像店铺订单 区分车票
		if (payRequest.getCmt() == 2 && userMirrorShop != null) {
			log.info("镜像店铺订单:{}", orderDon.getOrderNo());
			relation.setCmt(2);
			relation.setYhsId(userMirrorShop.getId());
			groupsRelationMapper.updateById(relation);
		}
		this.saveOrUpdate(orderDon);

		Long orderId = orderDon.getId();
		//使用银河币记录
		userGalaxyCoinService.handleUserGalaxyCoinOrderNotify(orderDon.getId(), orderDon.getUserId(), orderDon.getOrderNo(), OrderDonGalaxyCoinRecord.Source.ordinary);
		Long fUid = orderDon.getUserId();
		if (orderDon.getIsDp() != null && orderDon.getIsDp()) {
			//保存订单优惠加购规格 关系
			OrderDiscountPlusPurchaseSkuRelation orderDiscountPlusPurchaseSkuRelation = new OrderDiscountPlusPurchaseSkuRelation();
			orderDiscountPlusPurchaseSkuRelation.setOrderId(orderDon.getId());
			orderDiscountPlusPurchaseSkuRelation.setPlusSkuIds(dpSkuIds.toString());
			orderDiscountPlusPurchaseSkuRelation.setUserId(orderDon.getUserId());
			orderDiscountPlusPurchaseSkuRelationMapper.insert(orderDiscountPlusPurchaseSkuRelation);
		}

		if (Constant.realGoodsType.contains(goodsDon.getType()) && !goodsDon.getId().equals(27l)) {
			saveTransport(payRequest.getAddressId(), orderDon.getId());
		}
		//保存加购发货地址
		if (orderDon.getIsDp() != null && orderDon.getIsDp() && payRequest.getAddressId() != null) {
			redisService.set(RedisService.key.PLUS_GOODS_ADDRESS_KEY.getName() + orderDon.getId(), payRequest.getAddressId(), RedisService.key.PLUS_GOODS_ADDRESS_KEY.getTimeout());
		}
		if (orderDon.getDiscountPopularizeRecord() != null) {
			OrderDonUserDiscountPopularizeRecord discountPopularizeRecord = orderDon.getDiscountPopularizeRecord();
			discountPopularizeRecord.setOrderId(orderDon.getId());
			discountPopularizeRecord.setIp(payRequest.getIp());
			orderDonUserDiscountPopularizeRecordMapper.insert(discountPopularizeRecord);
		}

		//数据回传
		if (StringUtils.isNotBlank(payRequest.getCallback())) {
			orderDonPostService.savePostData(orderDon.getId(), payRequest.getCallback(), payRequest.getCallbackType());
		}
		//无回传前端传入 查询缓存中用户的回传信息
		if (StringUtils.isEmpty(payRequest.getCallback())) {
			String val = redisService.getStr(RedisService.key.ORDER_DON_POST_DATA_USER_KEY.getName() + user.getId());
			if (StrUtil.isNotBlank(val)) {
				try {
					Optional.ofNullable(Jsons.parseObject(val, OrderDonPostDataDto.class))
							.ifPresent(orderDonPostDataDto -> {
								log.info("用户ID:{}预下单 回传用户缓存 订单回传记录保存,callback:{},callbackType:{}", fUid, orderDonPostDataDto.getCallback(), orderDonPostDataDto.getCallbackType());
								orderDonPostService.savePostData(orderId, orderDonPostDataDto.getCallback(), orderDonPostDataDto.getCallbackType());
							});
				} catch (Exception e) {
					log.error("解析用户缓存回传信息错误,msg:{}", StringUtil.getErrorText(e));
				}
			}
		}
		//礼品卡购买记录
		if (CollUtil.isNotEmpty(giftCards)) {
			log.info("用户userId:{}购买礼品卡下单orderId:{}", userId, orderDon.getId());
			GiftCardOrderRelate giftCardOrderRelate = new GiftCardOrderRelate();
			giftCardOrderRelate.setOrderId(orderDon.getId());
			giftCardOrderRelate.setGcPayDetail(Jsons.toJson(gcPayInfo.getGcPayDetail()));
			giftCardOrderRelateMapper.insert(giftCardOrderRelate);
		}

		//礼品卡现金使用记录
		if (CollUtil.isNotEmpty(orderDon.getGcUseRecords())) {
			orderDon.getGcUseRecords().forEach(data -> {
				data.setOrderId(orderId);
			});
			giftCardOrderUseRecordService.saveBatch(orderDon.getGcUseRecords());
		}
		if (payRequest.getRadarId() != null && user != null) {
			CorpInteractiveUserOrderRelation corpInteractiveUserOrderRelation = new CorpInteractiveUserOrderRelation();
			corpInteractiveUserOrderRelation.setUserId(user.getId());
			corpInteractiveUserOrderRelation.setOrderId(orderDon.getId());
			corpInteractiveUserOrderRelation.setRadarId(payRequest.getRadarId());
			corpInteractiveUserOrderRelation.setIsNew(false);
			if (user.getCreatedTime().getTime() >= DateUtil.beginOfDay(DateTime.now()).getTime()) {
				corpInteractiveUserOrderRelation.setIsNew(true);
			}
			corpInteractiveUserOrderRelationMapper.insert(corpInteractiveUserOrderRelation);
		}
		//记录文章下单量
		if (payRequest.getInfoId() != null) {
			InformationClickUserRecord informationClickUserRecord = new InformationClickUserRecord();
			informationClickUserRecord.setInfoId(payRequest.getInfoId());
			informationClickUserRecord.setOrderId(orderDon.getId());
			informationClickUserRecordMapper.insert(informationClickUserRecord);
		}
		if (goodsDon != null) {
			orderDon.setGoodsDonType(goodsDon.getType());
		}

		if (sku != null) {
			orderDon.setIsMirror(sku.getIsMirror());
		}
		payRequest.setGoodsId(goodsId);
		//统一处理订单记录操作
		unifiedHandlerOrderRecordFunc(orderDon.getId(), payRequest);
		//余额支付订单
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
			orderDon = orderDonMapper.selectById(orderId);
			unifiedHandlerOrderNotify(orderDon, goodsDon, sku);
		}
		if (orderDon.getStatus() == OrderDon.Status.noPayment) {
			jobManager.addJob(EXPIRY_TIME, () -> {
				closeOrder(orderId, null);
			});
		}
		orderDon.setSpecialType(goodsDon.getSpecialType());
		return orderDon;
	}

	private OrderDon generateDifferOrderDon(OrderPayRequest payRequest, GoodsDon goodsDon, GoodsDonSku sku) {
		Long userId = payRequest.getUserId();
		Assert.notNull(userId, "请先登录");
		Integer selectCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
				.eq(OrderDon::getUserId, userId)
				.eq(OrderDon::getSkuId, sku.getId())
				.eq(OrderDon::getStatus, OrderDon.Status.noPayment));
		if (selectCount > 0) {
			throw BusinessRuntimeException.getInstance("您存在待支付的补差价订单");
		}
		OrderDon orderDon = new OrderDon();
		orderDon.setUserId(userId);
		orderDon.setGoodsId(sku.getGoodsId());
		orderDon.setSkuId(sku.getId());
		orderDon.setMoney(sku.getPrice().multiply(BigDecimal.valueOf(payRequest.getNum())));
		orderDon.setNum(payRequest.getNum());
		orderDon.setStatus(OrderDon.Status.noPayment);
		orderDon.setType(OrderDon.Type.getType(payRequest.getType()));
		orderDon.setIsWebPay(payRequest.getIsWebPay());
		orderDon.setSource(payRequest.getSource());
		orderDon.setPayDesc(goodsDon.getPayDesc());
		orderDon.setPayTitle(goodsDon.getTitle());
		orderDon.setRelationId(0l);
		//存在余额
		BigDecimal balance = payRequest.getBalance();
		User user = userMapper.selectById(userId);
		deductBalancePayOrderMoney(orderDon, balance, user);
		String donNo = SEQUENCE.nextId().toString();
		orderDon.setOrderNo(donNo);
		orderDonMapper.insert(orderDon);
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
			orderDon = orderDonMapper.selectById(orderDon.getId());
			unifiedHandlerOrderNotify(orderDon, goodsDon, sku);
		}
		return orderDon;
	}

	/**
	 * 统一处理订单记录操作
	 */
	private void unifiedHandlerOrderRecordFunc(Long orderId, OrderPayRequest payRequest) {

		//记录订单ip关联
		recordOrderDonLocationRelate(orderId, payRequest.getIp());
		//记录补贴订单关联
		recordOrderDonSubsidyRelate(orderId, payRequest.getSubsidyId());
		//试用车票跳转记录
		recordOrderTrialTicketJumpPay(orderId, payRequest.getAqType(), payRequest.getUserId(), payRequest.getSkuId());
		//记录用户推广海报下单记录
		recordPosterUserOrder(orderId, payRequest.getRid());
		//记录用户镜像店铺订单
		recordUserMirrorShopOrderRelate(orderId, payRequest.getUserId(), payRequest.getCmt(), payRequest.getCustomId());
		//记录用户环境下单数据
		recordEnvTypeOrderRelate(orderId, payRequest.getGoodsId(), payRequest.getEnvType());
		//记录银河币新入口续费数据
		recordOrderDonGalaxyCoinRenewRelate(orderId, payRequest.getRenewSource());
	}

	/**
	 * 记录用户权益下单
	 */
	private void recordUserBenefitsOrderRelate(OrderDon orderDon, UserBenefits userBenefits) {
		UserBenefitsOrderRecord userBenefitsOrderRecord = new UserBenefitsOrderRecord();
		userBenefitsOrderRecord.setOrderId(orderDon.getId());
		userBenefitsOrderRecord.setGoodsId(orderDon.getGoodsId());
		userBenefitsOrderRecord.setSkuId(orderDon.getSkuId());
		userBenefitsOrderRecord.setUserId(orderDon.getUserId());
		userBenefitsOrderRecord.setType(userBenefits.getType().name());
		userBenefitsOrderRecord.setBenefitsId(userBenefits.getId());
		userBenefitsOrderRecordMapper.insert(userBenefitsOrderRecord);
	}

	private void recordUserMirrorShopOrderRelate(Long orderId, Long userId, Integer cmt, String customId) {
		if (cmt == 2 && StrUtil.isNotBlank(customId)) {
			UserMirrorShop userMirrorShop = userMirrorShopMapper.selectOne(Wrappers.lambdaQuery(UserMirrorShop.class)
					.eq(UserMirrorShop::getCustomId, customId).last("limit 1"));
//			if (userMirrorShop.getUserId().equals(userId)) {
//				return;
//			}
			if (userMirrorShop == null || !userMirrorShop.getStatus()) {
				return;
			}
			UserMirrorShopOrderRelate userMirrorShopOrderRelate = new UserMirrorShopOrderRelate();
			userMirrorShopOrderRelate.setOrderId(orderId);
			userMirrorShopOrderRelate.setMpId(userMirrorShop.getId());
			userMirrorShopOrderRelateMapper.insert(userMirrorShopOrderRelate);
		}
	}

	private void recordEnvTypeOrderRelate(Long orderId, Long goodsId, GoodsClickUserOrderRecord.EnvType envType) {
		if (goodsId != null && envType != null) {
			GoodsClickUserOrderRecord goodsClickUserOrderRecord = new GoodsClickUserOrderRecord();
			goodsClickUserOrderRecord.setGoodsId(goodsId);
			goodsClickUserOrderRecord.setOrderId(orderId);
			goodsClickUserOrderRecord.setEnvType(envType);
			goodsClickUserOrderRecordMapper.insert(goodsClickUserOrderRecord);
		}
	}

	private void recordOrderDonGalaxyCoinRenewRelate(Long orderId, OrderPayRequest.RenewSource renewSource) {
		if (renewSource != null && renewSource == OrderPayRequest.RenewSource.galaxyCoin) {
			OrderDonGalaxyCoinRenewRelate orderDonGalaxyCoinRenewRelate = new OrderDonGalaxyCoinRenewRelate();
			orderDonGalaxyCoinRenewRelate.setOrderId(orderId);
			orderDonGalaxyCoinRenewRelateMapper.insert(orderDonGalaxyCoinRenewRelate);
		}
	}

	private Boolean checkIsNeedGroupsRelation(GoodsDon goodsDon) {
		if (goodsDon.getType() == 1) {
			//礼品卡特殊类型不需要车票
			if (goodsDon.getSpecialType() != null && goodsDon.getSpecialType() == GoodsDon.SpecialType.giftCard) {
				return false;
			}
			return true;
		}
		return false;
	}

	@Override
	public H5JsPayParams pay(Long orderId, String tradeType) throws Exception {
		log.info("调起微信支付[start] orderId:{}", orderId);

		OrderDon orderDon = this.getById(orderId);

		OrderAttach attach = new OrderAttach();
		attach.setO(orderDon.getId());

		String toWechatAttach = Codec.DoBase64.custom()
				.setData(Jsons.toJson(attach)).encodeAsText();
		//获取微信默认商户
		String shopId = sysConfigService.getDefaultShopConfigByType("wx");

		ShopConfig shopConfig = shopConfigMapper.getByChannelPopularizeId(orderDon.getPopularizeId(), "wx");
		if (shopConfig != null) {
			shopId = shopConfig.getAppId();
		}
		orderDon.setType(OrderDon.Type.WeChat);
		orderDon.setShopId(shopId);
		orderDon.setIsWebPay(false);
		this.updateById(orderDon);
		H5JsPayParams params = weChatService.getJsPayParams(
				weChatConfig.getAppid(),
				shopId,
				orderDon.getOpenId(),
				orderDon.getMoney().intValue(),
				orderDon.getOrderNo(),
				weChatConfig.getNotifyDomain() + "applets/order/prepay/notify",
				toWechatAttach,
				"银河录像局",
				tradeType,
				orderDon.getCreatedTime()
		);

		log.info("微信支付成功[end]");
		return params;
	}

	@Override
	public H5JsPayParams wxPcWebPay(Long orderId, String tradeType) throws Exception {
		log.info("调起微信支付[start] orderId:{}", orderId);
		OrderDon orderDon = this.getById(orderId);

		OrderAttach attach = new OrderAttach();
		attach.setO(orderDon.getId());

		String toWechatAttach = Codec.DoBase64.custom()
				.setData(Jsons.toJson(attach)).encodeAsText();

		//获取微信默认商户
		String shopId = sysConfigService.getDefaultShopConfigByType("wx");

		ShopConfig shopConfig = shopConfigMapper.getByChannelPopularizeId(orderDon.getPopularizeId(), "wx");
		if (shopConfig != null) {
			shopId = shopConfig.getAppId();
		}
		orderDon.setShopId(shopId);
		orderDon.setType(OrderDon.Type.WeChat);
		orderDon.setIsWebPay(true);
		this.updateById(orderDon);

		H5JsPayParams params = weChatService.getJsPayParams(
				weChatConfig.getAppid(),
				shopId,
				orderDon.getOpenId(),
				orderDon.getMoney().intValue(),
				orderDon.getOrderNo(),
				weChatConfig.getNotifyDomain() + "applets/order/pc/prepay/notify",
				toWechatAttach,
				"银河录像局",
				tradeType,
				orderDon.getCreatedTime()
		);

		log.info("微信支付成功[end]");
		return params;
	}


	@Transactional(rollbackFor = Throwable.class)
	@Override
	public void prepayNotify(Map<String, String> map) throws Exception {
		/* 此处处理订单等业务逻辑 */
		// 获取订单 和 微信订单号 和 支付的金额

		String attach = Codec.DoBase64.custom().setData(map.get("attach")).decodeAsText();

		OrderAttach orderAttach = Jsons.parseObject(attach, OrderAttach.class);

		final Long oid = orderAttach.getO();

		//final Long shareId = orderAttach.getShared();

		OrderDon order = this.getById(oid);

		if (null == order) {
			throw BusinessRuntimeException.getInstance("订单不存在.");
		}
		log.info("微信商家订单号orderNo:{},status:{},进行回调", order.getOrderNo(), order.getStatus());

		String appId = map.get("mch_id");

		// 校验签名
		boolean f = weChatService.checkSignWithMd5(map, shopConfigMapper.getByAppId(appId).getSecret());
		if (!f) {
			log.error("回调数据：{}", map);
			throw BusinessRuntimeException.getInstance("支付成功回调, 校验签名失败.");
		}
		GoodsDonSku sku = null;
		if (order.getSkuId() != null) {
			sku = goodsDonSkuMapper.selectById(order.getSkuId());
		}
		GoodsDon goodsDon = goodsDonMapper.selectById(order.getGoodsId());

		String transactionId = map.get("transaction_id");

		if (!order.getStatus().equals(OrderDon.Status.noPayment) && !order.getStatus().equals(OrderDon.Status.close)) {
			log.info("已回调，重复修改状态 id:{}", order.getId());
			return;
		}

		// 更改订单状态
		order.setTransactionId(transactionId);

		order.setPayTime(DateUtil.parse(map.get("time_end"), "yyyyMMddHHmmss"));
		order.setShopId(appId);
		Long goodsId = order.getGoodsId();
		if (order.getIsNoLogin()) {
			order.setExCode(exchangeCodeService.getExCode(goodsId, order.getSkuId(), 1));
		}
		if (StringUtils.isBlank(order.getOpenId())) {
			order.setOpenId(map.get("openid"));
		}
		order.setType(OrderDon.Type.WeChat);

		unifiedHandlerOrderNotify(order, goodsDon, sku);
	}

	@Override
	public List<RealGoodsInterestUser> selectNoPaymentRealGoods() {
		return orderDonMapper.selectNoPaymentRealGoods();
	}

	@Override
	public Integer updateHasPaymentInterestRealGoods() {
		return orderDonMapper.updateHasPaymentInterestRealGoods();
	}

	@Override
	public void updateHasPaymentInterestRealGoodsPayTime() {
		orderDonMapper.updateHasPaymentInterestRealGoodsPayTime();
	}

	@Transactional(rollbackFor = Throwable.class)
	@Override
	public void closeOrder(Long orderId, Long userId) {
		String orderCloseKey = RedisService.key.CLOSE_ORDER_TIME_KEY.getName() + orderId;
		if (!redisService.setNx(orderCloseKey, orderId, RedisService.key.CLOSE_ORDER_TIME_KEY.getTimeout())) {
			throw BusinessRuntimeException.getInstance("订单正在关闭中..");
		}
		//关闭订单逻辑
		OrderDon orderDon = getById(orderId);
		if (orderDon == null) {
			return;
		}
		if (userId != null) {
			List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null);
			if (!relationUserIdList.contains(orderDon.getUserId())) {
				return;
			}
		}
		log.info("关闭订单 orderId:{}", orderId);
		if (OrderDon.Status.noPayment.equals(orderDon.getStatus())) {
			//调用微信、支付宝第三方接口查询订单是否支付
			OrderDon.Status status = isHasPaid(orderDon);
			if (status == OrderDon.Status.noPayment) {
				//查询微信支付是否已支付
				orderDon.setStatus(OrderDon.Status.close);
				updateById(orderDon);
				//关闭车位锁定
				GroupsRelation groupsRelation = groupsRelationMapper.selectById(orderDon.getRelationId());
				if (groupsRelation != null) {
					if (!groupsRelation.getUserId().equals(orderDon.getUserId())) {
						TASK_POOL.execute(() -> {
							orderDon.setStatus(OrderDon.Status.close);
							updateById(orderDon);
						});
						if (groupsRelation.getUserId() != 0) {
							User user = userMapper.selectById(orderDon.getUserId());
							if (user != null) {
								checkIsSameUser(groupsRelation.getUserId(), user);
							}
						}
						//throw new BusinessRuntimeException("订单用户与车位用户不匹配！");
					} else {
						clearUserLockingRelation(groupsRelation, orderDon);
					}
				}
				//返还优惠券
				if (orderDon.getCouponUserId() != 0) {
					couponFontService.updateOrderDonCouponStatus(orderDon);
				}
				//返还余额
				if (orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) {
					userBenefitsService.addUserBalance(orderDon.getUserId(), orderDon.getBalance(), UserBalanceSourceRecord.Source.order_close, null, orderId, UserBalanceSourceRecord.Source.order_close.getDesc(), true);
				}

				//返回银河币
				UserGalaxyCoinRecord userGalaxyCoinRecord = userGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(UserGalaxyCoinRecord.class)
						.eq(UserGalaxyCoinRecord::getOrderId, orderDon.getId())
						.eq(UserGalaxyCoinRecord::getSource, OrderDonGalaxyCoinRecord.Source.ordinary.ordinal())
						.last("limit 1"));
				if (userGalaxyCoinRecord != null) {
					userGalaxyCoinService.sendOrderGalaxyCloseOrder(orderDon.getId(), orderDon.getUserId(), userGalaxyCoinRecord.getGalaxyCoin().abs(), OrderDonGalaxyCoinRecord.Source.ordinary);
				}

				//是否是礼品卡 现金支付订单
				BigDecimal gcCash = orderDon.getGcCash();
				if (gcCash != null && gcCash.compareTo(BigDecimal.ZERO) > 0) {
					giftCardOrderUseRecordService.returnGiftCardCash(orderDon.getId());
				}
				//恢复支付宝 每日限单数
				if (DateTime.now().toDateStr().equals(DateUtil.format(orderDon.getCreatedTime(), "YYYY-MM-dd"))) {
					zfbShopOrderDayLimitMapper.incrDayLimitRemainOrders(orderDon.getShopId());
				}
				//当前时间短可恢复 小时限单数
				if (DateUtil.hour(orderDon.getCreatedTime(), true) == DateUtil.hour(DateTime.now(), true)) {
					zfbShopOrderDayLimitMapper.incrHourLimitRemainOrders(orderDon.getShopId());
				}
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public OrderDon renewal(OrderPayRequest payRequest) throws Exception {
		Long userId = payRequest.getUserId();
		User user = userMapper.selectById(userId);
		if (user == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
		if (user.getIsBlack()) throw BusinessRuntimeException.getInstance("系统检测操作异常，请稍后再试");
		Long renewSkuId = payRequest.getSkuId();
		CouponUser couponUser = null;
		if (StrUtil.isNotBlank(payRequest.getCouponExCode()) || payRequest.getCouponId() != null) {
			CouponPopularizeDto couponPopularizeDto = checkCouponStatus(renewSkuId, payRequest.getCouponExCode(), payRequest.getCouponId(), payRequest.getUserId(), true);
			//记录优惠券使用状态
			couponUser = couponStatusRecord(payRequest.getCouponExCode(), payRequest.getCouponId(), payRequest.getUserId(), couponPopularizeDto);
		}
		Long relationId = payRequest.getRelationId();
		if (relationId == null || relationId <= 0 || renewSkuId == null || payRequest.getNum() == null) {
			throw new BusinessRuntimeException("缺少必填参数");
		}
		String customId = payRequest.getCustomId();
		Long yhsId = 0l;
		if (payRequest.getCmt() == 1) {
			//若存在店铺id,校验店铺状态
			yhsId = yhShopFrontService.checkShopCustomIdAndReturnShopId(customId);
		} else if (payRequest.getCmt() == 2) {
			UserMirrorShop userMirrorShop = userMirrorShopMapper.selectOne(Wrappers.lambdaQuery(UserMirrorShop.class)
					.eq(UserMirrorShop::getCustomId, customId)
					.last("limit 1"));
			if (!userMirrorShop.getStatus()) {
				throw BusinessRuntimeException.getInstance("店铺已关闭");
			}
		}

		//是否有其他规格的续费订单 若有请先关闭
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, user);
		if (payRequest.getCmt() == 2) {
			//关闭其他待支付订单
			orderDonMapper.update(null, Wrappers.lambdaUpdate(OrderDon.class)
					.set(OrderDon::getStatus, OrderDon.Status.close)
					.eq(OrderDon::getUserId, userId)
					.eq(OrderDon::getStatus, OrderDon.Status.noPayment));
		} else {
			Integer count = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
					.eq(OrderDon::getRelationId, payRequest.getRelationId())
					.eq(OrderDon::getYhsId, yhsId)
					.in(OrderDon::getUserId, userIdList)
					.eq(OrderDon::getStatus, OrderDon.Status.noPayment).eq(OrderDon::getOrderType, 2));
			if (count > 0) {
				throw BusinessRuntimeException.getInstance("您有该车票未支付的续费订单..");
			}
		}
		GoodsDonSku sku = adjustGoodsDonSku(yhsId, false, renewSkuId);

		if (sku == null || !sku.getStatus()) {
			throw BusinessRuntimeException.getInstance("该规格已下架,无法续费..");
		}

		GroupsRelation relation = groupsRelationMapper.selectById(relationId);
		if (relation == null) {
			throw new BusinessRuntimeException("");
		}

		//todo 多账号同一用户绑定 续费
		if (!relation.getUserId().equals(user.getId())) {
			checkIsSameUser(relation.getUserId(), user);
		}
		//大会员车票不支持续费
		if (relation.getIsVip()) {
			throw BusinessRuntimeException.getInstance("不支持单独续费");
		}
		GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
		if (groupsTrips == null) {
			throw BusinessRuntimeException.getInstance("该车队不存在,请联系客服");
		}
		GoodsDon goodsDon = goodsDonMapper.selectById(sku.getGoodsId());

		if (goodsDon == null || !goodsDon.getStatus()) {
			throw new BusinessRuntimeException("商品已下架");
		}

		if (goodsDon.getType() == 2) {
			throw new BusinessRuntimeException("实物不支持续费");
		}

		if (goodsDon.getSpecialType() != null && goodsDon.getSpecialType() == GoodsDon.SpecialType.recharge) {
			throw new BusinessRuntimeException("代充账号不允许续费");
		}
		//用户车票规格
		Long tripsSkuId = groupsTrips.getSkuId();
		GoodsDonSkuView tripGoodsDonSkuView = beanSearcher.searchFirst(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getGoodsId, goodsDon.getId())
				.field(GoodsDonSkuView::getSkuId, tripsSkuId).build());
		if (tripGoodsDonSkuView == null) {
			throw BusinessRuntimeException.getInstance("该续费规格不属于该车队");
		}
		//非镜像规格 不能续费镜像规格
		if (tripGoodsDonSkuView.getIsMirror() != sku.getIsMirror()) {
			throw BusinessRuntimeException.getInstance("续费规格错误");
		}

		if (GroupsTrips.Status.waiting.equals(groupsTrips.getStatus())) {
			if (!noChekGoodsTemp.contains(goodsDon.getTitle())) {
				throw new BusinessRuntimeException("亲,该车次还未发车,需等待客服发车才能续费哦.");
			}
		}
		//netflix 续费逻辑 月付可续费所有规格 其他规格只能续费对应规格
		//netflix月付 续费其他规格 更换车队车位
		Boolean isChangeTicket = false;
		if (goodsDon.getType() == 1 && goodsDon.getId() == 1) {
			if (tripsSkuId != 4 && tripsSkuId != renewSkuId) {
				if (tripsSkuId == 5) {
					throw BusinessRuntimeException.getInstance("季付车票只能续费季付");
				} else if (tripsSkuId == 6) {
					throw BusinessRuntimeException.getInstance("年付车票只能续费年付");
				} else {
					//天数可续费其他规格
					if (tripGoodsDonSkuView.getDays() == null || tripGoodsDonSkuView.getDays() <= 0) {
						throw BusinessRuntimeException.getInstance("请选择对应规格的车票续费");
					}
				}
			} else if (tripsSkuId == 4 && tripsSkuId != renewSkuId) {
				isChangeTicket = true;
			}
		}

		//claude code续费 校验续费套餐等级
		if (goodsDon.getId() == Constant.CLAUDE_CODE_GOODS_ID) {
			ClaudeCodeUser claudeCodeUser = claudeCodeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeCodeUser.class).eq(ClaudeCodeUser::getRelationId, relationId).last("limit 1"));
			Long thisCodeRenewSkuId = claudeCodeUser.getRenewSkuId();
			if (thisCodeRenewSkuId != null) {
				//claude code积分上限
				GoodsDonSku renewSku = goodsDonSkuMapper.selectById(renewSkuId);
				if (claudeCodeUser.getClaudeDailyLimit() < renewSku.getClaudeDailyLimit()) {
					throw BusinessRuntimeException.getInstance("选择的续费套餐错误");
				}
			}
		}

		String payOpenId = user.getOpenId();

		/* 生成订单 */
		String donNo = SEQUENCE.nextId().toString();
		OrderDon orderDon = new OrderDon();

		orderDon.setOrderNo(donNo);
		orderDon.setOpenId(payOpenId);
		orderDon.setYhsId(yhsId);
		orderDon.setMoney(sku.getPrice().multiply(BigDecimal.valueOf(payRequest.getNum())));
		orderDon.setSkuId(renewSkuId);
		orderDon.setRelationId(relation.getId());
		//续费订单
		orderDon.setOrderType(2);
		orderDon.setStatus(OrderDon.Status.noPayment);
		orderDon.setUserId(userId);
		//续费后 是否需要更换车票
		if (isChangeTicket) {
			orderDon.setIsChangeTicket(isChangeTicket);
			orderDon.setPreSkuId(tripsSkuId);
		}
		orderDon.setGoodsId(goodsDon.getId());
		if (relation != null && relation.getStatus() == GroupsRelation.Status.outside) {
			orderDon.setIsOt(true);
		}
		if (orderDon.getYhsId() == 0) {
			//虚拟商品订单,是否是分销订单
			setDistributeOrderMark(orderDon, goodsDon.getType(), userId);
		}
		orderDon.setRealMoney(orderDon.getMoney());
		//独立规格续费升级
		RenewUpgradePackage renewUpgradeIndependentPackage = null;
		if ((payRequest.getPackageId() != null || payRequest.getOriginalOrderId() != null) && sku.getNum() == 1) {
			renewUpgradeIndependentPackage = renewUpgradePackageMapper.selectOne(Wrappers.lambdaQuery(RenewUpgradePackage.class)
					.eq(RenewUpgradePackage::getSkuId, tripsSkuId)
					.apply("JSON_CONTAINS(upgrade_sku_ids,'\"" + renewSkuId + "\"')")
					.eq(RenewUpgradePackage::getStatus, 1)
					.eq(RenewUpgradePackage::getDeleted, 1)
					.last("limit 1"));
			if (renewUpgradeIndependentPackage == null) {
				throw BusinessRuntimeException.getInstance("续费规格不存在");
			}
			BigDecimal discount = renewUpgradeIndependentPackage.getDiscount();
			orderDon.setMoney(sku.getPrice().multiply(discount));
		}
		//扣除使用优惠券、余额的订单金额
		deductOrderMoney(orderDon, couponUser, payRequest.getBalance(), user, sku.getPrice(), goodsDon, payRequest.getGcCash(), payRequest.getGcpIds(), false, null, sku, payRequest.getGalaxyCoin());
		this.saveOrUpdate(orderDon);

		Long orderId = orderDon.getId();
		//使用银河币记录
		userGalaxyCoinService.handleUserGalaxyCoinOrderNotify(orderDon.getId(), orderDon.getUserId(), orderDon.getOrderNo(), OrderDonGalaxyCoinRecord.Source.ordinary);
		//礼品卡现金使用记录
		if (CollUtil.isNotEmpty(orderDon.getGcUseRecords())) {
			orderDon.getGcUseRecords().forEach(data -> {
				data.setOrderId(orderId);
			});
			giftCardOrderUseRecordService.saveBatch(orderDon.getGcUseRecords());
		}
		if (payRequest.getRadarId() != null && user != null) {
			CorpInteractiveUserOrderRelation corpInteractiveUserOrderRelation = new CorpInteractiveUserOrderRelation();
			corpInteractiveUserOrderRelation.setUserId(user.getId());
			corpInteractiveUserOrderRelation.setOrderId(orderDon.getId());
			corpInteractiveUserOrderRelation.setRadarId(payRequest.getRadarId());
			corpInteractiveUserOrderRelation.setIsNew(false);
			if (user.getCreatedTime().getTime() >= DateUtil.beginOfDay(DateTime.now()).getTime()) {
				corpInteractiveUserOrderRelation.setIsNew(true);
			}
			corpInteractiveUserOrderRelationMapper.insert(corpInteractiveUserOrderRelation);
		}

		//处理镜像规格续费目前升级的规格
		handlerMirrorRenewPresentPackage(orderDon, sku, tripsSkuId, renewSkuId, groupsTrips);
		if (renewUpgradeIndependentPackage != null) {
			//独立规格续费订单记录
			recordIndependentRenewOrderDon(orderDon, renewUpgradeIndependentPackage, groupsTrips);
		}
		//统一处理订单记录操作
		unifiedHandlerOrderRecordFunc(orderDon.getId(), payRequest);
		//订单金额为0 且订单为已完成 更新虚物车票
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
			orderDon = orderDonMapper.selectById(orderId);
			unifiedHandlerOrderNotify(orderDon, goodsDon, sku);
		}
		if (orderDon.getStatus() == OrderDon.Status.noPayment) {
			jobManager.addJob(EXPIRY_TIME, () -> {
				closeOrder(orderId, null);
			});
		}
		//记录镜像过期车票 续费订单关联
		if (relation.getExpiryTime() != null && relation.getExpiryTime().compareTo(DateTime.now()) <= 0) {
			MirrorExpiryRenewOrderRelate mirrorExpiryRenewOrderRelate = new MirrorExpiryRenewOrderRelate();
			mirrorExpiryRenewOrderRelate.setOrderId(orderId);
			mirrorExpiryRenewOrderRelateMapper.insert(mirrorExpiryRenewOrderRelate);
		}
		return orderDon;
	}

	@Override
	public OrderDetailView getDetail(Long orderId, Long userId) {
		OrderDon orderDon = this.getById(orderId);
		MapBuilder builder = MapUtils.builder()
				.field(OrderDonView::getId, orderId)
				.orderBy(OrderDonView::getId).desc();
		if (userId != null && orderDon.getOrderType() != 2) {
			builder.field(OrderDonView::getUserId, userId);
		}
		OrderDetailView detail = beanSearcher.searchFirst(OrderDetailView.class, builder.build());
		//获取对应车票订单 账号密码
		if (userId != null) {
			List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
			RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder()
					.field(RenewalView::getUserId, userIdList).op(Operator.InList)
					.field(RenewalView::getRelationId, detail.getRelationId())
					.onlySelect(RenewalView::getAccount, RenewalView::getPassword)
					.build());
			if (renewalView != null) {
				detail.setAccount(renewalView.getAccount());
				detail.setPassword(renewalView.getPassword());
			}
		}

		if (detail.getRelationId() != 0) {
			detail.setTransport(transportMapper.selectOne(Wrappers.lambdaQuery(OrderDonTransport.class).eq(OrderDonTransport::getOrderId, detail.getId()).last(" limit 1")));
			detail.setWaybill(waybillMapper.selectOne(Wrappers.lambdaQuery(OrderDonWaybill.class).eq(OrderDonWaybill::getOrderId, detail.getId()).last(" limit 1")));
		}
		return detail;
	}

	@Override
	public List<OrderDon> getAppleOneOrderDons(List<Long> skuIds, List<String> noOrderStatus, Date yesZeroDate, Date thisZeroDate) {
		return orderDonMapper.getAppleOneOrderDons(skuIds, noOrderStatus, yesZeroDate, thisZeroDate);
	}

	@Override
	public AliPayParams aliPay(AlipayOrderDonReq re, String productCode, String qrPayMode) throws Exception {
		return aliPayCommonService.unifiedPay(re, productCode, qrPayMode);
	}

	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void aliPayNotify(Map<String, String> params) throws Exception {
		//调用SDK验证签名
		String body = Codec.DoBase64.custom().setData(params.get("body")).decodeAsText();
		OrderAttach orderAttach = Jsons.parseObject(body, OrderAttach.class);
		Long oderId = orderAttach.getO();
		String orderNo = params.get("out_trade_no");
		OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
				.eq(OrderDon::getOrderNo, orderNo)
				.last("limit 1"));
		if (null == orderDon) {
			throw BusinessRuntimeException.getInstance("订单不存在.");
		}
		if (orderDon.getPopularizeId() == null) {
			orderDon.setShopId(null);
		}
		String appId = params.get("app_id");
		boolean signVerified = AlipaySignature.rsaCheckV1(params, shopConfigMapper.getByAppId(appId).getPublicKey(), BaseZfbConfig.charset, BaseZfbConfig.signType);
		if (!signVerified) {
			log.error("支付宝回调校验签名错误,自定义入参:{}", params.get("body"));
			throw BusinessRuntimeException.getInstance("支付宝回调校验签名错误");
		}
		String transactionId = params.get("trade_no");
		String payTimeStr = params.get("gmt_payment");
		//买家支付宝账号
		String buyerId = Optional.ofNullable(params.get("buyer_id")).orElse(params.get("buyer_open_id"));
		log.info("支付宝回调信息:{}", Jsons.toJson(params));
		if (!orderDon.getStatus().equals(OrderDon.Status.noPayment) && !orderDon.getStatus().equals(OrderDon.Status.close)) {
			log.info("支付宝已回调，重复修改状态 id:{}", orderDon.getId());
			return;
		}
		Long goodsId = orderDon.getGoodsId();
		if (orderDon.getIsNoLogin() != null && orderDon.getIsNoLogin()) {
			orderDon.setExCode(exchangeCodeService.getExCode(goodsId, orderDon.getSkuId(), 1));
		}
		GoodsDonSku sku = null;
		if (orderDon.getSkuId() != null) {
			sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
		}
		GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
		Date payTime = DateTime.now();
		if (StringUtils.isNotBlank(payTimeStr)) {
			payTime = DateUtil.parse(payTimeStr, "yyyy-MM-dd HH:mm:ss");
		}
		// 更改订单状态
		orderDon.setTransactionId(transactionId);
		orderDon.setPayTime(payTime);
		orderDon.setShopId(appId);
		orderDon.setType(OrderDon.Type.ALI_PAY);
		orderDon.setBuyerId(buyerId);
		//该支付账号id 是否被后台拉黑
		Integer count1 = userPayOrderBlockMapper.selectCount(Wrappers.lambdaQuery(UserPayOrderBlock.class)
				.eq(UserPayOrderBlock::getBuyerId, buyerId));
		if (count1 > 0) {
			log.info("该支付账号id：{} 已被后台拉黑", buyerId);
			notifyRefundOrder(orderDon, goodsDon, sku);
			return;
		}

		//是否是河南濮阳ip 直接退款mj
		if (orderDon.getGoodsId() == 26) {
			OrderDonLocationRelate orderDonLocationRelate = orderDonLocationRelateMapper.selectOne(Wrappers.lambdaQuery(OrderDonLocationRelate.class)
					.eq(OrderDonLocationRelate::getOrderId, orderDon.getId())
					.last("limit 1"));
			if (orderDonLocationRelate != null) {
				String address = StringUtil.paidIpAddress(orderDonLocationRelate.getIp());
				if (address.contains("濮阳")) {
					log.info("该支付账号id：{} 河南濮阳ip 直接退款mj", buyerId);
					notifyRefundOrder(orderDon, goodsDon, sku);
					//记录
					OrderDonExceptionUserRecord exceptionUserRecord = new OrderDonExceptionUserRecord();
					exceptionUserRecord.setOrderId(orderDon.getId());
					exceptionUserRecord.setUserId(orderDon.getUserId());
					exceptionUserRecord.setBuyerId(orderDon.getBuyerId());
					exceptionUserRecord.setIp(orderDonLocationRelate.getIp());
					exceptionUserRecord.setAddress(address);
					orderDonExceptionUserRecordMapper.insert(exceptionUserRecord);
					return;
				}
			}
		}

		//单个支付每月限购2单奈飞
		if (orderDon.getGoodsId() == 1) {
			Boolean isCheck = true;
			SysConfig purchaseLimitConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
					.eq(SysConfig::getSysKey, Constant.NF_PURCHASE_LIMIT_KEY)
					.last("limit 1"));
			if (purchaseLimitConfig != null && StrUtil.isNotEmpty(purchaseLimitConfig.getSysValue())) {
				SysConfig one = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
						.eq(SysConfig::getSysKey, Constant.NF_PURCHASE_LIMIT_WHITE_KEY)
						.last("limit 1"));
				if (one != null && StrUtil.isNotBlank(one.getSysValue())) {
					List<Long> whiteUserIds = Jsons.parseList(one.getSysValue(), Long.class);
					if (whiteUserIds.contains(orderDon.getUserId())) {
						isCheck = false;
					}
				}
				if (isCheck) {
					Integer count = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
							.eq(OrderDon::getBuyerId, orderDon.getBuyerId())
							.eq(OrderDon::getGoodsId, 1)
							.ne(OrderDon::getId, orderDon.getId())
							.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
							.ge(OrderDon::getCreatedTime, DateUtil.offsetMonth(DateTime.now(), -1)));
					//超过1单 自动退款
					if (count > 0) {
						notifyRefundOrder(orderDon, goodsDon, sku);
						return;
					}
				}
			}
		}


		if (orderDon.getOrderType() == 1 && StrUtil.isNotEmpty(buyerId)) {
			//近一个月同一买家id 只能购买一次 多人 非镜像
			if (orderDon.getGoodsId() == 26l && sku.getNum() != 1 && !sku.getIsMirror()) {
				List<Long> userIdList = userBindRelationService.getRelationUserIdList(orderDon.getUserId(), null);
				Integer count = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
						.ne(OrderDon::getId, orderDon.getId())
						.eq(OrderDon::getGoodsId, orderDon.getGoodsId())
						.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
						.ge(OrderDon::getCreatedTime, DateUtil.offsetMonth(DateTime.now(), -1))
						//同一买家或者同一用户
						.and(o -> o.eq(OrderDon::getBuyerId, buyerId).or().in(OrderDon::getUserId, userIdList)));
				if (count > 1) {
					//退款
					log.info("一个月内同一买家id购买过Midjourney账号，对订单号:{}进行退款", orderDon.getOrderNo());
					notifyRefundOrder(orderDon, goodsDon, sku);
					return;
				}
			}
		}
		//回调
		unifiedHandlerOrderNotify(orderDon, goodsDon, sku);
	}

	public void setRelation(GroupsRelation relation) {
		Long relationId = relation.getId();
		Long userId = relation.getUserId();
		Long groupsId = relation.getGroupsId();
		GroupsRelation.Status status = relation.getStatus();
		String relation_num_key = RedisKey.GROUPS_RELATION_NUM_KEY + relationId;
		if (!redisService.setNx(relation_num_key, userId, 60 * 5L)) {
			GroupsRelation dbRelation = groupsRelationMapper.selectById(relationId);
			if (dbRelation.getUserId() != 0) {
				log.info("=====>用户:{}未抢到座位:{}", userId, relationId);
				throw new BusinessRuntimeException("系统繁忙，请重试...");
			}
		}
		if (status == GroupsRelation.Status.outside) {
			return;
		}
		int count = groupsMapper.decrAvailableNum(groupsId);
		if (count == 0) {
			log.error("车位异常 groupId:{}", groupsId);
			groupsMapper.updateAvailableNum(groupsId);
			//清除座位缓存key
			delRelationKey(relationId, userId);
			throw new BusinessRuntimeException("车位异常");
		}
	}

	@Override
	public void saveTransport(Long addressId, Long orderId) {
		if (addressId == null) {
			throw new BusinessRuntimeException("请选择收货地址.");
		}
		Address address = addressMapper.selectById(addressId);
		if (address == null) {
			throw new BusinessRuntimeException("请添加收货地址.");
		}
		saveTransportByAddress(address, orderId);
	}

	@Override
	public AlipayFundTransCommonQueryResponse getTransFerStatusByTid(String translationId) throws Exception {
		AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(ShopConfig.ZFB_DEFAULT_APP_ID);
		AlipayFundTransCommonQueryRequest request = new AlipayFundTransCommonQueryRequest();
		AlipayFundTransCommonQueryModel model = new AlipayFundTransCommonQueryModel();
		model.setOrderId(translationId);
		model.setBizScene(TransferConstant.DIRECT_TRANSFER);
		model.setProductCode(ZfbProductCode.STD_RED_PACKET.getProductCode());
		request.setBizModel(model);
		AlipayFundTransCommonQueryResponse response = alipayClient.certificateExecute(request);
		return response;
	}

	/**
	 * 查询支付宝订单详情
	 */
	@Override
	public AlipayTradeQueryResponse getZfbOrderDetail(String shopId, String orderNo) throws AlipayApiException {
		AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(shopId);
		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
		AlipayTradeWapPayModel bizModel = new AlipayTradeWapPayModel();
		bizModel.setOutTradeNo(orderNo);
		request.setBizModel(bizModel);
		AlipayTradeQueryResponse response;
		ShopConfig shopConfig = shopConfigMapper.selectOne(Wrappers.lambdaQuery(ShopConfig.class).eq(ShopConfig::getAppId, shopId));
		if (shopConfig != null && shopConfig.getIsCert()) {
			response = alipayClient.certificateExecute(request);
		} else {
			response = alipayClient.execute(request);
		}
		if (response.isSuccess()) {
			return response;
		}
		return null;
	}

	/**
	 * 查询支付宝退款订单详情
	 */
	@Override
	public AlipayTradeFastpayRefundQueryResponse getZfbRefundDetail(String shopId, String orderNo) throws AlipayApiException {
		AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(shopId);
		AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
		AlipayTradeRefundModel bizModel = new AlipayTradeRefundModel();
		bizModel.setOutTradeNo(orderNo);
		bizModel.setOutRequestNo(orderNo);
		request.setBizModel(bizModel);
		AlipayTradeFastpayRefundQueryResponse response;
		ShopConfig shopConfig = shopConfigMapper.selectOne(Wrappers.lambdaQuery(ShopConfig.class).eq(ShopConfig::getAppId, shopId));
		if (shopConfig != null && shopConfig.getIsCert()) {
			response = alipayClient.certificateExecute(request);
		} else {
			response = alipayClient.execute(request);
		}
		if (response.isSuccess()) {
			return response;
		}
		return null;
	}

	@Override
	public void zeroOrderConfirm(Long orderId) {
		OrderDon orderDon = this.getById(orderId);
		if (orderDon == null) throw BusinessRuntimeException.getInstance("订单不存在");
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) {
			throw BusinessRuntimeException.getInstance("订单异常");
		}
		if (orderDon.getStatus() != OrderDon.Status.noPayment) {
			throw BusinessRuntimeException.getInstance("订单状态已修改");
		}
		GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
		GoodsDonSku sku = null;
		if (orderDon.getSkuId() != null) {
			sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
		}
		if (orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) {
			orderDon.setType(OrderDon.Type.BALANCE);
			orderDon.setPayTime(DateTime.now());
		}
		unifiedHandlerOrderNotify(orderDon, goodsDon, sku);
	}

	@Override
	public void zeroUpgradeOrderConfirm(Long orderId) {
		UpgradeOrderDon orderDon = upgradeOrderDonMapper.selectById(orderId);
		if (orderDon == null) throw BusinessRuntimeException.getInstance("订单不存在");
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) {
			throw BusinessRuntimeException.getInstance("订单异常");
		}
		if (orderDon.getStatus() != UpgradeOrderDon.Status.noPayment) {
			throw BusinessRuntimeException.getInstance("订单状态已修改");
		}
		UpgradePackage upgradePackage = null;
		if (orderDon.getPackageId() != null) {
			upgradePackage = upgradePackageMapper.selectById(orderDon.getPackageId());
		}
		if (orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) {
			orderDon.setType(UpgradeOrderDon.Type.BALANCE);
			orderDon.setPayTime(DateTime.now());
		}
		unifiedHandlerUpgradeOrderNotify(orderDon, upgradePackage);
	}

	public void updateCarParkAndSendMsg(GoodsDon goodsDon, GoodsDonSku sku, OrderDon order) {
		if (goodsDon.getType() == 1) {
			//修改车位状态
			GroupsRelation relation = groupsRelationMapper.selectById(order.getRelationId());
			if (relation == null) {
				log.info("无需更新车票信息");
				return;
			}
			log.info("虚物订单orderNo:{}开始更新车票信息", order.getOrderNo());
			if (order.getIsDp() != null && order.getIsDp()) {
				//是否已经发送优惠加购车票
				OrderDiscountPlusPurchaseSkuRelation purchaseSkuRelation = orderDiscountPlusPurchaseSkuRelationMapper.selectOne(Wrappers.lambdaQuery(OrderDiscountPlusPurchaseSkuRelation.class)
						.eq(OrderDiscountPlusPurchaseSkuRelation::getOrderId, order.getId()));
				if (purchaseSkuRelation != null) {
					String plusSkuIdsStr = purchaseSkuRelation.getPlusSkuIds();
					String relationIdsStr = purchaseSkuRelation.getRelationIds();
					if (StrUtil.isNotEmpty(plusSkuIdsStr) && StrUtil.isEmpty(relationIdsStr)) {
						try {
							List<Long> plusSkuIds = Jsons.parseList(plusSkuIdsStr, Long.class);
							//发送优惠加购 规格车票
							List<Long> dis_relation_ids = null;
							List<Long> plus_order_ids = null;
							Address address = null;
							for (Long plus_skuId : plusSkuIds) {
								GoodsDonSku plus_sku = goodsDonSkuMapper.selectById(plus_skuId);
								if (plus_sku == null) {
									log.error("订单id:{}优惠加购规格已被删除 skuId:{},车票未发送", order.getId(), plus_skuId);
									continue;
								}
								GoodsDon plus_goods = goodsDonMapper.selectById(plus_sku.getGoodsId());
								if (plus_goods.getType() != 1) {
									log.info("orderId:{}存在非虚拟规格加购,添加{}发货信息", order.getId(), plus_goods.getTitle());
									if (plus_order_ids == null) {
										plus_order_ids = new ArrayList<>();
									}
									if (address == null) {
										Long addressId = Long.parseLong(redisService.getStr(RedisService.key.PLUS_GOODS_ADDRESS_KEY.getName() + order.getId()));
										if (addressId == null) {
											log.error("用户userId{}缓存的收货地址addressId:{}不存在", order.getUserId(), addressId);
											continue;
										}
										address = addressMapper.selectById(addressId);
										if (address == null) {
											log.error("用户userId{}收货地址addressId:{}已不存在", order.getUserId(), addressId);
											continue;
										}
									}
									//生成实物订单 0元实物订单
									createRealOrderAndTransport(order.getUserId(), address, plus_goods, plus_sku, plus_order_ids);
									continue;
								}
								if (dis_relation_ids == null) {
									dis_relation_ids = new ArrayList<>();
								}
								GroupsRelation relationNoOrder = exchangeCodeService.getRelationNoOrder(plus_sku, order.getUserId(), order.getYhsId());
								dis_relation_ids.add(relationNoOrder.getId());
							}
							redisService.del(RedisService.key.PLUS_GOODS_ADDRESS_KEY.getName() + order.getId());
							//保存订单关联优惠加购车票
							orderDiscountPlusPurchaseSkuRelationMapper.update(null, Wrappers.lambdaUpdate(OrderDiscountPlusPurchaseSkuRelation.class)
									.set(CollUtil.isNotEmpty(dis_relation_ids), OrderDiscountPlusPurchaseSkuRelation::getRelationIds, Jsons.toJson(dis_relation_ids))
									.set(CollUtil.isNotEmpty(plus_order_ids), OrderDiscountPlusPurchaseSkuRelation::getPlusOrderIds, Jsons.toJson(plus_order_ids))
									.eq(OrderDiscountPlusPurchaseSkuRelation::getOrderId, order.getId()));
						} catch (Exception e) {
						}
					}
				}
			}
			if (order.getRelationId() != 0 && !relation.getUserId().equals(order.getUserId()) && order.getOrderType() == 1) {
				GroupsRelation relationNoOrder = exchangeCodeService.getRelationNoOrder(sku, order.getUserId(), order.getYhsId());
				if (relationNoOrder == null) {
					log.error("用户userId:{}支付订单orderId:{}回调后,未分配车票", order.getUserId(), order.getId());
					return;
				}
				log.info("重新安排userId:{}支付订单orderId:{},规格skuId:{},车位relationId:{}", order.getUserId(), order.getId(), order.getSkuId(), relationNoOrder.getId());
				order.setRelationId(relationNoOrder.getId());
				if (order.getYhsId() != 0) {
					relationNoOrder.setYhsId(order.getYhsId());
					groupsRelationMapper.updateById(relationNoOrder);
				}
				return;
			}

			GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
			if (GroupsRelation.Status.locking.equals(relation.getStatus()) || GroupsRelation.Status.validity.equals(relation.getStatus()) || GroupsRelation.Status.outside.equals(relation.getStatus())) {
				log.info("订单号orderNo:{}开始修改车位:{}状态", order.getOrderNo(), relation.getId());
				if (relation.getNum() > groupsTrips.getNum()) {
					relation.setStatus(GroupsRelation.Status.outside);
				} else {
					relation.setStatus(GroupsRelation.Status.validity);
				}
				//续费后,下一次续费意愿状态为false
				relation.setRenewStatus(false);
				relation.setIsHandle(false);
				//若存在错误镜像店铺车票
				if (relation.getCmt() == 2 && relation.getYhsId() == 0) {
					relation.setCmt(0);
				}
				//代充平台以及部分邀请制平台
				//需填写账号
				if ((goodsDon.getSpecialType() != null && goodsDon.getSpecialType() == GoodsDon.SpecialType.recharge) || Constant.RECHARGE_INVITE_GOODS_IDS.contains(order.getGoodsId())) {
					relation.setRechargeStatus(GroupsRelation.RechargeStatus.waiting);
					relation.setSubmitTime(DateTime.now());
					//GPT代充
					if (goodsDon.getId() == Constant.GPT_RECHARGE_GOODS_ID) {
						//代充次数
						relation.setRechargeNum(sku.getMonths());
						relation.setRechargeRemainNum(relation.getRechargeNum());
					}
				}
				GroupsTrips.Status tripsStatus = groupsTrips.getStatus();
				//邀请制 不给车票设置时间
				if (goodsDon.getSecondType() != null && goodsDon.getSecondType() == 1) {
					tripsStatus = GroupsTrips.Status.waiting;
				}
				if (GroupsTrips.Status.validity.equals(tripsStatus) || GroupsTrips.Status.down.equals(tripsStatus)) {
					//如果续费增加时间，如果首次则设置当前时间为初始时间
					Date expiryTime = Optional.ofNullable(relation.getExpiryTime()).orElse(new Date());
					GoodsDonSku donSku = goodsDonSkuMapper.selectById(order.getSkuId());
					Date newDate;
					Date skuNewExpiryTime;
					//天数、月份
					if (donSku.getDays() != null && donSku.getDays() > 0) {
						newDate = DateUtil.offsetDay(expiryTime, donSku.getDays() * order.getNum());
						skuNewExpiryTime = DateUtil.offsetDay(DateTime.now(), donSku.getDays() * order.getNum());
					} else {
						//奈飞月付 按30天计算
						if (sku.getId() == 4) {
							newDate = DateUtil.offsetDay(expiryTime, 30 * order.getNum());
							skuNewExpiryTime = DateUtil.offsetDay(DateTime.now(), 30 * order.getNum());
						} else {
							newDate = DateUtil.offset(expiryTime, DateField.MONTH, donSku.getMonths() * order.getNum());
							skuNewExpiryTime = DateUtil.offset(DateTime.now(), DateField.MONTH, donSku.getMonths() * order.getNum());
						}
					}
					//若车票已过期 镜像车票续费
					if (sku.getIsMirror() && relation.getExpiryTime() != null && relation.getExpiryTime().compareTo(DateTime.now()) <= 0) {
						relation.setExpiryTime(skuNewExpiryTime);
					} else {
						relation.setExpiryTime(newDate);
					}
					relation.setStartTime(relation.getStartTime() == null ? new Date() : null);

					//镜像续费升级
					handleMirrorRenew(sku, order, groupsTrips, relation.getId(), skuNewExpiryTime);
				} else if (GroupsTrips.Status.waiting.equals(tripsStatus)) {
					log.info("车位groupsId:{}未发车,修改订单号orderNo:{}订单为已付款状态:{}", groupsTrips.getId(), order.getOrderNo());
					order.setStatus(OrderDon.Status.hasPayment);
					if (goodsDon.getSpecialType() != null && goodsDon.getSpecialType() == GoodsDon.SpecialType.courseware) {
						order.setStatus(OrderDon.Status.complete);
					}
				}
//				//下架POE会员车队 || GPT Plus独立规格 下架
//				if (order.getGoodsId() != null && Constant.DOWN_GOODS_PAY.contains(order.getGoodsId()) || goodsDonSkuMapper.selectSingleSkuIdsByGoodsId(Constant.AI_goodsIds.get(0)).contains(groupsTrips.getSkuId())) {
//					if (groupsTrips.getAccountId() != null && groupsTrips.getStatus() == GroupsTrips.Status.validity) {
//						groupsTrips.setStatus(GroupsTrips.Status.down);
//						groupsMapper.updateById(groupsTrips);
//					}
//				}
				//独立车位下单后 车队下架
				if (sku.getNum() != null && sku.getNum() == 1) {
					if (groupsTrips.getAccountId() != null && tripsStatus == GroupsTrips.Status.validity) {
						groupsTrips.setStatus(GroupsTrips.Status.down);
						groupsMapper.updateById(groupsTrips);
					}
				}
				//体验规格 将车票类型改为体验
				if (sku.getGoodsId() == Constant.GPT_PLUS_GID && Constant.GPT_PLUS_O1_TRIAL_SKU_ID.equals(sku.getId())) {
					relation.setAqType(2);
				}
				//TODO 如未发车逻辑
				groupsRelationMapper.updateById(relation);
				Account account = null;
				if (envCommonService.isPrdEnv() && order.getOrderType() == 2) {
					//ChatGPT plus 独立和Midjourney 独立有人续费了发短信
					if (Constant.AI_goodsIds.contains(order.getGoodsId()) && sku.getNum() == 1) {
						try {
							String accountStr = StrUtil.EMPTY;
							account = accountMapper.selectById(groupsTrips.getAccountId());
							if (account != null) {
								accountStr = account.getAccount();
							}
							String renew_msg = String.format(Constant.AI_RENEW_MSG, order.getUserId(), goodsDon.getTitle(), sku.getSpecVal(), accountStr);
							SmsUtil.sendLuoKey2Msg(Constant.SERVICE_PHONE, renew_msg);
						} catch (Exception e) {
						}
					}
				}
				//GPT 代充 发送短信通知
				if (envCommonService.isPrdEnv() && order.getGoodsId() == 40l) {
					try {
						String pay_msg = String.format(Constant.PAY_MSG, order.getUserId(), goodsDon.getTitle(), sku.getSpecVal());
						SmsUtil.sendLuoKey2Msg(Constant.SERVICE_PHONE, pay_msg);
					} catch (Exception e) {
					}
				}


				if (order.getOrderType() == 1 && order.getGoodsId() == Constant.NANO_GOODS_ID) {
					//创建nano user
					createNanoUser(order.getUserId(), order.getRelationId(), sku);
				}
			}
		}
	}

	private void createNanoUser(Long userId, Long relationId, GoodsDonSku sku) {
		//nano
		//是否存在nano 推广体验车票
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		GroupsRelationView groupsRelationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getSkuId, Constant.DISTRIBUTE_NANO_TRIAL_SKU_ID).field(GroupsRelationView::getUserId, userIdList).build());
		if (groupsRelationView != null) {
			//清除车票
			Long trialRelationId = groupsRelationView.getId();
			GroupsRelation trialRelation = groupsRelationMapper.selectById(trialRelationId);
			groupRelationClearService.clearTicket(trialRelation, UserTicketClearedRecord.Source.vip_deduct);

			NanoUserQuota nanoUserQuota = nanoUserQuotaMapper.selectOne(Wrappers.lambdaQuery(NanoUserQuota.class).eq(NanoUserQuota::getRelationId, trialRelationId).last("limit 1"));
			nanoUserQuota.setTotalQuota(nanoUserQuota.getTotalQuota() + sku.getNanoQuota());
			nanoUserQuota.setRemainingQuota(nanoUserQuota.getRemainingQuota() + sku.getNanoQuota());
			nanoUserQuota.setRelationId(relationId);
			nanoUserQuotaMapper.updateById(nanoUserQuota);
			return;
		}
		try {
			User user = userMapper.selectById(userId);
			NanoUserQuota nanoUserQuota = new NanoUserQuota();
			nanoUserQuota.setUid(userId);
			nanoUserQuota.setRelationId(relationId);
			nanoUserQuota.setUserToken(UUID.randomUUID().toString());
			nanoUserQuota.setNickname(user.getNickname());
			nanoUserQuota.setAvatar(user.getHeadimgurl());
			nanoUserQuota.setPurchaseDate(DateTime.now());
			nanoUserQuota.setTotalQuota(sku.getNanoQuota());
			nanoUserQuota.setRemainingQuota(nanoUserQuota.getTotalQuota());
			nanoUserQuotaMapper.insert(nanoUserQuota);
		} catch (DuplicateKeyException e) {

		}
	}

	/**
	 * 分销待发积分记录
	 */
	public void distributeWaitingSendPointsRecord(OrderDon order) {
		log.info("订单id:{}产生分销积分开始--->", order.getId());
		DistributeWaitingSendPoints distributeWaitingSendPoints = new DistributeWaitingSendPoints();
		distributeWaitingSendPoints.setOrderId(order.getId());
		distributeWaitingSendPoints.setUserId(order.getUserId());
		BigDecimal orderMoney = order.getMoney();
		//是否是加购订单
		if (order.getIsDp() != null && order.getIsDp()) {
			//加购订单使用 主平台金额 分销
			orderMoney = order.getOriMoney();
			if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
				log.info("orderId:{}之前加购订单，无主平台金额,使用规格金额", order.getId());
				GoodsDonSku sku = goodsDonSkuMapper.selectById(order.getSkuId());
				orderMoney = sku.getPrice();
			}
		}
		order.setDsMoney(orderMoney);
		BigDecimal points = null;
		BigDecimal returnMoney = null;
		Long businessId = null;
		//普通分销
		GoodsDon goodsDon = goodsDonMapper.selectById(order.getGoodsId());
		GoodsDonSku goodsDonSku = null;
		if (goodsDon == null || !goodsDon.getIsDistribute()) {
			log.info("分销订单orderId:{}对应平台goodsId:{}不存在或已不参与分成比例", order.getId(), order.getGoodsId());
			return;
		}
		if (order.getSkuId() != null) {
			goodsDonSku = goodsDonSkuMapper.selectById(order.getSkuId());
		}
		UserDistributeShared userDistributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class).eq(UserDistributeShared::getUserId, order.getUserId()).last("limit 1"));
		if (userDistributeShared != null) {
			distributeWaitingSendPoints.setSharedId(userDistributeShared.getSharedId());
			DistributePointsExchangeMoney distributePointsExchangeMoney = distributePointsExchangeMoneyMapper.selectOne(Wrappers.lambdaQuery(DistributePointsExchangeMoney.class).orderByDesc(DistributePointsExchangeMoney::getPoints).last("limit 1"));
			if (distributePointsExchangeMoney == null) {
				log.info("分销兑换积分比例未配置");
			} else {
				UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, userDistributeShared.getSharedId()).eq(UserDistribute::getDeleted, true).last("limit 1"));
				//分销比例
				Integer rate = 0;
				if (userDistribute == null) {
					//普通分销者 是否享受过该用户的首单分销
					DistributeWaitingSendPoints isReceived = distributeWaitingSendPointsMapper.selectOne(Wrappers.lambdaQuery(DistributeWaitingSendPoints.class)
							.eq(DistributeWaitingSendPoints::getSharedId, userDistributeShared.getSharedId())
							.eq(DistributeWaitingSendPoints::getUserId, order.getUserId())
							.in(DistributeWaitingSendPoints::getSendStatus, List.of(DistributeWaitingSendPoints.Status.waiting.name(), DistributeWaitingSendPoints.Status.success.name()))
							.last("limit 1"));
					if (isReceived != null) {
						return;
					}
					rate = goodsDon.getRate();
					//实物分销比例
					if (goodsDon.getType() == 2) {
						if (goodsDonSku != null) {
							//不包含套餐权益
							if (!goodsDonSku.getIsBenefits()) {
								rate = goodsDon.getSecondRate();
							}
						}
					}
					//该平台是否开启规格分销
					if (goodsDon.getIsSkuDistribute()) {
						//是否设置对应规格分销比例
						DistributeGeneralSkuRate skuRate = distributeGeneralSkuRateMapper.selectOne(Wrappers.lambdaQuery(DistributeGeneralSkuRate.class)
								.eq(DistributeGeneralSkuRate::getSkuId, goodsDonSku.getId()).last("limit 1"));
						if (skuRate != null) rate = skuRate.getRate();
					}
					//特定普通渠道 所有平台比例改成10%
					if (ObjectUtil.equal(userDistributeShared.getSharedId(), Constant.SPECIAL_DISTRIBUTE_USER_ID) && rate > 0) {
						rate = 10;
					}
					returnMoney = orderMoney.multiply(BigDecimal.valueOf(rate)).divide(BigDecimal.valueOf(100));
				} else {
					businessId = userDistribute.getBusinessId();
					UserPlatDistributeRate userPlatDistributeRate = null;
					Integer secondRate = 0;
					//该商品是否开启了 规格分销
					if (goodsDon.getIsSkuDistribute()) {
						//规格分销 比例
						UserPlatSkuDistributeRate userPlatSkuDistributeRate = userPlatSkuDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatSkuDistributeRate.class)
								.eq(UserPlatSkuDistributeRate::getDistributeId, userDistribute.getId())
								.eq(UserPlatSkuDistributeRate::getSkuId, order.getSkuId()).last("limit 1"));
						if (userPlatSkuDistributeRate != null) {
							userPlatDistributeRate = getUserPlatDistributeRate(userPlatSkuDistributeRate.getRate(), userPlatSkuDistributeRate.getSecondRate());
						}
					}
					if (userPlatDistributeRate == null) {
						//默认规格分销比例
						if (goodsDon.getIsSkuDistribute()) {
							BusinessDistributeDefaultSkuRateConfig businessDistributeDefaultSkuRateConfig = businessDistributeDefaultSkuRateConfigMapper.selectOne(Wrappers.lambdaQuery(BusinessDistributeDefaultSkuRateConfig.class)
									.eq(BusinessDistributeDefaultSkuRateConfig::getSkuId, order.getSkuId())
									.last("limit 1"));
							if (businessDistributeDefaultSkuRateConfig != null) {
								userPlatDistributeRate = getUserPlatDistributeRate(businessDistributeDefaultSkuRateConfig.getRate(), businessDistributeDefaultSkuRateConfig.getSecondRate());
							}
						}
					}
					if (userPlatDistributeRate == null) {
						//固定推广分销 平台比例
						userPlatDistributeRate = userPlatDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatDistributeRate.class)
								.eq(UserPlatDistributeRate::getGoodsId, order.getGoodsId())
								.eq(UserPlatDistributeRate::getDistributeId, userDistribute.getId())
								.last("limit 1"));
					}
					//未配置平台分销比例 寻找默认比例
					if (userPlatDistributeRate == null) {
						BusinessDistributeDefaultRateConfig defaultRateConfig = businessDistributeDefaultRateConfigMapper.selectOne(Wrappers.lambdaQuery(BusinessDistributeDefaultRateConfig.class)
								.eq(BusinessDistributeDefaultRateConfig::getGoodsId, order.getGoodsId())
								.last("limit 1"));
						if (defaultRateConfig != null) {
							userPlatDistributeRate = getUserPlatDistributeRate(defaultRateConfig.getRate(), defaultRateConfig.getSecondRate());
						}
					}
					if (userPlatDistributeRate != null) {
						rate = userPlatDistributeRate.getRate();
						secondRate = userPlatDistributeRate.getSecondRate();
						if (goodsDon.getType() == 2) {
							goodsDonSku = goodsDonSkuMapper.selectById(order.getSkuId());
							if (goodsDonSku != null) {
								//不包含套餐权益
								if (!goodsDonSku.getIsBenefits()) {
									rate = secondRate;
								}
							}
							distributeWaitingSendPoints.setIsDelivery(false);
						}
						returnMoney = orderMoney.multiply(BigDecimal.valueOf(rate)).divide(BigDecimal.valueOf(100));
					}
				}
				if (returnMoney != null) {
					BigDecimal returnPoints = returnMoney.multiply(BigDecimal.valueOf(distributePointsExchangeMoney.getPoints())).divide(distributePointsExchangeMoney.getMoney(), 2, RoundingMode.HALF_DOWN);
					points = returnPoints;
				}
				if (userDistribute != null) {
					UserDistributeEquipment userDistributeEquipment = null;
					if (goodsDon.getType() == 2) {
						userDistributeEquipment = userDistributeEquipmentMapper.selectOne(Wrappers.lambdaQuery(UserDistributeEquipment.class)
								.eq(UserDistributeEquipment::getUserId, userDistribute.getUserId()).last("limit 1"));
					}
					//是否特殊渠道设备分销用户
					if (userDistributeEquipment != null) {
						BigDecimal takeMoney = handlerEquipmentDistribute(order, goodsDonSku, userDistributeEquipment);
						points = takeMoney.multiply(BigDecimal.valueOf(distributePointsExchangeMoney.getPoints())).divide(distributePointsExchangeMoney.getMoney(), 2, RoundingMode.HALF_DOWN);
						distributeWaitingSendPoints.setIsSpecialEp(true);
					} else {
						//处理渠道规则分销
						points = handlerDistributeRule(order, distributeWaitingSendPoints, userDistribute.getId(), distributePointsExchangeMoney, points);
					}
				}

				distributeWaitingSendPoints.setPoints(points);
				if (points != null && points.compareTo(BigDecimal.ZERO) > 0) {
					log.info("用户{}邀请{},产生分销订单分发积分记录入库", userDistributeShared.getSharedId(), order.getUserId());
					distributeWaitingSendPoints.setSendStatus(DistributeWaitingSendPoints.Status.waiting);
					distributeWaitingSendPoints.setSendTime(DateUtil.offsetDay(order.getPayTime(), 3));
					distributeWaitingSendPoints.setRate(rate);
					//普通分销 额外返利
					if (userDistribute == null && points.compareTo(BigDecimal.ZERO) > 0) {
						distributeWaitingSendPoints.setOriPoints(points);
						if (goodsDonSku == null) {
							goodsDonSku = goodsDonSkuMapper.selectById(order.getSkuId());
						}
						if (goodsDonSku.getIsMirror()) {
							//镜像规格 默认百分之20 提成
							distributeWaitingSendPoints.setRate(20);
							//最新返利积分
							BigDecimal newReturnMoney = orderMoney.multiply(BigDecimal.valueOf(distributeWaitingSendPoints.getRate())).divide(BigDecimal.valueOf(100));
							points = newReturnMoney.multiply(BigDecimal.valueOf(distributePointsExchangeMoney.getPoints())).divide(distributePointsExchangeMoney.getMoney(), 2, RoundingMode.HALF_DOWN);
							distributeWaitingSendPoints.setPoints(points);
						} else {
							//额外返利 去除
//							DistributeExtraRebateConfig distributeExtraRebateConfig = distributeExtraRebateService.getRandomExtraRebate();
//							if (distributeExtraRebateConfig != null) {
//								BigDecimal multiple = distributeExtraRebateConfig.getMultiple();
//								if (multiple.compareTo(BigDecimal.ONE) > 0) {
//									//最终奖励
//									BigDecimal finalPoints = points.multiply(multiple);
//									distributeWaitingSendPoints.setPoints(finalPoints);
//
//									distributeWaitingSendPoints.setExtraMultiple(multiple);
//									distributeWaitingSendPoints.setExtraRebate(finalPoints.subtract(points));
//								}
//							}
						}
					}
					try {
						distributeWaitingSendPointsMapper.insert(distributeWaitingSendPoints);
						//暂定虚物 商务可首单提成
						//普通订单
						if (order.getOrderType() == 1 && businessId != null) {
							//是否是绑定两个月内的渠道
							Date businessBindTime = userDistribute.getBusinessBindTime();
							if (businessBindTime != null && businessBindTime.after(DateUtil.offsetMonth(DateTime.now(), -2))) {
								//给商务人员 分配提成权益
								userBusinessFrontService.taskDistributeRateBenefits(userDistributeShared.getSharedId(), businessId, goodsDon.getType(), order, rate);
							}
						}
						//是否是cc普通推广
						//并且购买claude code作为首单
						if (userDistribute == null && Constant.CC_DISTRIBUTE_MARK.equals(userDistributeShared.getRemark()) && order.getGoodsId() == Constant.CLAUDE_CODE_GOODS_ID) {
							//普通推广用户首单，给上级渠道发放 claude code 积分卡
							try {
								claudeCodeService.adjUserRestNum(order.getId(), userDistributeShared.getSharedId(), 1, "新用户下单");
								log.info("用户{}邀请新用户{}首单，发放claude code积分卡成功", userDistributeShared.getSharedId(), order.getUserId());
							} catch (Exception e) {
								log.error("给用户{}发放claude code积分卡失败：{}", userDistributeShared.getSharedId(), e.getMessage());
							}
						}
					} catch (DuplicateKeyException e) {

					}
				}
			}
		}
	}

	public CouponPopularizeDto checkCouponStatus(Long skuId, String couponExCode, Long couponId, Long userId, Boolean isRenew) throws Exception {
		log.info("开始校验兑换码:{},优惠券id:{}状态", couponExCode, couponId);
		//实物还是虚物商品
		GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(skuId);
		GoodsDon goodsDon = goodsDonMapper.selectById(goodsDonSku.getGoodsId());
		if (StrUtil.isNotBlank(couponExCode) && couponId != null) {
			throw BusinessRuntimeException.getInstance("优惠券与优惠码不可同时使用..");
		}
		if (StrUtil.isNotBlank(couponExCode)) {
			CouponPopularizeDto exists = couponMapper.checkExCode(couponExCode);
			if (exists == null) {
				throw BusinessRuntimeException.getInstance("该优惠码不存在");
			}
			//推广码
			if (exists.getIsGeneral() != null) {
				if (exists.getIsGeneral() && userId.equals(exists.getUserId())) {
					throw BusinessRuntimeException.getInstance("不可以使用自己的优惠码");
				}
				if (!exists.getIsGeneral()) {
					UserDistribute userDistribute = userDistributeMapper.selectById(exists.getDistributeId());
					if (userDistribute != null && userDistribute.getUserId().equals(userId)) {
						throw BusinessRuntimeException.getInstance("不可以使用自己的优惠码");
					}
				}
				//是否有上下级关系
				if (exists.getIsGeneral()) {
					UserDistributeShared userDistributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class)
							.eq(UserDistributeShared::getUserId, userId).last("limit 1"));
					if (userDistributeShared == null) {
						//是否是 当天注册新用户 且下过单
						User user = userMapper.selectById(userId);
						if (user.getCreatedTime().before(DateUtil.beginOfDay(DateTime.now()))) {
							throw BusinessRuntimeException.getInstance("该优惠码只适用于新用户");
						}
						CouponNewUserView couponNewUserView = beanSearcher.searchFirst(CouponNewUserView.class, MapUtils.builder().field(CouponNewUserView::getUserId, userId).op(Operator.Equal).build());
						if (couponNewUserView != null)
							throw BusinessRuntimeException.getInstance("该优惠码只适用于新用户");
					}
					if (userDistributeShared != null && !userDistributeShared.getSharedId().equals(exists.getUserId())) {
						throw BusinessRuntimeException.getInstance("您已有推广,无法使用其他人推广码");
					}
				}
			}
			checkCouponGoods(goodsDon, skuId, exists.getCouponId(), true);
			//检验是优惠券使用范围
			if (isRenew && exists.getUseScope() == Coupon.UseScope.orders) {
				throw BusinessRuntimeException.getInstance("该优惠码续费时不可使用");
			}
			if (!isRenew && exists.getUseScope() == Coupon.UseScope.renew) {
				throw BusinessRuntimeException.getInstance("该优惠码下单时不可使用");
			}
			if (exists.getScope() == Coupon.Scope.newUser) {
				CouponNewUserView couponNewUserView = beanSearcher.searchFirst(CouponNewUserView.class, MapUtils.builder().field(CouponNewUserView::getUserId, userId).op(Operator.Equal).build());
				if (couponNewUserView != null) {
					throw BusinessRuntimeException.getInstance("该新用户优惠码有且仅可使用一次");
				}
			}
			if (exists.getIsValidTime() && exists.getValidEndTime().before(DateTime.now())) {
				throw BusinessRuntimeException.getInstance("该优惠码已失效");
			}
			if (exists.getIsValidTime() && exists.getValidStartTime().after(DateTime.now())) {
				throw BusinessRuntimeException.getInstance("该优惠码待生效");
			}
			return exists;
		} else if (couponId != null) {
			CouponUserView couponUserView = beanSearcher.searchFirst(CouponUserView.class, MapUtils.builder()
					.field(CouponUserView::getCouponId, couponId).op(Operator.Equal)
					.field(CouponUserView::getUserId, userId).op(Operator.Equal)
					.build());
			if (couponUserView == null) {
				throw BusinessRuntimeException.getInstance("该优惠券不存在");
			}
			if (couponUserView.getCouponUserStatus() == CouponUser.Status.used) {
				throw BusinessRuntimeException.getInstance("该优惠券已使用");
			}
			couponFontService.setCouponUserStatus(couponUserView, DateTime.now());
			if (couponUserView.getCouponUserStatus() != CouponUser.Status.unused) {
				throw BusinessRuntimeException.getInstance(couponUserView.getReason());
			}
			checkCouponGoods(goodsDon, skuId, couponUserView.getCouponId(), false);
			//检验是优惠券使用范围
			if (isRenew && couponUserView.getUseScope() == Coupon.UseScope.orders) {
				throw BusinessRuntimeException.getInstance("该优惠券续费时不可使用");
			}
			if (!isRenew && couponUserView.getUseScope() == Coupon.UseScope.renew) {
				throw BusinessRuntimeException.getInstance("该优惠券下单时不可使用");
			}
		}
		return null;
	}

	private CouponUser couponStatusRecord(String couponExCode, Long couponId, Long userId, CouponPopularizeDto exists) {
		log.info("兑换码:{},优惠券id:{},更新其优惠券状态", couponExCode, couponId);
		CouponUser couponUser = null;
		if (StrUtil.isNotBlank(couponExCode)) {
			if (exists == null) {
				throw BusinessRuntimeException.getInstance("该优惠码不存在");
			}
			couponUser = new CouponUser();
			couponUser.setCouponId(exists.getCouponId());
			if (exists.getPopularizeId() != null) {
				couponUser.setCouponId(exists.getPopularizeCouponId());
				couponUser.setPopularizeId(exists.getPopularizeId());
			}
			//续费优惠码可重复使用
			if (exists.getUseScope() != Coupon.UseScope.renew) {
				//非渠道推广 推广优惠码只可使用一次
				if ((exists.getPopularizeId() != null && exists.getIsGeneral()) || exists.getPopularizeId() == null) {
					CouponUser received = couponUserMapper.selectOne(Wrappers.lambdaQuery(CouponUser.class).eq(CouponUser::getUserId, userId).eq(CouponUser::getCouponId, couponUser.getCouponId()).last("limit 1"));
					if (received != null && received.getStatus() != CouponUser.Status.unused) {
						throw BusinessRuntimeException.getInstance("您已使用该优惠码所对应的优惠券");
					}
					couponUser.setUserId(userId);
					couponUser.setStatus(CouponUser.Status.used);
					couponUser.setChannel(CouponUser.Channel.exCode);
					couponFontService.updateCouponUserValidTime(couponUser.getCouponId(), couponUser);
					try {
						couponUserMapper.insert(couponUser);
					} catch (DuplicateKeyException e) {
						log.info("用户已领取该{}优惠券", couponUser.getCouponId());
						throw BusinessRuntimeException.getInstance("您已领取该优惠码对应的优惠券,请使用优惠券");
					}
				}
			}
		} else {
			couponUser = couponUserMapper.selectOne(Wrappers.lambdaQuery(CouponUser.class).eq(CouponUser::getUserId, userId).eq(CouponUser::getCouponId, couponId).last("limit 1"));
			if (couponUser == null) {
				throw BusinessRuntimeException.getInstance("该优惠券不存在");
			}
			couponUser.setStatus(CouponUser.Status.used);
			couponUserMapper.updateById(couponUser);
		}
		return couponUser;
	}

	public void checkCouponGoods(GoodsDon goodsDon, Long skuId, Long couponId, Boolean isCouponCode) throws Exception {
		if (goodsDon.getType() == 1) {
			CouponSku couponSku = couponSkuMapper.selectOne(Wrappers.lambdaQuery(CouponSku.class)
					.eq(CouponSku::getSkuId, skuId)
					.eq(CouponSku::getCouponId, couponId)
					.select(CouponSku::getId).last("limit 1"));
			if (couponSku == null) {
				throw BusinessRuntimeException.getInstance(String.format("该%s不适用于该规格", isCouponCode ? "优惠码" : "优惠券"));
			}
		} else {
			//实物、潮玩 优惠码优惠券 针对平台
			Long gid = goodsDon.getId();
			CouponSku couponSku = couponSkuMapper.selectOne(Wrappers.lambdaQuery(CouponSku.class)
					.eq(CouponSku::getGoodsId, gid)
					.eq(CouponSku::getCouponId, couponId)
					.select(CouponSku::getId).last("limit 1"));
			if (couponSku == null) {
				throw BusinessRuntimeException.getInstance(String.format("该%s不可用于该商品", isCouponCode ? "优惠码" : "优惠券"));
			}
		}
	}

	/**
	 * 校验是否还有多余的车位
	 */
	private void checkNoGroupsTripsAndSendMsg(GoodsDonSku sku, OrderDon order) {
		GroupsTrips groups = groupsMapper.selectOne(Wrappers.lambdaQuery(GroupsTrips.class)
				.eq(GroupsTrips::getSkuId, sku.getId())
				.gt(GroupsTrips::getAvailableNum, 0).last("limit 1")
				.ne(GroupsTrips::getStatus, GroupsTrips.Status.down)
				.orderByAsc(GroupsTrips::getAvailableNum));
		if (groups == null) {
			//新增空车队发送模板消息
			TASK_POOL.execute(() -> {
				groupsFuncService.createNewGroupsTrips(sku);
			});
		}
	}

	public void handleServiceRenewOrder(OrderDon orderDon) {
		//续费订单
		if (orderDon.getOrderType() == 2) {
			Long relationId = orderDon.getRelationId();
			GroupsRelation relation = groupsRelationMapper.selectById(relationId);
			if (StrUtil.isNotBlank(relation.getCustomerService())) {
				//记录客服续费订单业绩
				CustomerServiceRenewOrderRecord renewOrderRecord = new CustomerServiceRenewOrderRecord();
				renewOrderRecord.setUserId(orderDon.getUserId());
				renewOrderRecord.setOrderId(orderDon.getId());
				renewOrderRecord.setCustomerService(relation.getCustomerService());
				customerServiceRenewOrderRecordMapper.insert(renewOrderRecord);

				groupsRelationMapper.updateCustomerService(relation.getId());
			}
		}
	}

	/**
	 * 使用推广者的优惠码增加上下级
	 */
	private void addDistributeCouponCode(Long userId, String couponExCode) {
		UserDistributeShared userDistributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class)
				.eq(UserDistributeShared::getUserId, userId).last("limit 1"));
		if (userDistributeShared == null) {
			CouponDistributePopularize couponDistributePopularize = couponDistributePopularizeMapper.selectOne(Wrappers.lambdaQuery(CouponDistributePopularize.class).eq(CouponDistributePopularize::getExCode, couponExCode).eq(CouponDistributePopularize::getDeleted, 1).last("limit 1"));
			Optional.ofNullable(couponDistributePopularize).ifPresent(popularize -> {
				try {
					Long sharedId;
					//是否是普通推广专属关联
					if (popularize.getIsGeneral()) {
						sharedId = popularize.getUserId();
					} else {
						UserDistribute userDistribute = userDistributeMapper.selectById(popularize.getDistributeId());
						if (userDistribute == null || !userDistribute.getDeleted()) {
							return;
						}
						sharedId = userDistribute.getUserId();
					}
					if (sharedId.equals(userId)) {
						return;
					}
					UserDistributeShared ud = new UserDistributeShared();
					ud.setUserId(userId);
					ud.setSharedId(sharedId);
					ud.setRemark("优惠码");
					userDistributeSharedMapper.insert(ud);
					log.info("userId:{}使用优惠码:{}与推广用户sharedId:{}建立关系", userId, couponExCode, sharedId);
				} catch (DuplicateKeyException e) {

				}
			});
		}
	}

	/**
	 * @param orderDon 续费订单
	 * @param afterSku 续费之后的规格
	 */
	private void changeTicketAndRecord(OrderDon orderDon, GoodsDonSku afterSku) {
		Long preSkuId = orderDon.getSkuId();
		Long preRelationId = orderDon.getRelationId();
		Long orderId = orderDon.getId();
		Integer num = orderDon.getNum();
		Long userId = orderDon.getUserId();
		//清理之前的车票
		GroupsRelation relation = groupsRelationMapper.selectById(preRelationId);
		if (relation != null) {
			//记录更换车票记录
			Date preStartTime = relation.getStartTime();
			Date preExpiryTime = relation.getExpiryTime();

			groupRelationClearService.clearRenewGroupRelation(relation);
			//获取续费规格的车票
			GroupsRelation afterRelation = exchangeCodeService.getRelationNoOrder(afterSku, userId, orderDon.getYhsId());

			DateTime afterExpiryTime = DateUtil.offsetMonth(preExpiryTime, num * afterSku.getMonths());

			afterRelation.setStartTime(preStartTime);
			afterRelation.setExpiryTime(afterExpiryTime);
			groupsRelationMapper.updateById(afterRelation);

			//更新订单对应的relation_id
			orderDon.setRelationId(afterRelation.getId());
			orderDonMapper.updateById(orderDon);

			//保存更换车票记录
			saveChangeTicketRecord(preStartTime, preExpiryTime, preRelationId, userId, preSkuId, orderId, num, afterSku, afterRelation.getId());

			GroupsRelationView groupsRelationView = groupsRelationMapper.getGroupRelationViewByUserIdAndRelationId(userId, afterRelation.getId());

			try {
				//发放更换车票模板消息通知用户
				log.info("发送更换用户:{}车票:{}通知消息start=====>", userId, groupsRelationView.getId());
				templateCommonService.sendUpdateAccountMsgNotify(groupsRelationView);
				log.info("发送更换用户车票通知消息end=====>");
			} catch (Exception e) {
				log.error("发送更换用户:{}车票:{}通知消息错误e:{}", userId, groupsRelationView.getId(), StringUtil.getErrorText(e));
			}
		} else {
			//之前的车票已被清除  加续费时间加到新的车票上
			GroupsRelationView relationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getUserId, userId)
					.field(GroupsRelationView::getGoodsId, afterSku.getGoodsId()).build());
			Date preStartTime = relation.getStartTime();
			Date preExpiryTime = relation.getExpiryTime();
			DateTime afterExpiryTime = DateUtil.offsetMonth(relationView.getExpiryTime(), num * afterSku.getMonths());

			log.info("用户:{}重复续费,将过期时间累加到新车票:{}上", userId, relationView.getId());
			relationView.setExpiryTime(afterExpiryTime);
			groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
					.set(GroupsRelation::getExpiryTime, relationView.getExpiryTime())
					.eq(GroupsRelation::getId, relationView.getId()));

			//更新订单对应的relation_id
			orderDon.setRelationId(relationView.getId());
			orderDonMapper.updateById(orderDon);

			//保存更换车票记录
			saveChangeTicketRecord(preStartTime, preExpiryTime, relationView.getId(), userId, preSkuId, orderId, num, afterSku, relationView.getId());
		}
	}

	/**
	 * @param preStartTime    续费之前的开始时间
	 * @param preExpiryTime   续费之前的过期时间
	 * @param preRelationId   之前的座位id
	 * @param userId          用户id
	 * @param preSkuId        之前座位的规格id
	 * @param orderId         订单id
	 * @param num             订单数量
	 * @param afterSku        续费之后的规格id
	 * @param afterRelationId 续费之后的座位id
	 */
	public void saveChangeTicketRecord(Date preStartTime, Date preExpiryTime, Long preRelationId, Long userId, Long preSkuId, Long orderId, Integer num, GoodsDonSku afterSku, Long afterRelationId) {
		Long afterSkuId = afterSku.getId();
		//记录更换车票记录
		UserRenewChangeTicketRecord record = new UserRenewChangeTicketRecord();
		record.setUserId(userId);
		record.setPreRelationId(preRelationId);
		record.setPreSkuId(preSkuId);
		record.setPreStartTime(preStartTime);
		record.setPreExpiryTime(preExpiryTime);
		record.setRenewOrderId(orderId);

		record.setAfterSkuId(afterSkuId);
		record.setAfterRelationId(afterRelationId);
		DateTime afterExpiryTime = DateUtil.offsetMonth(preExpiryTime, num * afterSku.getMonths());
		record.setAfterExpiryTime(afterExpiryTime);

		userRenewChangeTicketRecordMapper.insert(record);
	}

	/**
	 * 查询第三放接口订单是否已支付
	 */
	public OrderDon.Status isHasPaid(OrderDon orderDon) {
		GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
		if (orderDon.getType() == OrderDon.Type.WeChat) {
			try {
				Map<String, String> reMap = weChatService.getWxOrderDetail(orderDon.getShopId(), orderDon.getOrderNo());
				if (reMap != null) {
					String orderStatus = reMap.get("trade_state");
					if ("SUCCESS".equals(orderStatus)) {
						orderDon.setStatus(goodsDon.getType() == 1 && goodsDon.getSecondType() == 2 ? OrderDon.Status.complete : OrderDon.Status.hasPayment);
						orderDon.setTransactionId(reMap.get("transaction_id"));
						return updateNoPayment(orderDon, goodsDon);
					}
				}
			} catch (Exception e) {

			}
		} else if (orderDon.getType() == OrderDon.Type.ALI_PAY) {
			try {
				AlipayTradeQueryResponse zfbOrderDetail = getZfbOrderDetail(orderDon.getShopId(), orderDon.getOrderNo());
				if (zfbOrderDetail != null) {
					String tradeStatus = zfbOrderDetail.getTradeStatus();
					if ("TRADE_SUCCESS".equals(tradeStatus)) {
						orderDon.setStatus(goodsDon.getType() == 1 && goodsDon.getSecondType() == 2 ? OrderDon.Status.complete : OrderDon.Status.hasPayment);
						orderDon.setTransactionId(zfbOrderDetail.getTradeNo());
						Date sendPayDate = zfbOrderDetail.getSendPayDate();
						orderDon.setPayTime(sendPayDate);
						//买家支付宝账号
						String buyerId = Optional.ofNullable(zfbOrderDetail.getBuyerUserId()).orElse(zfbOrderDetail.getBuyerOpenId());
						orderDon.setBuyerId(buyerId);
						return updateNoPayment(orderDon, goodsDon);
					}
				}
			} catch (Exception e) {

			}
		}
		return orderDon.getStatus();
	}

	private OrderDon.Status updateNoPayment(OrderDon orderDon, GoodsDon goodsDon) {
		GoodsDonSku sku = null;
		if (orderDon.getSkuId() != null) {
			sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
		}
		unifiedHandlerOrderNotify(orderDon, goodsDon, sku);
		return orderDon.getStatus();
	}

	public void checkIsSameUser(Long relationUserId, User renewUser) {
		List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(renewUser.getId(), renewUser);
		if (!relationUserIdList.contains(relationUserId)) {
			throw BusinessRuntimeException.getInstance("");
		}
	}

	/**
	 * 购买Midjourney课程 赠送车票
	 */
	private void sendMidjourneyTicketIfCourse(Long userId) {
		SysConfig config = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
				.eq(SysConfig::getSysKey, Constant.MIDJOURNEY_TICKET_SKU_IDS).last("limit 1"));
		if (config != null) {
			String sysValue = config.getSysValue();
			if (StrUtil.isNotBlank(sysValue)) {
				try {
					//Midjourney车票、ChatGPT独立规格车票
					List<Long> skuIds = Jsons.parseList(sysValue, Long.class);
					skuIds.forEach(skuId -> {
						GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
						if (sku != null && sku.getStatus()) {
							GroupsRelation relation = exchangeCodeService.getRelationNoOrder(sku, userId, null);
							if (relation.getExpiryTime() == null || relation.getStartTime() == null) {
								DateTime now = DateTime.now();
								relation.setStartTime(now);
								relation.setExpiryTime(DateUtil.offsetMonth(now, sku.getMonths() * 1));
								groupsRelationMapper.updateById(relation);
							}
						}
					});
				} catch (Exception e) {
					log.error("购买midJourney课程赠送车票错误,errMsg:{}", StringUtil.getErrorText(e));
				}
			}
		}
	}

	/**
	 * chatGPT Plus账号购买限购校验
	 */
	public void checkChatGPTPlusPurchaseLimit(Long userId, Long goodsId, String title, Long skuId, String specVal) {
		if (goodsId == 18 || goodsId == 26) {
			SysConfig sysConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
					.eq(SysConfig::getSysKey, Constant.CHAT_GPT_PLUS_SKU_PURCHASE_LIMIT).last("limit 1"));
			if (sysConfig != null) {
				String sysValue = sysConfig.getSysValue();
				if (StrUtil.isNotBlank(sysValue)) {
					List<ChatGPTPlusPurchaseLimitDto> chatGPTPlusPurchaseLimitDtos = null;
					try {
						chatGPTPlusPurchaseLimitDtos = Jsons.parseList(sysValue, ChatGPTPlusPurchaseLimitDto.class);
					} catch (Exception e) {
						log.info("ChatGPT Plus限购配置错误");
						return;
					}
					if (CollUtil.isNotEmpty(chatGPTPlusPurchaseLimitDtos)) {
						for (ChatGPTPlusPurchaseLimitDto chatGPTPlusPurchaseLimitDto : chatGPTPlusPurchaseLimitDtos) {
							Long limitSkuId = chatGPTPlusPurchaseLimitDto.getSkuId();
							Integer time = chatGPTPlusPurchaseLimitDto.getTime();
							Integer days = chatGPTPlusPurchaseLimitDto.getDays();
							if (limitSkuId != null && skuId.equals(limitSkuId)) {
								//半个月内是否购买过1单 chatGPT Plus
								Integer count = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
										.eq(OrderDon::getUserId, userId)
										.eq(OrderDon::getSkuId, skuId)
										.gt(OrderDon::getCreatedTime, DateUtil.offsetDay(DateTime.now(), -days))
										.notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
								if (count > time - 1)
									throw BusinessRuntimeException.getInstance(String.format("%s天内只能购买%s次%s %s规格账号", days, time, title, specVal.replaceAll(";", "")));
								break;
							}
						}
					}
				}
			}
		}
	}

	/**
	 * 获取车位
	 * yshId 店铺id
	 */
	public GroupsRelation getRelation(OrderPayRequest payRequest, GoodsDonSku sku, Long yhsId) {
		Long payRelationId = payRequest.getRelationId();
		Long userId = payRequest.getUserId();
		String ip = null;
		//MJ车票统一ip不允许上同一车次
		if (sku.getGoodsId() == 26) {
			//去除限制
			ip = null;
		}
		//获取车票车位
		GroupsRelation relation = groupRelationFrontService.getRelation(payRelationId, userId, sku, ip);

		//锁定座位
		setRelation(relation);
		//校验座位
		int update = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
				.set(GroupsRelation::getUserId, userId)
				.eq(GroupsRelation::getUserId, 0)
				.eq(GroupsRelation::getId, relation.getId()));
		if (update == 0) {
			throw BusinessRuntimeException.getInstance("系统繁忙，请重试");
		}
		relation.setUserId(userId);
		//重新置为锁定
		relation.setStatus(GroupsRelation.Status.locking);
		relation.setYhsId(yhsId);
		groupsRelationMapper.updateById(relation);

		Long skuId = sku.getId();
		Long groupsId = relation.getGroupsId();
		//校验指定平台规格的 目前车队的可停车位数
		groupRelationFrontService.checkGroupsAvailParkingNum(skuId, groupsId, relation.getGroupsAvailParkingNum(), relation.getMaxNum());
		return relation;
	}

	/**
	 * 使用优惠营销 订单金额抵扣
	 */
	public void deductOrderMoney(OrderDon orderDon, CouponUser couponUser, BigDecimal balance, User user, BigDecimal skuMoney, GoodsDon goodsDon, BigDecimal gcCash, List<Long> gcpIds, Boolean isAcReduce, Long subsidyId, GoodsDonSku sku, BigDecimal galaxyCoin) throws Exception {
		Integer goodsType = goodsDon.getType();
		if (gcCash != null && gcCash.compareTo(BigDecimal.ZERO) > 0 && couponUser != null && (balance != null && balance.compareTo(BigDecimal.ZERO) > 0)) {
			throw BusinessRuntimeException.getInstance("现金卡不能与其他优惠叠加使用");
		}
		BigDecimal first_money = orderDon.getMoney();
		//礼品卡现金支付 不参与其他优惠
		if (subsidyId == null && gcCash != null && gcCash.compareTo(BigDecimal.ZERO) > 0) {
			List<Long> userIdList = userBindRelationService.getRelationUserIdList(user.getId(), user);
			if (CollUtil.isEmpty(gcpIds)) {
				throw BusinessRuntimeException.getInstance("礼品卡现金支付参数异常");
			}
			BigDecimal money = orderDon.getMoney();
			if (gcCash.compareTo(money) > 0) {
				gcCash = money;
			}
			List<GiftCardUserRecord> availableGiftCards = giftCardUserRecordService.list(Wrappers.lambdaQuery(GiftCardUserRecord.class)
					.in(GiftCardUserRecord::getToUserId, userIdList)
					.in(GiftCardUserRecord::getId, gcpIds)
					.eq(GiftCardUserRecord::getIsPay, true)
					.eq(GiftCardUserRecord::getGcType, 1)
					.gt(GiftCardUserRecord::getRemainCash, 0));
			if (availableGiftCards.size() != gcpIds.size()) {
				throw BusinessRuntimeException.getInstance("礼品卡使用异常,请刷新页面重试");
			}
			//需要扣除的礼品卡现金
			BigDecimal deductCash = gcCash;
			List<GiftCardOrderUseRecord> gcUseRecords = new ArrayList<>();
			for (GiftCardUserRecord giftCard : availableGiftCards) {
				if (deductCash.compareTo(BigDecimal.ZERO) <= 0) {
					break;
				}
				BigDecimal remainCash = giftCard.getRemainCash();
				//扣完
				if (remainCash.compareTo(deductCash) == 0) {
					deductGiftCardCash(user.getId(), giftCard.getId(), deductCash, remainCash, gcUseRecords, true);
					deductCash = BigDecimal.ZERO;
				} else if (remainCash.compareTo(deductCash) < 0) {
					deductGiftCardCash(user.getId(), giftCard.getId(), remainCash, remainCash, gcUseRecords, true);
					deductCash = deductCash.subtract(remainCash);
				} else if (remainCash.compareTo(deductCash) > 0) {
					deductGiftCardCash(user.getId(), giftCard.getId(), deductCash, remainCash, gcUseRecords, false);
					deductCash = BigDecimal.ZERO;
				}
			}
			orderDon.setMoney(orderDon.getMoney().subtract(gcCash));
			orderDon.setGcCash(gcCash);
			if (!gcUseRecords.isEmpty()) {
				orderDon.setGcUseRecords(gcUseRecords);
			}
			return;
		}
		//针对设备 满减活动优惠 不支持使用优惠券等优惠
		if (isAcReduce != null && isAcReduce && orderDon.getGoodsId() == 15) {
			epOrderDonActivityReduce(orderDon);
			//存在余额
			deductBalancePayOrderMoney(orderDon, balance, user);
			return;
		}
		//存在优惠券
		if (couponUser != null && subsidyId == null) {
			Long couponId = couponUser.getCouponId();
			Coupon coupon = couponMapper.getCouponById(couponId);
			BigDecimal couponMoney = null;
			BigDecimal payMoney = orderDon.getMoney();
			BigDecimal needDeductMoney = payMoney;
			if (orderDon.getOriMoney() == null) {
				orderDon.setOriMoney(payMoney);
			}
			if (orderDon.getIsDp() != null && orderDon.getIsDp()) {
				needDeductMoney = needDeductMoney.subtract(orderDon.getDpMoney());
			}
			if (coupon.getType() == Coupon.Type.discount) {
				couponMoney = needDeductMoney.multiply(BigDecimal.valueOf(1).subtract(coupon.getDiscount()));
				//需支付金额
				orderDon.setMoney(payMoney.subtract(couponMoney));

				orderDon.setOriMoney(orderDon.getOriMoney().multiply(coupon.getDiscount()));
				//记录折扣 用于分销
				couponUser.setDiscount(coupon.getDiscount());
				couponUserMapper.updateById(couponUser);
			} else if (coupon.getType() == Coupon.Type.reduce) {
				if (goodsType == 2) {
					if (skuMoney.compareTo(coupon.getReduceCondition()) < 0) {
						throw BusinessRuntimeException.getInstance(String.format("满%s可用", coupon.getReduceCondition().divide(BigDecimal.valueOf(100))));
					}
				}
				BigDecimal subtractMoney = payMoney.subtract(coupon.getReduceMoney());
				orderDon.setMoney(subtractMoney);
				couponMoney = coupon.getReduceMoney();

				orderDon.setOriMoney(orderDon.getOriMoney().subtract(coupon.getReduceMoney()));
			}
			if (couponMoney != null && couponMoney.compareTo(first_money) >= 0) {
				throw BusinessRuntimeException.getInstance("支付金额不能小于优惠金额");
			}
			orderDon.setCouponMoney(couponMoney);
			orderDon.setCouponUserId(couponUser.getId());
			orderDon.setCouponId(couponUser.getCouponId());
		}
		//特殊渠道推广优惠. 360
		if (subsidyId == null && orderDon.getPopularizeId() != null && orderDon.getPopularizeId() != 0L) {
			String name = channelPopularizeMapper.selectChannelByPid(orderDon.getPopularizeId());
			if (StrUtil.isNotBlank(name)) {
				//使用了优惠券 不再使用360渠道 折扣
				if (couponUser == null && goodsType == 1) {
					if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0)) || name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(1))) {
						String key;
						if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0))) {
							//百度渠道 专门优惠链接
							key = Constant.CHANNEL_BAIDU_DISCOUNT_KEY;
						} else {
							//抖音
							key = Constant.CHANNEL_DY_DISCOUNT_KEY;
						}
						SysConfig channelNoSignConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
								.eq(SysConfig::getSysKey, key).last("limit 1"));
						if (channelNoSignConfig != null) {
							String sysValue = channelNoSignConfig.getSysValue();
							if (StrUtil.isNotBlank(sysValue)) {
								try {
									ChannelBaiDuDiscountDto baiDuDiscountDto = Jsons.parseObject(sysValue, ChannelBaiDuDiscountDto.class);
									List<Long> baiduPopularizeIds = baiDuDiscountDto.getPopularizeIds();
									BigDecimal discount = baiDuDiscountDto.getDiscount();
									if (CollUtil.isNotEmpty(baiduPopularizeIds) && discount != null && discount.compareTo(BigDecimal.ZERO) > 0) {
										if (baiduPopularizeIds.contains(orderDon.getPopularizeId())) {
											BigDecimal discountMoney = orderDon.getMoney().multiply(discount);
											orderDon.setMoney(discountMoney);
										}
									}
								} catch (Exception e) {
								}
							}
						}
					} else {
						SysConfig discountPopularizeConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
								.eq(SysConfig::getSysKey, Constant.DISCOUNT_POPULARIZE_KEY).last("limit 1"));
						if (discountPopularizeConfig != null) {
							String sysValue = discountPopularizeConfig.getSysValue();
							if (StrUtil.isNotBlank(sysValue)) {
								if (user == null) {
									throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
								}
								DiscountPopularizeDto discountPopularizeDto = Jsons.parseObject(sysValue, DiscountPopularizeDto.class);
								List<Long> popularizeIds = discountPopularizeDto.getPopularizeIds();
								if (CollUtil.isNotEmpty(popularizeIds) && popularizeIds.contains(orderDon.getPopularizeId())) {
									List<Long> userIdList = userBindRelationService.getRelationUserIdList(user.getId(), user);
									Integer count = orderDonUserDiscountPopularizeRecordMapper.selectUserPopularzieDiscountRecordByUidAndPid(userIdList, orderDon.getPopularizeId());
									if (count == 0) {
										log.info("用户:{}首次使用折扣特殊链接:{} 折扣:{}，修改支付金额", user.getId(), orderDon.getPopularizeId(), discountPopularizeDto.getDiscount());
										BigDecimal discountMoney = orderDon.getMoney().multiply(discountPopularizeDto.getDiscount());
										orderDon.setMoney(discountMoney);

										//记录用户使用折扣链接
										orderDon.setDiscountPopularizeRecord(createPopularizeDiscountRecord(orderDon, discountPopularizeDto.getDiscount()));
									}
								}
							}
						}
					}
				} else {
					//360
//					if (Constant.CHANNEL_NAME_360.equals(name)) {
//						SysConfig sysConfig = sysConfigService.getBaseMapper().selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.CHANNEL_360_DISCOUNT));
//						if (sysConfig != null) {
//							BigDecimal discountMoney = orderDon.getMoney().multiply(BigDecimal.valueOf(Double.valueOf(sysConfig.getSysValue())));
//							orderDon.setMoney(discountMoney);
//						}
//					}
				}
			}
		}
		//第三方商品不支持余额支付
		if (goodsDon.getIsThirdGoods()) {
			return;
		}
		//存在银河币
		deductGalaxyCoinPayOrderMoney(orderDon, sku.getPrice(), galaxyCoin, user);
		//存在余额
		deductBalancePayOrderMoney(orderDon, balance, user);
	}

	public void deductGalaxyCoinPayOrderMoney(OrderDon orderDon, BigDecimal renewSkuDiscountPrice, BigDecimal toUseGalaxyCoin, User user) {
		//存在银河币
		if (toUseGalaxyCoin != null && toUseGalaxyCoin.compareTo(BigDecimal.ZERO) > 0) {
			BigDecimal userGalaxyCoin = user.getGalaxyCoin();
			if (userGalaxyCoin.compareTo(toUseGalaxyCoin) < 0) {
				throw BusinessRuntimeException.getInstance("您的银河币不足!");
			}
			BigDecimal orderMoney = orderDon.getMoney();
			//订单金额不大于0
			if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
				return;
			}
			//去掉余额 多出的部分
			BigDecimal subGalxyCoin = toUseGalaxyCoin;
			SysConfig galaxyCoinPayConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
					.eq(SysConfig::getSysKey, Constant.GALAXY_COIN_PAY_DEDUCT_KEY).last("limit 1"));
			GalaxyCoinPayConfigDto galaxyCoinPayConfigDto = null;
			if (galaxyCoinPayConfig != null && StrUtil.isNotEmpty(galaxyCoinPayConfig.getSysValue())) {
				try {
					galaxyCoinPayConfigDto = Jsons.parseObject(galaxyCoinPayConfig.getSysValue(), GalaxyCoinPayConfigDto.class);
				} catch (Exception e) {
				}
				if (galaxyCoinPayConfigDto == null) {
					throw BusinessRuntimeException.getInstance("银河币抵扣系统错误，请联系客服");
				}
				//每个银河币可抵扣金额
				BigDecimal deductMoneyEachCoin = galaxyCoinPayConfigDto.getMoney().divide(galaxyCoinPayConfigDto.getGalaxyCoin());
				//此次使用抵扣金额
				BigDecimal thisDeductMoney = toUseGalaxyCoin.multiply(deductMoneyEachCoin);
				//该笔平台最高可抵扣金额
				BigDecimal maxDeductMoney = renewSkuDiscountPrice.multiply(galaxyCoinPayConfigDto.getMaxRate());
				if (thisDeductMoney.compareTo(maxDeductMoney) > 0) {
					thisDeductMoney = maxDeductMoney;
				}
				//此次使用的银河币超过订单金额
				if (thisDeductMoney.compareTo(orderMoney) > 0) {
					thisDeductMoney = orderMoney;
				}
				//此时需要扣除的银河币
				subGalxyCoin = thisDeductMoney.divide(deductMoneyEachCoin);
				//银河币抵扣
				List<UserGalaxyCoinRecord> availableGalaxyCoinList = userGalaxyCoinRecordMapper.selectList(Wrappers.lambdaQuery(UserGalaxyCoinRecord.class)
						.eq(UserGalaxyCoinRecord::getUserId, orderDon.getUserId())
						.eq(UserGalaxyCoinRecord::getIsUsed, Boolean.FALSE)
						.gt(UserGalaxyCoinRecord::getExpiryTime, DateTime.now())
						.gt(UserGalaxyCoinRecord::getRemainGalaxyCoin, 0));
				//需要使用的银河币
				BigDecimal userFinalUseGalaxyCoin = subGalxyCoin;
				for (UserGalaxyCoinRecord galaxyCoinRecord : availableGalaxyCoinList) {
					if (userFinalUseGalaxyCoin.compareTo(BigDecimal.ZERO) <= 0) {
						break;
					}
					BigDecimal remainGalaxyCoin = galaxyCoinRecord.getRemainGalaxyCoin();
					Long galaxyCoinRecordId = galaxyCoinRecord.getId();
					//扣完
					if (remainGalaxyCoin.compareTo(userFinalUseGalaxyCoin) == 0) {
						//完全抵扣
						deductUserGalaxyCoin(galaxyCoinRecordId, remainGalaxyCoin, remainGalaxyCoin, true);
						userFinalUseGalaxyCoin = BigDecimal.ZERO;
					} else if (remainGalaxyCoin.compareTo(userFinalUseGalaxyCoin) < 0) {
						//不足以抵扣
						deductUserGalaxyCoin(galaxyCoinRecordId, remainGalaxyCoin, remainGalaxyCoin, true);
						userFinalUseGalaxyCoin = userFinalUseGalaxyCoin.subtract(remainGalaxyCoin);
					} else if (remainGalaxyCoin.compareTo(userFinalUseGalaxyCoin) > 0) {
						//足以抵扣
						deductUserGalaxyCoin(galaxyCoinRecordId, userFinalUseGalaxyCoin, remainGalaxyCoin, false);
						userFinalUseGalaxyCoin = BigDecimal.ZERO;
					}
				}
				//最终消耗的银河币需要为0 大于0则说明抵扣失败
				if (userFinalUseGalaxyCoin.compareTo(BigDecimal.ZERO) > 0) {
					throw BusinessRuntimeException.getInstance("您的银河币不足!");
				}
				//扣除银河币 是否成功
				Integer success = userMapper.subUserGalaxyCoin(user.getId(), subGalxyCoin, userGalaxyCoin);
				if (success != 1) throw BusinessRuntimeException.getInstance("您的银河币不足!");
				//记录使用详情
				OrderDonGalaxyCoinRecord orderDonGalaxyCoinRecord = new OrderDonGalaxyCoinRecord();
				orderDonGalaxyCoinRecord.setUserId(user.getId());
				orderDonGalaxyCoinRecord.setOrderNo(orderDon.getOrderNo());
				orderDonGalaxyCoinRecord.setGalaxyCoin(subGalxyCoin);
				orderDonGalaxyCoinRecord.setDeductMoney(thisDeductMoney);
				orderDonGalaxyCoinRecordMapper.insert(orderDonGalaxyCoinRecord);
				orderDon.setMoney(orderMoney.subtract(thisDeductMoney));
			}
		}
	}

	private void deductUserGalaxyCoin(Long galaxyCoinRecordId, BigDecimal deductGalaxyCoin, BigDecimal remainGalaxyCoin, boolean isUsed) {
		Integer update = userGalaxyCoinRecordMapper.update(null, Wrappers.lambdaUpdate(UserGalaxyCoinRecord.class)
				.set(UserGalaxyCoinRecord::getRemainGalaxyCoin, remainGalaxyCoin.subtract(deductGalaxyCoin))
				.set(isUsed, UserGalaxyCoinRecord::getIsUsed, isUsed)
				.eq(UserGalaxyCoinRecord::getId, galaxyCoinRecordId)
				.eq(UserGalaxyCoinRecord::getIsUsed, Boolean.FALSE)
				.eq(UserGalaxyCoinRecord::getRemainGalaxyCoin, remainGalaxyCoin));
		if (update == 0) {
			throw BusinessRuntimeException.getInstance("银河币抵扣异常,请刷新页面重试");
		}
	}

	/**
	 * 生成用户使用折扣链接记录
	 */
	private OrderDonUserDiscountPopularizeRecord createPopularizeDiscountRecord(OrderDon orderDon, BigDecimal discount) {
		OrderDonUserDiscountPopularizeRecord discountPopularizeRecord = new OrderDonUserDiscountPopularizeRecord();
		discountPopularizeRecord.setDiscount(discount);
		discountPopularizeRecord.setUserId(orderDon.getUserId());
		discountPopularizeRecord.setPopularizeId(orderDon.getPopularizeId());
		return discountPopularizeRecord;
	}

	/**
	 * 更新车票状态
	 */
	public void updateGroupsTicket(OrderDon orderDon, GoodsDon goodsDon, GoodsDonSku sku) {
		if (orderDon.getOrderType() != null && orderDon.getOrderType() == 2 && orderDon.getIsChangeTicket() != null && orderDon.getIsChangeTicket()) {
			//将奈飞月付车票更换成其他规格的车票
			changeTicketAndRecord(orderDon, sku);
		} else {
			//修改车位状态并发送模板消息
			updateCarParkAndSendMsg(goodsDon, sku, orderDon);
		}
		//同步车票是否重购 记录
		TASK_POOL.execute(() -> {
			if (goodsDon.getId() == 1) {
				//设置netflix座位号
				GroupsRelation relation = groupsRelationMapper.selectById(orderDon.getRelationId());
				GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
				if (groupsTrips.getStatus() != GroupsTrips.Status.waiting) {
					Account account = accountMapper.selectById(groupsTrips.getAccountId());
					User user = userMapper.selectById(orderDon.getUserId());
					AtomicInteger start = new AtomicInteger(1);
					groupsRelationNetflixService.timingSetNetflix(relation.getNum(), user.getNickname(), account.getAccount(), account.getPassword(), relation.getExpiryTime(), start);
				}
			}
			groupsRelationExpiryRecordService.syncGroupsRelationExpiryRecord(orderDon, goodsDon, sku);
			if (orderDon.getYhsId() == 0) {
				//发送下单后 若有手机 发送短信
				sendOrderPhoneMsg(orderDon.getUserId());
			}
		});
	}

	private void sendOrderPhoneMsg(Long userId) {
		User user = userMapper.selectById(userId);
		String phone = null;
		if (StrUtil.isNotBlank(user.getLoginPhone())) {
			phone = user.getLoginPhone();
		} else {
			//获取对应手机号
			UserBindDetail userBindDetail = userBindDetailMapper.selectOne(Wrappers.lambdaQuery(UserBindDetail.class)
					.eq(StrUtil.isNotBlank(user.getOpenId()), UserBindDetail::getUserId, user.getId())
					.eq(StrUtil.isNotBlank(user.getEmail()), UserBindDetail::getEmailUserId, user.getId()));
			if (userBindDetail != null && StrUtil.isNotBlank(userBindDetail.getPhone())) {
				phone = userBindDetail.getPhone();
			}
		}
		if (StrUtil.isNotBlank(phone)) {
			//是否发送过手机短信
			UserPhoneSendRecord userPhoneSendRecord = userPhoneSendRecordMapper.selectOne(Wrappers.lambdaQuery(UserPhoneSendRecord.class)
					.eq(UserPhoneSendRecord::getPhone, phone).last("limit 1"));
			if (userPhoneSendRecord == null) {
				try {
					Boolean is_success = SmsUtil.sendLuoKey2Msg(phone, String.format(Constant.ORDER_MSG_FIRST_NOTIFY, user.getNickname()));
					if (is_success) {
						log.info("用户userId:{},购买成功,发送第一次手机号:{}短信官网信息通知", userId, phone);
						userPhoneSendRecord = new UserPhoneSendRecord();
						userPhoneSendRecord.setOrderUserId(userId);
						userPhoneSendRecord.setPhone(phone);
						userPhoneSendRecordMapper.insert(userPhoneSendRecord);
					}
				} catch (Exception e) {
				}
			}
		}
	}


	@Override
	public void orderNotify(OrderDon orderDon) {
		Long goodsId = orderDon.getGoodsId();
		if (orderDon.getIsNoLogin() != null && orderDon.getIsNoLogin()) {
			orderDon.setExCode(exchangeCodeService.getExCode(goodsId, orderDon.getSkuId(), 1));
		}
		GoodsDonSku sku = null;
		if (orderDon.getSkuId() != null) {
			sku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
		}
		GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
		unifiedHandlerOrderNotify(orderDon, goodsDon, sku);
	}

	/**
	 * 统一订单信息回调
	 */
	public void unifiedHandlerOrderNotify(OrderDon orderDon, GoodsDon goodsDon, GoodsDonSku sku) {
		orderDon.setStatus(goodsDon.getType() == 1 && goodsDon.getSecondType() == 2 ? OrderDon.Status.complete : OrderDon.Status.hasPayment);
		//补差价
		if (goodsDon.getType() != null && goodsDon.getType() == 5) {
			orderDon.setStatus(OrderDon.Status.complete);
			orderDonMapper.updateById(orderDon);
			//补差价 返银河币
			returnGalaxyCoin(orderDon);
			return;
		}
		//实物权益优惠订单
		if (orderDon.getGoodsId() == 15) {
			Integer selectCount = userBenefitsOrderRecordMapper.selectCount(Wrappers.lambdaQuery(UserBenefitsOrderRecord.class)
					.eq(UserBenefitsOrderRecord::getOrderId, orderDon.getId()));
			if (selectCount > 0) {
				orderDon.setStatus(OrderDon.Status.complete);
			}
		}
		boolean isSuccess = update(Wrappers.lambdaUpdate(OrderDon.class)
				.set(OrderDon::getStatus, orderDon.getStatus())
				.in(OrderDon::getStatus, List.of(OrderDon.Status.noPayment, OrderDon.Status.close))
				.eq(OrderDon::getId, orderDon.getId()));
		if (!isSuccess) {
			log.info("该订单{}状态已修改", orderDon.getOrderNo());
			return;
		}

		//codex 抵扣
		CodexDeductRecord codexDeductRecord = codexDeductRecordMapper.selectOne(Wrappers.lambdaQuery(CodexDeductRecord.class).eq(CodexDeductRecord::getOrderId, orderDon.getId()).last("limit 1"));
		if (codexDeductRecord != null) {
			//codex 抵扣车票id
			Long relationId = codexDeductRecord.getRelationId();
			//清除codex 抵扣的车票
			groupRelationClearService.clearTicket(groupsRelationMapper.selectById(relationId), UserTicketClearedRecord.Source.codex_deduct);
			//是否需要清除cc 无赠送codex
			Long ccRelationId = codexDeductRecord.getCcRelationId();
			if (ccRelationId != null) {
				//清除codex 抵扣的车票
				groupRelationClearService.clearTicket(groupsRelationMapper.selectById(ccRelationId), UserTicketClearedRecord.Source.codex_deduct);
			}
			codexDeductRecord.setStatus(Boolean.TRUE);
			codexDeductRecordMapper.updateById(codexDeductRecord);
		}

		if (orderDon.getIsNoLogin() != null && orderDon.getIsNoLogin()) {
			orderDon.setStatus(OrderDon.Status.hasPayment);
		}

		//mj镜像续费订单
		if (orderDon.getOrderType() != null && orderDon.getOrderType() == 2 && orderDon.getGoodsId() == 26) {
			GroupsRelation groupsRelation = groupsRelationMapper.selectById(orderDon.getRelationId());
			if (groupsRelation != null) {
				Date expiryTime = groupsRelation.getExpiryTime();

				//mj续费订单当天过期和已过期续费直接加次数
				if (expiryTime != null && new Date().after(DateUtil.beginOfDay(expiryTime))) {
					mjRenewOrder(orderDon);
				}
				//同步user时间
				midjourneyUserMapper.update(null, Wrappers.lambdaUpdate(MidjourneyUser.class)
						.set(MidjourneyUser::getExpireTime, DateUtil.offsetMonth(expiryTime, sku.getMonths()))
						.eq(MidjourneyUser::getRelationId, orderDon.getRelationId()));
			}
		}

		Long goodsId = goodsDon.getId();
		if (orderDon.getIsNoLogin() != null && !orderDon.getIsNoLogin() && sku != null) {
			//更新座位信息
			updateGroupsTicket(orderDon, goodsDon, sku);
			if (goodsDon.getType() == 1) {
				//无车队,新增车队
				checkNoGroupsTripsAndSendMsg(sku, orderDon);
			}
			//客服续费订单
			handleServiceRenewOrder(orderDon);
		}

		this.updateById(orderDon);

		//调整指定规格车队下次可 停用车位数的时间
		groupRelationFrontService.adjustGroupsParkingTime(orderDon.getRelationId(), sku);

		//余额使用记录
		if (orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) {
			userBenefitsService.recordBalanceBySource(orderDon.getUserId(), orderDon.getBalance().negate(), UserBalanceSourceRecord.Source.payment, orderDon.getId(), goodsDon.getTitle() + UserBalanceSourceRecord.Source.payment.getDesc(), null, null);
		}
		//是否需要返回银河币
		AtomicBoolean isNeedReturnGalaxyCoin = new AtomicBoolean(Boolean.TRUE);

		TASK_POOL.execute(() -> {
			try {
				//发放积分
				if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0 && orderDon.getIsDistribute()) {
					TASK_POOL.execute(() -> distributeWaitingSendPointsRecord(orderDon));
				}
				//店铺分销 存在
				if (orderDon.getYhsId() != null && orderDon.getYhsId() > 0) {
					TASK_POOL.execute(() -> yhShopDistributeService.distributeWaitingSendPointsRecord(orderDon));
				}
				//完成任务
				TaskType taskType = taskTypeMapper.selectOne(Wrappers.lambdaQuery(TaskType.class)
						.eq(TaskType::getName, TaskTypeEnum.yh_order.getDesc()).last("limit 1"));
				taskService.completeTask(taskType, orderDon.getUserId());
				//购买Midjourney课程 赠送Midjourney车票
				if (goodsId != null && goodsId.equals(27l)) {
					orderDon.setStatus(OrderDon.Status.complete);
					TASK_POOL.execute(() -> sendMidjourneyTicketIfCourse(orderDon.getUserId()));
				}
				//配置了特定奖池,增加抽奖机会
				marketFrontService.addSpecificChanceNum(orderDon.getUserId(), orderDon.getId(), orderDon.getGoodsId(), orderDon.getSkuId());
				//非分销订单
				if (goodsDon.getType() == 2 && !orderDon.getIsDistribute()) {
					equipmentDistributeService.addDistributeBenefitsChance(orderDon.getUserId(), orderDon.getId());
				}
				//若该订单使用了规定推广者的兑换码 增加上下级关系
				if (StrUtil.isNotBlank(orderDon.getCouponExCode())) {
					addDistributeCouponCode(orderDon.getUserId(), orderDon.getCouponExCode());
				}

				//礼品卡
				if (goodsDon.getSpecialType() != null && goodsDon.getSpecialType() == GoodsDon.SpecialType.giftCard) {
					//礼品卡购买记录
					GiftCardOrderRelate giftCardOrderRelate = giftCardOrderRelateMapper.selectOne(Wrappers.lambdaQuery(GiftCardOrderRelate.class)
							.eq(GiftCardOrderRelate::getOrderId, orderDon.getId())
							.eq(GiftCardOrderRelate::getIsPay, false).last("limit 1"));
					if (giftCardOrderRelate != null) {
						log.info("该订单:{}是礼品卡类型", orderDon.getId());
						int update = giftCardOrderRelateMapper.update(null, Wrappers.lambdaUpdate(GiftCardOrderRelate.class)
								.set(GiftCardOrderRelate::getIsPay, true)
								.eq(GiftCardOrderRelate::getId, giftCardOrderRelate.getId())
								.eq(GiftCardOrderRelate::getIsPay, false));
						if (update > 0) {
							log.info("礼品卡订单:{}开始回调", orderDon.getId());
							giftCardUserPayRecord(giftCardOrderRelate.getGcPayDetail(), orderDon);
						}
					}
					isNeedReturnGalaxyCoin.set(Boolean.FALSE);
				}
				//下级渠道目标额达标 提成金额发放
				sendSubDistributeRewards(orderDon);
				//删除用户意向标签
				clearEpIntentionTag(goodsDon, orderDon.getUserId());

				//HBO GO车队满员 车队自动下架
				setTripDownIfFull(orderDon);
				//用户镜像店铺分销订单
				handleUserMirrorSHopOrderDon(orderDon);
			} catch (Exception e) {
				log.error("回调修改订单信息错误,orderId:{},error:{}", orderDon.getId(), StringUtil.getErrorText(e));
			}
		});

		TASK_POOL.execute(() -> {
			try {
				orderDonPostService.postData(orderDon.getId(), orderDon.getGoodsId(), orderDon.getPopularizeId());
			} catch (Exception e) {
				log.error("回传错误 {}", StringUtil.getErrorText(e));
			}
		});

		//虚拟物品购买推送电报消息
//		if (goodsDon.getType() == 1) {
//			TASK_POOL.execute(() -> {
//				sendTelegramMsg(orderDon, goodsDon, sku);
//			});
//		}

		if (orderDon.getPopularizeId() != null && orderDon.getPopularizeId() != 0 && StrUtil.isNotEmpty(orderDon.getPhone())) {
			String name = channelPopularizeMapper.selectChannelByPid(orderDon.getPopularizeId());
			//百度渠道 专门优惠链接
			if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0)) || name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(1))) {
				String key;
				if (name.contains(Constant.NO_SIGN_CHANNEL_NAMES.get(0))) {
					//百度渠道 专门优惠链接
					key = Constant.CHANNEL_BAIDU_DISCOUNT_KEY;
				} else {
					//抖音
					key = Constant.CHANNEL_DY_DISCOUNT_KEY;
				}
				SysConfig channelNoSignConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
						.eq(SysConfig::getSysKey, key).last("limit 1"));
				if (channelNoSignConfig != null) {
					String sysValue = channelNoSignConfig.getSysValue();
					if (StrUtil.isNotBlank(sysValue)) {
						try {
							ChannelBaiDuDiscountDto baiDuDiscountDto = Jsons.parseObject(sysValue, ChannelBaiDuDiscountDto.class);
							List<Long> couponIds = baiDuDiscountDto.getCouponIds();
							//下单成功后 发送优惠券
							if (CollUtil.isNotEmpty(couponIds)) {
								List<Long> baiduPopularizeIds = baiDuDiscountDto.getPopularizeIds();
								if (baiduPopularizeIds.contains(orderDon.getPopularizeId())) {
									couponIds.forEach(couponId -> couponCommonService.sendCouponToUser(orderDon.getUserId(), couponId, null, null, null, CouponUser.Channel.manual));
								}
							}
						} catch (Exception e) {
						}
					}
				}
			}
		}

		//套餐优惠
		if (orderDon.getGoodsId() == 15) {
			Integer selectCount = userBenefitsOrderRecordMapper.selectCount(Wrappers.lambdaQuery(UserBenefitsOrderRecord.class)
					.eq(UserBenefitsOrderRecord::getOrderId, orderDon.getId()));
			if (selectCount > 0) {
				//发放用户车票套餐
				if (StrUtil.isNotEmpty(sku.getBenefitsList())) {
					try {
						List<GoodsDonSku> goodsDonSkus = Jsons.parseList(sku.getBenefitsList(), GoodsDonSku.class);
						userRealOrderBenefitsService.sendUserBenefitsTicket(orderDon, goodsDonSkus);
						//是否有对应的实物分销订单
						DistributeWaitingSendPoints distributeWaitingSendPoints = distributeWaitingSendPointsMapper.selectOne(Wrappers.lambdaQuery(DistributeWaitingSendPoints.class)
								.eq(DistributeWaitingSendPoints::getOrderId, orderDon.getId())
								.last("limit 1"));
						if (distributeWaitingSendPoints != null) {
							distributeWaitingSendPoints.setIsDelivery(true);
							distributeWaitingSendPointsMapper.updateById(distributeWaitingSendPoints);
						}
					} catch (Exception e) {
						log.error("发放用户:{}车票权益套餐错误：{}", orderDon.getUserId(), StringUtil.getErrorText(e));
					}
				}
			}
		}

		//银河币返回
		if (isNeedReturnGalaxyCoin.get()) {
			returnGalaxyCoin(orderDon);
		}

		//GPT独立会员续费 若为代充类型 同步代充次数
		if (orderDon.getGoodsId() == Constant.GPT_PLUS_GID && sku.getNum() == 1) {
			incrGroupsRelationRechargeRemainIfRecharge(orderDon.getRelationId(), sku.getMonths(), orderDon.getOrderType());
		}

		//查看该订单是否有关闭的余额
		deductIfCloseOrderReturnBalance(orderDon.getId(), UserBalanceSourceRecord.Source.order_close);

		//购买claude code
		if (orderDon.getGoodsId() == Constant.CLAUDE_CODE_GOODS_ID) {
			//生成所需的claude code用户信息
			claudeCodeService.generateOrUpdateClaudeCodeUserInfo(orderDon.getId(), orderDon.getRelationId(), orderDon.getUserId(), sku, orderDon.getOrderType());
		}
		//购买codex
		if (orderDon.getGoodsId() == Constant.CODEX_GOODS_ID) {
			codexService.createOrUpdateCodexUserInfo(orderDon.getId(), orderDon.getRelationId(), orderDon.getUserId(), sku, orderDon.getOrderType());
		}

		//GPT代充 回调兜底
		if (orderDon.getGoodsId() == Constant.GPT_RECHARGE_GOODS_ID) {
			GroupsRelation relation = groupsRelationMapper.selectById(orderDon.getRelationId());
			if (relation.getRechargeStatus() == null) {
				log.info("代充类型车票relationId:{}未配置代充状态，重新设置代充车票信息", relation.getId());
				relation.setRechargeStatus(GroupsRelation.RechargeStatus.waiting);
				relation.setSubmitTime(DateTime.now());
				//代充次数
				relation.setRechargeNum(sku.getMonths());
				relation.setRechargeRemainNum(relation.getRechargeNum());
				groupsRelationMapper.updateById(relation);
			}
		}
	}

	private void handleUserMirrorSHopOrderDon(OrderDon orderDon) throws Exception {
		Long orderId = orderDon.getId();
		UserMirrorShopOrderRelate userMirrorShopOrderRelate = userMirrorShopOrderRelateMapper.selectOne(Wrappers.lambdaQuery(UserMirrorShopOrderRelate.class)
				.eq(UserMirrorShopOrderRelate::getOrderId, orderId)
				.last("limit 1"));
		if (userMirrorShopOrderRelate != null) {
			Long mpId = userMirrorShopOrderRelate.getMpId();
			UserMirrorShop userMirrorShop = userMirrorShopMapper.selectById(mpId);
			if (userMirrorShop == null) {
				return;
			}
			log.info("用户镜像店铺:{}订单:{}分销，发放提成", userMirrorShop.getName(), orderId);
			SysConfig config = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
					.eq(SysConfig::getSysKey, Constant.MIRROR_SHOP_COMMISSION)
					.last("limit 1"));
			UserMirrorShopDistributeConfigDto shopDistributeConfigDto = Jsons.parseObject(config.getSysValue(), UserMirrorShopDistributeConfigDto.class);
			Integer consumeRate = shopDistributeConfigDto.getConsumeRate();

			UserMirrorShopDistributeWaitingSendPoints waitingSendPoints = new UserMirrorShopDistributeWaitingSendPoints();
			waitingSendPoints.setOrderId(orderId);
			waitingSendPoints.setShopUserId(userMirrorShop.getUserId());
			waitingSendPoints.setSendStatus(UserMirrorShopDistributeWaitingSendPoints.Status.waiting);
			waitingSendPoints.setMoney(BigDecimal.valueOf(consumeRate).divide(BigDecimal.valueOf(100)).multiply(orderDon.getMoney()));
			waitingSendPoints.setRate(consumeRate);
			waitingSendPoints.setUserId(orderDon.getUserId());
			waitingSendPoints.setSendTime(DateUtil.offsetDay(orderDon.getPayTime(), 3));
			userMirrorShopDistributeWaitingSendPointsMapper.insert(waitingSendPoints);
		}
	}

	private void setTripDownIfFull(OrderDon orderDon) {
		if (orderDon.getGoodsId() == 8l) {
			Long relationId = orderDon.getRelationId();
			GroupsRelation relation = groupsRelationMapper.selectById(relationId);
			GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
			if (groupsTrips.getStatus() == GroupsTrips.Status.validity) {
				Integer count = groupsRelationMapper.selectCount(Wrappers.lambdaQuery(GroupsRelation.class)
						.eq(GroupsRelation::getGroupsId, relation.getGroupsId())
						.in(GroupsRelation::getStatus, List.of(GroupsRelation.Status.none, GroupsRelation.Status.locking)));
				if (count == 0) {
					log.info("HBO GO车队:{}已满员，自动下架", relation.getGroupsId());
					groupsMapper.update(null, Wrappers.lambdaUpdate(GroupsTrips.class)
							.set(GroupsTrips::getStatus, GroupsTrips.Status.down)
							.eq(GroupsTrips::getId, relation.getGroupsId()));
				}
			}
		}
	}

	private void mjRenewOrder(OrderDon orderDon) {
		if (orderDon.getOrderType() == 2 && orderDon.getGoodsId() == 26) {
			GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(orderDon.getSkuId());
			if (goodsDonSku.getIsMirror()) {
				midjourneyUserMapper.update(null, Wrappers.lambdaUpdate(MidjourneyUser.class)
						.set(MidjourneyUser::getMjFastNum, goodsDonSku.getMjFastNum())
						.set(MidjourneyUser::getMjRelaxNum, goodsDonSku.getMjRelaxNum())
						.eq(MidjourneyUser::getRelationId, orderDon.getRelationId()));
				MidjourneyUser midjourneyUser = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class).eq(MidjourneyUser::getRelationId, orderDon.getRelationId()));
				log.info("恢复midjourney镜像使用次数: {}", midjourneyUser.getId());
				redisService.del(RedisService.key.MIDJOURNEY_FAST_LIMIT.getName() + midjourneyUser.getId());
				redisService.del(RedisService.key.MIDJOURNEY_RELAX_LIMIT.getName() + midjourneyUser.getId());
			}
		}
	}

	private void deductGiftCardCash(Long userId, Long gcId, BigDecimal deductCash, BigDecimal gcRemainCash, List<GiftCardOrderUseRecord> gcUseRecords, Boolean isUsed) {
		Boolean is_update = giftCardUserRecordService.update(null, Wrappers.lambdaUpdate(GiftCardUserRecord.class)
				.set(GiftCardUserRecord::getRemainCash, gcRemainCash.subtract(deductCash))
				.set(isUsed, GiftCardUserRecord::getIsUsed, isUsed)
				.eq(GiftCardUserRecord::getId, gcId)
				.eq(GiftCardUserRecord::getIsPay, true)
				.eq(GiftCardUserRecord::getRemainCash, gcRemainCash));
		if (!is_update) {
			throw BusinessRuntimeException.getInstance("礼品卡支付异常,请刷新页面重试");
		}
		//记录使用关系 订单关闭 退款使用
		GiftCardOrderUseRecord useRecord = new GiftCardOrderUseRecord();
		useRecord.setUserId(userId);
		useRecord.setCash(deductCash);
		useRecord.setGcId(gcId);
		gcUseRecords.add(useRecord);
	}

	/**
	 * 用户购买成功礼品卡记录
	 */
	private void giftCardUserPayRecord(String gcPayDetail, OrderDon orderDon) {
		try {
			//礼品卡规格
			List<GiftCardGoodsSkuFrontView> gcList = Jsons.parseList(gcPayDetail, GiftCardGoodsSkuFrontView.class);
			List<GiftCardUserRecord> gcUserPayRecords = new ArrayList<>();
			for (GiftCardGoodsSkuFrontView data : gcList) {
				for (Integer i = 0; i < data.getGcNum(); i++) {
					//礼品卡关系
					GiftCardUserRecord giftCardUserRecord = new GiftCardUserRecord();
					String gcDetail;
					if (data.getGcType() == 1) {
						gcDetail = String.format("现金卡%s%s", Constant.CN_CYS, data.getCash().divide(BigDecimal.valueOf(100)));
						giftCardUserRecord.setCash(data.getCash());
						giftCardUserRecord.setRemainCash(data.getCash());
					} else {
						gcDetail = String.format("虚拟卡%s%s", data.getGcGoodsTitle(), data.getGcSpecVal());
						giftCardUserRecord.setGcGoodsId(data.getGcGoodsId());
						giftCardUserRecord.setGcSkuId(data.getGcSkuId());
					}
					giftCardUserRecord.setOrderId(orderDon.getId());
					giftCardUserRecord.setUserId(orderDon.getUserId());
					giftCardUserRecord.setGcType(data.getGcType());
					giftCardUserRecord.setGcDetail(gcDetail);
					giftCardUserRecord.setType(data.getGcShowType());
					giftCardUserRecord.setImg(data.getGcImg());
					giftCardUserRecord.setIsPay(true);
					giftCardUserRecord.setRc(RandomUtil.randomString(6));
					giftCardUserRecord.setPayTime(Optional.ofNullable(orderDon.getPayTime()).orElse(orderDon.getCreatedTime()));
					gcUserPayRecords.add(giftCardUserRecord);
				}
			}
			if (CollUtil.isNotEmpty(gcUserPayRecords)) {
				giftCardUserRecordService.saveBatch(gcUserPayRecords);
			}
		} catch (Exception e) {
			log.info("用户userId:{}礼品订单orderId:{}支付成功,记录购买成功记录错误,e:{}", orderDon.getUserId(), orderDon.getId(), StringUtil.getErrorText(e));
		}
	}


	/**
	 * 生成实物订单
	 */
	public void createRealOrderAndTransport(Long userId, Address address, GoodsDon goodsDon, GoodsDonSku sku, List<Long> plusOrderIds) {
		OrderDon orderDon = new OrderDon();
		orderDon.setOrderNo(SEQUENCE.nextId().toString());
		orderDon.setUserId(userId);
		orderDon.setRelationId(0l);
		orderDon.setMoney(BigDecimal.ZERO);
		orderDon.setIsDp(true);
		orderDon.setSkuId(sku.getId());
		orderDon.setGoodsId(goodsDon.getId());
		orderDon.setPayTitle(goodsDon.getTitle() + sku.getSpecVal());
		orderDon.setStatus(OrderDon.Status.hasPayment);
		orderDonMapper.insert(orderDon);
		//处理收货地址
		saveTransportByAddress(address, orderDon.getId());

		plusOrderIds.add(orderDon.getId());
	}

	public void saveTransportByAddress(Address address, Long orderId) {
		OrderDonTransport transport = new OrderDonTransport();
		transport.setOrderId(orderId);
		transport.setReceiver(address.getReceiver());
		transport.setPhone(address.getPhone());
		transport.setProvince(address.getProvince());
		transport.setCity(address.getCity());
		transport.setDistrict(address.getDistrict());
		transport.setAddress(address.getAddress());
		orderDonTransportMapper.insert(transport);
	}

	private BigDecimal handlerDistributeRule(OrderDon order, DistributeWaitingSendPoints distributeWaitingSendPoints, Long distributeId, DistributePointsExchangeMoney distributePointsExchangeMoney, BigDecimal points) {
		//是否使用优惠券 且优惠券折扣小于低于9折
		if (order.getCouponUserId() != 0) {
			//是否开启了渠道规则分销
			SysConfig ruleConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
					.eq(SysConfig::getSysKey, Constant.DISTRIBUTE_RULE_KEY).last("limit 1"));
			if (ruleConfig != null && StrUtil.equals(Constant.ONE_STR, ruleConfig.getSysValue())) {
				//是否是规则过滤平台
				SysConfig ruleFilterGoods = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
						.eq(SysConfig::getSysKey, Constant.DISTRIBUTE_RULE_FILTER_GOODS_KEY).last("limit 1"));
				List<Long> filterGoodsIds = null;
				if (ruleFilterGoods != null && StrUtil.isNotBlank(ruleFilterGoods.getSysValue())) {
					try {
						filterGoodsIds = Jsons.parseList(ruleFilterGoods.getSysValue(), Long.class);
					} catch (Exception e) {
					}
				}
				if (filterGoodsIds == null || !filterGoodsIds.contains(order.getGoodsId())) {
					//优惠券折扣是否小于低于9折
					CouponUser couponUser = couponUserMapper.getCouponByCouponUserId(order.getCouponUserId());
					BigDecimal plat_discount = couponUser.getDiscount();
					BigDecimal nineDis = BigDecimal.valueOf(0.90);
					if (plat_discount != null && plat_discount.compareTo(BigDecimal.ZERO) > 0 && plat_discount.compareTo(nineDis) <= 0) {
						//是否参与渠道分销规则
						//用户下单订单 是否使用 优惠券小于低于9折
						//分销利润金额 减去（规格原价 * 目前使用的折扣 - 规格原价 * 渠道自身折扣 /2）
						BigDecimal realMoney = order.getRealMoney();
						//查询渠道对应的折扣
						Coupon coupon = couponDistributePopularizeMapper.selectDiscountCouponByUserId(distributeId, order.getSkuId());
						//未配置对应折扣
						//按优惠多少对半平摊
						BigDecimal real_points = points;
						if (coupon == null) {
							BigDecimal splitDiscount = BigDecimal.valueOf(1).subtract(plat_discount);
							BigDecimal avg = realMoney.multiply(splitDiscount).divide(BigDecimal.valueOf(2));
							points = points.subtract(avg.multiply(BigDecimal.valueOf(distributePointsExchangeMoney.getPoints())).divide(distributePointsExchangeMoney.getMoney(), 2, RoundingMode.HALF_DOWN));
							if (points.compareTo(BigDecimal.ZERO) < 0) {
								points = BigDecimal.ZERO;
							}
							distributeWaitingSendPoints.setIsRule(true);
							//平摊积分
							distributeWaitingSendPoints.setDeductPoints(real_points.subtract(points));
						}
						if (coupon != null) {
							BigDecimal distribute_discount = coupon.getDiscount();

							BigDecimal ds_money = realMoney.multiply(distribute_discount);
							BigDecimal plat_ds_money = realMoney.multiply(plat_discount);
							BigDecimal subtractMoney = ds_money.subtract(plat_ds_money);
							if (subtractMoney.compareTo(BigDecimal.ZERO) > 0) {
								BigDecimal avg = subtractMoney.divide(BigDecimal.valueOf(2));
								points = points.subtract(avg.multiply(BigDecimal.valueOf(distributePointsExchangeMoney.getPoints())).divide(distributePointsExchangeMoney.getMoney(), 2, RoundingMode.HALF_DOWN));
								if (points.compareTo(BigDecimal.ZERO) < 0) {
									points = BigDecimal.ZERO;
								}
								distributeWaitingSendPoints.setIsRule(true);
								//平摊积分
								distributeWaitingSendPoints.setDeductPoints(real_points.subtract(points));
							}
						}
					}
				}
			}
		}
		return points;
	}

	private void sendTelegramMsg(OrderDon orderDon, GoodsDon goodsDon, GoodsDonSku sku) {
		if (!redisService.hasKey(RedisKey.TELEGRAM_BOT_MSG)) {
			//礼品卡类似订单过滤
			if (orderDon.getRelationId() != null && orderDon.getRelationId() == 0) {
				return;
			}
			TelegramBotMsgReq msgReq = new TelegramBotMsgReq();
			msgReq.setGoodsName(goodsDon.getTitle());
			User user = userMapper.selectById(orderDon.getUserId());
			msgReq.setName(user.getNickname());
			GroupsRelation groupsRelation = groupsRelationMapper.selectById(orderDon.getRelationId());
			Date expiryTime = groupsRelation.getExpiryTime();
			if (expiryTime == null) {
				Integer days = sku.getDays();
				Integer months = sku.getMonths();
				if (days != null && days > 0) {
					expiryTime = DateUtil.offsetDay(new Date(), days);
				} else {
					expiryTime = DateUtil.offsetMonth(new Date(), months);
				}
			}
			long day = DateUtil.betweenDay(new Date(), expiryTime, true);
			if (day > 1000) {
				day = 365;
			}
			msgReq.setDay(day);
			msgReq.setNumber(groupsRelation.getNum() >= 10 ? RandomUtil.randomInt(10) + 1 : groupsRelation.getNum());
			try {
				telegramService.sendMsg(msgReq);
				redisService.set(RedisKey.TELEGRAM_BOT_MSG, 1, 60L * 3L);
			} catch (Exception e) {
				log.error("发送电报推送消息错误 msg:{}", StringUtil.getErrorText(e));
			}
		}
	}

	public void setDistributeOrderMark(OrderDon orderDon, Integer goodsType, Long userId) {
		if (userId == null || userId == 0) {
			return;
		}
		//虚拟商品订单,是否是分销订单
		if (goodsType == 1 || goodsType == 2) {
			//若该订单使用了规定推广者的兑换码 增加上下级关系
			if (StrUtil.isNotBlank(orderDon.getCouponExCode()) && orderDon.getUserId() != 0) {
				addDistributeCouponCode(orderDon.getUserId(), orderDon.getCouponExCode());
			}
			UserDistributeShared userDistributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class).eq(UserDistributeShared::getUserId, userId).last("limit 1"));
			if (userDistributeShared != null) {
				if (Constant.NO_DS_USER_ID.equals(userDistributeShared.getSharedId())) {
					log.info("用户:{}不参与分销", Constant.NO_DS_USER_ID);
					return;
				}
				orderDon.setIsDistribute(true);
				UserDistribute userDistribute = userDistributeMapper.selectOne(Wrappers.lambdaQuery(UserDistribute.class).eq(UserDistribute::getUserId, userDistributeShared.getSharedId()).eq(UserDistribute::getDeleted, 1));
				if (userDistribute != null) {
					orderDon.setCpsPopularizeId(userDistributeShared.getDsPopularizeId());
					//是否特殊渠道设备分销用户
					Integer selectCount = userDistributeEquipmentMapper.selectCount(Wrappers.lambdaQuery(UserDistributeEquipment.class)
							.eq(UserDistributeEquipment::getUserId, userDistribute.getUserId()));
					if (selectCount > 0) {
						orderDon.setIsFixedDistribute(true);
						return;
					}
					//直接去除
					if (!userDistributeShared.getIsBind()) {
						UserDistributeSharedRelateUnbind userDistributeSharedRelateUnbind = userDistributeSharedRelateUnbindMapper.selectOne(Wrappers.lambdaQuery(UserDistributeSharedRelateUnbind.class)
								.eq(UserDistributeSharedRelateUnbind::getUserId, userId)
								.eq(UserDistributeSharedRelateUnbind::getIsUnbind, 1)
								.last("limit 1"));
						if (userDistributeSharedRelateUnbind != null) {
							//是否是渠道用户白名单
							UserDistributeSharedWhite userDistributeSharedWhite = userDistributeSharedWhiteMapper.selectOne(Wrappers.lambdaQuery(UserDistributeSharedWhite.class)
									.eq(UserDistributeSharedWhite::getUserId, userDistributeShared.getSharedId())
									.last("limit 1"));
							if (userDistributeSharedWhite != null) {
								orderDon.setIsFixedDistribute(true);
								return;
							}
						}
						//是否和分销用户同一ip
						if (isSameIpAsDistribute(userDistributeShared)) {
							orderDon.setIsFixedDistribute(true);
							return;
						}
						orderDon.setIsDistribute(false);
					} else {
						//45天内是否下单成功 ==>改为30天
						Date createdTime = userDistributeShared.getCreatedTime();
						DateTime time = DateUtil.offsetDay(createdTime, 30);
						//在45天内
						Boolean is_fit = false;
						boolean before = DateTime.now().isBefore(time);
						//超过45天还未下过单
						//直接不参与后续的 提成
						if (before) {
							is_fit = true;
						} else {
							int count = this.count(Wrappers.lambdaQuery(OrderDon.class)
									.eq(OrderDon::getUserId, userId)
									.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
									.le(OrderDon::getCreatedTime, time));
							if (count > 0) {
								is_fit = true;
							} else {
								userDistributeShared.setIsBind(false);
								userDistributeSharedMapper.updateById(userDistributeShared);
							}
						}
						//未达标
						if (is_fit) {
							orderDon.setIsFixedDistribute(true);
						} else {
							orderDon.setIsDistribute(false);
							orderDon.setIsFixedDistribute(false);
						}
					}
				}
			}
		}
	}

	public GoodsDonSku adjustGoodsDonSku(Long yhsId, Boolean isPayReal, Long skuId) {
		GoodsDonSku sku;
		isPayReal = Optional.ofNullable(isPayReal).orElse(false);
		if (yhsId != 0 && !isPayReal) {
			sku = yhShopGoodsSkuMapper.selectGoodsDonSkuBySkuIdAndYhsId(yhsId, skuId);
		} else {
			sku = goodsDonSkuMapper.selectById(skuId);
		}
		if (sku == null) {
			throw BusinessRuntimeException.getInstance("商品不存在或已下架,请刷新页面重试");
		}
		//调整小店的规格价格
		if (sku.getYhShopSkuPrice() != null) {
			sku.setPrice(sku.getYhShopSkuPrice());
		}
		return sku;
	}

	public User saveOrGetOrderPhoneUser(OrderPayRequest payRequest) {
		String orderPhone = payRequest.getPhone();
		User user = userMapper.selectOne(Wrappers.lambdaQuery(User.class)
				.eq(User::getLoginPhone, orderPhone).last("limit 1"));
		if (user == null) {
			user = new User();
			StringBuilder name = new StringBuilder();
			name.append(Constant.DEFAULT_NAME);
			user.setPopularizeId(payRequest.getPopularizeId());
			user.setLoginPhone(orderPhone);
			user.setNickname(String.format("%s%s", name.toString(), RandomUtil.randomString(6)));
			//默认头像
			user.setHeadimgurl(Constant.DEFAULT_HEAD_IMG);
			String registerEnv = null;
			user.setRegisterEnv(StrUtil.isEmpty(registerEnv) ? User.RegisterEnv.pc.name() : registerEnv);
			userMapper.insert(user);
			if (StrUtil.isEmpty(user.getShowId())) {
				user.setShowId(userCommonService.getUserShowId(user.getId()));
			}
		}
		return user;
	}

	public UserPlatDistributeRate getUserPlatDistributeRate(Integer rate, Integer secondRate) {
		UserPlatDistributeRate userPlatDistributeRate = new UserPlatDistributeRate();
		userPlatDistributeRate.setRate(rate);
		userPlatDistributeRate.setSecondRate(secondRate);
		return userPlatDistributeRate;
	}

	private void clearUserLockingRelation(GroupsRelation groupsRelation, OrderDon orderDon) {
		if (groupsRelation == null) {
			return;
		}
		if (GroupsRelation.Status.locking == groupsRelation.getStatus()) {
			log.info("清理用户userId:{}未支付订单", orderDon.getUserId());
			groupsRelation.setUserId(0L);
			Long groupsId = groupsRelation.getGroupsId();
			GroupsTrips groupsTrips = groupsMapper.selectById(groupsId);
			if (groupsRelation.getNum() > groupsTrips.getNum()) {
				groupsRelation.setStatus(GroupsRelation.Status.outside);

				redisService.del(RedisService.key.GROUPS_TRIPS_OUTSIDE_RELATION.getNameFormat(groupsId, groupsRelation.getNum()));
			} else {
				groupsRelation.setStatus(GroupsRelation.Status.none);
			}
			groupsRelation.setYhsId(0l);
			groupsRelation.setCmt(0);
			groupsRelation.setAqType(1);
			groupsRelationMapper.updateById(groupsRelation);
			orderCommonService.delRelation(groupsRelation);
		}
	}

	/**
	 * 回调后 直接退款
	 */
	public void notifyRefundOrder(OrderDon orderDon, GoodsDon goodsDon, GoodsDonSku sku) throws Exception {
		//续费订单过滤
		if (orderDon.getOrderType() == 2) {
			return;
		}
		//退款
		OrderRefundReq orderRefundReq = new OrderRefundReq();
		orderRefundReq.setOrderId(orderDon.getId());
		orderRefundReq.setRefundType("ALI_PAY");
		orderRefundReq.setRefundMoney(orderDon.getMoney());
		orderDon.setRefundDesc(orderDon.getGoodsId() != 1 ? "近一个月内购买过Midjourney账号" : "近30天内购买奈飞账号限购");
		String outNo = orderRefundService.centerRefund(orderRefundReq, orderDon);

		orderDon.setStatus(OrderDon.Status.refund);
		orderDon.setRefundMoney(orderRefundReq.getRefundMoney());
		orderDonMapper.updateById(orderDon);

		clearUserLockingRelation(groupsRelationMapper.selectById(orderDon.getRelationId()), orderDon);

		//记录退款
		orderRefundService.refundRecord(orderDon, orderRefundReq.getRefundMoney(), orderRefundReq.getRefundBalance(), null, goodsDon, sku, outNo, orderDon.getType().getType(), null);
		return;
	}

	public void epOrderDonActivityReduce(OrderDon orderDon) {
		if (orderDon.getMoney().compareTo(Constant.FIVE_HUNDRED) < 0) {
			return;
		}
		DateTime now = DateTime.now();
		EquipmentActivityReduce equipmentActivityReduce = equipmentActivityReduceMapper.selectOne(Wrappers.lambdaQuery(EquipmentActivityReduce.class)
				.le(EquipmentActivityReduce::getSt, now)
				.gt(EquipmentActivityReduce::getEt, now)
				.eq(EquipmentActivityReduce::getDeleted, true)
				.last("limit 1"));
		if (equipmentActivityReduce == null) {
			return;
		}
		BigDecimal money = orderDon.getMoney();
		BigDecimal acReduceMoney = BigDecimal.ZERO;
		if (money.compareTo(Constant.FIVE_HUNDRED) >= 0 && money.compareTo(Constant.THOUSAND) < 0) {
			//500-1000
			acReduceMoney = equipmentActivityReduce.getF();
			log.info("活动设备订单号:{}达到500元资格，满减金额：{}", orderDon.getOrderNo(), acReduceMoney.divide(BigDecimal.valueOf(100)));
		} else if (money.compareTo(Constant.THOUSAND) >= 0 && money.compareTo(Constant.TWO_THOUSAND) < 0) {
			//1000-2000
			acReduceMoney = equipmentActivityReduce.getQ();
			log.info("活动设备订单号:{}达到1000元资格，满减金额：{}", orderDon.getOrderNo(), acReduceMoney.divide(BigDecimal.valueOf(100)));
		} else if (money.compareTo(Constant.TWO_THOUSAND) >= 0) {
			//2000
			acReduceMoney = equipmentActivityReduce.getTq();
			log.info("活动设备订单号:{}达到2000元资格，满减金额：{}", orderDon.getOrderNo(), acReduceMoney.divide(BigDecimal.valueOf(100)));
		}
		orderDon.setMoney(orderDon.getMoney().subtract(acReduceMoney));
		orderDon.setCouponMoney(acReduceMoney);
	}

	public void deductBalancePayOrderMoney(OrderDon orderDon, BigDecimal balance, User user) {
		//存在余额
		if (balance != null && balance.compareTo(BigDecimal.ZERO) > 0) {
			BigDecimal money = orderDon.getMoney();
			//订单金额不大于0
			if (money.compareTo(BigDecimal.ZERO) == 0) {
				return;
			}
			//去掉余额 多出的部分
			BigDecimal subBalance = balance;
			orderDon.setMoney(money.subtract(subBalance));
			if (balance.compareTo(money) >= 0) {
				orderDon.setMoney(BigDecimal.ZERO);
				orderDon.setBalance(money);
				subBalance = money;
				orderDon.setType(OrderDon.Type.BALANCE);
			}
			BigDecimal userBalance = user.getBalance();
			//扣除余额 是否成功
			Integer success = userMapper.deductBalance(user.getId(), subBalance, userBalance);
			if (success != 1) throw BusinessRuntimeException.getInstance("您的余额不足!");
			orderDon.setBalance(subBalance);
		}
	}

	/**
	 * 获取租赁商品的应付押金
	 */
	private BigDecimal getRentGoodsDonDeposit(Long goodsId, String specIdsStr) throws Exception {
		GoodsDonSpec rentGoodsDonSpec = goodsDonSpecMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSpec.class)
				.eq(GoodsDonSpec::getGoodsId, goodsId)
				.last("limit 1"));
		List<Integer> specIds = Jsons.parseList(specIdsStr, Integer.class);
		String specsJson = rentGoodsDonSpec.getSpecsJson();
		List<ReqGoodsSkuSpec> reqGoodsSkuSpec = Jsons.parseList(specsJson, ReqGoodsSkuSpec.class);
		for (ReqGoodsSkuSpec spec : reqGoodsSkuSpec) {
			if (spec.getKey().contains("版本")) {
				for (ReqGoodsSkuSpec.Node value : spec.getValues()) {
					if (specIds.contains(value.getId())) {
						return value.getDeposit();
					}
				}
			}
		}
		return null;
	}

	/**
	 * 特殊设备分销
	 */
	private BigDecimal handlerEquipmentDistribute(OrderDon orderDon, GoodsDonSku goodsDonSku, UserDistributeEquipment userDistributeEquipment) {
		BigDecimal takeMoney = BigDecimal.ZERO;
		try {
			//设备提成 含路由器
			if (goodsDonSku.getSpecJson().contains("路由")) {
				takeMoney = takeMoney.add(userDistributeEquipment.getEp());
			}
			BigDecimal couponMoney = orderDon.getCouponMoney();
			BigDecimal balance = orderDon.getBalance();
			List<Integer> specIdsList = Jsons.parseList(goodsDonSku.getSpecIds(), Integer.class);
			//包含Apple TV
			if (goodsDonSku.getSpecJson().contains("TV")) {
				takeMoney = takeMoney.add(userDistributeEquipment.getApTv());
			}
			//包含套餐
			if (userDistributeEquipment.getCombo() != null && userDistributeEquipment.getCombo().compareTo(BigDecimal.ZERO) > 0 && goodsDonSku.getSpecJson().contains("套餐")) {
				GoodsDonSpec goodsDonSpec = goodsDonSpecMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSpec.class)
						.eq(GoodsDonSpec::getGoodsId, orderDon.getGoodsId()).last("limit 1"));
				List<ReqGoodsSkuSpec> specs = Jsons.parseList(goodsDonSpec.getSpecsJson(), ReqGoodsSkuSpec.class);
				for (ReqGoodsSkuSpec e : specs) {
					if (e.getKey().contains("套餐")) {
						List<ReqGoodsSkuSpec.Node> values = e.getValues();
						for (ReqGoodsSkuSpec.Node node : values) {
							if (specIdsList.contains(node.getId())) {
								BigDecimal price = node.getPrice();
								takeMoney = takeMoney.add(price.multiply(userDistributeEquipment.getCombo()).divide(BigDecimal.valueOf(100)));
								break;
							}
						}
					}
				}
			}
			//使用优惠分摊一半
			if (couponMoney != null) {
				takeMoney = takeMoney.subtract(couponMoney.divide(BigDecimal.valueOf(2), 0, RoundingMode.DOWN));
			}
			if (balance != null) {
				takeMoney = takeMoney.subtract(balance.divide(BigDecimal.valueOf(2), 0, RoundingMode.DOWN));
			}
		} catch (Exception e) {
		}
		//防止超过订单金额
		if (takeMoney.compareTo(orderDon.getMoney()) > 0) {
			takeMoney = BigDecimal.ZERO;
		}
		return takeMoney;
	}

	/**
	 * 下级渠道奖励
	 */
	public void sendSubDistributeRewards(OrderDon orderDon) {
		if (orderDon.getIsDistribute()) {
			UserDistributeSub userDistributeSub = userDistributeSubMapper.getSubRelate(orderDon.getUserId());
			if (userDistributeSub != null) {
				//分销用户id
				Long userId = userDistributeSub.getUserId();
				//下级渠道用户id
				Long subUserId = userDistributeSub.getSubUserId();

				List<Integer> existLevels = userDistributeSubWaitingMapper.selectList(Wrappers.lambdaQuery(UserDistributeSubWaiting.class)
						.eq(UserDistributeSubWaiting::getUserId, userId)
						.eq(UserDistributeSubWaiting::getSubUserId, subUserId)
						.in(UserDistributeSubWaiting::getSendStatus, List.of(UserDistributeSubWaiting.Status.waiting, UserDistributeSubWaiting.Status.success))
						.select(UserDistributeSubWaiting::getLevel).last("limit 1")).stream().map(UserDistributeSubWaiting::getLevel).collect(Collectors.toList());
				List<UserDistributeSubRewards> userDistributeSubRewards = userDistributeSubRewardsMapper.selectList(Wrappers.lambdaQuery(UserDistributeSubRewards.class)
						.notIn(CollUtil.isNotEmpty(existLevels), UserDistributeSubRewards::getLevel, existLevels));
				for (UserDistributeSubRewards userDistributeSubReward : userDistributeSubRewards) {
					log.info("当前级别:{}对应的目标金额是{}", userDistributeSubReward.getLevel(), userDistributeSubReward.getTargetAmount().divide(BigDecimal.valueOf(100)));
					Integer rewardLevel = userDistributeSubReward.getLevel();
					Integer months = userDistributeSubReward.getMonths();
					BigDecimal targetAmount = userDistributeSubReward.getTargetAmount();
					//是否达到目标额
					BigDecimal subOrderMoney = Optional.ofNullable(orderDonMapper.selectSubChannelOrderMoney(subUserId, userDistributeSub.getCreatedTime(), DateUtil.offsetMonth(userDistributeSub.getCreatedTime(), months))).orElse(BigDecimal.ZERO);
					if (subOrderMoney.compareTo(BigDecimal.ZERO) > 0 && subOrderMoney.compareTo(targetAmount) >= 0) {
						try {
							UserDistributeSubWaiting waiting = Optional.ofNullable(userDistributeSubWaitingMapper.selectOne(Wrappers.lambdaQuery(UserDistributeSubWaiting.class)
									.eq(UserDistributeSubWaiting::getUserId, userId)
									.eq(UserDistributeSubWaiting::getSubUserId, subUserId)
									.eq(UserDistributeSubWaiting::getLevel, rewardLevel)
									.last("limit 1"))).orElse(new UserDistributeSubWaiting());
							if (waiting.getId() != null) {
								if (waiting.getSendStatus() == UserDistributeSubWaiting.Status.close) {
									userDistributeSubWaitingMapper.update(null, Wrappers.lambdaUpdate(UserDistributeSubWaiting.class)
											.set(UserDistributeSubWaiting::getSendStatus, UserDistributeSubWaiting.Status.waiting)
											.eq(UserDistributeSubWaiting::getSendStatus, UserDistributeSubWaiting.Status.close)
											.eq(UserDistributeSubWaiting::getId, waiting.getId()));
								}
							} else {
								waiting.setMoney(userDistributeSubReward.getMoney());
								waiting.setUserId(userId);
								waiting.setSubUserId(subUserId);
								waiting.setSendStatus(UserDistributeSubWaiting.Status.waiting);
								waiting.setSendTime(DateUtil.offsetDay(DateTime.now(), 3));
								waiting.setLevel(rewardLevel);
								userDistributeSubWaitingMapper.insert(waiting);
							}
							log.info("分销用户:{}下级渠道:{}达到:{}销售额,发送奖励成功", userId, subUserId, UserDistributeSubRewards.RewardLevel.values()[rewardLevel].getMsg());
						} catch (DuplicateKeyException e) {
						}
					}
				}
			}

		}
	}

	private void recordOrderDonLocationRelate(Long orderId, String ip) {
		OrderDonLocationRelate orderDonLocationRelate = new OrderDonLocationRelate();
		orderDonLocationRelate.setOrderId(orderId);
		orderDonLocationRelate.setIp(ip);
		orderDonLocationRelateMapper.insert(orderDonLocationRelate);
	}

	private void recordOrderDonSubsidyRelate(Long orderId, Long subsidyId) {
		if (subsidyId != null) {
			OrderDonSubsidyRelate orderDonSubsidyRelate = new OrderDonSubsidyRelate();
			orderDonSubsidyRelate.setSubsidyId(subsidyId);
			orderDonSubsidyRelate.setOrderId(orderId);
			orderDonSubsidyRelateMapper.insert(orderDonSubsidyRelate);
		}
	}

	/**
	 * 设置订单支付商品属性
	 */
	public void setOrderDonPayTile(AtomicBoolean isGiftCardPay, GiftCardDto gcPayInfo, List<GiftCardPayReq> giftCards, OrderDon orderDon, GoodsDon goodsDon, GoodsDonSku sku, List<Long> dpSkuIds) {
		StringBuilder payTitle = new StringBuilder();
//		if (isGiftCardPay != null && !isGiftCardPay.get()) {
//			payTitle.append(goodsDon.getTitle());
//		}
		if (sku != null) {
			payTitle.append(sku.getSpecVal());
		}
		if (isGiftCardPay != null && isGiftCardPay.get()) {
			//礼品卡规格
			Map<Long, Integer> giftCardPayNumMap = new ConcurrentHashMap<>();
			giftCards.stream().forEach(data -> {
				if (data.getNum() <= 0) {
					return;
				}
				giftCardPayNumMap.putIfAbsent(data.getGcId(), data.getNum());
			});
			if (giftCardPayNumMap.isEmpty()) {
				throw BusinessRuntimeException.getInstance("请选择要购买礼品卡的数量");
			}
			List<GiftCardGoodsSkuFrontView> giftCardViews = beanSearcher.searchAll(GiftCardGoodsSkuFrontView.class, MapUtils.builder().field(GiftCardGoodsSkuFrontView::getId, giftCardPayNumMap.keySet()).op(Operator.InList).build());
			if (giftCardViews.size() != giftCards.size()) {
				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重试");
			}
			BigDecimal gift_card_pay_money = BigDecimal.ZERO;
			for (GiftCardGoodsSkuFrontView data : giftCardViews) {
				//礼品卡数量
				Integer num = giftCardPayNumMap.get(data.getId());
				data.setGcNum(num);
				data.setGcShowType(gcPayInfo.getGcShowType());
				data.setGcImg(gcPayInfo.getGcImg());
				gift_card_pay_money = gift_card_pay_money.add(data.getPrice().multiply(BigDecimal.valueOf(num)));

				//礼品卡关系
				if (payTitle.length() > 0) {
					payTitle.append(" + ");
				}
				String gcDetail;
				if (data.getGcType() == 1) {
					gcDetail = String.format("%s张现金卡%s%s", num, Constant.CN_CYS, data.getCash().divide(BigDecimal.valueOf(100)));
					payTitle.append(gcDetail);
				} else {
					gcDetail = String.format("%s张虚拟卡%s%s", num, data.getGcGoodsTitle(), data.getGcSpecVal());
					payTitle.append(gcDetail);
				}
			}
			gcPayInfo.setGcPayDetail(giftCardViews);

			//调整礼品卡金额
			if (gift_card_pay_money.compareTo(orderDon.getMoney()) > 0) {
				orderDon.setMoney(gift_card_pay_money);
				orderDon.setRealMoney(gift_card_pay_money);
			}
		}
		if (orderDon.getIsDp() != null && orderDon.getIsDp()) {
			List<GoodsDonSkuView> dp_skuViewList = beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getSkuId, dpSkuIds).op(Operator.InList).build());
			if (dp_skuViewList.size() != dpSkuIds.size()) {
				throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重新下单");
			}
			dp_skuViewList.forEach(dp_SkuView -> {
				payTitle.append(" + ");
				payTitle.append(dp_SkuView.getGoodsTitle());
				payTitle.append(dp_SkuView.getSpecVal());
			});
		}
		orderDon.setPayTitle(payTitle.toString());
	}

	/**
	 * 百亿补贴订单
	 */
	private void setSubsidyOrderDonInfo(Long subsidyId, User user, OrderDon orderDon) {
		Assert.notNull(user, "用户不存在");
		GoodsDonSkuSubsidy goodsDonSkuSubsidy = goodsDonSkuSubsidyMapper.selectOne(Wrappers.lambdaQuery(GoodsDonSkuSubsidy.class)
				.eq(GoodsDonSkuSubsidy::getId, subsidyId)
				.eq(GoodsDonSkuSubsidy::getDeleted, 1)
				.last("limit 1"));
		if (goodsDonSkuSubsidy == null || !goodsDonSkuSubsidy.getDeleted()) {
			throw BusinessRuntimeException.getInstance("商品不存在");
		}
		if (!goodsDonSkuSubsidy.getStatus()) {
			throw BusinessRuntimeException.getInstance("规格已下架");
		}
		Long skuId = goodsDonSkuSubsidy.getSkuId();
		Long paySkuId = orderDon.getSkuId();
		if (!ObjectUtil.equal(skuId, paySkuId)) {
			throw BusinessRuntimeException.getInstance("规格不存在");
		}
		BigDecimal price = goodsDonSkuSubsidy.getPrice();
		if (price.compareTo(BigDecimal.ZERO) <= 0) {
			throw BusinessRuntimeException.getInstance("商品价格异常..");
		}
		//是否购买过该规格
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(user.getId(), user);
		Integer selectCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
				.eq(OrderDon::getSkuId, skuId)
				.in(OrderDon::getUserId, userIdList)
				.ne(OrderDon::getStatus, OrderDon.Status.close));
		if (selectCount > 0) {
			throw BusinessRuntimeException.getInstance("只可购买一次该补贴规格");
		}
		orderDon.setMoney(price);
	}

	/**
	 * 清除用户设备意向标签
	 */
	public void clearEpIntentionTag(GoodsDon goodsDon, Long userId) {
		//实物订单，用户有设备意向，删除对应标签
		if (goodsDon != null && goodsDon.getId() == 15) {
			User user = userMapper.selectById(userId);
			if (user != null && StrUtil.isNotBlank(user.getUnionid())) {
				String externalUserId = corpUserMapper.selectUserExternalUserId(user.getUnionid());
				if (StrUtil.isEmpty(externalUserId)) {
					return;
				}
				List<CorpUserTag> corpUserTags = corpUserTagMapper.selectIntentionUserTag(externalUserId, Constant.EP_INTENTION_GROUP_NAME);
				if (CollUtil.isNotEmpty(corpUserTags)) {
					//删除之前的意向标签
					corpUserTags.forEach(userTag -> {
						try {
							wxCorpOps.markTag(userTag.getExternalUserId(), userTag.getFollowId(), null, new String[]{userTag.getTagId()});
							corpUserTagMapper.deleteById(userTag.getId());
						} catch (Exception e) {
							log.error("删除用户设备意向标签错误：{}", StringUtil.getErrorText(e));
						}
					});
				}
			}
		}
	}


	@Override
	public UpgradeOrderDon submitUpgrade(OrderPayRequest payRequest) {
		User user = null;
		Long userId = payRequest.getUserId();
		String orderPhone = payRequest.getPhone();
		if (StrUtil.isNotBlank(orderPhone)) {
			user = saveOrGetOrderPhoneUser(payRequest);
			userId = user.getId();
			payRequest.setUserId(userId);
		}
		if (userId == null) {
			user = new User();
			user.setId(0l);
		} else {
			user = userMapper.selectById(userId);
			if (user == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
			if (user.getIsBlack()) throw BusinessRuntimeException.getInstance("系统检测操作异常，请稍后再试");
		}
		if (payRequest.getCmt() == 1) {
//			List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, user);
//			int noPayCount = upgradeOrderDonMapper.selectCount(Wrappers.lambdaQuery(UpgradeOrderDon.class)
//					.in(UpgradeOrderDon::getUserId, userIdList)
//					.eq(UpgradeOrderDon::getRelationId, payRequest.getRelationId())
//					.eq(UpgradeOrderDon::getStatus, UpgradeOrderDon.Status.noPayment.toString()));
//			if (noPayCount > 0) {
//				throw new BusinessRuntimeException("您有未支付订单.");
//			}
		} else if (payRequest.getCmt() == 2) {
			UserMirrorShop userMirrorShop = userMirrorShopMapper.selectOne(Wrappers.lambdaQuery(UserMirrorShop.class)
					.eq(UserMirrorShop::getCustomId, payRequest.getCustomId())
					.last("limit 1"));
			if (!userMirrorShop.getStatus()) {
				throw BusinessRuntimeException.getInstance("店铺已关闭");
			}
		}
		GroupsRelation groupsRelation = getGroupsRelation(payRequest.getUserId(), payRequest.getRelationId());
		GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
		GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(groupsTrips.getSkuId());

		if (goodsDonSku != null && goodsDonSku.getIsMirror()) {
			UpgradePackage upgradePackage = upgradePackageMapper.selectById(payRequest.getPackageId());
			if (upgradePackage == null) {
				throw BusinessRuntimeException.getInstance("套餐包不存在");
			}
			if (upgradePackage.getPrice() == null || upgradePackage.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
				throw BusinessRuntimeException.getInstance("下单商品价格异常");
			}
			if (goodsDonSku.getGoodsId() == 18) {
				ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, payRequest.getRelationId()));
				if (chatgptUser == null) {
					throw BusinessRuntimeException.getInstance("车票未激活gpt账号,请先激活");
				}
				Date expiryTime = groupsRelation.getExpiryTime();
				//剩余多少天
				DateTime now = DateTime.now();
				long remainDay = DateUtil.between(now, expiryTime, DateUnit.DAY) + 1;
				if (remainDay <= 0) {
					throw BusinessRuntimeException.getInstance("车票已过期");
				}
				Long upgradeSkuId = upgradePackage.getUpgradeSkuId();
				GoodsDonSku upgradeSku = goodsDonSkuMapper.selectById(upgradeSkuId);
				Integer upgradeSkuGptLimitNum = upgradeSku.getGptLimitNum();
				if (upgradeSkuGptLimitNum <= chatgptUser.getLimitNum()) {
					throw BusinessRuntimeException.getInstance("您已升级该套餐");
				}
				//两者之间的差价
				BigDecimal differPrice = upgradeSku.getPrice().subtract(goodsDonSku.getPrice());
				Long userUpgradePackageId = chatgptUser.getPackageId();
				//已升级的套餐包
				if (userUpgradePackageId != 0) {
					UpgradePackage hasUpgradePackage = upgradePackageMapper.selectById(userUpgradePackageId);
					BigDecimal thisPackagePrice = hasUpgradePackage.getPrice();
					differPrice = upgradePackage.getPrice().subtract(thisPackagePrice);
				}

				if (differPrice.compareTo(BigDecimal.ZERO) < 0) {
					throw BusinessRuntimeException.getInstance("车票套餐升级错误,请联系客服");
				}

				//自然月差价
				DateTime offset = DateUtil.offsetMonth(now, goodsDonSku.getMonths());
				long totalDays = DateUtil.between(now, offset, DateUnit.DAY) + 1;
				//待支付价格
				//每日单价
				BigDecimal singlePrice = differPrice.divide(BigDecimal.valueOf(totalDays), 0, RoundingMode.HALF_UP);

				BigDecimal payUpgradePackagePrice = singlePrice.multiply(BigDecimal.valueOf(remainDay));
				//车票当日买 当天升级 用套餐包原价
				if (DateUtil.isSameDay(now, groupsRelation.getStartTime())) {
					payUpgradePackagePrice = differPrice;
				}
				if (payRequest.getDonMoney().compareTo(payUpgradePackagePrice) < 0) {
					payRequest.setDonMoney(payUpgradePackagePrice);
				}
			}

			if (goodsDonSku.getGoodsId() == 26) {
				if (payRequest.getDonMoney().compareTo(upgradePackage.getPrice()) < 0) {
					log.info("套餐包:{}支付金额:{}异常,调整用户userId:{}支付金额为:{}", upgradePackage.getName(), payRequest.getDonMoney(), user.getId(), upgradePackage.getPrice());
					payRequest.setDonMoney(upgradePackage.getPrice());
				}
				MidjourneyUser midjourneyUser = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class).eq(MidjourneyUser::getRelationId, payRequest.getRelationId()));
				if (midjourneyUser == null) {
					throw BusinessRuntimeException.getInstance("车票未激活Midjourney账号,请先激活");
				}
			}

			String donNo = SEQUENCE.nextId().toString();
			UpgradeOrderDon upgradeOrderDon = new UpgradeOrderDon();
			upgradeOrderDon.setOrderNo(donNo);
			upgradeOrderDon.setUserId(payRequest.getUserId());
			upgradeOrderDon.setOriginalOrderId(payRequest.getOriginalOrderId());
			upgradeOrderDon.setRelationId(payRequest.getRelationId());
			upgradeOrderDon.setPackageId(payRequest.getPackageId());
			upgradeOrderDon.setPrice(upgradePackage.getPrice());
			upgradeOrderDon.setNum(upgradePackage.getNum());
			upgradeOrderDon.setTime(upgradePackage.getTime());
			upgradeOrderDon.setGoodsId(goodsDonSku.getGoodsId());
			upgradeOrderDon.setSkuId(goodsDonSku.getId());
			upgradeOrderDon.setMoney(payRequest.getDonMoney());
			upgradeOrderDon.setStatus(UpgradeOrderDon.Status.noPayment);
			upgradeOrderDon.setType(UpgradeOrderDon.Type.ALI_PAY);
			deductUpgradeBalancePayOrderMoney(upgradeOrderDon, payRequest,user);
			upgradeOrderDonMapper.insert(upgradeOrderDon);

			Long orderId = upgradeOrderDon.getId();
			//使用银河币记录
			userGalaxyCoinService.handleUserGalaxyCoinOrderNotify(upgradeOrderDon.getId(), upgradeOrderDon.getUserId(), upgradeOrderDon.getOrderNo(), OrderDonGalaxyCoinRecord.Source.upgrade);
			if (upgradeOrderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
				upgradeOrderDon = upgradeOrderDonMapper.selectById(orderId);
				unifiedHandlerUpgradeOrderNotify(upgradeOrderDon, upgradePackage);
			}
			if (upgradeOrderDon.getStatus() == UpgradeOrderDon.Status.noPayment) {
				jobManager.addJob(EXPIRY_TIME, () -> {
					closeUpgradeOrder(orderId, null);
				});
			}
			return upgradeOrderDon;
		}
		return null;
	}

	public void deductUpgradeBalancePayOrderMoney(UpgradeOrderDon orderDon, OrderPayRequest payRequest, User user) {
		BigDecimal galaxyCoin = payRequest.getGalaxyCoin();
		//存在银河币
		deductGalaxyCoinPayUpgradeOrderMoney(orderDon, orderDon.getMoney(), galaxyCoin, user);

		BigDecimal balance = payRequest.getBalance();
		//存在余额
		if (balance != null && balance.compareTo(BigDecimal.ZERO) > 0) {
			BigDecimal money = orderDon.getMoney();
			//去掉余额 多出的部分
			BigDecimal subBalance = balance;
			orderDon.setMoney(money.subtract(subBalance));
			if (balance.compareTo(money) >= 0) {
				orderDon.setMoney(BigDecimal.ZERO);
				orderDon.setBalance(money);
				subBalance = money;
				orderDon.setType(UpgradeOrderDon.Type.BALANCE);
			}
			BigDecimal userBalance = user.getBalance();
			//扣除余额 是否成功
			Integer success = userMapper.deductBalance(user.getId(), subBalance, userBalance);
			if (success != 1) throw BusinessRuntimeException.getInstance("您的余额不足!");
			orderDon.setBalance(subBalance);
			upgradeOrderDonMapper.updateById(orderDon);
		}
	}

	/**
	 * 获取车位信息
	 *
	 * @param userId
	 * @param relationId
	 * @return
	 */
	private GroupsRelation getGroupsRelation(Long userId, Long relationId) {
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		GroupsRelation groupsRelation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class).in(GroupsRelation::getUserId, userIdList).eq(GroupsRelation::getId, relationId));
		if (groupsRelation == null) {
			throw BusinessRuntimeException.getInstance("车票不存在");
		}
		return groupsRelation;
	}

	/**
	 * 获取车队信息
	 *
	 * @param groupsRelation
	 * @return
	 */
	private GroupsTrips getGroupsTrips(GroupsRelation groupsRelation) {
		GroupsTrips groupsTrips = groupsMapper.selectById(groupsRelation.getGroupsId());
		if (groupsTrips == null) {
			throw BusinessRuntimeException.getInstance("车队异常");
		}
		return groupsTrips;
	}

	@Override
	public AliPayParams aliPayUpgrade(AlipayOrderDonReq re, String productCode, String qrPayMode) throws Exception {
		return aliPayCommonService.unifiedPayUpgrade(re, productCode, qrPayMode);
	}


	@Override
	@Transactional(rollbackFor = Throwable.class)
	public void aliPayUpgradeNotify(Map<String, String> params) throws Exception {
		//调用SDK验证签名
		String body = Codec.DoBase64.custom().setData(params.get("body")).decodeAsText();
		OrderAttach orderAttach = Jsons.parseObject(body, OrderAttach.class);
		Long oderId = orderAttach.getO();
		String orderNo = params.get("out_trade_no");
		UpgradeOrderDon orderDon = upgradeOrderDonMapper.selectOne(Wrappers.lambdaQuery(UpgradeOrderDon.class)
				.eq(UpgradeOrderDon::getOrderNo, orderNo)
				.last("limit 1"));
		if (null == orderDon) {
			throw BusinessRuntimeException.getInstance("订单不存在.");
		}
		String appId = params.get("app_id");
		boolean signVerified = AlipaySignature.rsaCheckV1(params, shopConfigMapper.getByAppId(appId).getPublicKey(), BaseZfbConfig.charset, BaseZfbConfig.signType);
		if (!signVerified) {
			log.error("支付宝回调校验签名错误,自定义入参:{}", params.get("body"));
			throw BusinessRuntimeException.getInstance("支付宝回调校验签名错误");
		}
		String transactionId = params.get("trade_no");
		String payTimeStr = params.get("gmt_payment");
		//买家支付宝账号
		String buyerId = Optional.ofNullable(params.get("buyer_id")).orElse(params.get("buyer_open_id"));
		log.info("支付宝回调信息:{}", Jsons.toJson(params));
		if (!orderDon.getStatus().equals(UpgradeOrderDon.Status.noPayment) && !orderDon.getStatus().equals(UpgradeOrderDon.Status.close)) {
			log.info("支付宝已回调，重复修改状态 id:{}", orderDon.getId());
			return;
		}
		UpgradePackage upgradePackage = upgradePackageMapper.selectById(orderDon.getPackageId());
		Date payTime = DateTime.now();
		if (StringUtils.isNotBlank(payTimeStr)) {
			payTime = DateUtil.parse(payTimeStr, "yyyy-MM-dd HH:mm:ss");
		}
		// 更改订单状态
		orderDon.setTransactionId(transactionId);
		orderDon.setPayTime(payTime);
		orderDon.setShopId(appId);
		orderDon.setType(UpgradeOrderDon.Type.ALI_PAY);
		orderDon.setBuyerId(buyerId);
		upgradeOrderDonMapper.updateById(orderDon);
		//该支付账号id 是否被后台拉黑
		Integer count1 = userPayOrderBlockMapper.selectCount(Wrappers.lambdaQuery(UserPayOrderBlock.class)
				.eq(UserPayOrderBlock::getBuyerId, buyerId));
		if (count1 > 0) {
			log.info("该支付账号id：{} 已被后台拉黑", buyerId);
			//notifyRefundOrder(orderDon, goodsDon, sku);
			return;
		}

		//回调
		unifiedHandlerUpgradeOrderNotify(orderDon, upgradePackage);
	}


	/**
	 * 统一订单信息回调
	 */
	public void unifiedHandlerUpgradeOrderNotify(UpgradeOrderDon orderDon, UpgradePackage upgradePackage) {
		orderDon.setStatus(UpgradeOrderDon.Status.complete);
		int isSuccess = upgradeOrderDonMapper.update(null, Wrappers.lambdaUpdate(UpgradeOrderDon.class)
				.set(UpgradeOrderDon::getStatus, orderDon.getStatus())
				.in(UpgradeOrderDon::getStatus, List.of(UpgradeOrderDon.Status.noPayment, UpgradeOrderDon.Status.close))
				.eq(UpgradeOrderDon::getId, orderDon.getId()));
		if (isSuccess == 0) {
			log.info("该订单{}状态已修改", orderDon.getOrderNo());
			return;
		}

		//余额使用记录
		if (orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) {
			userBenefitsService.recordBalanceBySource(orderDon.getUserId(), orderDon.getBalance().negate(), UserBalanceSourceRecord.Source.payment, orderDon.getId(), upgradePackage.getName() + UserBalanceSourceRecord.Source.payment.getDesc(), null, null);
		}

		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()).eq(MidjourneyUser::getId, midjourneyUser.getId()));
				if (update == 0) {
					log.info("midjourneyUser 套餐包增值失败 id:{},orderId:{}", midjourneyUser.getId(), orderDon.getId());
				}
				Object fastNum = redisService.get(RedisService.key.MIDJOURNEY_UPGRADE_LIMIT.getName() + midjourneyUser.getId());
				if (fastNum == null) {
					redisService.set(RedisService.key.MIDJOURNEY_UPGRADE_LIMIT.getName() + midjourneyUser.getId(), midjourneyUser.getMjUpgradeNum() + upgradePackage.getNum().longValue(), RedisService.key.MIDJOURNEY_FAST_LIMIT.getTimeout());
				} else {
					redisService.incr(RedisService.key.MIDJOURNEY_UPGRADE_LIMIT.getName() + midjourneyUser.getId(), upgradePackage.getNum().longValue());
				}
			}
		}

		//gpt 升级套餐
		if (upgradePackage.getGoodsId() == 18) {
			ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, orderDon.getRelationId()));
			if (chatgptUser != null) {
				Long time = upgradePackage.getTime();
				Integer num = upgradePackage.getNum();
				//下次清洗用户套餐包时间 避免续费时间修改
				Date clearPackageTime = chatgptUser.getExpireTime();

				int update = chatgptUserMapper.update(null, Wrappers.lambdaUpdate(ChatgptUser.class)
						.set(ChatgptUser::getLimitTime, time)
						.set(ChatgptUser::getLimitNum, num)
						.set(ChatgptUser::getPackageId, orderDon.getPackageId())
						.set(ChatgptUser::getClearPackageTime, clearPackageTime)
						.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()).eq(LumaUser::getId, lumaUser.getId()));
				if (update == 0) {
					log.info("lumaUser 套餐包增值失败 id:{},orderId:{}", lumaUser.getId(), orderDon.getId());
				}
				Object num = redisService.get(RedisService.key.LUMA_NUM_LIMIT.getName() + lumaUser.getId());
				if (num == null) {
					redisService.set(RedisService.key.LUMA_NUM_LIMIT.getName() + lumaUser.getId(), lumaUser.getNum() + upgradePackage.getNum().longValue(), RedisService.key.LUMA_NUM_LIMIT.getTimeout());
				} else {
					redisService.incr(RedisService.key.LUMA_NUM_LIMIT.getName() + lumaUser.getId(), upgradePackage.getNum().longValue());
				}
			}
		}

		//nano
		if (upgradePackage.getGoodsId() == Constant.NANO_GOODS_ID) {
			NanoUserQuota nanoUserQuota = nanoUserQuotaMapper.selectOne(Wrappers.lambdaQuery(NanoUserQuota.class).eq(NanoUserQuota::getRelationId, orderDon.getRelationId()));
			if (nanoUserQuota != null) {
				int update = nanoUserQuotaMapper.update(null, Wrappers.lambdaUpdate(NanoUserQuota.class)
						.set(NanoUserQuota::getRemainingQuota, nanoUserQuota.getRemainingQuota() + upgradePackage.getNum())
						.set(NanoUserQuota::getTotalQuota, nanoUserQuota.getTotalQuota() + upgradePackage.getNum())
						.eq(NanoUserQuota::getId, nanoUserQuota.getId()));
				if (update == 0) {
					log.info("nano user 套餐包增值失败 id:{},orderId:{}", nanoUserQuota.getId(), orderDon.getId());
				}
			}
		}

		//银河币返回
		returnUpgradeGalaxyCoin(orderDon);
		//查看该订单是否有关闭的余额
		deductIfCloseOrderReturnBalance(orderDon.getId(), UserBalanceSourceRecord.Source.upgrade_close);
	}

	private void returnUpgradeGalaxyCoin(UpgradeOrderDon orderDon) {
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) {
			Long userId = orderDon.getUserId();
			BigDecimal money = orderDon.getMoney();
			SysConfig galaxyCoinConsumeReturnRateConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
					.eq(SysConfig::getSysKey, Constant.GALAXY_COIN_CONSUME_RETURN_RATE_KEY)
					.last("limit 1"));
			BigDecimal retrunGalaxyCoin = BigDecimal.ZERO;
			if (galaxyCoinConsumeReturnRateConfig != null && StrUtil.isNotEmpty(galaxyCoinConsumeReturnRateConfig.getSysValue())) {
				try {
					GalaxyCoinConsumeRateDto galaxyCoinConsumeRateDto = Jsons.parseObject(galaxyCoinConsumeReturnRateConfig.getSysValue(), GalaxyCoinConsumeRateDto.class);
					BigDecimal moneyAvg = galaxyCoinConsumeRateDto.getMoney();
					//返回银河币倍数
					BigDecimal number = money.divide(moneyAvg, 0, RoundingMode.DOWN);;
					retrunGalaxyCoin = number.multiply(galaxyCoinConsumeRateDto.getGalaxyCoin());
					//发送银河币并记录
					userGalaxyCoinService.sendOrderCashback(orderDon.getId(), userId, retrunGalaxyCoin.intValue(), PointsRecordConst.ORDER_CASHBACK, OrderDonGalaxyCoinRecord.Source.upgrade);
				} catch (Exception e) {
					log.error("发送用户：{}银河币points：{}套餐升级错误:{}", userId, retrunGalaxyCoin, StringUtil.getErrorText(e));
				}

			}
		}
	}


	@Transactional(rollbackFor = Throwable.class)
	@Override
	public void closeUpgradeOrder(Long orderId, Long userId) {
		String orderCloseKey = RedisService.key.CLOSE_UPGRADE_ORDER_TIME_KEY.getName() + orderId;
		if (!redisService.setNx(orderCloseKey, orderId, RedisService.key.CLOSE_UPGRADE_ORDER_TIME_KEY.getTimeout())) {
			throw BusinessRuntimeException.getInstance("订单正在关闭中..");
		}
		//关闭订单逻辑
		UpgradeOrderDon orderDon = upgradeOrderDonMapper.selectById(orderId);
		if (orderDon == null) {
			return;
		}
		if (userId != null) {
			List<Long> relationUserIdList = userBindRelationService.getRelationUserIdList(userId, null);
			if (!relationUserIdList.contains(orderDon.getUserId())) {
				return;
			}
		}
		log.info("关闭订单 orderId:{}", orderId);
		if (UpgradeOrderDon.Status.noPayment.equals(orderDon.getStatus())) {
			//调用微信、支付宝第三方接口查询订单是否支付
			UpgradeOrderDon.Status status = isHasPaid(orderDon);
			if (status == UpgradeOrderDon.Status.noPayment) {
				//查询微信支付是否已支付
				orderDon.setStatus(UpgradeOrderDon.Status.close);
				upgradeOrderDonMapper.updateById(orderDon);
				//返还余额
				if (orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) {
					userBenefitsService.addUserBalance(orderDon.getUserId(), orderDon.getBalance(), UserBalanceSourceRecord.Source.upgrade_close, null, orderId, UserBalanceSourceRecord.Source.upgrade_close.getDesc(), true);
				}
				//返回银河币
				UserGalaxyCoinRecord userGalaxyCoinRecord = userGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(UserGalaxyCoinRecord.class)
						.eq(UserGalaxyCoinRecord::getOrderId, orderDon.getId())
						.eq(UserGalaxyCoinRecord::getSource, OrderDonGalaxyCoinRecord.Source.upgrade.ordinal())
						.last("limit 1"));
				if (userGalaxyCoinRecord != null) {
					userGalaxyCoinService.sendOrderGalaxyCloseOrder(orderDon.getId(), orderDon.getUserId(), userGalaxyCoinRecord.getGalaxyCoin().abs(), OrderDonGalaxyCoinRecord.Source.upgrade);
				}
			}
		}
	}


	/**
	 * 查询第三放接口订单是否已支付
	 */
	public UpgradeOrderDon.Status isHasPaid(UpgradeOrderDon orderDon) {
		UpgradePackage upgradePackage = upgradePackageMapper.selectById(orderDon.getPackageId());
		if (orderDon.getType() == UpgradeOrderDon.Type.WeChat) {
			try {
				Map<String, String> reMap = weChatService.getWxOrderDetail(orderDon.getShopId(), orderDon.getOrderNo());
				if (reMap != null) {
					String orderStatus = reMap.get("trade_state");
					if ("SUCCESS".equals(orderStatus)) {
						orderDon.setStatus(UpgradeOrderDon.Status.complete);
						orderDon.setTransactionId(reMap.get("transaction_id"));
						return updateUpgradeNoPayment(orderDon, upgradePackage);
					}
				}
			} catch (Exception e) {

			}
		} else if (orderDon.getType() == UpgradeOrderDon.Type.ALI_PAY) {
			try {
				AlipayTradeQueryResponse zfbOrderDetail = getZfbOrderDetail(orderDon.getShopId(), orderDon.getOrderNo());
				if (zfbOrderDetail != null) {
					String tradeStatus = zfbOrderDetail.getTradeStatus();
					if ("TRADE_SUCCESS".equals(tradeStatus)) {
						orderDon.setStatus(UpgradeOrderDon.Status.complete);
						orderDon.setTransactionId(zfbOrderDetail.getTradeNo());
						return updateUpgradeNoPayment(orderDon, upgradePackage);
					}
				}
			} catch (Exception e) {

			}
		}
		return orderDon.getStatus();
	}

	private UpgradeOrderDon.Status updateUpgradeNoPayment(UpgradeOrderDon orderDon, UpgradePackage upgradePackage) {
		unifiedHandlerUpgradeOrderNotify(orderDon, upgradePackage);
		return orderDon.getStatus();
	}


	@Override
	public UpgradeOrderDetailView getUpgradeOrderDetail(Long orderId, Long userId) {
		MapBuilder builder = MapUtils.builder()
				.field(OrderDonView::getId, orderId)
				.orderBy(OrderDonView::getId).desc();
		if (userId != null) {
			builder.field(UpgradeOrderDetailView::getUserId, userId);
		}
		return beanSearcher.searchFirst(UpgradeOrderDetailView.class, builder.build());
	}

	@Override
	public OrderDon submitRenewUpgrade(OrderPayRequest payRequest) {
		Long packageId = payRequest.getPackageId();
		Long relationId = payRequest.getRelationId();
		if (relationId == null) {
			throw BusinessRuntimeException.getInstance("系统异常");
		}
		Long userId = payRequest.getUserId();
		User user = userMapper.selectById(userId);
		if (user == null) throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
		if (user.getIsBlack()) throw BusinessRuntimeException.getInstance("系统检测操作异常，请稍后再试");
		if (payRequest.getCmt() == 1) {
			List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, user);
			int noPayCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
					.in(OrderDon::getUserId, userIdList)
					.eq(OrderDon::getRelationId, payRequest.getRelationId())
					.eq(OrderDon::getStatus, OrderDon.Status.noPayment.toString()));
			if (noPayCount > 0) {
				throw new BusinessRuntimeException("您有未支付订单.");
			}
		} else if (payRequest.getCmt() == 2) {
			UserMirrorShop userMirrorShop = userMirrorShopMapper.selectOne(Wrappers.lambdaQuery(UserMirrorShop.class)
					.eq(UserMirrorShop::getCustomId, payRequest.getCustomId())
					.last("limit 1"));
			if (!userMirrorShop.getStatus()) {
				throw BusinessRuntimeException.getInstance("店铺已关闭");
			}
		}
		GroupsRelation groupsRelation = getGroupsRelation(payRequest.getUserId(), payRequest.getRelationId());
		GroupsTrips groupsTrips = getGroupsTrips(groupsRelation);
		GoodsDonSku goodsDonSku = goodsDonSkuMapper.selectById(groupsTrips.getSkuId());
		GoodsDon goodsDon = goodsDonMapper.selectById(goodsDonSku.getGoodsId());
		if (!goodsDonSku.getIsMirror()) {
			throw BusinessRuntimeException.getInstance("系统异常");
		}
		Long renewSkuId = payRequest.getSkuId();
		GoodsDonSku renewSku = goodsDonSkuMapper.selectById(renewSkuId);
		//校验同规格
		if (!ObjectUtil.equal(goodsDonSku.getGoodsId(), renewSku.getGoodsId())) {
			throw BusinessRuntimeException.getInstance("系统异常");
		}
		//大会员车票不支持续费
		if (groupsRelation.getIsVip()) {
			throw BusinessRuntimeException.getInstance("不支持单独续费");
		}

		//claude code 续费升级
//		if (goodsDon.getId() == Constant.CLAUDE_CODE_GOODS_ID) {
//			//是否存在已购买的codex
//			List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
//			Integer selectCount = groupsRelationMapper.selectCountByGoodsId(userIdList, Constant.CODEX_GOODS_ID, DateTime.now());
//			if (selectCount > 0) {
//				throw BusinessRuntimeException.getInstance("您已购买了codex套餐，如需claude可用codex抵扣升级，不可重复购买");
//			}
//		}

		OrderDon orderDon = new OrderDon();
		orderDon.setUserId(userId);
		orderDon.setGoodsId(goodsDonSku.getGoodsId());
		orderDon.setRelationId(relationId);
		orderDon.setSkuId(renewSkuId);
		//续费订单
		orderDon.setOrderType(2);
		RenewUpgradePackage renewUpgradePackage = renewUpgradePackageMapper.selectOne(Wrappers.lambdaQuery(RenewUpgradePackage.class)
				.eq(RenewUpgradePackage::getId, packageId)
				.eq(RenewUpgradePackage::getStatus, 1)
				.eq(RenewUpgradePackage::getDeleted, 1));
		if (renewUpgradePackage == null) {
			throw BusinessRuntimeException.getInstance("续费升级套餐不存在");
		}
		BigDecimal price = renewSku.getPrice();
		orderDon.setOriMoney(price);
		orderDon.setRealMoney(price);
		BigDecimal discountPrice = price.multiply(renewUpgradePackage.getDiscount());
		//去掉小数
		if (orderDon.getGoodsId() == 75) {
			discountPrice = discountPrice.divide(BigDecimal.valueOf(100), 0, RoundingMode.DOWN).multiply(BigDecimal.valueOf(100));
		}
		orderDon.setMoney(discountPrice);

		StringBuilder payTitle = new StringBuilder();
		payTitle.append(goodsDon.getTitle()).append(renewSku.getSpecVal());
		orderDon.setPayTitle(payTitle.toString());
		String donNo = SEQUENCE.nextId().toString();
		orderDon.setOrderNo(donNo);
		orderDon.setStatus(OrderDon.Status.noPayment);

		//虚拟商品订单,是否是分销订单
		setDistributeOrderMark(orderDon, goodsDon.getType(), user.getId());

		//存在银河币
		deductGalaxyCoinPayOrderMoney(orderDon, discountPrice, payRequest.getGalaxyCoin(), user);
		//存在余额
		deductBalancePayOrderMoney(orderDon, payRequest.getBalance(), user);

		orderDonMapper.insert(orderDon);
		//记录续费升级的规格
		recordRenewOrderDon(orderDon, renewUpgradePackage, groupsTrips);
		Long orderId = orderDon.getId();
		//使用银河币记录
		userGalaxyCoinService.handleUserGalaxyCoinOrderNotify(orderDon.getId(), orderDon.getUserId(), orderDon.getOrderNo(), OrderDonGalaxyCoinRecord.Source.ordinary);
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
			orderDon = orderDonMapper.selectById(orderId);
			unifiedHandlerOrderNotify(orderDon, goodsDon, renewSku);
		}
		if (orderDon.getStatus() == OrderDon.Status.noPayment) {
			jobManager.addJob(EXPIRY_TIME, () -> {
				closeOrder(orderId, null);
			});
		}
		//统一处理订单记录操作
		unifiedHandlerOrderRecordFunc(orderId, payRequest);

		//记录镜像过期车票 续费订单关联
		if (groupsRelation.getExpiryTime() != null && groupsRelation.getExpiryTime().compareTo(DateTime.now()) <= 0) {
			MirrorExpiryRenewOrderRelate mirrorExpiryRenewOrderRelate = new MirrorExpiryRenewOrderRelate();
			mirrorExpiryRenewOrderRelate.setOrderId(orderId);
			mirrorExpiryRenewOrderRelateMapper.insert(mirrorExpiryRenewOrderRelate);
		}
		return orderDon;
	}

	@Override
	public OrderDon userBenefitsSubmit(OrderPayRequest orderPayRequest) throws Exception {
		Long userId = orderPayRequest.getUserId();
		String ip = orderPayRequest.getIp();
		Long benefitsId = orderPayRequest.getBenefitsId();
		Assert.notNull(benefitsId, "下单错误");
		UserBenefits userBenefits = userBenefitsMapper.selectOne(Wrappers.lambdaQuery(UserBenefits.class)
				.eq(UserBenefits::getId, benefitsId)
				.eq(UserBenefits::getStatus, true)
				.last("limit 1"));
		if (userBenefits == null) {
			throw BusinessRuntimeException.getInstance("权益已不存在");
		}
		User user = userMapper.selectById(userId);
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, user);
		Integer count = userBenefitsOrderRecordMapper.selectNoPaymentRecord(userIdList, benefitsId);
		if (count > 0) {
			throw BusinessRuntimeException.getInstance("存在待支付权益订单");
		}
		//用户是否满足该权益 并且未领取
		checkUserBenefitsStatus(userBenefits, userIdList);
		OrderDon orderDon = new OrderDon();
		orderDon.setOrderNo(SEQUENCE.nextId().toString());
		if (userBenefits.getType() == UserBenefits.Type.COMBO) {
			if (orderPayRequest.getSkuId() == null) {
				throw BusinessRuntimeException.getInstance("请选择对应套餐");
			}
			String comboSkuIds = userBenefits.getComboSkuIds();
			if (!Jsons.parseList(comboSkuIds, Long.class).contains(orderPayRequest.getSkuId())) {
				throw BusinessRuntimeException.getInstance("错误套餐");
			}
		}
		GoodsDonSku sku;
		if (userBenefits.getType() == UserBenefits.Type.RENEW) {
			sku = goodsDonSkuMapper.selectById(userBenefits.getSkuId());
		} else {
			sku = goodsDonSkuMapper.selectById(orderPayRequest.getSkuId());
		}
		orderDon.setMoney(sku.getPrice());
		orderDon.setOrderType(1);
		GoodsDon goodsDon = goodsDonMapper.selectById(sku.getGoodsId());
		Long relationId = 0l;
		if (userBenefits.getType() == UserBenefits.Type.RENEW) {
			relationId = orderPayRequest.getRelationId();
			Assert.notNull(relationId, "请选择对应车票");
			GroupsRelation relation = groupsRelationMapper.selectOne(Wrappers.lambdaQuery(GroupsRelation.class)
					.eq(GroupsRelation::getId, relationId)
					.in(GroupsRelation::getUserId, userIdList)
					.isNotNull(GroupsRelation::getExpiryTime));
			Assert.notNull(relation, "车票不存在");
			GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
			if (groupsTrips.getSkuId().intValue() != userBenefits.getSkuId().intValue()) {
				throw BusinessRuntimeException.getInstance("续费规格错误");
			}
			if (relation != null && relation.getStatus() == GroupsRelation.Status.outside) {
				orderDon.setIsOt(true);
			}
			//目前续费减免下单次数
			Integer renewCount = userBenefitsOrderRecordMapper.selectUseComboRecordByUid(userIdList, userBenefits.getType(), userBenefits.getGoodsId(), userBenefits.getSkuId(), Constant.noOrderAllStatus, null, relation.getStartTime(), relation.getId());
			String renewConfig = userBenefits.getRenewConfig();
			List<UserBenefits.RenewConfig> renewConfigs = Jsons.parseList(renewConfig, UserBenefits.RenewConfig.class);
			Integer start = userBenefits.getStartRenew();
			BigDecimal reduce;
			if (renewCount > start) {
				UserBenefits.RenewConfig thisLevel = renewConfigs.get(start);
				reduce = thisLevel.getReduce();
			} else {
				Optional<UserBenefits.RenewConfig> first = renewConfigs.stream().filter(e -> e.getIndex() == renewCount + 1).findFirst();
				if (!first.isPresent()) {
					log.error("暂无skuId:{}目前等级:{}的权益", sku.getId(), renewCount + 1);
					throw BusinessRuntimeException.getInstance("系统异常");
				}
				reduce = first.get().getReduce();
			}
			orderDon.setMoney(orderDon.getMoney().subtract(reduce));
			//续费订单
			orderDon.setOrderType(2);
		}
		//订单实际支付金额
		BigDecimal orderDonMoney = orderDon.getMoney();
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) < 0) {
			throw BusinessRuntimeException.getInstance("订单金额错误");
		}
		orderDon.setRealMoney(sku.getPrice());
		orderDon.setOriMoney(sku != null ? sku.getPrice() : orderDon.getMoney());
		//渠道链接id
		if (orderPayRequest.getPopularizeId() != null) {
			orderDon.setPopularizeId(orderPayRequest.getPopularizeId());
		}
		orderDon.setSkuId(sku.getId());
		orderDon.setRelationId(relationId);
		orderDon.setNum(1);
		orderDon.setGoodsId(goodsDon.getId());
		orderDon.setStatus(OrderDon.Status.noPayment);
		orderDon.setUserId(user.getId());
		orderDon.setType(OrderDon.Type.getType(orderPayRequest.getType()));
		orderDon.setIsWebPay(orderPayRequest.getIsWebPay());
		orderDon.setSource(orderPayRequest.getSource());
		orderDon.setCouponExCode(orderPayRequest.getCouponExCode());
		orderDon.setIsNoLogin(false);

		String customId = orderPayRequest.getCustomId();
		Long yhsId = yhShopFrontService.checkShopCustomIdAndReturnShopId(customId);
		orderDon.setYhsId(yhsId);
		if (orderDon.getYhsId() == 0) {
			//虚拟商品订单,是否是分销订单
			setDistributeOrderMark(orderDon, goodsDon.getType(), user.getId());
		}
		//存在银河币
		deductGalaxyCoinPayOrderMoney(orderDon, orderDonMoney, orderPayRequest.getGalaxyCoin(), user);
		BigDecimal balance = orderPayRequest.getBalance();
		//存在余额
		deductBalancePayOrderMoney(orderDon, balance, user);
		orderDon.setPayDesc(goodsDon.getPayDesc());
		//设置订单支付商品信息
		setOrderDonPayTile(null, null, null, orderDon, goodsDon, sku, null);
		this.saveOrUpdate(orderDon);
		//使用银河币记录
		userGalaxyCoinService.handleUserGalaxyCoinOrderNotify(orderDon.getId(), orderDon.getUserId(), orderDon.getOrderNo(), OrderDonGalaxyCoinRecord.Source.ordinary);
		if (orderDon.getStatus() == OrderDon.Status.noPayment) {
			jobManager.addJob(EXPIRY_TIME, () -> {
				closeOrder(orderDon.getId(), null);
			});
		}
		//统一处理订单记录操作
		unifiedHandlerOrderRecordFunc(orderDon.getId(), orderPayRequest);
		//记录用户权益下单
		recordUserBenefitsOrderRelate(orderDon, userBenefits);

		//订单金额为0 且订单为已完成
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
			// 更改订单状态
			orderDon.setPayTime(DateTime.now());
			unifiedHandlerOrderNotify(orderDon, goodsDon, sku);
		}
		return orderDon;
	}

	@Override
	public UserPayEquipmentAvailableBenefits getComboOptionalTicketRecord(long userId, Long orderId) {
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		UserPayEquipmentAvailableBenefits userPayEquipmentAvailableBenefits = userPayEquipmentAvailableBenefitsMapper.selectOne(Wrappers.lambdaQuery(UserPayEquipmentAvailableBenefits.class)
				.eq(UserPayEquipmentAvailableBenefits::getRealOrderId, orderId)
				.in(UserPayEquipmentAvailableBenefits::getUserId, userIdList)
				.eq(UserPayEquipmentAvailableBenefits::getDeleted, 1)
				.last("limit 1"));
		return userPayEquipmentAvailableBenefits;
	}

	@Override
	public AliPayParams aliPaySpotifyUpgrade(AlipayOrderDonReq re, String productCode, String qrPayMode) throws Exception {
		return aliPayCommonService.aliPaySpotifyUpgrade(re, productCode, qrPayMode);
	}

	@Override
	public void aliPaySpotifyUpgradeNotify(Map<String, String> params) throws Exception {
		//调用SDK验证签名
		String body = Codec.DoBase64.custom().setData(params.get("body")).decodeAsText();
		OrderAttach orderAttach = Jsons.parseObject(body, OrderAttach.class);
		Long oderId = orderAttach.getO();
		SpotifyUserUpgradeOrder orderDon = spotifyUserUpgradeOrderMapper.selectById(oderId);
		if (null == orderDon) {
			throw BusinessRuntimeException.getInstance("订单不存在.");
		}
		String appId = params.get("app_id");
		boolean signVerified = AlipaySignature.rsaCheckV1(params, shopConfigMapper.getByAppId(appId).getPublicKey(), BaseZfbConfig.charset, BaseZfbConfig.signType);
		if (!signVerified) {
			log.error("支付宝回调校验签名错误,自定义入参:{}", params.get("body"));
			throw BusinessRuntimeException.getInstance("支付宝回调校验签名错误");
		}
		String transactionId = params.get("trade_no");
		String payTimeStr = params.get("gmt_payment");
		//买家支付宝账号
		String buyerId = Optional.ofNullable(params.get("buyer_id")).orElse(params.get("buyer_open_id"));
		log.info("支付宝回调信息:{}", Jsons.toJson(params));
		if (!orderDon.getStatus().equals(SpotifyUserUpgradeOrder.Status.noPayment) && !orderDon.getStatus().equals(SpotifyUserUpgradeOrder.Status.close)) {
			log.info("支付宝已回调，重复修改状态 id:{}", orderDon.getId());
			return;
		}
		Date payTime = DateTime.now();
		if (StringUtils.isNotBlank(payTimeStr)) {
			payTime = DateUtil.parse(payTimeStr, "yyyy-MM-dd HH:mm:ss");
		}
		// 更改订单状态
		orderDon.setTransactionId(transactionId);
		orderDon.setPayTime(payTime);
		orderDon.setShopId(appId);
		orderDon.setStatus(SpotifyUserUpgradeOrder.Status.hasPayment);
		orderDon.setType(SpotifyUserUpgradeOrder.Type.ALI_PAY);
		spotifyUserUpgradeOrderMapper.updateById(orderDon);
	}

	@Override
	public void receiveGptMirrorDayCard(Long orderId) throws Exception {
		OrderDon orderDon = orderDonMapper.selectOne(Wrappers.lambdaQuery(OrderDon.class)
				.eq(OrderDon::getId, orderId)
				.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
				.last("limit 1"));
		if (orderDon != null) {
			sendGptMirrorDayTicket(orderDon);
		}
	}

	private void checkUserBenefitsStatus(UserBenefits userBenefits, List<Long> userIdList) {
		UserBenefits.Type type = userBenefits.getType();
		int fhCount = 0;
		if (type == UserBenefits.Type.COMBO) {
			//是否已经购买实物
			fhCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class).in(OrderDon::getUserId, userIdList).eq(OrderDon::getGoodsId, Constant.NF_EP_GID).notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
			if (fhCount > 0) {
				//近一年是否已经使用过该权益
				DateTime lastYear = DateUtil.offsetMonth(DateTime.now(), -12);
				Integer comboCount = userBenefitsOrderRecordMapper.selectUseComboRecordByUid(userIdList, userBenefits.getType(), userBenefits.getGoodsId(), null, Constant.noOrderStatus, lastYear, null, null);
				if (comboCount > 0) {
					throw BusinessRuntimeException.getInstance("你今年已享受该套餐优惠");
				}
			}
		} else if (type == UserBenefits.Type.RENEW) {
			//是否购买过该规格套餐
			Long skuId = userBenefits.getSkuId();
			fhCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class).in(OrderDon::getUserId, userIdList).eq(OrderDon::getSkuId, skuId).notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
		} else {
			throw BusinessRuntimeException.getInstance("权益下单异常");
		}
		if (fhCount == 0) {
			throw BusinessRuntimeException.getInstance("你未完成该权益目标");
		}
	}


	/**
	 * 试用车票跳转购买正式车票订单记录
	 */
	public void recordOrderTrialTicketJumpPay(Long orderId, Integer aqType, Long userId, Long skuId) {
		if (aqType != null) {
			//普通试用
			if (aqType == 2) {
				UserTrialTicketJumpPayRecord userTrialTicketJumpPayRecord = new UserTrialTicketJumpPayRecord();
				userTrialTicketJumpPayRecord.setOrderId(orderId);
				userTrialTicketJumpPayRecordMapper.insert(userTrialTicketJumpPayRecord);
			}
			//镜像裂变试用
			if (aqType == 3) {
				List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
				GoodsDonSku sku = goodsDonSkuMapper.selectById(skuId);
				UserMirrorFissionReceiveRecord receiveRecord = userMirrorFissionReceiveRecordMapper.selectOne(Wrappers.lambdaQuery(UserMirrorFissionReceiveRecord.class)
						.in(UserMirrorFissionReceiveRecord::getUserId, userIdList)
						.eq(UserMirrorFissionReceiveRecord::getGoodsId, sku.getGoodsId())
						.last("limit 1"));
				if (receiveRecord != null) {
					UserMirrorFissionInvertRecord invertRecord = new UserMirrorFissionInvertRecord();
					invertRecord.setOrderId(orderId);
					invertRecord.setUserId(receiveRecord.getUserId());
					invertRecord.setFissionId(receiveRecord.getFissionId());
					userMirrorFissionInvertRecordMapper.insert(invertRecord);
				}
			}
		}
	}

	/**
	 * 记录续费升级的规格
	 */
	private void recordRenewOrderDon(OrderDon orderDon, RenewUpgradePackage renewUpgradePackage, GroupsTrips groupsTrips) {
		OrderDonRenewRecord orderDonRenewRecord = new OrderDonRenewRecord();
		orderDonRenewRecord.setOrderId(orderDon.getId());
		orderDonRenewRecord.setUserId(orderDon.getUserId());
		orderDonRenewRecord.setPackageId(renewUpgradePackage.getId());
		orderDonRenewRecord.setDiscount(renewUpgradePackage.getDiscount());
		orderDonRenewRecord.setOriSkuId(groupsTrips.getSkuId());
		orderDonRenewRecord.setOrderType(orderDon.getOrderType());
		orderDonRenewRecordMapper.insert(orderDonRenewRecord);
	}

	/**
	 * 记录套餐升级 续费订单
	 */
	private void recordUpgradeRenewOrderDon(OrderDon orderDon, Long packageId, GroupsTrips groupsTrips) {
		OrderDonUpgradeRenewRecord orderDonUpgradeRenewRecord = new OrderDonUpgradeRenewRecord();
		orderDonUpgradeRenewRecord.setOrderId(orderDon.getId());
		orderDonUpgradeRenewRecord.setUserId(orderDon.getUserId());
		orderDonUpgradeRenewRecord.setPackageId(packageId);
		orderDonUpgradeRenewRecord.setOriSkuId(groupsTrips.getSkuId());
		orderDonUpgradeRenewRecordMapper.insert(orderDonUpgradeRenewRecord);
	}

	private void recordIndependentRenewOrderDon(OrderDon orderDon, RenewUpgradePackage renewUpgradePackage, GroupsTrips groupsTrips) {
		OrderDonIndependentRenewRecord independentRenewRecord = new OrderDonIndependentRenewRecord();
		independentRenewRecord.setOrderId(orderDon.getId());
		independentRenewRecord.setUserId(orderDon.getUserId());
		independentRenewRecord.setPackageId(renewUpgradePackage.getId());
		independentRenewRecord.setDiscount(renewUpgradePackage.getDiscount());
		independentRenewRecord.setOriSkuId(groupsTrips.getSkuId());
		independentRenewRecord.setRelationId(orderDon.getRelationId());
		independentRenewRecordMapper.insert(independentRenewRecord);
	}

	//镜像续费升级
	private void handleMirrorRenew(GoodsDonSku sku, OrderDon order, GroupsTrips groupsTrips, Long relationId, Date newDate) {
		if (sku.getGoodsId() == Constant.GPT_PLUS_GID && sku.getIsMirror() && order.getOrderType() == 2) {
			OrderDonRenewRecord orderDonRenewRecord = orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class)
					.eq(OrderDonRenewRecord::getOrderId, order.getId())
					.last("limit 1"));
			//升级gptUser次数
			ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class)
					.eq(ChatgptUser::getRelationId, relationId)
					.last("limit 1"));
			if (chatgptUser == null) {
				return;
			}
			if (orderDonRenewRecord != null) {
				//同规格续费新或者同属性低规格 无需更新
				if (!ObjectUtil.equal(groupsTrips.getSkuId(), order.getSkuId())) {
					Long gtSkuId = groupsTrips.getSkuId();
					GoodsDonSku groupsSku = goodsDonSkuMapper.selectById(gtSkuId);
					//同属性 低规格 只增加车票时长
					if (sku.getMonths() < groupsSku.getMonths() && sku.getGptLimitNum() == groupsSku.getGptLimitNum()) {
						return;
					}
					//同规格续费不处理
					if (chatgptUser.getRenewSkuId() != null && chatgptUser.getRenewSkuId().equals(order.getSkuId())) {
						return;
					}
					log.info("GPT用户续费升级订单skuId:{}将用户车票relationId:{}套餐续费升级", order.getSkuId(), relationId);
					chatgptUser.setLimitTime(sku.getGptLimitTime());
					chatgptUser.setLimitNum(sku.getGptLimitNum());
					chatgptUser.setDsLimitTime(sku.getDsLimitTime());
					chatgptUser.setDsLimitNum(sku.getDsLimitNum());
					chatgptUser.setOtherLimitTime(sku.getOtherLimitTime());
					chatgptUser.setOtherLimitNum(sku.getOtherLimitNum());
					//记录续费升级过期的时间
					chatgptUser.setRenewExpiryTime(newDate);
					chatgptUser.setRenewOrderId(order.getId());
					chatgptUser.setRenewSkuId(order.getSkuId());
				}
			}

			//套餐升级 续费订单
			OrderDonUpgradeRenewRecord orderDonUpgradeRenewRecord = null;
			if (orderDonRenewRecord == null) {
				orderDonUpgradeRenewRecord = orderDonUpgradeRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonUpgradeRenewRecord.class)
						.eq(OrderDonUpgradeRenewRecord::getOrderId, order.getId())
						.last("limit 1"));
			}
			if (orderDonUpgradeRenewRecord != null) {
				Date clearPackageTime = chatgptUser.getClearPackageTime();
				clearPackageTime = DateUtil.offsetMonth(clearPackageTime, sku.getMonths());
				log.info("GPT镜像套餐升级,user套餐升级过期时间:{} ---> {}", chatgptUser.getRenewExpiryTime(), clearPackageTime);
				chatgptUser.setClearPackageTime(clearPackageTime);
			}
			chatgptUserMapper.updateById(chatgptUser);
		}

		//claude pro续费升级
		if (sku.getGoodsId() == Constant.CLAUDE_PRO_GID && sku.getIsMirror() && order.getOrderType() == 2) {
			OrderDonRenewRecord orderDonRenewRecord = orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class)
					.eq(OrderDonRenewRecord::getOrderId, order.getId())
					.last("limit 1"));
			if (orderDonRenewRecord != null) {
				//升级gptUser次数
				ClaudeUser claudeUser = claudeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeUser.class)
						.eq(ClaudeUser::getRelationId, relationId)
						.last("limit 1"));
				if (claudeUser == null) {
					return;
				}
				//同规格续费新或者同属性低规格 无需更新
				if (!ObjectUtil.equal(groupsTrips.getSkuId(), order.getSkuId())) {
					Long gtSkuId = groupsTrips.getSkuId();
					GoodsDonSku groupsSku = goodsDonSkuMapper.selectById(gtSkuId);
					//同属性 低规格 只增加车票时长
					if (sku.getGptLimitNum() <= groupsSku.getGptLimitNum()) {
						return;
					}
					//同规格续费不处理
					if (claudeUser.getRenewSkuId() != null && claudeUser.getRenewSkuId().equals(order.getSkuId())) {
						return;
					}
					log.info("CLAUDE PRO用户续费升级订单skuId:{}将用户车票relationId:{}套餐续费升级", order.getSkuId(), relationId);
					claudeUser.setLimitTime(sku.getGptLimitTime());
					claudeUser.setLimitNum(sku.getGptLimitNum());
					//记录续费升级过期的时间
					claudeUser.setRenewExpiryTime(newDate);
					claudeUser.setRenewOrderId(order.getId());
					claudeUser.setRenewSkuId(order.getSkuId());
					claudeUserMapper.updateById(claudeUser);
				}
			}
		}
	}

	/**
	 * 用户通过海报下单记录
	 */
	private void recordPosterUserOrder(Long orderId, Long rid) {
		if (rid != null) {
			OrderDonPosterRelate orderDonPosterRelate = new OrderDonPosterRelate();
			orderDonPosterRelate.setOrderId(orderId);
			orderDonPosterRelate.setRecordId(rid);
			orderDonPosterRelateMapper.insert(orderDonPosterRelate);
		}
	}

	/**
	 * 是否存在相同ip信息
	 */
	private boolean isSameIpAsDistribute(UserDistributeShared userDistributeShared) {
		List<String> userIpList = userIpRecordMapper.getUserIpList(userDistributeShared.getUserId());
		if (CollUtil.isEmpty(userIpList)) {
			return false;
		}
		Integer count = userIpRecordMapper.selectCount(Wrappers.lambdaQuery(UserIpRecord.class)
				.eq(UserIpRecord::getUserId, userDistributeShared.getSharedId())
				.in(UserIpRecord::getIp, userIpList));
		if (count > 0) {
			log.info("分销人:{}于被邀请人:{}存在相同ip信息，判定为相同用户，将绑定关系恢复", userDistributeShared.getSharedId(), userDistributeShared.getUserId());
			userDistributeShared.setIsBind(true);
			userDistributeSharedMapper.updateById(userDistributeShared);
			return true;
		}
		return false;
	}

	private void checkNfPayLimit(Long goodsId, Long userId) throws Exception {
		if (goodsId != null && goodsId == 1) {
			Boolean isCheck = true;
			SysConfig config = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
					.eq(SysConfig::getSysKey, Constant.NF_PURCHASE_LIMIT_KEY)
					.last("limit 1"));
			if (config == null) {
				return;
			}
			if (StrUtil.isEmpty(config.getSysValue())) {
				return;
			}
			SysConfig nfLimitPayWhiteConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
					.eq(SysConfig::getSysKey, Constant.NF_PURCHASE_LIMIT_WHITE_KEY)
					.last("limit 1"));
			if (nfLimitPayWhiteConfig != null && StrUtil.isNotBlank(nfLimitPayWhiteConfig.getSysValue())) {
				List<Long> whiteUserIds = Jsons.parseList(nfLimitPayWhiteConfig.getSysValue(), Long.class);
				if (whiteUserIds.contains(userId)) {
					isCheck = false;
				}
			}
			if (isCheck) {
				List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
				Integer selectCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
						.in(OrderDon::getUserId, userIdList)
						.eq(OrderDon::getGoodsId, 1)
						.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
						.ge(OrderDon::getCreatedTime, DateUtil.offsetMonth(DateTime.now(), -1)));
				if (selectCount > 0) {
					throw BusinessRuntimeException.getInstance("奈飞近30天内限购一单");
				}
			}
		}
	}

	/**
	 * 处理镜像车票续费升级后的规格
	 */
	private void handlerMirrorRenewPresentPackage(OrderDon orderDon, GoodsDonSku sku, Long tripsSkuId, Long renewSkuId, GroupsTrips groupsTrips) {
		//GPT续费升级 目前升级套餐续费
		//Claude pro
		if ((orderDon.getGoodsId() == 18 || orderDon.getGoodsId() == 75) && sku.getIsMirror()) {
			try {
				//记录续费升级订单 目前升级规格续费
				Integer limitNum = null;
				Long limitTime = null;
				if (orderDon.getGoodsId() == 18) {
					ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class)
							.eq(ChatgptUser::getRelationId, orderDon.getRelationId())
							.last("limit 1"));
					if (chatgptUser == null) {
						return;
					}
					limitNum = chatgptUser.getLimitNum();
					limitTime = chatgptUser.getLimitTime();
				}
				if (orderDon.getGoodsId() == 75) {
					ClaudeUser claudeUser = claudeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeUser.class)
							.eq(ClaudeUser::getRelationId, orderDon.getRelationId())
							.last("limit 1"));
					if (claudeUser == null) {
						return;
					}
					limitNum = claudeUser.getLimitNum();
					limitTime = claudeUser.getLimitTime();
				}
				if (tripsSkuId.intValue() != renewSkuId.intValue()) {
					//是续费升级的规格
					//全部归纳到续费升级的关联订单
					if (limitNum == sku.getGptLimitNum() && limitTime == sku.getGptLimitTime()) {
						RenewUpgradePackage upgradePackage = renewUpgradePackageMapper.selectOne(Wrappers.lambdaQuery(RenewUpgradePackage.class)
								.eq(RenewUpgradePackage::getSkuId, tripsSkuId)
								.apply("JSON_CONTAINS(upgrade_sku_ids,'\"" + renewSkuId + "\"')")
								.eq(RenewUpgradePackage::getStatus, 1)
								.eq(RenewUpgradePackage::getDeleted, 1)
								.last("limit 1"));
						//无优惠折扣 但订单可使用优惠码
						RenewUpgradePackage renewUpgradePackage = new RenewUpgradePackage();
						renewUpgradePackage.setId(upgradePackage.getId());
						renewUpgradePackage.setDiscount(BigDecimal.ONE);
						recordRenewOrderDon(orderDon, renewUpgradePackage, groupsTrips);
					}
				}
			} catch (Exception e) {
				log.error("记录续费升级错误:{}", StringUtil.getErrorText(e));
			}
		}
	}

	/**
	 * 赠送gpt镜像天卡
	 */
	private void sendGptMirrorDayTicket(OrderDon orderDon) throws Exception {
		Long userId = orderDon.getUserId();
		Long orderId = orderDon.getId();
		Long goodsId = orderDon.getGoodsId();
		GptMirrorDayCardGiveawayActivity gptMirrorDayCardGiveawayActivity = gptMirrorDayCardGiveawayActivityMapper.selectOne(Wrappers.lambdaQuery(GptMirrorDayCardGiveawayActivity.class)
				.last("limit 1"));
		if (orderDon.getCreatedTime().compareTo(gptMirrorDayCardGiveawayActivity.getCreatedTime()) < 0) {
			return;
		}
		if (gptMirrorDayCardGiveawayActivity != null) {
			String buyGoodsIds = gptMirrorDayCardGiveawayActivity.getBuyGoodsIds();
			if (StrUtil.isNotBlank(buyGoodsIds)) {
				List<Long> cyGoodsIds = Jsons.parseList(buyGoodsIds, Long.class);
				if (cyGoodsIds.contains(goodsId)) {
					try {
						GptMirrorDayCardActivityRecord gptMirrorDayCardActivityRecord = new GptMirrorDayCardActivityRecord();
						gptMirrorDayCardActivityRecord.setOrderId(orderId);
						gptMirrorDayCardActivityRecord.setUserId(userId);
						gptMirrorDayCardActivityRecordMapper.insert(gptMirrorDayCardActivityRecord);

						//发送GPT天卡
						Long relationId = groupRelationFrontService.getTrialTicketByUserIdAndGoodsId(userId, Constant.GPT_MIRROR_COMMON_SKU_ID, 2);
						gptMirrorDayCardActivityRecord.setRelationId(relationId);
						gptMirrorDayCardActivityRecordMapper.updateById(gptMirrorDayCardActivityRecord);
					} catch (DuplicateKeyException e) {

					}
				}
			}
		}
	}

	public void returnGalaxyCoin(OrderDon orderDon) {
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) {
			Long userId = orderDon.getUserId();
			BigDecimal money = orderDon.getMoney();
			SysConfig galaxyCoinConsumeReturnRateConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
					.eq(SysConfig::getSysKey, Constant.GALAXY_COIN_CONSUME_RETURN_RATE_KEY)
					.last("limit 1"));
			BigDecimal retrunGalaxyCoin = BigDecimal.ZERO;
			if (galaxyCoinConsumeReturnRateConfig != null && StrUtil.isNotEmpty(galaxyCoinConsumeReturnRateConfig.getSysValue())) {
				try {
					GalaxyCoinConsumeRateDto galaxyCoinConsumeRateDto = Jsons.parseObject(galaxyCoinConsumeReturnRateConfig.getSysValue(), GalaxyCoinConsumeRateDto.class);
					BigDecimal moneyAvg = galaxyCoinConsumeRateDto.getMoney();
					//返回银河币倍数
					BigDecimal number = money.divide(moneyAvg, 0, RoundingMode.DOWN);
					retrunGalaxyCoin = number.multiply(galaxyCoinConsumeRateDto.getGalaxyCoin());
					//发送银河币并记录
					userGalaxyCoinService.sendOrderCashback(orderDon.getId(), userId, retrunGalaxyCoin.intValue(), PointsRecordConst.ORDER_CASHBACK, OrderDonGalaxyCoinRecord.Source.ordinary);
				} catch (Exception e) {
					log.error("发送用户：{}银河币points：{}错误:{}", userId, retrunGalaxyCoin, StringUtil.getErrorText(e));
				}

			}
		}
	}

	public void deductGalaxyCoinPayUpgradeOrderMoney(UpgradeOrderDon orderDon, BigDecimal discountPrice, BigDecimal toUseGalaxyCoin, User user) {
		//存在银河币
		if (toUseGalaxyCoin != null && toUseGalaxyCoin.compareTo(BigDecimal.ZERO) > 0) {
			BigDecimal userGalaxyCoin = user.getGalaxyCoin();
			if (userGalaxyCoin.compareTo(toUseGalaxyCoin) < 0) {
				throw BusinessRuntimeException.getInstance("您的银河币不足!");
			}
			BigDecimal orderMoney = orderDon.getMoney();
			//订单金额不大于0
			if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
				return;
			}
			//去掉余额 多出的部分
			BigDecimal subGalxyCoin;
			SysConfig galaxyCoinPayConfig = sysConfigService.getOne(Wrappers.lambdaQuery(SysConfig.class)
					.eq(SysConfig::getSysKey, Constant.GALAXY_COIN_PAY_DEDUCT_KEY).last("limit 1"));
			GalaxyCoinPayConfigDto galaxyCoinPayConfigDto = null;
			if (galaxyCoinPayConfig != null && StrUtil.isNotEmpty(galaxyCoinPayConfig.getSysValue())) {
				try {
					galaxyCoinPayConfigDto = Jsons.parseObject(galaxyCoinPayConfig.getSysValue(), GalaxyCoinPayConfigDto.class);
				} catch (Exception e) {
				}
				if (galaxyCoinPayConfigDto == null) {
					throw BusinessRuntimeException.getInstance("银河币抵扣系统错误，请联系客服");
				}
				//每个银河币可抵扣金额
				BigDecimal deductMoneyEachCoin = galaxyCoinPayConfigDto.getMoney().divide(galaxyCoinPayConfigDto.getGalaxyCoin());
				//此次使用抵扣金额
				BigDecimal thisDeductMoney = toUseGalaxyCoin.multiply(deductMoneyEachCoin);
				//该笔平台最高可抵扣金额
				BigDecimal maxDeductMoney = discountPrice.multiply(galaxyCoinPayConfigDto.getMaxRate());
				if (thisDeductMoney.compareTo(maxDeductMoney) > 0) {
					thisDeductMoney = maxDeductMoney;
				}
				//此次使用的银河币超过订单金额
				if (thisDeductMoney.compareTo(orderMoney) > 0) {
					thisDeductMoney = orderMoney;
				}
				//此时需要扣除的银河币
				subGalxyCoin = thisDeductMoney.divide(deductMoneyEachCoin);
				//银河币抵扣
				List<UserGalaxyCoinRecord> availableGalaxyCoinList = userGalaxyCoinRecordMapper.selectList(Wrappers.lambdaQuery(UserGalaxyCoinRecord.class)
						.eq(UserGalaxyCoinRecord::getUserId, orderDon.getUserId())
						.eq(UserGalaxyCoinRecord::getIsUsed, Boolean.FALSE)
						.gt(UserGalaxyCoinRecord::getExpiryTime, DateTime.now())
						.gt(UserGalaxyCoinRecord::getRemainGalaxyCoin, 0));
				//需要使用的银河币
				BigDecimal userFinalUseGalaxyCoin = subGalxyCoin;
				for (UserGalaxyCoinRecord galaxyCoinRecord : availableGalaxyCoinList) {
					if (userFinalUseGalaxyCoin.compareTo(BigDecimal.ZERO) <= 0) {
						break;
					}
					BigDecimal remainGalaxyCoin = galaxyCoinRecord.getRemainGalaxyCoin();
					Long galaxyCoinRecordId = galaxyCoinRecord.getId();
					//扣完
					if (remainGalaxyCoin.compareTo(userFinalUseGalaxyCoin) == 0) {
						//完全抵扣
						deductUserGalaxyCoin(galaxyCoinRecordId, remainGalaxyCoin, remainGalaxyCoin, true);
						userFinalUseGalaxyCoin = BigDecimal.ZERO;
					} else if (remainGalaxyCoin.compareTo(userFinalUseGalaxyCoin) < 0) {
						//不足以抵扣
						deductUserGalaxyCoin(galaxyCoinRecordId, remainGalaxyCoin, remainGalaxyCoin, true);
						userFinalUseGalaxyCoin = userFinalUseGalaxyCoin.subtract(remainGalaxyCoin);
					} else if (remainGalaxyCoin.compareTo(userFinalUseGalaxyCoin) > 0) {
						//足以抵扣
						deductUserGalaxyCoin(galaxyCoinRecordId, userFinalUseGalaxyCoin, remainGalaxyCoin, false);
						userFinalUseGalaxyCoin = BigDecimal.ZERO;
					}
				}
				//最终消耗的银河币需要为0 大于0则说明抵扣失败
				if (userFinalUseGalaxyCoin.compareTo(BigDecimal.ZERO) > 0) {
					throw BusinessRuntimeException.getInstance("您的银河币不足!");
				}
				//扣除银河币 是否成功
				Integer success = userMapper.subUserGalaxyCoin(user.getId(), subGalxyCoin, userGalaxyCoin);
				if (success != 1) throw BusinessRuntimeException.getInstance("您的银河币不足!");
				//记录使用详情
				OrderDonGalaxyCoinRecord orderDonGalaxyCoinRecord = new OrderDonGalaxyCoinRecord();
				orderDonGalaxyCoinRecord.setUserId(user.getId());
				orderDonGalaxyCoinRecord.setOrderNo(orderDon.getOrderNo());
				orderDonGalaxyCoinRecord.setGalaxyCoin(subGalxyCoin);
				orderDonGalaxyCoinRecord.setDeductMoney(thisDeductMoney);
				//套餐升级来源
				orderDonGalaxyCoinRecord.setSource(OrderDonGalaxyCoinRecord.Source.upgrade.ordinal());
				orderDonGalaxyCoinRecordMapper.insert(orderDonGalaxyCoinRecord);
				orderDon.setMoney(orderMoney.subtract(thisDeductMoney));
			}
		}
	}

	/**
	 * 清除座位缓存key
	 */
	public void delRelationKey(Long relationId, Long userId) {
		String relation_num_key = RedisKey.GROUPS_RELATION_NUM_KEY + relationId;
		Object object = redisService.get(relation_num_key);
		if (object != null) {
			try {
				Long keyUserId = Long.parseLong(object.toString());
				//清除车票key
				if (ObjectUtil.equal(userId, keyUserId)) {
					redisService.del(relation_num_key);
				}
			} catch (Exception e) {
				log.error("删除缓存key错误:{}", StringUtil.getErrorText(e));
			}
		}
	}

	private void incrGroupsRelationRechargeRemainIfRecharge(Long relationId, Integer addNum, Integer orderType) {
		GroupsRelation relation = groupsRelationMapper.selectById(relationId);
		if (orderType == 1) {
			//已发车
			GroupsTrips groupsTrips = groupsMapper.selectById(relation.getGroupsId());
			if (groupsTrips.getAccountId() != null) {
				Account account = accountMapper.selectById(groupsTrips.getAccountId());
				if (account != null) {
					relation.setRechargeStatus(GroupsRelation.RechargeStatus.complete);
					relation.setRechargeNum(addNum);
					relation.setRechargeRemainNum(addNum - 1);
					relation.setSubmitTime(DateTime.now());
					relation.setSendTime(relation.getSubmitTime());
					relation.setAccount(account.getAccount());
					relation.setPassword(account.getPassword());
					groupsRelationMapper.updateById(relation);
					//记录gpt代充记录
					gptUserRechargeRecordService.recordGptUserRechargeNum(relation.getUserId(), relation.getId(), relation.getAccount(), relation.getRechargeRemainNum(), null, "下单");
				}
			}
		} else {
			//续费订单
			if (relation.getRechargeStatus() != null) {
				//增加代充次数
				Integer rechargeRemainNum = relation.getRechargeRemainNum();
				Integer rechargeNum = relation.getRechargeNum();
				int update = 0;
				while (update == 0) {
					update = groupsRelationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
							.set(GroupsRelation::getRechargeRemainNum, rechargeRemainNum + addNum)
							.set(GroupsRelation::getRechargeNum, rechargeNum + addNum)
							.eq(GroupsRelation::getId, relationId)
							.eq(GroupsRelation::getRechargeRemainNum, rechargeRemainNum));
					if (update == 1) {
						//记录gpt代充记录
						gptUserRechargeRecordService.recordGptUserRechargeNum(relation.getUserId(), relation.getId(), relation.getAccount(), addNum, null, "订单续费");
					}
				}
			}
		}
	}

	/**
	 * 存在关闭订单退款余额的记录
	 */
	private void deductIfCloseOrderReturnBalance(Long orderId, UserBalanceSourceRecord.Source source) {
		UserBalanceSourceRecord userBalanceSourceRecord = userBalanceSourceRecordMapper.selectOne(Wrappers.lambdaQuery(UserBalanceSourceRecord.class).eq(UserBalanceSourceRecord::getOrderId, orderId).eq(UserBalanceSourceRecord::getSource, source).last("limit 1"));
		if (userBalanceSourceRecord != null) {
			BigDecimal balance = userBalanceSourceRecord.getBalance();
			//扣除余额并删除记录
			userBenefitsService.deductUserBalance(userBalanceSourceRecord.getUserId(), balance);
			userBalanceSourceRecordMapper.deleteById(userBalanceSourceRecord.getId());
		}
	}

	private void checkCCTrialCardNum(List<Long> userIdList) {
		Integer payCcTy = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getSkuId, Constant.DISTRIBUTE_CLAUDE_CODE_TRIAL_SKU_ID).in(OrderDon::getUserId, userIdList).notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
		if (payCcTy > 0) {
			throw BusinessRuntimeException.getInstance("claude code体验天卡车票仅可体验一次");
		}
		if (payCcTy == 0) {
			Number number = beanSearcher.searchCount(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getUserId, userIdList).op(Operator.InList).field(GroupsRelationView::getSkuId, Constant.DISTRIBUTE_CLAUDE_CODE_TRIAL_SKU_ID).build());
			if (number.intValue() > 0) {
				throw BusinessRuntimeException.getInstance("claude code体验天卡车票仅可体验一次");
			}
			if (number.intValue() == 0) {
				Integer ccCount = userTicketClearedRecordMapper.selectCount(Wrappers.lambdaQuery(UserTicketClearedRecord.class).in(UserTicketClearedRecord::getUserId, userIdList).eq(UserTicketClearedRecord::getSkuId, Constant.DISTRIBUTE_CLAUDE_CODE_TRIAL_SKU_ID));
				if (ccCount > 0) {
					throw BusinessRuntimeException.getInstance("claude code体验天卡车票仅可体验一次");
				}
			}
		}
	}
}
