|
|
@@ -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) {
|