|
|
@@ -3,6 +3,7 @@ package com.cyksj.service.codex.impl;
|
|
|
import cn.hutool.core.date.DateTime;
|
|
|
import cn.hutool.core.date.DateUtil;
|
|
|
import cn.hutool.core.util.ObjectUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
import cn.hutool.http.HttpResponse;
|
|
|
import cn.hutool.http.HttpUtil;
|
|
|
import cn.hutool.http.Method;
|
|
|
@@ -16,6 +17,12 @@ import com.cyksj.dto.RedisKey;
|
|
|
import com.cyksj.mapper.*;
|
|
|
import com.cyksj.mapper.codex.CodexDeductRecordMapper;
|
|
|
import com.cyksj.mapper.codex.CodexUserRenewExpiryRecordMapper;
|
|
|
+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.UserDistributeMapper;
|
|
|
+import com.cyksj.mapper.manage.distribute.UserDistributeSharedMapper;
|
|
|
+import com.cyksj.model.dto.CouponPopularizeDto;
|
|
|
import com.cyksj.model.entity.*;
|
|
|
import com.cyksj.model.manage.views.GroupsRelationView;
|
|
|
import com.cyksj.model.request.CodexUpgradePayReq;
|
|
|
@@ -24,8 +31,11 @@ import com.cyksj.model.request.codex.CodexUserPackageReq;
|
|
|
import com.cyksj.model.response.CodexDeductResp;
|
|
|
import com.cyksj.model.response.claudecode.ClaudeCodeResp;
|
|
|
import com.cyksj.model.views.CodexUserInfoView;
|
|
|
+import com.cyksj.model.views.CouponNewUserView;
|
|
|
+import com.cyksj.model.views.CouponUserView;
|
|
|
import com.cyksj.redis.RedisService;
|
|
|
import com.cyksj.service.codex.CodexService;
|
|
|
+import com.cyksj.service.coupon.CouponFontService;
|
|
|
import com.cyksj.service.groups.GroupsFuncService;
|
|
|
import com.cyksj.service.user.UserBindRelationService;
|
|
|
import com.ejlchina.searcher.BeanSearcher;
|
|
|
@@ -66,6 +76,10 @@ public class CodexServiceImpl implements CodexService {
|
|
|
|
|
|
private final GoodsDonSkuMapper skuMapper;
|
|
|
|
|
|
+ private final GoodsDonMapper goodsDonMapper;
|
|
|
+
|
|
|
+ private final CouponMapper couponMapper;
|
|
|
+
|
|
|
private final GroupsRelationMapper relationMapper;
|
|
|
|
|
|
private final GroupsMapper groupsMapper;
|
|
|
@@ -82,6 +96,18 @@ public class CodexServiceImpl implements CodexService {
|
|
|
|
|
|
private final CodexDeductRecordMapper codexDeductRecordMapper;
|
|
|
|
|
|
+ private final CouponSkuMapper couponSkuMapper;
|
|
|
+
|
|
|
+ private final CouponUserMapper couponUserMapper;
|
|
|
+
|
|
|
+ private final UserDistributeMapper userDistributeMapper;
|
|
|
+
|
|
|
+ private final UserDistributeSharedMapper userDistributeSharedMapper;
|
|
|
+
|
|
|
+ private final UserMapper userMapper;
|
|
|
+
|
|
|
+ private final CouponFontService couponFontService;
|
|
|
+
|
|
|
private static final Sequence SEQUENCE = new Sequence(0);
|
|
|
@Override
|
|
|
public CodexUserInfoView getCodexUserInfo(Long userId) {
|
|
|
@@ -217,16 +243,17 @@ public class CodexServiceImpl implements CodexService {
|
|
|
BigDecimal deductMoney;
|
|
|
if (groupsRelationView == null || groupsRelationView.getExpiryTime().before(DateTime.now())) {
|
|
|
deductMoney = BigDecimal.ZERO;
|
|
|
+ } else {
|
|
|
+ CodexUser codexUser = codexUserMapper.selectById(relationId);
|
|
|
+ deductMoney = getFinalDeductMoney(relationId, groupsRelationView.getSkuId(), codexUser.getRenewSkuId(), codexUser.getRenewOrderId(), codexUser.getRenewExpiryTime(), groupsRelationView.getStartTime(), groupsRelationView.getExpiryTime(), DateTime.now(), userIdList);
|
|
|
}
|
|
|
- CodexUser codexUser = codexUserMapper.selectById(relationId);
|
|
|
- deductMoney = getFinalDeductMoney(relationId, groupsRelationView.getSkuId(), codexUser.getRenewSkuId(), codexUser.getRenewOrderId(), codexUser.getRenewExpiryTime(), groupsRelationView.getStartTime(), groupsRelationView.getExpiryTime(), DateTime.now(), userIdList);
|
|
|
codexDeductResp.setDeductMoney(deductMoney);
|
|
|
return codexDeductResp;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Throwable.class)
|
|
|
- public OrderDon deductSubmitOrder(CodexUpgradePayReq payReq) {
|
|
|
+ public OrderDon deductSubmitOrder(CodexUpgradePayReq payReq) throws Exception {
|
|
|
Long userId = payReq.getUserId();
|
|
|
//codex 车票id
|
|
|
Long relationId = payReq.getRelationId();
|
|
|
@@ -236,8 +263,9 @@ public class CodexServiceImpl implements CodexService {
|
|
|
}
|
|
|
//抵扣金额
|
|
|
BigDecimal deductMoney = codexDeductResp.getDeductMoney();
|
|
|
+ Long skuId = payReq.getSkuId();
|
|
|
|
|
|
- GoodsDonSku sku = skuMapper.selectById(payReq.getSkuId());
|
|
|
+ GoodsDonSku sku = skuMapper.selectById(skuId);
|
|
|
if (sku == null || sku.getGoodsId() != Constant.CLAUDE_CODE_GOODS_ID || !sku.getIsCodex()) {
|
|
|
throw BusinessRuntimeException.getInstance("系统异常,请刷新页面重试");
|
|
|
}
|
|
|
@@ -252,6 +280,12 @@ public class CodexServiceImpl implements CodexService {
|
|
|
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 {
|
|
|
@@ -259,6 +293,8 @@ public class CodexServiceImpl implements CodexService {
|
|
|
orderDon.setGoodsId(sku.getGoodsId());
|
|
|
orderDon.setSkuId(sku.getId());
|
|
|
orderDon.setUserId(userId);
|
|
|
+ //优惠 --> 订单金额
|
|
|
+ deductOrderMoney(orderDon, couponUser);
|
|
|
orderDon.setMoney(sku.getPrice().subtract(deductMoney));
|
|
|
|
|
|
/* 生成订单 */
|
|
|
@@ -266,6 +302,8 @@ public class CodexServiceImpl implements CodexService {
|
|
|
orderDon.setOrderNo(donNo);
|
|
|
|
|
|
//锁一个cc的车票id
|
|
|
+ //是否存在无赠送的claude code 直接原规格上抵扣
|
|
|
+
|
|
|
GroupsRelation relation = getClaudeCodeRelation(userId, sku);
|
|
|
orderDon.setRelationId(relation.getId());
|
|
|
orderDonMapper.insert(orderDon);
|
|
|
@@ -887,4 +925,205 @@ public class CodexServiceImpl implements CodexService {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ public CouponPopularizeDto checkCouponStatus(Long skuId, String couponExCode, Long couponId, Long userId, Boolean isRenew) throws Exception {
|
|
|
+ log.info("开始校验兑换码:{},优惠券id:{}状态", couponExCode, couponId);
|
|
|
+ //实物还是虚物商品
|
|
|
+ GoodsDonSku goodsDonSku = skuMapper.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 ? "优惠码" : "优惠券"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 使用优惠营销 订单金额抵扣
|
|
|
+ */
|
|
|
+ public void deductOrderMoney(OrderDon orderDon, CouponUser couponUser) throws Exception {
|
|
|
+ BigDecimal first_money = orderDon.getMoney();
|
|
|
+ //存在优惠券
|
|
|
+ if (couponUser != 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) {
|
|
|
+ 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());
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|