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,6 +16,7 @@ import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
16 import cn.iocoder.yudao.module.member.api.user.MemberUserApi; 16 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
17 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 17 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
18 import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; 18 import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
  19 +import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
19 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; 20 import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
20 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; 21 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
21 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; 22 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
@@ -344,8 +345,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -344,8 +345,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
344 345
345 // TODO 芋艿:OrderLog 346 // TODO 芋艿:OrderLog
346 347
347 - // todo 增加用户积分  
348 - 348 + // 增加用户积分
  349 + addUserPointAsync(order.getUserId(), order.getPayPrice(), order.getId());
349 // 增加用户经验 350 // 增加用户经验
350 addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId()); 351 addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId());
351 } 352 }
@@ -615,9 +616,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -615,9 +616,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
615 616
616 // TODO 芋艿:未来如果有分佣,需要更新相关分佣订单为已失效 617 // TODO 芋艿:未来如果有分佣,需要更新相关分佣订单为已失效
617 618
618 - // todo 取消用户积分  
619 -  
620 - // 取消用户经验 619 + // 扣减用户积分
  620 + reduceUserPointAsync(order.getUserId(), orderRefundPrice, afterSaleId);
  621 + // 扣减用户经验
621 reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId); 622 reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId);
622 } 623 }
623 624
@@ -673,8 +674,20 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -673,8 +674,20 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
673 } 674 }
674 675
675 @Async 676 @Async
676 - protected void reduceUserExperienceAsync(Long userId, Integer refundPrice, Long afterSaleId){ 677 + protected void reduceUserExperienceAsync(Long userId, Integer refundPrice, Long afterSaleId) {
677 int bizType = MemberExperienceBizTypeEnum.REFUND.getType(); 678 int bizType = MemberExperienceBizTypeEnum.REFUND.getType();
678 memberLevelApi.addExperience(userId, -refundPrice, bizType, String.valueOf(afterSaleId)); 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 package cn.iocoder.yudao.module.member.api.user; 1 package cn.iocoder.yudao.module.member.api.user;
2 2
3 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 3 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
  4 +import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
4 5
5 import java.util.Collection; 6 import java.util.Collection;
6 import java.util.List; 7 import java.util.List;
@@ -57,4 +58,13 @@ public interface MemberUserApi { @@ -57,4 +58,13 @@ public interface MemberUserApi {
57 */ 58 */
58 MemberUserRespDTO getUserByMobile(String mobile); 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,7 +4,7 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
4 4
5 /** 5 /**
6 * Member 错误码枚举类 6 * Member 错误码枚举类
7 - * 7 + * <p>
8 * member 系统,使用 1-004-000-000 段 8 * member 系统,使用 1-004-000-000 段
9 */ 9 */
10 public interface ErrorCodeConstants { 10 public interface ErrorCodeConstants {
@@ -32,6 +32,7 @@ public interface ErrorCodeConstants { @@ -32,6 +32,7 @@ public interface ErrorCodeConstants {
32 //========== 积分配置 1004007000 ========== 32 //========== 积分配置 1004007000 ==========
33 33
34 //========== 积分记录 1004008000 ========== 34 //========== 积分记录 1004008000 ==========
  35 + ErrorCode POINT_RECORD_BIZ_NOT_SUPPORT = new ErrorCode(1004008000, "用户积分记录业务类型不支持");
35 36
36 //========== 签到配置 1004009000 ========== 37 //========== 签到配置 1004009000 ==========
37 ErrorCode SIGN_IN_CONFIG_NOT_EXISTS = new ErrorCode(1004009000, "签到天数规则不存在"); 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,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 private final int type; 32 private final int type;
  33 + /**
  34 + * 标题
  35 + */
30 private final String title; 36 private final String title;
  37 + /**
  38 + * 描述
  39 + */
31 private final String description; 40 private final String description;
  41 + /**
  42 + * 是否为扣减积分
  43 + */
  44 + private final boolean isReduce;
32 45
33 public static MemberExperienceBizTypeEnum getByType(Integer type) { 46 public static MemberExperienceBizTypeEnum getByType(Integer type) {
34 return EnumUtil.getBy(MemberExperienceBizTypeEnum.class, 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 package cn.iocoder.yudao.module.member.enums.point; 1 package cn.iocoder.yudao.module.member.enums.point;
2 2
  3 +import cn.hutool.core.util.EnumUtil;
3 import cn.iocoder.yudao.framework.common.core.IntArrayValuable; 4 import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
4 import lombok.AllArgsConstructor; 5 import lombok.AllArgsConstructor;
5 import lombok.Getter; 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,9 +16,9 @@ import lombok.Getter;
13 @Getter 16 @Getter
14 public enum MemberPointBizTypeEnum implements IntArrayValuable { 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,10 +28,24 @@ public enum MemberPointBizTypeEnum implements IntArrayValuable {
25 * 名字 28 * 名字
26 */ 29 */
27 private final String name; 30 private final String name;
  31 + /**
  32 + * 描述
  33 + */
  34 + private final String description;
  35 + /**
  36 + * 是否为扣减积分
  37 + */
  38 + private final boolean isReduce;
28 39
29 @Override 40 @Override
30 public int[] array() { 41 public int[] array() {
31 return new int[0]; 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,6 +3,8 @@ package cn.iocoder.yudao.module.member.api.user;
3 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 3 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
4 import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; 4 import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
5 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; 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 import cn.iocoder.yudao.module.member.service.user.MemberUserService; 8 import cn.iocoder.yudao.module.member.service.user.MemberUserService;
7 import org.springframework.stereotype.Service; 9 import org.springframework.stereotype.Service;
8 import org.springframework.validation.annotation.Validated; 10 import org.springframework.validation.annotation.Validated;
@@ -11,6 +13,9 @@ import javax.annotation.Resource; @@ -11,6 +13,9 @@ import javax.annotation.Resource;
11 import java.util.Collection; 13 import java.util.Collection;
12 import java.util.List; 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 * 会员用户的 API 实现类 20 * 会员用户的 API 实现类
16 * 21 *
@@ -23,6 +28,9 @@ public class MemberUserApiImpl implements MemberUserApi { @@ -23,6 +28,9 @@ public class MemberUserApiImpl implements MemberUserApi {
23 @Resource 28 @Resource
24 private MemberUserService userService; 29 private MemberUserService userService;
25 30
  31 + @Resource
  32 + private MemberPointRecordService memberPointRecordService;
  33 +
26 @Override 34 @Override
27 public MemberUserRespDTO getUser(Long id) { 35 public MemberUserRespDTO getUser(Long id) {
28 MemberUserDO user = userService.getUser(id); 36 MemberUserDO user = userService.getUser(id);
@@ -44,4 +52,13 @@ public class MemberUserApiImpl implements MemberUserApi { @@ -44,4 +52,13 @@ public class MemberUserApiImpl implements MemberUserApi {
44 return MemberUserConvert.INSTANCE.convert2(userService.getUserByMobile(mobile)); 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,6 +235,9 @@ public class MemberLevelServiceImpl implements MemberLevelService {
235 if (experience == 0) { 235 if (experience == 0) {
236 return; 236 return;
237 } 237 }
  238 + if (bizType.isReduce() && experience > 0) {
  239 + experience = -experience;
  240 + }
238 241
239 MemberUserDO user = memberUserService.getUser(userId); 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,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO; 5 import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO;
6 import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO; 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 * 用户积分记录 Service 接口 10 * 用户积分记录 Service 接口
@@ -29,4 +30,13 @@ public interface MemberPointRecordService { @@ -29,4 +30,13 @@ public interface MemberPointRecordService {
29 */ 30 */
30 PageResult<MemberPointRecordDO> getPointRecordPage(Long userId, PageParam pageVO); 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 package cn.iocoder.yudao.module.member.service.point; 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 import cn.iocoder.yudao.framework.common.pojo.PageParam; 6 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.module.member.api.user.MemberUserApi; 8 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
6 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 9 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
7 import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO; 10 import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO;
8 import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO; 11 import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO;
  12 +import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
9 import cn.iocoder.yudao.module.member.dal.mysql.point.MemberPointRecordMapper; 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 import org.apache.commons.lang3.StringUtils; 16 import org.apache.commons.lang3.StringUtils;
11 import org.springframework.stereotype.Service; 17 import org.springframework.stereotype.Service;
12 import org.springframework.util.CollectionUtils; 18 import org.springframework.util.CollectionUtils;
@@ -33,6 +39,8 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService { @@ -33,6 +39,8 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService {
33 39
34 @Resource 40 @Resource
35 private MemberUserApi memberUserApi; 41 private MemberUserApi memberUserApi;
  42 + @Resource
  43 + private MemberUserService memberUserService;
36 44
37 @Override 45 @Override
38 public PageResult<MemberPointRecordDO> getPointRecordPage(MemberPointRecordPageReqVO pageReqVO) { 46 public PageResult<MemberPointRecordDO> getPointRecordPage(MemberPointRecordPageReqVO pageReqVO) {
@@ -55,4 +63,29 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService { @@ -55,4 +63,29 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService {
55 return recordMapper.selectPage(userId, pageVO); 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,4 +158,12 @@ public interface MemberUserService {
158 * @return 用户数量 158 * @return 用户数量
159 */ 159 */
160 Long getUserCountByTagId(Long tagId); 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,4 +254,9 @@ public class MemberUserServiceImpl implements MemberUserService {
254 return memberUserMapper.selectCountByTagId(tagId); 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 }