Commit d4acacec60c137aa3ab916357f176f65b406d0f8

Authored by owen
1 parent dad56fd0

trade: 1.支付成功后,增加用户积分;2.退款成功后,扣减用户积分

yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
... ... @@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
16 16 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
17 17 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
18 18 import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
  19 +import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
19 20 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
20 21 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
21 22 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
... ... @@ -344,8 +345,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
344 345  
345 346 // TODO 芋艿:OrderLog
346 347  
347   - // todo 增加用户积分
348   -
  348 + // 增加用户积分
  349 + addUserPointAsync(order.getUserId(), order.getPayPrice(), order.getId());
349 350 // 增加用户经验
350 351 addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId());
351 352 }
... ... @@ -615,9 +616,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
615 616  
616 617 // TODO 芋艿:未来如果有分佣,需要更新相关分佣订单为已失效
617 618  
618   - // todo 取消用户积分
619   -
620   - // 取消用户经验
  619 + // 扣减用户积分
  620 + reduceUserPointAsync(order.getUserId(), orderRefundPrice, afterSaleId);
  621 + // 扣减用户经验
621 622 reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId);
622 623 }
623 624  
... ... @@ -673,8 +674,20 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
673 674 }
674 675  
675 676 @Async
676   - protected void reduceUserExperienceAsync(Long userId, Integer refundPrice, Long afterSaleId){
  677 + protected void reduceUserExperienceAsync(Long userId, Integer refundPrice, Long afterSaleId) {
677 678 int bizType = MemberExperienceBizTypeEnum.REFUND.getType();
678 679 memberLevelApi.addExperience(userId, -refundPrice, bizType, String.valueOf(afterSaleId));
679 680 }
  681 +
  682 + @Async
  683 + protected void addUserPointAsync(Long userId, Integer payPrice, Long orderId) {
  684 + int bizType = MemberPointBizTypeEnum.ORDER_BUY.getType();
  685 + memberUserApi.addPoint(userId, payPrice, bizType, String.valueOf(orderId));
  686 + }
  687 +
  688 + @Async
  689 + protected void reduceUserPointAsync(Long userId, Integer refundPrice, Long afterSaleId) {
  690 + int bizType = MemberPointBizTypeEnum.ORDER_CANCEL.getType();
  691 + memberUserApi.addPoint(userId, -refundPrice, bizType, String.valueOf(afterSaleId));
  692 + }
680 693 }
... ...
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApi.java
1 1 package cn.iocoder.yudao.module.member.api.user;
2 2  
3 3 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
  4 +import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
4 5  
5 6 import java.util.Collection;
6 7 import java.util.List;
... ... @@ -57,4 +58,13 @@ public interface MemberUserApi {
57 58 */
58 59 MemberUserRespDTO getUserByMobile(String mobile);
59 60  
  61 + /**
  62 + * 增加用户积分
  63 + *
  64 + * @param userId 用户编号
  65 + * @param point 积分
  66 + * @param bizType 业务类型 {@link MemberPointBizTypeEnum}
  67 + * @param bizId 业务编号
  68 + */
  69 + void addPoint(Long userId, Integer point, Integer bizType, String bizId);
60 70 }
... ...
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
... ... @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
4 4  
5 5 /**
6 6 * Member 错误码枚举类
7   - *
  7 + * <p>
8 8 * member 系统,使用 1-004-000-000 段
9 9 */
10 10 public interface ErrorCodeConstants {
... ... @@ -32,6 +32,7 @@ public interface ErrorCodeConstants {
32 32 //========== 积分配置 1004007000 ==========
33 33  
34 34 //========== 积分记录 1004008000 ==========
  35 + ErrorCode POINT_RECORD_BIZ_NOT_SUPPORT = new ErrorCode(1004008000, "用户积分记录业务类型不支持");
35 36  
36 37 //========== 签到配置 1004009000 ==========
37 38 ErrorCode SIGN_IN_CONFIG_NOT_EXISTS = new ErrorCode(1004009000, "签到天数规则不存在");
... ...
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/MemberExperienceBizTypeEnum.java
... ... @@ -18,17 +18,30 @@ public enum MemberExperienceBizTypeEnum {
18 18 /**
19 19 * 管理员调整、邀请新用户、下单、退单、签到、抽奖
20 20 */
21   - ADMIN(0, "管理员调整", "管理员调整获得 {} 经验"),
22   - INVITE_REGISTER(1, "邀新奖励", "邀请好友获得 {} 经验"),
23   - ORDER(2, "下单奖励", "下单获得 {} 经验"),
24   - REFUND(3, "退单扣除", "退单获得 {} 经验"),
25   - SIGN_IN(4, "签到奖励", "签到获得 {} 经验"),
26   - LOTTERY(5, "抽奖奖励", "抽奖获得 {} 经验"),
  21 + ADMIN(0, "管理员调整", "管理员调整获得 {} 经验", false),
  22 + INVITE_REGISTER(1, "邀新奖励", "邀请好友获得 {} 经验", false),
  23 + ORDER(2, "下单奖励", "下单获得 {} 经验", false),
  24 + REFUND(3, "退单扣除", "退单获得 {} 经验", true),
  25 + SIGN_IN(4, "签到奖励", "签到获得 {} 经验", false),
  26 + LOTTERY(5, "抽奖奖励", "抽奖获得 {} 经验", false),
27 27 ;
28 28  
  29 + /**
  30 + * 业务类型
  31 + */
29 32 private final int type;
  33 + /**
  34 + * 标题
  35 + */
30 36 private final String title;
  37 + /**
  38 + * 描述
  39 + */
31 40 private final String description;
  41 + /**
  42 + * 是否为扣减积分
  43 + */
  44 + private final boolean isReduce;
32 45  
33 46 public static MemberExperienceBizTypeEnum getByType(Integer type) {
34 47 return EnumUtil.getBy(MemberExperienceBizTypeEnum.class,
... ...
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java
1 1 package cn.iocoder.yudao.module.member.enums.point;
2 2  
  3 +import cn.hutool.core.util.EnumUtil;
3 4 import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
4 5 import lombok.AllArgsConstructor;
5 6 import lombok.Getter;
6 7  
  8 +import java.util.Objects;
  9 +
7 10 /**
8 11 * 会员积分的业务类型枚举
9 12 *
... ... @@ -13,9 +16,9 @@ import lombok.Getter;
13 16 @Getter
14 17 public enum MemberPointBizTypeEnum implements IntArrayValuable {
15 18  
16   - SIGN(1, "签到"),
17   - ORDER_BUY(10, "订单消费"),
18   - ORDER_CANCEL(11, "订单取消"); // 退回积分
  19 + SIGN(1, "签到", "签到获得 {} 积分", false),
  20 + ORDER_BUY(10, "订单消费", "下单获得 {} 积分", false),
  21 + ORDER_CANCEL(11, "订单取消", "退单获得 {} 积分", true); // 退回积分
19 22  
20 23 /**
21 24 * 类型
... ... @@ -25,10 +28,24 @@ public enum MemberPointBizTypeEnum implements IntArrayValuable {
25 28 * 名字
26 29 */
27 30 private final String name;
  31 + /**
  32 + * 描述
  33 + */
  34 + private final String description;
  35 + /**
  36 + * 是否为扣减积分
  37 + */
  38 + private final boolean isReduce;
28 39  
29 40 @Override
30 41 public int[] array() {
31 42 return new int[0];
32 43 }
33 44  
  45 +
  46 + public static MemberPointBizTypeEnum getByType(Integer type) {
  47 + return EnumUtil.getBy(MemberPointBizTypeEnum.class,
  48 + e -> Objects.equals(type, e.getType()));
  49 + }
  50 +
34 51 }
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/user/MemberUserApiImpl.java
... ... @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.member.api.user;
3 3 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
4 4 import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
5 5 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
  6 +import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
  7 +import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService;
6 8 import cn.iocoder.yudao.module.member.service.user.MemberUserService;
7 9 import org.springframework.stereotype.Service;
8 10 import org.springframework.validation.annotation.Validated;
... ... @@ -11,6 +13,9 @@ import javax.annotation.Resource;
11 13 import java.util.Collection;
12 14 import java.util.List;
13 15  
  16 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  17 +import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.POINT_RECORD_BIZ_NOT_SUPPORT;
  18 +
14 19 /**
15 20 * 会员用户的 API 实现类
16 21 *
... ... @@ -23,6 +28,9 @@ public class MemberUserApiImpl implements MemberUserApi {
23 28 @Resource
24 29 private MemberUserService userService;
25 30  
  31 + @Resource
  32 + private MemberPointRecordService memberPointRecordService;
  33 +
26 34 @Override
27 35 public MemberUserRespDTO getUser(Long id) {
28 36 MemberUserDO user = userService.getUser(id);
... ... @@ -44,4 +52,13 @@ public class MemberUserApiImpl implements MemberUserApi {
44 52 return MemberUserConvert.INSTANCE.convert2(userService.getUserByMobile(mobile));
45 53 }
46 54  
  55 + @Override
  56 + public void addPoint(Long userId, Integer point, Integer bizType, String bizId) {
  57 + MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType);
  58 + if (bizTypeEnum == null) {
  59 + throw exception(POINT_RECORD_BIZ_NOT_SUPPORT);
  60 + }
  61 + memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId);
  62 + }
  63 +
47 64 }
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java
... ... @@ -235,6 +235,9 @@ public class MemberLevelServiceImpl implements MemberLevelService {
235 235 if (experience == 0) {
236 236 return;
237 237 }
  238 + if (bizType.isReduce() && experience > 0) {
  239 + experience = -experience;
  240 + }
238 241  
239 242 MemberUserDO user = memberUserService.getUser(userId);
240 243  
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordService.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO;
6 6 import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO;
  7 +import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
7 8  
8 9 /**
9 10 * 用户积分记录 Service 接口
... ... @@ -29,4 +30,13 @@ public interface MemberPointRecordService {
29 30 */
30 31 PageResult<MemberPointRecordDO> getPointRecordPage(Long userId, PageParam pageVO);
31 32  
  33 + /**
  34 + * 创建用户积分记录
  35 + *
  36 + * @param userId 用户ID
  37 + * @param point 变动积分
  38 + * @param bizType 业务类型
  39 + * @param bizId 业务编号
  40 + */
  41 + void createPointRecord(Long userId, Integer point, MemberPointBizTypeEnum bizType, String bizId);
32 42 }
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordServiceImpl.java
1 1 package cn.iocoder.yudao.module.member.service.point;
2 2  
  3 +import cn.hutool.core.util.NumberUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.hutool.core.util.StrUtil;
3 6 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 8 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
6 9 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
7 10 import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO;
8 11 import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO;
  12 +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
9 13 import cn.iocoder.yudao.module.member.dal.mysql.point.MemberPointRecordMapper;
  14 +import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
  15 +import cn.iocoder.yudao.module.member.service.user.MemberUserService;
10 16 import org.apache.commons.lang3.StringUtils;
11 17 import org.springframework.stereotype.Service;
12 18 import org.springframework.util.CollectionUtils;
... ... @@ -33,6 +39,8 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService {
33 39  
34 40 @Resource
35 41 private MemberUserApi memberUserApi;
  42 + @Resource
  43 + private MemberUserService memberUserService;
36 44  
37 45 @Override
38 46 public PageResult<MemberPointRecordDO> getPointRecordPage(MemberPointRecordPageReqVO pageReqVO) {
... ... @@ -55,4 +63,29 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService {
55 63 return recordMapper.selectPage(userId, pageVO);
56 64 }
57 65  
  66 + @Override
  67 + public void createPointRecord(Long userId, Integer point, MemberPointBizTypeEnum bizType, String bizId) {
  68 + if (bizType.isReduce() && point > 0) {
  69 + point = -point;
  70 + }
  71 +
  72 + MemberUserDO user = memberUserService.getUser(userId);
  73 + Integer userPoint = ObjectUtil.defaultIfNull(user.getPoint(), 0);
  74 + // 用户变动后的积分,防止扣出负数
  75 + Integer totalPoint = NumberUtil.max(userPoint + point, 0);
  76 + // 增加积分记录
  77 + MemberPointRecordDO recordDO = new MemberPointRecordDO()
  78 + .setUserId(userId)
  79 + .setBizId(bizId)
  80 + .setBizType(bizType.getType())
  81 + .setTitle(bizType.getName())
  82 + .setDescription(StrUtil.format(bizType.getDescription(), point))
  83 + .setPoint(point)
  84 + .setTotalPoint(totalPoint);
  85 + recordMapper.insert(recordDO);
  86 +
  87 + // 更新用户积分
  88 + memberUserService.updateUserPoint(userId, totalPoint);
  89 + }
  90 +
58 91 }
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserService.java
... ... @@ -158,4 +158,12 @@ public interface MemberUserService {
158 158 * @return 用户数量
159 159 */
160 160 Long getUserCountByTagId(Long tagId);
  161 +
  162 + /**
  163 + * 更新用户的积分
  164 + *
  165 + * @param userId 用户ID
  166 + * @param point 积分数量
  167 + */
  168 + void updateUserPoint(Long userId, Integer point);
161 169 }
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImpl.java
... ... @@ -254,4 +254,9 @@ public class MemberUserServiceImpl implements MemberUserService {
254 254 return memberUserMapper.selectCountByTagId(tagId);
255 255 }
256 256  
  257 + @Override
  258 + public void updateUserPoint(Long userId, Integer point) {
  259 + memberUserMapper.updateById(new MemberUserDO().setId(userId).setPoint(point));
  260 + }
  261 +
257 262 }
... ...