mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-07-24 16:05:08 +08:00
积分:完善积分获得、退还、使用 相关逻辑
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.member.api.point;
|
||||
|
||||
import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO;
|
||||
import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
@ -11,6 +12,13 @@ import javax.validation.constraints.Min;
|
||||
*/
|
||||
public interface MemberPointApi {
|
||||
|
||||
/**
|
||||
* 获得积分配置
|
||||
*
|
||||
* @return 积分配置
|
||||
*/
|
||||
MemberPointConfigRespDTO getConfig();
|
||||
|
||||
/**
|
||||
* 增加用户积分
|
||||
*
|
||||
|
@ -0,0 +1,30 @@
|
||||
package cn.iocoder.yudao.module.member.api.point.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 用户信息 Response DTO
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Data
|
||||
public class MemberPointConfigRespDTO {
|
||||
/**
|
||||
* 积分抵扣开关
|
||||
*/
|
||||
private Boolean tradeDeductEnable;
|
||||
/**
|
||||
* 积分抵扣,单位:分
|
||||
* <p>
|
||||
* 1 积分抵扣多少分
|
||||
*/
|
||||
private Integer tradeDeductUnitPrice;
|
||||
/**
|
||||
* 积分抵扣最大值
|
||||
*/
|
||||
private Integer tradeDeductMaxPrice;
|
||||
/**
|
||||
* 1 元赠送多少分
|
||||
*/
|
||||
private Integer tradeGivePoint;
|
||||
}
|
@ -33,5 +33,8 @@ public class MemberUserRespDTO {
|
||||
* 手机
|
||||
*/
|
||||
private String mobile;
|
||||
|
||||
/**
|
||||
* 积分
|
||||
*/
|
||||
private Integer point;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在");
|
||||
ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1004001001, "手机号未注册用户");
|
||||
ErrorCode USER_MOBILE_USED = new ErrorCode(1004001002, "修改手机失败,该手机号({})已经被使用");
|
||||
ErrorCode USER_POINT_NOT_ENOUGH = new ErrorCode(1004001003, "用户积分余额不足");
|
||||
|
||||
// ========== AUTH 模块 1004003000 ==========
|
||||
ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确");
|
||||
|
@ -18,8 +18,10 @@ public enum MemberPointBizTypeEnum implements IntArrayValuable {
|
||||
|
||||
SIGN(1, "签到", "签到获得 {} 积分", true),
|
||||
ORDER_REWARD(10, "订单奖励", "下单获得 {} 积分", true),
|
||||
ORDER_CANCEL(11, "订单取消", "退单获得 {} 积分", false), // 退回积分
|
||||
ORDER_CANCEL(11, "订单取消", "订单取消,退还 {} 积分", true), // 退回积分
|
||||
ORDER_USE(12, "订单使用", "下单使用 {} 积分", false), // 扣减积分
|
||||
AFTER_SALE_REFUND_USED(13, "订单退款", "订单退款,退还 {} 积分", true), // 退回积分
|
||||
AFTER_SALE_DEDUCT_GIVE(14, "订单退款", "订单退款,扣除赠送的 {} 积分", false), // 扣减积分
|
||||
;
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,10 @@
|
||||
package cn.iocoder.yudao.module.member.api.point;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO;
|
||||
import cn.iocoder.yudao.module.member.convert.point.MemberPointConfigConvert;
|
||||
import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
|
||||
import cn.iocoder.yudao.module.member.service.point.MemberPointConfigService;
|
||||
import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@ -21,9 +25,17 @@ public class MemberPointApiImpl implements MemberPointApi {
|
||||
|
||||
@Resource
|
||||
private MemberPointRecordService memberPointRecordService;
|
||||
@Resource
|
||||
private MemberPointConfigService memberPointConfigService;
|
||||
|
||||
@Override
|
||||
public MemberPointConfigRespDTO getConfig() {
|
||||
return MemberPointConfigConvert.INSTANCE.convert01(memberPointConfigService.getPointConfig());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPoint(Long userId, Integer point, Integer bizType, String bizId) {
|
||||
Assert.isTrue(point > 0);
|
||||
MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType);
|
||||
if (bizTypeEnum == null) {
|
||||
throw exception(POINT_RECORD_BIZ_NOT_SUPPORT);
|
||||
@ -33,11 +45,12 @@ public class MemberPointApiImpl implements MemberPointApi {
|
||||
|
||||
@Override
|
||||
public void reducePoint(Long userId, Integer point, Integer bizType, String bizId) {
|
||||
Assert.isTrue(point > 0);
|
||||
MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType);
|
||||
if (bizTypeEnum == null) {
|
||||
throw exception(POINT_RECORD_BIZ_NOT_SUPPORT);
|
||||
}
|
||||
memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId);
|
||||
memberPointRecordService.createPointRecord(userId, -point, bizTypeEnum, bizId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.member.convert.point;
|
||||
|
||||
import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO;
|
||||
import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigRespVO;
|
||||
import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigSaveReqVO;
|
||||
import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO;
|
||||
@ -20,4 +21,5 @@ public interface MemberPointConfigConvert {
|
||||
|
||||
MemberPointConfigDO convert(MemberPointConfigSaveReqVO bean);
|
||||
|
||||
MemberPointConfigRespDTO convert01(MemberPointConfigDO pointConfig);
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
package cn.iocoder.yudao.module.member.dal.mysql.user;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
||||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
@ -62,4 +64,33 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
|
||||
.apply("FIND_IN_SET({0}, tag_ids)", tagId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户积分(增加)
|
||||
*
|
||||
* @param id 用户编号
|
||||
* @param incrCount 增加积分(正数)
|
||||
*/
|
||||
default void updatePointIncr(Long id, Integer incrCount) {
|
||||
Assert.isTrue(incrCount > 0);
|
||||
LambdaUpdateWrapper<MemberUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<MemberUserDO>()
|
||||
.setSql(" point = point + " + incrCount)
|
||||
.eq(MemberUserDO::getId, id);
|
||||
update(null, lambdaUpdateWrapper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户积分(减少)
|
||||
*
|
||||
* @param id 用户编号
|
||||
* @param incrCount 增加积分(负数)
|
||||
* @return 更新行数
|
||||
*/
|
||||
default int updatePointDecr(Long id, Integer incrCount) {
|
||||
Assert.isTrue(incrCount < 0);
|
||||
LambdaUpdateWrapper<MemberUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<MemberUserDO>()
|
||||
.setSql(" point = point + " + incrCount) // 负数,所以使用 + 号
|
||||
.eq(MemberUserDO::getId, id);
|
||||
return update(null, lambdaUpdateWrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO;
|
||||
import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO;
|
||||
import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO;
|
||||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||
import cn.iocoder.yudao.module.member.dal.mysql.point.MemberPointRecordMapper;
|
||||
@ -14,6 +13,7 @@ import cn.iocoder.yudao.module.member.service.user.MemberUserService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
@ -21,7 +21,9 @@ import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.USER_POINT_NOT_ENOUGH;
|
||||
|
||||
|
||||
/**
|
||||
@ -36,8 +38,6 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService {
|
||||
|
||||
@Resource
|
||||
private MemberPointRecordMapper memberPointRecordMapper;
|
||||
@Resource
|
||||
private MemberPointConfigService memberPointConfigService;
|
||||
|
||||
@Resource
|
||||
private MemberUserService memberUserService;
|
||||
@ -64,32 +64,28 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void createPointRecord(Long userId, Integer point, MemberPointBizTypeEnum bizType, String bizId) {
|
||||
MemberPointConfigDO pointConfig = memberPointConfigService.getPointConfig();
|
||||
if (pointConfig == null || pointConfig.getTradeGivePoint() == null) {
|
||||
log.error("[createPointRecord][增加积分失败:tradeGivePoint 未配置,userId({}) point({}) bizType({}) bizId({})]",
|
||||
userId, point, bizType.getType(), bizId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 根据配置的比例,换算实际的积分
|
||||
point = point * pointConfig.getTradeGivePoint();
|
||||
if (!bizType.isAdd() && point > 0) {
|
||||
point = -point;
|
||||
}
|
||||
|
||||
// 2. 增加积分记录
|
||||
// 1. 校验用户积分余额
|
||||
MemberUserDO user = memberUserService.getUser(userId);
|
||||
Integer userPoint = ObjectUtil.defaultIfNull(user.getPoint(), 0);
|
||||
Integer totalPoint = userPoint + point; // 用户变动后的积分
|
||||
int totalPoint = userPoint + point; // 用户变动后的积分
|
||||
if (totalPoint < 0) {
|
||||
throw exception(USER_POINT_NOT_ENOUGH);
|
||||
}
|
||||
|
||||
// 2. 更新用户积分
|
||||
boolean success = memberUserService.updateUserPoint(userId, point);
|
||||
if (!success) {
|
||||
throw exception(USER_POINT_NOT_ENOUGH);
|
||||
}
|
||||
|
||||
// 3. 增加积分记录
|
||||
MemberPointRecordDO record = new MemberPointRecordDO()
|
||||
.setUserId(userId).setBizId(bizId).setBizType(bizType.getType())
|
||||
.setTitle(bizType.getName()).setDescription(StrUtil.format(bizType.getDescription(), point))
|
||||
.setPoint(point).setTotalPoint(totalPoint);
|
||||
memberPointRecordMapper.insert(record);
|
||||
|
||||
// 3. 更新用户积分
|
||||
memberUserService.updateUserPoint(userId, totalPoint);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -164,6 +164,7 @@ public interface MemberUserService {
|
||||
*
|
||||
* @param userId 用户编号
|
||||
* @param point 积分数量
|
||||
* @return 更新结果
|
||||
*/
|
||||
void updateUserPoint(Long userId, Integer point);
|
||||
boolean updateUserPoint(Long userId, Integer point);
|
||||
}
|
||||
|
@ -260,8 +260,13 @@ public class MemberUserServiceImpl implements MemberUserService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUserPoint(Long userId, Integer point) {
|
||||
memberUserMapper.updateById(new MemberUserDO().setId(userId).setPoint(point));
|
||||
public boolean updateUserPoint(Long id, Integer point) {
|
||||
if (point > 0) {
|
||||
memberUserMapper.updatePointIncr(id, point);
|
||||
} else if (point < 0) {
|
||||
return memberUserMapper.updatePointDecr(id, point) > 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user