소스 검색

codex 抵扣升级

zoujiajian 3 달 전
부모
커밋
a663a2893a

+ 1 - 1
netflix-dao/src/main/java/com/cyksj/mapper/codex/CodexUserRenewExpiryRecordMapper.java

@@ -16,5 +16,5 @@ import java.util.List;
 public interface CodexUserRenewExpiryRecordMapper extends BaseMapper<CodexUserRenewExpiryRecord> {
 	CodexUserRenewExpiryRecord getOtherRenewSku(@Param("orderId") Long orderId, @Param("relationId") Long relationId, @Param("userIds") List<Long> userIds);
 
-	List<OrderDon> getOtherRenewSkus(Long renewOrderId, Long relationId, List<Long> userIdList);
+	List<OrderDon> getOtherRenewSkus(@Param("orderId") Long renewOrderId, @Param("relationId") Long relationId, @Param("userIds") List<Long> userIdList);
 }

+ 2 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/CodexDeductRecord.java

@@ -25,4 +25,6 @@ public class CodexDeductRecord extends BaseEntity{
 	 * 抵扣状态 默认false
 	 */
 	private Boolean status;
+
+    private Integer extendsDays;
 }

+ 10 - 0
netflix-dao/src/main/java/com/cyksj/model/request/CodexUpgradePayReq.java

@@ -25,4 +25,14 @@ public class CodexUpgradePayReq {
 	 * 使用优惠券
 	 */
 	private Long couponId;
+
+	/**
+	 * 使用银河币
+	 */
+	private java.math.BigDecimal galaxyCoin;
+
+	/**
+	 * 使用余额
+	 */
+	private java.math.BigDecimal balance;
 }

+ 6 - 0
netflix-dao/src/main/java/com/cyksj/model/response/CodexDeductResp.java

@@ -20,4 +20,10 @@ public class CodexDeductResp {
 	 * 是否可抵扣
 	 */
 	private Boolean isDeduct = Boolean.TRUE;
+
+
+    /**
+     * 超出部分可延长天数
+     */
+    private Integer extendsDays;
 }

+ 2 - 4
netflix-service/src/main/java/com/cyksj/service/codex/CodexService.java

@@ -3,10 +3,8 @@ package com.cyksj.service.codex;
 import com.cyksj.model.entity.CodexUser;
 import com.cyksj.model.entity.GoodsDonSku;
 import com.cyksj.model.entity.GroupsRelation;
-import com.cyksj.model.entity.OrderDon;
 import com.cyksj.model.request.ClaudeCodeApiKeysReq;
 import com.cyksj.model.request.ClaudeCodeDelReq;
-import com.cyksj.model.request.CodexUpgradePayReq;
 import com.cyksj.model.request.UpdateDailyLimitRequest;
 import com.cyksj.model.request.codex.CodexUserPackageReq;
 import com.cyksj.model.response.CodexDeductResp;
@@ -61,9 +59,9 @@ public interface CodexService {
 
     ClaudeCodeResp createOrUpdateCodexUserPackageApi(Long userId, String planName, Integer openaiDailyLimit, Integer openaiQuota, Date expiryTime) throws Exception;
 
-    CodexDeductResp getDeductMoney(Long userId, Long relationId);
+    CodexDeductResp getDeductMoney(Long userId, Long relationId, Long upgradeSkuId);
 
-    OrderDon deductSubmitOrder(CodexUpgradePayReq payReq) throws Exception;
+    GroupsRelation getClaudeCodeRelation(Long userId, GoodsDonSku sku);
 
     Boolean getUserSubs(Long userId);
 

+ 26 - 104
netflix-service/src/main/java/com/cyksj/service/codex/impl/CodexServiceImpl.java

@@ -29,7 +29,6 @@ import com.cyksj.model.dto.CouponPopularizeDto;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.request.ClaudeCodeApiKeysReq;
 import com.cyksj.model.request.ClaudeCodeDelReq;
-import com.cyksj.model.request.CodexUpgradePayReq;
 import com.cyksj.model.request.UpdateDailyLimitRequest;
 import com.cyksj.model.request.codex.CodexUserPackageReq;
 import com.cyksj.model.response.CodexDeductResp;
@@ -53,7 +52,6 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.dao.DuplicateKeyException;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -158,7 +156,7 @@ public class CodexServiceImpl implements CodexService {
 	}
 
 	@Override
-	public CodexDeductResp getDeductMoney(Long userId, Long relationId) {
+    public CodexDeductResp getDeductMoney(Long userId, Long relationId, Long upgradeSkuId) {
 		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
 		CodexDeductResp codexDeductResp = new CodexDeductResp();
 		List<Long> sendCodexSkuIds = skuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class).eq(GoodsDonSku::getGoodsId, Constant.CLAUDE_CODE_GOODS_ID).eq(GoodsDonSku::getIsCodex, Boolean.TRUE)).stream().map(GoodsDonSku::getId).collect(Collectors.toList());
@@ -174,6 +172,11 @@ public class CodexServiceImpl implements CodexService {
 				return codexDeductResp;
 			}
 		}
+        GoodsDonSku upgradeSku = skuMapper.selectById(upgradeSkuId);
+        if (upgradeSku.getGoodsId() != Constant.CODEX_GOODS_ID) {
+            codexDeductResp.setDeductMoney(BigDecimal.ZERO);
+            return codexDeductResp;
+        }
 		MapBuilder builder = MapUtils.builder();
 		if (relationId != null) {
 			builder.field(GroupsRelationMirrorView::getId, relationId);
@@ -183,111 +186,17 @@ public class CodexServiceImpl implements CodexService {
 				.field(GroupsRelationMirrorView::getUserId, userIdList).op(Operator.InList)
 				.field(GroupsRelationMirrorView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
 				.build());
-		BigDecimal deductMoney;
 		if (groupsRelationMirrorView == null || groupsRelationMirrorView.getExpiryTime().before(DateTime.now())) {
-			deductMoney = BigDecimal.ZERO;
-		} else {
+            codexDeductResp.setDeductMoney(BigDecimal.ZERO);
+        } else {
 			relationId = groupsRelationMirrorView.getId();
 			CodexUser codexUser = codexUserMapper.selectOne(Wrappers.lambdaQuery(CodexUser.class).eq(CodexUser::getRelationId, relationId).last("limit 1"));
 			Assert.notNull(codexUser, "系统异常,请联系客服");
-			deductMoney = getFinalDeductMoney(relationId, groupsRelationMirrorView.getSkuId(), codexUser.getRenewSkuId(), codexUser.getRenewOrderId(), codexUser.getRenewExpiryTime(), groupsRelationMirrorView.getStartTime(), groupsRelationMirrorView.getExpiryTime(), DateTime.now(), userIdList);
+            codexDeductResp = getFinalDeductMoney(relationId, groupsRelationMirrorView.getSkuId(), codexUser.getRenewSkuId(), codexUser.getRenewOrderId(), codexUser.getRenewExpiryTime(), groupsRelationMirrorView.getStartTime(), groupsRelationMirrorView.getExpiryTime(), DateTime.now(), userIdList, upgradeSku);
 		}
-		codexDeductResp.setDeductMoney(deductMoney);
 		return codexDeductResp;
 	}
 
-	@Override
-	@Transactional(rollbackFor = Throwable.class)
-	public OrderDon deductSubmitOrder(CodexUpgradePayReq payReq) throws Exception {
-		Long userId = payReq.getUserId();
-		//codex 车票id
-		Long relationId = payReq.getRelationId();
-		CodexDeductResp codexDeductResp = getDeductMoney(userId, relationId);
-		if (!codexDeductResp.getIsDeduct()) {
-			throw BusinessRuntimeException.getInstance("你存在claude code 无法抵扣");
-		}
-		//抵扣金额
-		BigDecimal deductMoney = codexDeductResp.getDeductMoney();
-		Long skuId = payReq.getSkuId();
-
-		GoodsDonSku sku = skuMapper.selectById(skuId);
-		if (sku == null || sku.getGoodsId() != Constant.CLAUDE_CODE_GOODS_ID || !sku.getIsCodex()) {
-			throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重试");
-		}
-		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
-		int noPayCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class).in(OrderDon::getUserId, userIdList).eq(OrderDon::getGoodsId, sku.getGoodsId())
-				.eq(OrderDon::getStatus, OrderDon.Status.noPayment.toString()));
-		if (noPayCount > 0) {
-			throw new BusinessRuntimeException("您有未支付订单.");
-		}
-		String cacheKye = "codex_deduct_cache_key:" + relationId;
-		boolean b = redisService.setNx(cacheKye, relationId, 10L);
-		if (!b) {
-			throw BusinessRuntimeException.getInstance("系统繁忙,请刷新页面重试");
-		}
-		CouponUser couponUser = null;
-		if (payReq.getCouponId() != null) {
-			CouponPopularizeDto couponPopularizeDto = checkCouponStatus(skuId, null, payReq.getCouponId(), userId, false);
-			//记录优惠券使用状态
-			couponUser = couponStatusRecord(null, payReq.getCouponId(), userId, couponPopularizeDto);
-		}
-
-		OrderDon orderDon;
-		try {
-			orderDon = new OrderDon();
-			orderDon.setGoodsId(sku.getGoodsId());
-			orderDon.setSkuId(sku.getId());
-			orderDon.setUserId(userId);
-			//优惠 --> 订单金额
-			deductOrderMoney(orderDon, couponUser);
-			orderDon.setMoney(sku.getPrice().subtract(deductMoney));
-			orderDon.setType(OrderDon.Type.ALI_PAY);
-
-			/* 生成订单 */
-			String donNo = SEQUENCE.nextId().toString();
-			orderDon.setOrderNo(donNo);
-			orderDon.setStatus(OrderDon.Status.noPayment);
-
-			//锁一个cc的车票id
-			//是否存在无赠送的claude code 直接原规格上抵扣
-			List<Long> sendCodexSkuIds = skuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class).eq(GoodsDonSku::getGoodsId, Constant.CLAUDE_CODE_GOODS_ID).eq(GoodsDonSku::getIsCodex, Boolean.TRUE)).stream().map(GoodsDonSku::getId).collect(Collectors.toList());
-			//cc车票id
-			Long ccRelationId = null;
-			if (CollUtil.isEmpty(sendCodexSkuIds)) {
-				//是否存在cc
-				Integer selectCount = claudeCodeUserMapper.selectCount(Wrappers.lambdaQuery(ClaudeCodeUser.class).in(ClaudeCodeUser::getUserId, userIdList));
-				if (selectCount > 0) {
-					throw BusinessRuntimeException.getInstance("你存在claude code 无法抵扣");
-				}
-			} else {
-				GroupsRelationMirrorView groupsRelationMirrorView = beanSearcher.searchFirst(GroupsRelationMirrorView.class, MapUtils.builder()
-						.field(GroupsRelationMirrorView::getUserId, userIdList).op(Operator.InList)
-						.field(GroupsRelationMirrorView::getSkuId, sendCodexSkuIds).op(Operator.NotIn)
-						.field(GroupsRelationMirrorView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
-						.build());
-				if (groupsRelationMirrorView != null) {
-					ccRelationId = groupsRelationMirrorView.getId();
-				}
-			}
-
-			GroupsRelation relation = getClaudeCodeRelation(userId, sku);
-			orderDon.setRelationId(relation.getId());
-			orderDonMapper.insert(orderDon);
-
-			//记录抵扣记录
-			CodexDeductRecord codexDeductRecord = new CodexDeductRecord();
-			codexDeductRecord.setCcRelationId(ccRelationId);
-			codexDeductRecord.setOrderId(orderDon.getId());
-			codexDeductRecord.setRelationId(relationId);
-			codexDeductRecordMapper.insert(codexDeductRecord);
-		} finally {
-			if (redisService.hasKey(cacheKye)) {
-				redisService.del(cacheKye);
-			}
-		}
-		return orderDon;
-	}
-
 	@Override
 	public Boolean getUserSubs(Long userId) {
 		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
@@ -429,7 +338,8 @@ public class CodexServiceImpl implements CodexService {
 		return null;
 	}
 
-	private GroupsRelation getClaudeCodeRelation(Long userId, GoodsDonSku sku) {
+	@Override
+	public GroupsRelation getClaudeCodeRelation(Long userId, GoodsDonSku sku) {
 		//获取车票车位
 		GroupsRelation relation = getRelation(sku);
 		//锁定座位
@@ -472,7 +382,7 @@ public class CodexServiceImpl implements CodexService {
 		return relation;
 	}
 
-	public BigDecimal getFinalDeductMoney(Long relationId, Long relationSkuId, Long renewSkuId, Long renewOrderId, Date renewExpiryTime, Date relationStartTime, Date relationExpiryTime, DateTime now, List<Long> userIdList) {
+    public CodexDeductResp getFinalDeductMoney(Long relationId, Long relationSkuId, Long renewSkuId, Long renewOrderId, Date renewExpiryTime, Date relationStartTime, Date relationExpiryTime, DateTime now, List<Long> userIdList, GoodsDonSku upgradeSku) {
 		BigDecimal deductMoney = BigDecimal.ZERO;
 		//一个月当30天算单价 往上取整
 		//续费规格
@@ -563,13 +473,25 @@ public class CodexServiceImpl implements CodexService {
 
 			}
 		}
-		if (relationExpiryTime.after(now)) {
+        CodexDeductResp codexDeductResp = new CodexDeductResp();
+        if (relationExpiryTime.after(now)) {
 			//该车票抵扣金额
 			BigDecimal deductMoneyFromTicket = getDeductMoneyFromTicket(relationId, userIdList, relationSkuId, now, relationStartTime, relationExpiryTime);
 			deductMoney = deductMoney.add(deductMoneyFromTicket);
 		}
+        //超出可抵扣的金额 直接返回
+        if (deductMoney.compareTo(upgradeSku.getPrice()) >= 0) {
+            BigDecimal overMoney = deductMoney.subtract(upgradeSku.getPrice());
+            //超过抵扣金额可换延长会员多少天
+            //每天单价
+            BigDecimal daySingle = upgradeSku.getPrice().divide(BigDecimal.valueOf(upgradeSku.getMonths())).divide(BigDecimal.valueOf(30), 0, RoundingMode.DOWN);
+            //超出部分可换取多少天 低于每天单价为0天
+            BigDecimal extendsDays = overMoney.divide(daySingle, 0, RoundingMode.UP);
+            codexDeductResp.setExtendsDays(extendsDays.intValue());
+        }
 		log.info("codex车票id:{}最终到期时间为:{}车票可返回 抵扣金额:{}", relationId, DateUtil.format(relationExpiryTime, "yyyy-MM-dd HH:mm:ss"), deductMoney);
-		return deductMoney;
+        codexDeductResp.setDeductMoney(deductMoney);
+		return codexDeductResp;
 	}
 
 	private Retryer<ClaudeCodeResp> getApiRetryer(int wait, int stop) {

+ 3 - 0
netflix-service/src/main/java/com/cyksj/service/order/OrderDonService.java

@@ -10,6 +10,7 @@ import com.cyksj.model.dto.H5JsPayParams;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.UpgradeOrderDetailView;
 import com.cyksj.model.request.AlipayOrderDonReq;
+import com.cyksj.model.request.CodexUpgradePayReq;
 import com.cyksj.model.request.OrderPayRequest;
 
 import java.util.Date;
@@ -115,4 +116,6 @@ public interface OrderDonService extends IService<OrderDon> {
 	void receiveGptMirrorDayCard(Long orderId) throws Exception;
 
     OrderDon ccDeductSubmitOrder(OrderPayRequest payRequest);
+
+	OrderDon deductSubmitOrder(CodexUpgradePayReq payReq) throws Exception;
 }

+ 110 - 17
netflix-service/src/main/java/com/cyksj/service/order/impl/OrderDonServiceImpl.java

@@ -81,6 +81,7 @@ 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.response.CodexDeductResp;
 import com.cyksj.model.views.*;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.chatgpt.GptUserRechargeRecordService;
@@ -3197,23 +3198,6 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			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);
 		}
@@ -3480,6 +3464,29 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 			}
 		}
 
+        //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);
+            //延长
+            if (codexDeductRecord.getExtendsDays() != null && codexDeductRecord.getExtendsDays() > 0) {
+                GroupsRelation newRelation = groupsRelationMapper.selectById(orderDon.getRelationId());
+                newRelation.setExpiryTime(DateUtil.offsetDay(newRelation.getExpiryTime(), codexDeductRecord.getExtendsDays()));
+                groupsRelationMapper.updateById(newRelation);
+            }
+            codexDeductRecordMapper.updateById(codexDeductRecord);
+        }
+
 		if (orderDon.getOrderType() == 1 && sku.getIsDown()) {
 			try {
 				GroupsRelation relation = groupsRelationMapper.selectById(orderDon.getRelationId());
@@ -4987,6 +4994,92 @@ public class OrderDonServiceImpl extends ServiceImpl<OrderDonMapper, OrderDon> i
 		return orderDon;
 	}
 
+	@Override
+	@Transactional(rollbackFor = Throwable.class)
+	public OrderDon deductSubmitOrder(CodexUpgradePayReq payReq) throws Exception {
+		Long userId = payReq.getUserId();
+		Long relationId = payReq.getRelationId();
+		CodexDeductResp codexDeductResp = codexService.getDeductMoney(userId, relationId, payReq.getSkuId());
+		if (!codexDeductResp.getIsDeduct()) {
+			throw BusinessRuntimeException.getInstance("你存在claude code 无法抵扣");
+		}
+		BigDecimal deductMoney = codexDeductResp.getDeductMoney();
+		Integer extendsDays = codexDeductResp.getExtendsDays();
+		Long skuId = payReq.getSkuId();
+		GoodsDonSku upgradeSku = goodsDonSkuMapper.selectById(skuId);
+		if (upgradeSku == null || upgradeSku.getGoodsId() != Constant.CODEX_GOODS_ID) {
+			throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重试");
+		}
+		User user = userMapper.selectById(userId);
+		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
+		int noPayCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class)
+				.in(OrderDon::getUserId, userIdList)
+				.eq(OrderDon::getGoodsId, upgradeSku.getGoodsId())
+				.eq(OrderDon::getStatus, OrderDon.Status.noPayment.toString()));
+		if (noPayCount > 0) {
+			throw new BusinessRuntimeException("您有未支付订单.");
+		}
+		String cacheKey = "codex_deduct_cache_key:" + relationId;
+		if (!redisService.setNx(cacheKey, relationId, 10L)) {
+			throw BusinessRuntimeException.getInstance("系统繁忙,请刷新页面重试");
+		}
+		CouponUser couponUser = null;
+		if (payReq.getCouponId() != null) {
+			CouponPopularizeDto couponPopularizeDto = checkCouponStatus(skuId, null, payReq.getCouponId(), userId, false);
+			couponUser = couponStatusRecord(null, payReq.getCouponId(), userId, couponPopularizeDto);
+		}
+		GoodsDon goodsDon = goodsDonMapper.selectById(upgradeSku.getGoodsId());
+		OrderDon orderDon;
+		try {
+			orderDon = new OrderDon();
+			orderDon.setGoodsId(upgradeSku.getGoodsId());
+			orderDon.setSkuId(upgradeSku.getId());
+			orderDon.setUserId(userId);
+			//抵扣升级订单
+			orderDon.setOrderType(1);
+			BigDecimal price = upgradeSku.getPrice();
+			orderDon.setOriMoney(price);
+			orderDon.setRealMoney(price);
+			BigDecimal discountPrice = price.subtract(deductMoney);
+			orderDon.setMoney(discountPrice.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : discountPrice);
+			orderDon.setPayTitle(goodsDon.getTitle() + upgradeSku.getSpecVal());
+			orderDon.setType(OrderDon.Type.ALI_PAY);
+			orderDon.setOrderNo(SEQUENCE.nextId().toString());
+			orderDon.setStatus(OrderDon.Status.noPayment);
+			//虚拟商品订单,是否是分销订单
+			setDistributeOrderMark(orderDon, goodsDon.getType(), userId);
+			//存在银河币
+			deductGalaxyCoinPayOrderMoney(orderDon, discountPrice, payReq.getGalaxyCoin(), user);
+			//存在余额
+			deductBalancePayOrderMoney(orderDon, payReq.getBalance(), user);
+			GroupsRelation relation = codexService.getClaudeCodeRelation(userId, upgradeSku);
+			orderDon.setRelationId(relation.getId());
+			orderDonMapper.insert(orderDon);
+			//记录抵扣记录
+			CodexDeductRecord codexDeductRecord = new CodexDeductRecord();
+			codexDeductRecord.setCcRelationId(null);
+			codexDeductRecord.setOrderId(orderDon.getId());
+			codexDeductRecord.setRelationId(relationId);
+			codexDeductRecord.setExtendsDays(extendsDays);
+			codexDeductRecordMapper.insert(codexDeductRecord);
+			Long orderId = orderDon.getId();
+			//使用银河币记录
+			userGalaxyCoinService.handleUserGalaxyCoinOrderNotify(orderId, userId, orderDon.getOrderNo(), OrderDonGalaxyCoinRecord.Source.ordinary);
+			if (orderDon.getMoney().compareTo(BigDecimal.ZERO) == 0) {
+				orderDon = orderDonMapper.selectById(orderId);
+				unifiedHandlerOrderNotify(orderDon, goodsDon, upgradeSku);
+			}
+			if (orderDon.getStatus() == OrderDon.Status.noPayment) {
+				jobManager.addJob(EXPIRY_TIME, () -> closeOrder(orderId, null));
+			}
+		} finally {
+			if (redisService.hasKey(cacheKey)) {
+				redisService.del(cacheKey);
+			}
+		}
+		return orderDon;
+	}
+
 	@Override
 	public OrderDon userBenefitsSubmit(OrderPayRequest orderPayRequest) throws Exception {
 		Long userId = orderPayRequest.getUserId();

+ 7 - 4
netflix-web/src/main/java/com/cyksj/web/controller/codex/CodexController.java

@@ -21,6 +21,7 @@ import com.cyksj.model.response.CodexDeductResp;
 import com.cyksj.model.response.claudecode.ClaudeCodeResp;
 import com.cyksj.model.views.*;
 import com.cyksj.service.codex.CodexService;
+import com.cyksj.service.order.OrderDonService;
 import com.cyksj.service.user.UserBindRelationService;
 import com.cyksj.web.util.StpUserUtil;
 import com.ejlchina.searcher.BeanSearcher;
@@ -50,6 +51,8 @@ public class CodexController {
     
     private final CodexService codexService;
 
+    private final OrderDonService orderDonService;
+
     private final UserBindRelationService userBindRelationService;
 
     private final CodexUserMapper codexUserMapper;
@@ -160,10 +163,10 @@ public class CodexController {
     /**
      * 抵扣车票金额
      */
-    @GetMapping("/get/deduct/money")
-    public Result<CodexDeductResp> getDeductMoney() {
+    @GetMapping("/get/deduct/money/{relationId}/{upgradeSkuId}")
+    public Result<CodexDeductResp> getDeductMoney(@PathVariable Long relationId, @PathVariable Long upgradeSkuId) {
         long userId = StpUserUtil.getLoginIdAsLong();
-        CodexDeductResp codexDeductResp = codexService.getDeductMoney(userId, null);
+        CodexDeductResp codexDeductResp = codexService.getDeductMoney(userId, relationId, upgradeSkuId);
         return GatewayResponse.SUCCESS.newBuilder().toResult(codexDeductResp);
     }
 
@@ -174,7 +177,7 @@ public class CodexController {
     public Result<OrderDon> deductSubmitOrder(@RequestBody CodexUpgradePayReq payReq) throws Exception {
         long userId = StpUserUtil.getLoginIdAsLong();
         payReq.setUserId(userId);
-        OrderDon orderDon = codexService.deductSubmitOrder(payReq);
+        OrderDon orderDon = orderDonService.deductSubmitOrder(payReq);
         return GatewayResponse.SUCCESS.newBuilder().toResult(orderDon);
     }