19 changed files with 436 additions and 47 deletions
@ -1,16 +1,31 @@ |
|||
package com.youlai.boot.mini.converter; |
|||
|
|||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.youlai.boot.mini.model.entity.MiniPointRule; |
|||
import com.youlai.boot.mini.model.form.AddPointRuleForm; |
|||
import com.youlai.boot.mini.model.vo.RuleListVO; |
|||
import org.mapstruct.Mapper; |
|||
import org.mapstruct.Mapping; |
|||
|
|||
/** |
|||
* 积分规则对象转换器 |
|||
*/ |
|||
@Mapper(componentModel = "spring") |
|||
public interface MiniPointRuleConverter { |
|||
|
|||
IPage<RuleListVO> toRulePageVo(Page<MiniPointRule> pageList); |
|||
/** |
|||
* 分页对象转换 |
|||
*/ |
|||
Page<RuleListVO> toRulePageVo(Page<MiniPointRule> pageList); |
|||
|
|||
/** |
|||
* 单个对象转换 |
|||
*/ |
|||
RuleListVO toRuleVo(MiniPointRule entity); |
|||
|
|||
/** |
|||
* 新增表单转实体 |
|||
*/ |
|||
MiniPointRule toEntity(AddPointRuleForm form); |
|||
|
|||
} |
|||
|
|||
@ -1,20 +1,46 @@ |
|||
package com.youlai.boot.mini.model.vo; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
|
|||
import java.util.Date; |
|||
|
|||
@Data |
|||
@Builder |
|||
@EqualsAndHashCode(callSuper = false) |
|||
@Schema(description = "用户积分信息VO") |
|||
public class PointAccountVO { |
|||
|
|||
@Schema(description = "uuid") |
|||
@Schema(description = "积分账户ID") |
|||
private Long id; |
|||
|
|||
@Schema(description = "uuid唯一标识") |
|||
private String uuid; |
|||
|
|||
@Schema(description = "用户ID") |
|||
private Long userId; |
|||
|
|||
@Schema(description = "用户昵称") |
|||
private String nickname; |
|||
|
|||
@Schema(description = "用户手机号") |
|||
private String mobile; |
|||
|
|||
@Schema(description = "用户头像") |
|||
private String avatar; |
|||
|
|||
@Schema(description = "用户积分") |
|||
private Integer points; |
|||
|
|||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
|||
@Schema(description = "创建时间") |
|||
private Date createTime; |
|||
|
|||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
|||
@Schema(description = "更新时间") |
|||
private Date updateTime; |
|||
|
|||
} |
|||
|
|||
@ -1,13 +1,53 @@ |
|||
package com.youlai.boot.mini.model.vo; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonFormat; |
|||
import io.swagger.v3.oas.annotations.media.Schema; |
|||
import lombok.AllArgsConstructor; |
|||
import lombok.Builder; |
|||
import lombok.Data; |
|||
import lombok.EqualsAndHashCode; |
|||
import lombok.NoArgsConstructor; |
|||
|
|||
import java.time.LocalDateTime; |
|||
|
|||
@Data |
|||
@Builder |
|||
@EqualsAndHashCode(callSuper = false) |
|||
@NoArgsConstructor |
|||
@AllArgsConstructor |
|||
@Schema(description = "积分流水列表VO") |
|||
public class PointRecordVO { |
|||
|
|||
@Schema(description = "积分记录ID") |
|||
private Long id; |
|||
|
|||
@Schema(description = "唯一标识uuid") |
|||
private String uuid; |
|||
|
|||
@Schema(description = "用户ID") |
|||
private Long userId; |
|||
|
|||
@Schema(description = "用户昵称") |
|||
private String userNickname; |
|||
|
|||
@Schema(description = "用户手机号") |
|||
private String userMobile; |
|||
|
|||
@Schema(description = "积分变化值,正数增加,负数扣减") |
|||
private Integer changeAmount; |
|||
|
|||
@Schema(description = "变更后积分余额") |
|||
private Integer balanceAfter; |
|||
|
|||
@Schema(description = "业务类型,sign_in签到/system_increase后台增加等") |
|||
private String bizType; |
|||
|
|||
@Schema(description = "备注说明") |
|||
private String remark; |
|||
|
|||
@Schema(description = "操作人ID") |
|||
private Long createBy; |
|||
|
|||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
|||
@Schema(description = "创建时间/操作时间") |
|||
private LocalDateTime createTime; |
|||
|
|||
} |
|||
|
|||
@ -1,4 +1,25 @@ |
|||
package com.youlai.boot.mini.service; |
|||
|
|||
public interface MiniPointRecordService { |
|||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|||
import com.baomidou.mybatisplus.extension.service.IService; |
|||
import com.youlai.boot.mini.model.entity.MiniPointRecord; |
|||
import com.youlai.boot.mini.model.form.AdjustUserPointForm; |
|||
import com.youlai.boot.mini.model.query.PointRecordQuery; |
|||
import com.youlai.boot.mini.model.vo.PointRecordVO; |
|||
|
|||
public interface MiniPointRecordService extends IService<MiniPointRecord> { |
|||
|
|||
/** |
|||
* 后台手动调整用户积分 |
|||
* @param form 调整参数 |
|||
*/ |
|||
void adjustPoint(AdjustUserPointForm form); |
|||
|
|||
/** |
|||
* 分页查询所有积分记录(后台管理端) |
|||
* @param query 查询参数 |
|||
* @return 分页结果 |
|||
*/ |
|||
IPage<PointRecordVO> pageAllRecord(PointRecordQuery query); |
|||
|
|||
} |
|||
|
|||
@ -1,9 +1,29 @@ |
|||
package com.youlai.boot.mini.service; |
|||
|
|||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|||
import com.baomidou.mybatisplus.extension.service.IService; |
|||
import com.youlai.boot.mini.model.entity.MiniPointRule; |
|||
import com.youlai.boot.mini.model.form.AddPointRuleForm; |
|||
import com.youlai.boot.mini.model.query.RulePageQuery; |
|||
import com.youlai.boot.mini.model.vo.RuleListVO; |
|||
|
|||
public interface MiniPointRuleService { |
|||
public interface MiniPointRuleService extends IService<MiniPointRule> { |
|||
IPage<RuleListVO> pageRule(RulePageQuery queryParams); |
|||
|
|||
/** |
|||
* 新增积分规则 |
|||
*/ |
|||
void addRule(AddPointRuleForm form); |
|||
|
|||
/** |
|||
* 逻辑删除积分规则 |
|||
*/ |
|||
void deleteRule(Long id); |
|||
|
|||
/** |
|||
* 启用/禁用积分规则 |
|||
* @param id 规则ID |
|||
* @param status 状态:false-启用,true-禁用 |
|||
*/ |
|||
void changeStatus(Long id, Boolean status); |
|||
} |
|||
|
|||
@ -1,15 +1,84 @@ |
|||
package com.youlai.boot.mini.service.impl; |
|||
|
|||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|||
import com.baomidou.mybatisplus.core.metadata.IPage; |
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
|||
import com.youlai.boot.common.exception.MsgException; |
|||
import com.youlai.boot.framework.security.util.SecurityUtils; |
|||
import com.youlai.boot.mini.mapper.MiniPointRecordMapper; |
|||
import com.youlai.boot.mini.model.entity.MiniPointAccount; |
|||
import com.youlai.boot.mini.model.entity.MiniPointRecord; |
|||
import com.youlai.boot.mini.model.form.AdjustUserPointForm; |
|||
import com.youlai.boot.mini.model.query.PointRecordQuery; |
|||
import com.youlai.boot.mini.model.vo.PointRecordVO; |
|||
import com.youlai.boot.mini.service.MiniPointAccountService; |
|||
import com.youlai.boot.mini.service.MiniPointRecordService; |
|||
import lombok.RequiredArgsConstructor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Service; |
|||
import org.springframework.transaction.annotation.Transactional; |
|||
|
|||
import java.util.Date; |
|||
import java.util.UUID; |
|||
|
|||
@Service |
|||
@RequiredArgsConstructor |
|||
@Slf4j |
|||
public class MiniPointRecordServiceImpl extends ServiceImpl<MiniPointRecordMapper, MiniPointRecord> implements MiniPointRecordService { |
|||
|
|||
private final MiniPointAccountService miniPointAccountService; |
|||
|
|||
|
|||
@Override |
|||
@Transactional(rollbackFor = Exception.class) |
|||
public void adjustPoint(AdjustUserPointForm form) { |
|||
// 1. 参数校验:调整值不能为0
|
|||
if (form.getChangeAmount() == null || form.getChangeAmount() == 0) { |
|||
throw new MsgException("积分调整值不能为0"); |
|||
} |
|||
|
|||
// 2. 直接根据前端传的用户主键userId查询积分账户(后台操作接口,不需要转uuid,直接用主键更高效)
|
|||
MiniPointAccount account = miniPointAccountService.getOne(new LambdaQueryWrapper<MiniPointAccount>() |
|||
.eq(MiniPointAccount::getUserId, form.getUserId()) |
|||
.eq(MiniPointAccount::getDeleted, false)); |
|||
if (account == null) { |
|||
throw new MsgException("用户积分账户不存在"); |
|||
} |
|||
|
|||
// 4. 计算变更后余额,校验扣减后不能为负数
|
|||
Integer afterBalance = account.getPoints() + form.getChangeAmount(); |
|||
if (afterBalance < 0) { |
|||
throw new MsgException("积分不足,扣减后余额不能为负数"); |
|||
} |
|||
|
|||
// 5. 更新用户积分账户余额
|
|||
MiniPointAccount updateAccount = new MiniPointAccount(); |
|||
updateAccount.setId(account.getId()); |
|||
updateAccount.setPoints(afterBalance); |
|||
updateAccount.setUpdateBy(SecurityUtils.getUserId()); |
|||
updateAccount.setUpdateTime(new Date()); |
|||
updateAccount.setUpdateTimestamp(System.currentTimeMillis()); |
|||
miniPointAccountService.updateById(updateAccount); |
|||
|
|||
// 6. 插入积分流水记录
|
|||
MiniPointRecord record = new MiniPointRecord(); |
|||
record.setUuid(UUID.randomUUID().toString().replace("-", "")); |
|||
record.setUserId(account.getUserId()); |
|||
record.setChangeAmount(form.getChangeAmount()); |
|||
record.setBalanceAfter(afterBalance); |
|||
record.setBizType(form.getBizType()); |
|||
record.setBizId(UUID.randomUUID().toString().replace("-", "")); // 业务唯一ID,保证幂等
|
|||
record.setCreateBy(SecurityUtils.getUserId()); |
|||
record.setCreateTime(new Date()); |
|||
record.setCreateTimestamp(System.currentTimeMillis()); |
|||
this.save(record); |
|||
} |
|||
|
|||
@Override |
|||
public IPage<PointRecordVO> pageAllRecord(PointRecordQuery query) { |
|||
Page<MiniPointRecord> page = new Page<>(query.getPageNum(), query.getPageSize()); |
|||
// 调用mapper关联查询,直接返回VO分页结果
|
|||
return baseMapper.pageAllRecord(page, query); |
|||
} |
|||
} |
|||
|
|||
Loading…
Reference in new issue