package com.cyksj.service.order.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeQueryRequest;
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.constant.Constant;
import com.cyksj.common.constant.PointsRecordConst;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.common.snowflake.Sequence;
import com.cyksj.common.util.Codec;
import com.cyksj.common.util.Jsons;
import com.cyksj.common.util.StringUtil;
import com.cyksj.config.zfb.AliPayClientFactory;
import com.cyksj.config.zfb.BaseZfbConfig;
import com.cyksj.config.zfb.ZfbProductCode;
import com.cyksj.enums.GatewayApiCode;
import com.cyksj.mapper.*;
import com.cyksj.mapper.channel.ShopConfigMapper;
import com.cyksj.mapper.manage.distribute.*;
import com.cyksj.mapper.sys.SysConfigMapper;
import com.cyksj.mapper.vip.VipGoodsSkuMapper;
import com.cyksj.mapper.vip.VipOrderDonDeductRelationMapper;
import com.cyksj.mapper.vip.VipOrderDonMapper;
import com.cyksj.mapper.vip.VipUserMapper;
import com.cyksj.model.dto.AliPayParams;
import com.cyksj.model.dto.GalaxyCoinConsumeRateDto;
import com.cyksj.model.dto.GalaxyCoinPayConfigDto;
import com.cyksj.model.dto.VipDeductDto;
import com.cyksj.model.entity.*;
import com.cyksj.model.manage.views.GroupsRelationView;
import com.cyksj.model.request.AlipayOrderDonReq;
import com.cyksj.model.request.OrderAttach;
import com.cyksj.model.request.VipOrderDonPayReq;
import com.cyksj.redis.RedisService;
import com.cyksj.service.chatgpt.ChatGptAccountService;
import com.cyksj.service.claude.ClaudeService;
import com.cyksj.service.coin.UserGalaxyCoinService;
import com.cyksj.service.order.VipOrderDonService;
import com.cyksj.service.pay.AliPayCommonService;
import com.cyksj.service.relation.GroupRelationClearService;
import com.cyksj.service.relation.GroupRelationFrontService;
import com.cyksj.service.sys.SysConfigService;
import com.cyksj.service.user.UserBenefitsService;
import com.cyksj.service.user.UserBindRelationService;
import com.cyksj.service.vip.VipFrontService;
import com.cyksj.task.JobManager;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.param.Operator;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 项目名: yhlxj2
 * 文件名: VipOrderDonServiceImpl
 * 创建者: JavaZou
 * 创建时间:2025/5/13 11:14
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class VipOrderDonServiceImpl extends ServiceImpl<VipOrderDonMapper, VipOrderDon> implements VipOrderDonService {
	private static final Sequence SEQUENCE = new Sequence(0);

	private final UserMapper userMapper;

	private final UserBenefitsService userBenefitsService;

	private final VipUserMapper vipUserMapper;

	private final VipGoodsSkuMapper vipGoodsSkuMapper;

	private final UserBindRelationService userBindRelationService;

	private final SysConfigMapper sysConfigMapper;

	private final AliPayCommonService aliPayCommonService;

	private final ShopConfigMapper shopConfigMapper;

	private final GroupRelationFrontService groupRelationFrontService;

	private final GroupsRelationMapper relationMapper;

	private final VipFrontService vipFrontService;

	private final VipOrderDonDeductRelationMapper vipOrderDonDeductRelationMapper;

	private final BeanSearcher beanSearcher;

	private final MidjourneyUserMapper midjourneyUserMapper;

	private final ChatgptUserMapper chatgptUserMapper;

	private final ClaudeUserMapper claudeUserMapper;

	private final LumaUserMapper lumaUserMapper;

	private final GrokUserMapper grokUserMapper;

	private final RedisService redisService;

	private final GoodsDonSkuMapper skuMapper;

	private final ChatGptAccountService chatGptAccountService;

	private final ClaudeService claudeService;

	private final UserDistributeMapper userDistributeMapper;

	private final UserDistributeSharedMapper userDistributeSharedMapper;

	private final DistributePointsExchangeMoneyMapper distributePointsExchangeMoneyMapper;

	private final DistributeWaitingSendPointsMapper distributeWaitingSendPointsMapper;

	private final GoodsDonMapper goodsDonMapper;

	private final UserPlatDistributeRateMapper userPlatDistributeRateMapper;

	private final GroupRelationClearService relationClearService;

	private final BusinessDistributeDefaultRateConfigMapper businessDistributeDefaultRateConfigMapper;

	private final SysConfigService sysConfigService;

	private final UserGalaxyCoinRecordMapper userGalaxyCoinRecordMapper;

	private final OrderDonGalaxyCoinRecordMapper orderDonGalaxyCoinRecordMapper;

	private final UserGalaxyCoinService userGalaxyCoinService;

	private final JobManager jobManager;

	private final UserBalanceSourceRecordMapper userBalanceSourceRecordMapper;

	private final NanoUserQuotaMapper nanoUserQuotaMapper;

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

	@Override
	public VipOrderDon submit(VipOrderDonPayReq payRequest) {
		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("系统检测操作异常，请稍后再试");
		/* 生成订单 */
		String donNo = SEQUENCE.nextId().toString();
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		Integer selectCount = this.count(Wrappers.lambdaQuery(VipOrderDon.class)
				.in(VipOrderDon::getUserId, userIdList)
				.eq(VipOrderDon::getStatus, VipOrderDon.Status.noPayment));
		if (selectCount > 0) {
			throw BusinessRuntimeException.getInstance("您存在待支付的会员订单");
		}
		VipOrderDon orderDon = new VipOrderDon();
		orderDon.setOrderNo(donNo);
		orderDon.setOpenId(user.getOpenId());
		//获取会员价格
		VipDeductDto vipMoneyIfDeduct = getVipMoneyIfDeduct(user, payRequest.getIsDeduct(), payRequest.getNum());
		BigDecimal vipMoney = getVipMoney(payRequest.getNum());
		BigDecimal actuallyPayMoney = vipMoney;
		payRequest.setDonMoney(vipMoney);
		if (vipMoneyIfDeduct != null) {
			payRequest.setDonMoney(vipMoney.subtract(vipMoneyIfDeduct.getDeductMoney()));
		}
		orderDon.setMoney(payRequest.getDonMoney());
		//渠道链接id
		if (payRequest.getPopularizeId() != null) {
			orderDon.setPopularizeId(payRequest.getPopularizeId());
		}
		orderDon.setStatus(VipOrderDon.Status.noPayment);
		orderDon.setUserId(user.getId());
		orderDon.setType(VipOrderDon.Type.getType(payRequest.getType()));
		orderDon.setIsWebPay(payRequest.getIsWebPay());
		//扣除使用优惠券、余额的订单金额
		deductOrderMoney(orderDon, user, payRequest, actuallyPayMoney);
		//设置订单支付商品信息
		orderDon.setPayTitle(Constant.VIP_TITLE);
		orderDon.setGoodsId(Constant.VIP_RELATE_GOODS_ID);
		//购买月数
		orderDon.setNum(payRequest.getNum());
		if (vipMoneyIfDeduct != null) {
			orderDon.setDeductMoney(vipMoneyIfDeduct.getDeductMoney());
			orderDon.setActuallyDeductMoney(vipMoneyIfDeduct.getActuallyDeDuctMoney());
			orderDon.setExtendsDays(vipMoneyIfDeduct.getExtendsDays());
		}

		this.saveOrUpdate(orderDon);

		Long orderId = orderDon.getId();
		//使用银河币记录
		userGalaxyCoinService.handleUserGalaxyCoinOrderNotify(orderDon.getId(), orderDon.getUserId(), orderDon.getOrderNo(), OrderDonGalaxyCoinRecord.Source.vip);
		//存在抵扣 记录抵扣成功后 需清除车票的ids
		if (vipMoneyIfDeduct != null) {
			List<Long> deductRelationIds = vipMoneyIfDeduct.getDeductRelationIds();
			recordVipDeductRelationIds(orderDon.getId(), orderDon.getUserId(), deductRelationIds);
		}
		//余额支付订单
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
			orderDon = getById(orderId);
			unifiedHandlerOrderNotify(orderDon);
		}
		VipOrderDon finalOrderDon = orderDon;
		if (finalOrderDon.getStatus() == VipOrderDon.Status.noPayment) {
			jobManager.addJob(EXPIRY_TIME, () -> {
				closeOrderDon(finalOrderDon.getUserId(), orderId);
			});
		}
		return orderDon;
	}

	@Override
	public AliPayParams aliPay(AlipayOrderDonReq re) throws Exception {
		String productCode = StrUtil.EMPTY;
		if (re.getType() == 1) {
			productCode = ZfbProductCode.MOBILE_WEB.getProductCode();
		}
		if (re.getType() == 2) {
			productCode = ZfbProductCode.PC_WEB.getProductCode();
		}
		return aliPayCommonService.unifiedPayVip(re.getOrderId(), productCode, re.getPayMode(), re.getReturnUrl());
	}

	@Override
	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();
		VipOrderDon orderDon = this.getById(oderId);
		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(VipOrderDon.Status.noPayment) && !orderDon.getStatus().equals(VipOrderDon.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.setType(VipOrderDon.Type.ALI_PAY);
		orderDon.setBuyerId(buyerId);
		//回调
		unifiedHandlerOrderNotify(orderDon);
	}

	@Override
	public void orderNotify(VipOrderDon orderDon) {
		unifiedHandlerOrderNotify(orderDon);
	}

	@Override
	public VipOrderDon renew(VipOrderDonPayReq payRequest) {
		Long userId = payRequest.getUserId();
		User user = userMapper.selectById(userId);
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, user);
		Integer selectCount = vipUserMapper.selectCount(Wrappers.lambdaQuery(VipUser.class)
				.in(VipUser::getUserId, userIdList)
				.gt(VipUser::getExpiryTime, DateTime.now()));
		if (selectCount == 0) {
			throw BusinessRuntimeException.getInstance("您会员已过期，无法续费");
		}
		Integer noPayOrderCount = this.count(Wrappers.lambdaQuery(VipOrderDon.class)
				.in(VipOrderDon::getUserId, userIdList)
				.eq(VipOrderDon::getStatus, VipOrderDon.Status.noPayment));
		if (noPayOrderCount > 0) {
			throw BusinessRuntimeException.getInstance("您存在待支付的会员订单");
		}
		/* 生成订单 */
		String donNo = SEQUENCE.nextId().toString();
		VipOrderDon orderDon = new VipOrderDon();
		orderDon.setOrderNo(donNo);
		orderDon.setOpenId(user.getOpenId());
		//获取续费会员价格
		payRequest.setDonMoney(getVipMoney(payRequest.getNum()));
		//续费订单
		orderDon.setOrderType(2);
		orderDon.setMoney(payRequest.getDonMoney());
		//渠道链接id
		if (payRequest.getPopularizeId() != null) {
			orderDon.setPopularizeId(payRequest.getPopularizeId());
		}
		orderDon.setStatus(VipOrderDon.Status.noPayment);
		orderDon.setUserId(user.getId());
		orderDon.setType(VipOrderDon.Type.getType(payRequest.getType()));
		orderDon.setIsWebPay(payRequest.getIsWebPay());
		//扣除使用优惠券、余额的订单金额
		deductOrderMoney(orderDon, user, payRequest, orderDon.getMoney());
		//设置订单支付商品信息
		orderDon.setPayTitle(Constant.VIP_TITLE);
		orderDon.setGoodsId(Constant.VIP_RELATE_GOODS_ID);
		orderDon.setNum(payRequest.getNum());

		this.saveOrUpdate(orderDon);

		Long orderId = orderDon.getId();
		//使用银河币记录
		userGalaxyCoinService.handleUserGalaxyCoinOrderNotify(orderDon.getId(), orderDon.getUserId(), orderDon.getOrderNo(), OrderDonGalaxyCoinRecord.Source.vip);
		//余额支付订单
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
			orderDon = getById(orderId);
			unifiedHandlerOrderNotify(orderDon);
		}
		return orderDon;
	}

	@Override
	public void closeOrderDon(long userId, Long orderId) {
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		VipOrderDon orderDon = getById(orderId);
		if (!userIdList.contains(orderDon.getUserId())) {
			throw BusinessRuntimeException.getInstance("订单错误");
		}
		if (orderDon.getStatus() != VipOrderDon.Status.noPayment) {
			throw BusinessRuntimeException.getInstance("订单状态错误");
		}
		VipOrderDon.Status status = isHasPaid(orderDon);
		if (status == VipOrderDon.Status.noPayment) {
			log.info("关闭订单 orderId:{}", orderId);
			orderDon.setStatus(VipOrderDon.Status.close);
			updateById(orderDon);
			//返还余额
			if (orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) {
				userBenefitsService.addUserBalance(orderDon.getUserId(), orderDon.getBalance(), UserBalanceSourceRecord.Source.vip_order_close, null, orderId, UserBalanceSourceRecord.Source.vip_order_close.getDesc(), true);
			}
			//返回银河币
			UserGalaxyCoinRecord userGalaxyCoinRecord = userGalaxyCoinRecordMapper.selectOne(Wrappers.lambdaQuery(UserGalaxyCoinRecord.class)
					.eq(UserGalaxyCoinRecord::getOrderId, orderDon.getId())
					.eq(UserGalaxyCoinRecord::getSource, OrderDonGalaxyCoinRecord.Source.vip.ordinal())
					.last("limit 1"));
			if (userGalaxyCoinRecord != null) {
				userGalaxyCoinService.sendOrderGalaxyCloseOrder(orderDon.getId(), orderDon.getUserId(), userGalaxyCoinRecord.getGalaxyCoin().abs(), OrderDonGalaxyCoinRecord.Source.vip);
			}
		}
	}

	private VipOrderDon.Status isHasPaid(VipOrderDon orderDon) {
		if (orderDon.getType() == VipOrderDon.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(VipOrderDon.Status.complete);
						orderDon.setTransactionId(zfbOrderDetail.getTradeNo());
						Date sendPayDate = zfbOrderDetail.getSendPayDate();
						orderDon.setPayTime(sendPayDate);
						//买家支付宝账号
						String buyerId = Optional.ofNullable(zfbOrderDetail.getBuyerUserId()).orElse(zfbOrderDetail.getBuyerOpenId());
						orderDon.setBuyerId(buyerId);
						unifiedHandlerOrderNotify(orderDon);
					}
				}
			} catch (Exception e) {

			}
		}
		return orderDon.getStatus();
	}

	/**
	 * 查询支付宝订单详情
	 */
	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;
	}

	private void unifiedHandlerOrderNotify(VipOrderDon orderDon) {
		orderDon.setStatus(VipOrderDon.Status.complete);
		this.updateById(orderDon);
		//余额使用记录
		if (orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) {
			userBenefitsService.recordBalanceBySource(orderDon.getUserId(), orderDon.getBalance().negate(), UserBalanceSourceRecord.Source.vip_order, orderDon.getId(), UserBalanceSourceRecord.Source.vip_order.getDesc(), null, null);
		}
		Long userId = orderDon.getUserId();
		//只选择一个号
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		VipUser vipUser = Optional.ofNullable(vipUserMapper.selectOne(Wrappers.lambdaQuery(VipUser.class)
				.in(VipUser::getUserId, userIdList)
				.last("limit 1"))).orElse(new VipUser());
		vipUser.setUserId(userId);
		int offsetMonths = orderDon.getNum();
		//发放会员车票 普通订单
		if (orderDon.getOrderType() == 1) {
			vipUser.setStartTime(DateTime.now());
			vipUser.setExpiryTime(DateUtil.offsetMonth(vipUser.getStartTime(), offsetMonths));
			//延长用户会员时长
			if (orderDon.getExtendsDays() > 0) {
				vipUser.setExpiryTime(DateUtil.offsetDay(vipUser.getExpiryTime(), orderDon.getExtendsDays()));
			}
			if (vipUser.getId() == null) {
				try {
					vipUserMapper.insert(vipUser);
				} catch (DuplicateKeyException e) {
				}
			} else vipUserMapper.updateById(vipUser);
			//发送车票
			sendVipTicketToUser(orderDon.getNum(), vipUser.getUserId(), vipUser.getStartTime(), vipUser.getExpiryTime(), userIdList, orderDon.getId());
		} else {
			//续费订单
			vipUser.setExpiryTime(DateUtil.offsetMonth(vipUser.getExpiryTime(), offsetMonths));
			vipUserMapper.updateById(vipUser);
			//续费订单
			setTicketToVipExpiryTime(userIdList, vipUser.getUserId(), vipUser.getExpiryTime());

			//增加nano剩余次数
			GroupsRelationView groupsRelationView = beanSearcher.searchFirst(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getGoodsId, Constant.NANO_GOODS_ID).field(GroupsRelationView::getUserId, userIdList).op(Operator.InList).field(GroupsRelationView::getIsVip, Boolean.TRUE).build());
			if (groupsRelationView != null) {
				NanoUserQuota nanoUserQuota = nanoUserQuotaMapper.selectOne(Wrappers.lambdaQuery(NanoUserQuota.class).eq(NanoUserQuota::getRelationId, groupsRelationView.getId()).last("limit 1"));
				if (nanoUserQuota != null) {
					Long skuId = groupsRelationView.getSkuId();
					GoodsDonSku sku = skuMapper.selectById(skuId);
					Integer offestNum = offsetMonths * sku.getNanoQuota();
					nanoUserQuota.setTotalQuota(nanoUserQuota.getTotalQuota() + offestNum);
					nanoUserQuota.setRemainingQuota(nanoUserQuota.getRemainingQuota() + offestNum);
					nanoUserQuotaMapper.updateById(nanoUserQuota);
				}
			}
		}
		//金额大于0 是否是分销订单
		if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) {
			handlerDistributeOrder(orderDon);
			this.saveOrUpdate(orderDon);
		}

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

	private void sendVipTicketToUser(Integer num, Long userId, Date vipStartTime, Date vipExpiryTime, List<Long> userIds, Long orderId) {
		//是否存在抵扣 抵扣成功 清除车票
		VipOrderDonDeductRelation vipOrderDonDeductRelation = vipOrderDonDeductRelationMapper.selectOne(Wrappers.lambdaQuery(VipOrderDonDeductRelation.class)
				.eq(VipOrderDonDeductRelation::getOrderId, orderId)
				.last("limit 1"));
		List<Long> deductRelationIds = null;
		if (vipOrderDonDeductRelation != null) {
			try {
				deductRelationIds = Jsons.parseList(vipOrderDonDeductRelation.getRelationIds(), Long.class);
				vipOrderDonDeductRelation.setStatus(true);
				vipOrderDonDeductRelationMapper.updateById(vipOrderDonDeductRelation);
			} catch (Exception e) {
			}
		}
		List<VipGoodsSku> skus = vipGoodsSkuMapper.selectList(null);
		List<Long> deductSkuIds = null;
		if (CollUtil.isNotEmpty(deductRelationIds)) {
			List<GroupsRelationView> groupsRelationViews = beanSearcher.searchAll(GroupsRelationView.class, MapUtils.builder()
					.field(GroupsRelationView::getUserId, userIds).op(Operator.InList)
					.field(GroupsRelationView::getId, deductRelationIds).op(Operator.InList).build());
			deductSkuIds = new ArrayList<>();
			//不是同规格车票直接清除
			List<Long> vipSkuIds = skus.stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
			Map<Long, List<VipGoodsSku>> vipGoodsSkuMap = skus.stream().collect(Collectors.groupingBy(VipGoodsSku::getGoodsId));
			for (GroupsRelationView groupsRelationView : groupsRelationViews) {
				Long goodsId = groupsRelationView.getGoodsId();
				Long skuId = groupsRelationView.getSkuId();
				Long relationId = groupsRelationView.getId();
				Long newRelationId = relationId;
				Long vipSkuId = skuId;
				if (vipSkuIds.contains(skuId)) {
					//同规格抵扣会员
					//将车票弄成会员类型
					relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
							.set(GroupsRelation::getUserId, userId)
							.set(GroupsRelation::getIsVip, Boolean.TRUE)
							.set(GroupsRelation::getStartTime, vipStartTime)
							.set(GroupsRelation::getExpiryTime, vipExpiryTime)
							.in(GroupsRelation::getUserId, userIds)
							.eq(GroupsRelation::getId, relationId));
				} else {
					//获取对应类型 会员规格id
					List<VipGoodsSku> thisGoodsVipSkuIds = vipGoodsSkuMap.get(goodsId);
					vipSkuId = thisGoodsVipSkuIds.get(0).getSkuId();
					newRelationId = groupRelationFrontService.getTicket(userId, vipSkuId, Boolean.TRUE);
					GroupsRelation relation = relationMapper.selectById(relationId);
					relation.setNewRelationId(newRelationId);
					//清除不是同规格旧车票
					relationClearService.clearTicket(relation, UserTicketClearedRecord.Source.vip_deduct);
				}
				//抵扣规格
				deductSkuIds.add(vipSkuId);
				//重置镜像user
				resetMirrorUser(goodsId, vipSkuId, relationId, newRelationId, vipExpiryTime, num);
			}
		}
		for (VipGoodsSku sku : skus) {
			//未有抵扣 直接发送会员车票
			if (deductSkuIds == null || !deductSkuIds.contains(sku.getSkuId())) {
				Long relationId = groupRelationFrontService.getTicket(userId, sku.getSkuId(), Boolean.TRUE);
				if (relationId != null && sku.getGoodsId() == Constant.NANO_GOODS_ID) {
					User user = userMapper.selectById(userId);
					GoodsDonSku goodsDonSku = skuMapper.selectById(sku.getSkuId());
					createNanoUser(relationId, user, goodsDonSku.getNanoQuota() * num);
				}
			}
		}
	}

	private void deductOrderMoney(VipOrderDon orderDon, User user, VipOrderDonPayReq payRequest, BigDecimal actuallyPayMoney) {
		//存在银河币
		deductGalaxyCoinPayOrderMoney(orderDon, payRequest.getGalaxyCoin(), user, actuallyPayMoney);
		BigDecimal balance = payRequest.getBalance();
		//存在余额
		deductBalancePayOrderMoney(orderDon, balance, user);
	}

	private VipDeductDto getVipMoneyIfDeduct(User user, Boolean isDeduct, Integer months) {
		//若用户抵扣
		if (isDeduct) {
			return vipFrontService.checkAndGetOrderDeductMoney(user.getId(), months);
		}
		return null;
	}

	public void deductGalaxyCoinPayOrderMoney(VipOrderDon orderDon, BigDecimal toUseGalaxyCoin, User user, BigDecimal actuallyPayMoney) {
		//存在银河币
		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 = actuallyPayMoney.multiply(galaxyCoinPayConfigDto.getMaxRate());
				if (thisDeductMoney.compareTo(maxDeductMoney) > 0) {
					thisDeductMoney = maxDeductMoney;
					//此时需要扣除的银河币
					subGalxyCoin = thisDeductMoney.divide(deductMoneyEachCoin);
				}
				if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
					orderDon.setType(VipOrderDon.Type.GALAXY_COIN);
				}
				//银河币抵扣
				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.vip.ordinal());
				orderDonGalaxyCoinRecordMapper.insert(orderDonGalaxyCoinRecord);
				orderDon.setMoney(orderMoney.subtract(thisDeductMoney));
				if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
					orderDon.setType(VipOrderDon.Type.GALAXY_COIN);
				}
			}
		}
	}

	public void deductBalancePayOrderMoney(VipOrderDon orderDon, BigDecimal balance, User user) {
		//存在余额
		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(VipOrderDon.Type.BALANCE);
			}
			BigDecimal userBalance = user.getBalance();
			//扣除余额 是否成功
			Integer success = userMapper.deductBalance(user.getId(), subBalance, userBalance);
			if (success != 1) throw BusinessRuntimeException.getInstance("您的余额不足!");
			orderDon.setBalance(subBalance);
		}
	}

	/**
	 * 设置会员车票同一过期时间
	 */
	private void setTicketToVipExpiryTime(List<Long> userIds, Long vipUserId, Date expiryTime) {
		List<Long> vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
		List<Long> selfSkuIds = beanSearcher.searchAll(GroupsRelationView.class, MapUtils.builder()
				.field(GroupsRelationView::getUserId, userIds).op(Operator.InList)
				.field(GroupsRelationView::getSkuId, vipSkuIds).op(Operator.InList)
				.field(GroupsRelationView::getIsVip, true)
				.onlySelect(GroupsRelationView::getSkuId)
				.build()).stream().map(GroupsRelationView::getSkuId).collect(Collectors.toList());
		if (selfSkuIds.size() != vipSkuIds.size()) {
			vipSkuIds.forEach(vipSkuId->{
				if (!selfSkuIds.contains(vipSkuId)) {
					//发送 缺少的规格
					groupRelationFrontService.getTicket(vipUserId, vipSkuId, Boolean.TRUE);
				}
			});
		}
		relationMapper.update(null, Wrappers.lambdaUpdate(GroupsRelation.class)
				.set(GroupsRelation::getExpiryTime, expiryTime)
				.set(GroupsRelation::getUpdateTime, DateTime.now())
				.in(GroupsRelation::getUserId, userIds)
				.eq(GroupsRelation::getStatus, GroupsRelation.Status.validity)
				.eq(GroupsRelation::getIsVip, Boolean.TRUE));
	}

	private BigDecimal getVipMoney(Integer num) {
		SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class)
				.eq(SysConfig::getSysKey, Constant.VIP_FEE_KEY)
				.last("limit 1"));
		if (sysConfig == null || StrUtil.isEmpty(sysConfig.getSysValue())) {
			throw BusinessRuntimeException.getInstance("系统异常");
		}
		//校验月数
		if (num != 1 && num != 3 && num != 12) {
			throw BusinessRuntimeException.getInstance("购买的会员月数错误");
		}
		BigDecimal vipFee = BigDecimal.valueOf(Long.valueOf(sysConfig.getSysValue()));
		return vipFee.multiply(BigDecimal.valueOf(num));
	}

	private void recordVipDeductRelationIds(Long orderId, Long userId, List<Long> deductRelationIds) {
		VipOrderDonDeductRelation vipOrderDonDeductRelation = new VipOrderDonDeductRelation();
		vipOrderDonDeductRelation.setOrderId(orderId);
		vipOrderDonDeductRelation.setUserId(userId);
		vipOrderDonDeductRelation.setRelationIds(deductRelationIds.toString());
		vipOrderDonDeductRelationMapper.insert(vipOrderDonDeductRelation);
	}

	/**
	 * 重置镜像user
	 */
	private void resetMirrorUser(Long goodsId, Long skuId, Long oldRelationId, Long newRelationId, Date vipExpiryTime, Integer payNum) {
		GoodsDonSku sku = skuMapper.selectById(skuId);
		if (goodsId == Constant.MJ_GID) {
			MidjourneyUser user = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class)
					.eq(MidjourneyUser::getRelationId, oldRelationId)
					.last("limit 1"));
			if (user != null) {
				user.setMjFastNum(sku.getMjFastNum());
				user.setMjRelaxNum(sku.getMjRelaxNum());
				user.setIsVip(Boolean.TRUE);
				user.setExpireTime(vipExpiryTime);
				user.setRelationId(newRelationId);
				midjourneyUserMapper.updateById(user);
				redisService.del(RedisService.key.MIDJOURNEY_USER.getName() + user.getUserToken());
			}
		}
		if (goodsId == Constant.GPT_PLUS_GID) {
			ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class)
					.eq(ChatgptUser::getRelationId, oldRelationId)
					.last("limit 1"));
			if (chatgptUser != null) {
				chatgptUser.setLimitNum(sku.getGptLimitNum());
				chatgptUser.setLimitTime(sku.getGptLimitTime());
				chatgptUser.setDsLimitNum(sku.getDsLimitNum());
				chatgptUser.setDsLimitTime(sku.getDsLimitTime());
				chatgptUser.setOtherLimitNum(sku.getOtherLimitNum());
				chatgptUser.setOtherLimitTime(sku.getOtherLimitTime());
				chatgptUser.setPackageId(0l);
				chatgptUser.setClearPackageTime(null);
				chatgptUser.setRenewOrderId(0l);
				chatgptUser.setRenewSkuId(null);
				chatgptUser.setRenewExpiryTime(null);
				chatgptUser.setIsVip(Boolean.TRUE);
				chatgptUser.setExpireTime(vipExpiryTime);
				chatgptUser.setRelationId(newRelationId);
				chatgptUserMapper.updateById(chatgptUser);
				try {
					//清除次数
					chatGptAccountService.clearGptNum(oldRelationId);
				} catch (Exception e) {
				}
			}
		}
		if (goodsId == Constant.CALUDE_GOODS_ID) {
			ClaudeUser claudeUser = claudeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeUser.class)
					.eq(ClaudeUser::getRelationId, oldRelationId)
					.last("limit 1"));
			if (claudeUser != null) {
				claudeUser.setLimitNum(sku.getGptLimitNum());
				claudeUser.setLimitTime(sku.getGptLimitTime());
				claudeUser.setRenewOrderId(null);
				claudeUser.setRenewExpiryTime(null);
				claudeUser.setRenewSkuId(null);
				claudeUser.setIsVip(Boolean.TRUE);
				claudeUser.setExpireTime(vipExpiryTime);
				claudeUser.setRelationId(newRelationId);
				claudeUserMapper.updateById(claudeUser);
				try {
					//清除次数
					claudeService.clearNum(claudeUser.getUserToken());
				} catch (Exception e) {
				}
			}
		}
		if (goodsId == Constant.GROK_GOODS_ID) {
			GrokUser grokUser = grokUserMapper.selectOne(Wrappers.lambdaQuery(GrokUser.class)
					.eq(GrokUser::getRelationId, oldRelationId)
					.last("limit 1"));
			if (grokUser != null) {
				grokUser.setLimitNum(sku.getGptLimitNum());
				grokUser.setLimitTime(sku.getGptLimitTime());
				grokUser.setIsVip(Boolean.TRUE);
				grokUser.setExpireTime(vipExpiryTime);
				grokUser.setRelationId(newRelationId);
				grokUserMapper.updateById(grokUser);
			}
		}
		if (goodsId == Constant.LUMA_GOODS_ID) {
			LumaUser lumaUser = lumaUserMapper.selectOne(Wrappers.lambdaQuery(LumaUser.class)
					.eq(LumaUser::getRelationId, oldRelationId)
					.last("limit 1"));
			if (lumaUser != null) {
				lumaUser.setNum(sku.getLumaNum());
				lumaUser.setIsVip(Boolean.TRUE);
				lumaUser.setExpireTime(vipExpiryTime);
				lumaUser.setRelationId(newRelationId);
				lumaUserMapper.updateById(lumaUser);
				redisService.del(RedisService.key.LUMA_NUM_LIMIT.getName() + lumaUser.getId());
			}
		}

		//nano 抵扣
		if (goodsId == Constant.NANO_GOODS_ID) {
			NanoUserQuota nanoUserQuota = nanoUserQuotaMapper.selectOne(Wrappers.lambdaQuery(NanoUserQuota.class)
					.eq(NanoUserQuota::getRelationId, oldRelationId)
					.last("limit 1"));
			if (nanoUserQuota != null) {
				//payNum 会员月数
				nanoUserQuota.setTotalQuota(sku.getNanoQuota() * payNum);
				nanoUserQuota.setRemainingQuota(nanoUserQuota.getTotalQuota());
				nanoUserQuota.setUsedQuota(0);
				nanoUserQuota.setPurchaseDate(DateTime.now());
				nanoUserQuota.setRelationId(newRelationId);
				nanoUserQuotaMapper.updateById(nanoUserQuota);
			}
		}
	}

	/**
	 * 处理会员分销
	 */
	private void handlerDistributeOrder(VipOrderDon orderDon) {
		Long userId = orderDon.getUserId();
		UserDistributeShared distributeShared = userDistributeSharedMapper.selectOne(Wrappers.lambdaQuery(UserDistributeShared.class)
				.eq(UserDistributeShared::getUserId, userId)
				.last("limit 1"));
		if (distributeShared == null || !distributeShared.getIsBind()) {
			return;
		}
		//分销订单
		orderDon.setIsDistribute(Boolean.TRUE);
		orderDon.setCpsPopularizeId(distributeShared.getDsPopularizeId());
		Long sharedId = distributeShared.getSharedId();
		Long goodsId = Constant.VIP_RELATE_GOODS_ID;
		GoodsDon goodsDon = goodsDonMapper.selectById(goodsId);
		if (goodsDon == null) {
			log.info("会员分销关联平台不存在，不分销");
			return;
		}
		BigDecimal points = null;
		BigDecimal returnMoney = null;
		BigDecimal orderMoney = orderDon.getMoney();
		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, sharedId)
					.eq(UserDistribute::getDeleted, Boolean.TRUE)
					.last("limit 1"));
			//分销比例
			Integer rate = 0;
			if (userDistribute == null) {
				//普通分销者 是否享受过该用户的首单分销
				DistributeWaitingSendPoints isReceived = distributeWaitingSendPointsMapper.selectOne(Wrappers.lambdaQuery(DistributeWaitingSendPoints.class)
						.eq(DistributeWaitingSendPoints::getSharedId, sharedId)
						.eq(DistributeWaitingSendPoints::getUserId, userId)
						.in(DistributeWaitingSendPoints::getSendStatus, List.of(DistributeWaitingSendPoints.Status.waiting.name(), DistributeWaitingSendPoints.Status.success.name()))
						.last("limit 1"));
				if (isReceived != null) {
					return;
				}
				rate = goodsDon.getRate();
				//特定普通渠道 所有平台比例改成10%
				if (ObjectUtil.equal(sharedId, Constant.SPECIAL_DISTRIBUTE_USER_ID) && rate > 0) {
					rate = 10;
				}
				returnMoney = orderMoney.multiply(BigDecimal.valueOf(rate)).divide(BigDecimal.valueOf(100));
			} else {
				//渠道推广
				orderDon.setIsFixedDistribute(Boolean.TRUE);
				//固定推广分销 平台比例
				UserPlatDistributeRate userPlatDistributeRate = userPlatDistributeRateMapper.selectOne(Wrappers.lambdaQuery(UserPlatDistributeRate.class)
						.eq(UserPlatDistributeRate::getGoodsId, goodsId)
						.eq(UserPlatDistributeRate::getDistributeId, userDistribute.getId())
						.last("limit 1"));
				//未配置平台分销比例 寻找默认比例
				if (userPlatDistributeRate == null) {
					BusinessDistributeDefaultRateConfig defaultRateConfig = businessDistributeDefaultRateConfigMapper.selectOne(Wrappers.lambdaQuery(BusinessDistributeDefaultRateConfig.class)
							.eq(BusinessDistributeDefaultRateConfig::getGoodsId, goodsId)
							.last("limit 1"));
					if (defaultRateConfig != null) {
						userPlatDistributeRate = getUserPlatDistributeRate(defaultRateConfig.getRate(), defaultRateConfig.getSecondRate());
					}
				}
				if (userPlatDistributeRate != null) {
					rate = userPlatDistributeRate.getRate();
					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 (points != null && points.compareTo(BigDecimal.ZERO) > 0) {
				log.info("用户{}邀请{},产生会员分销订单分发积分记录入库", sharedId, userId);
				DistributeWaitingSendPoints distributeWaitingSendPoints = new DistributeWaitingSendPoints();
				distributeWaitingSendPoints.setSharedId(sharedId);
				distributeWaitingSendPoints.setUserId(userId);
				distributeWaitingSendPoints.setIsVip(Boolean.TRUE);
				distributeWaitingSendPoints.setOrderId(orderDon.getId());
				distributeWaitingSendPoints.setPoints(points);
				distributeWaitingSendPoints.setSendStatus(DistributeWaitingSendPoints.Status.waiting);
				distributeWaitingSendPoints.setSendTime(DateUtil.offsetDay(orderDon.getPayTime(), 3));
				distributeWaitingSendPoints.setRate(rate);
				distributeWaitingSendPointsMapper.insert(distributeWaitingSendPoints);
			}
		}
	}

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

	public 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("银河币抵扣异常,请刷新页面重试");
		}
	}


	public void returnGalaxyCoin(VipOrderDon 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.vip);
				} catch (Exception e) {
					log.error("发送会员用户：{}银河币points：{}错误:{}", userId, retrunGalaxyCoin, StringUtil.getErrorText(e));
				}

			}
		}
	}

	/**
	 * 存在关闭订单退款余额的记录
	 */
	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 NanoUserQuota createNanoUser(Long relationId, User user, Integer nanoQuota) {
		NanoUserQuota nanoUserQuota = new NanoUserQuota();
		nanoUserQuota.setUid(user.getId());
		nanoUserQuota.setRelationId(relationId);
		nanoUserQuota.setUserToken(UUID.randomUUID().toString());
		nanoUserQuota.setNickname(user.getNickname());
		nanoUserQuota.setAvatar(user.getHeadimgurl());
		nanoUserQuota.setPurchaseDate(DateTime.now());
		nanoUserQuota.setTotalQuota(nanoQuota);
		nanoUserQuota.setRemainingQuota(nanoUserQuota.getTotalQuota());
		try {
			nanoUserQuotaMapper.insert(nanoUserQuota);
		} catch (DuplicateKeyException e) {

		}
		return nanoUserQuota;
	}
}
