feat(用户余额): 新增用户余额变更日志功能
添加用户余额变更日志模块,包括数据库表、实体类、服务层及领域模型 实现余额变更记录功能,支持消费和审批归还场景的日志记录 新增查询接口,支持按用户余额ID、订单ID等条件查询变更日志
This commit is contained in:
parent
ec9a9243d2
commit
348b932556
|
|
@ -209,6 +209,11 @@ public enum ErrorCode implements ErrorCodeInterface {
|
|||
* 余额金额无效
|
||||
*/
|
||||
BALANCE_AMOUNT_INVALID(11006, "余额金额无效", "Business.BALANCE_AMOUNT_INVALID"),
|
||||
|
||||
/**
|
||||
* 该值不允许为空
|
||||
*/
|
||||
VALUE_NOT_ALLOWED(11007, "该值不允许为空", "Business.VALUE_NOT_ALLOWED"),
|
||||
;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,249 @@
|
|||
package com.agileboot.domain.ab98.user_balance_log;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.domain.ab98.user_balance_log.command.AddUserBalanceLogCommand;
|
||||
import com.agileboot.domain.ab98.user_balance_log.command.UpdateUserBalanceLogCommand;
|
||||
import com.agileboot.domain.ab98.user_balance_log.db.UserBalanceLogEntity;
|
||||
import com.agileboot.domain.ab98.user_balance_log.db.UserBalanceLogService;
|
||||
import com.agileboot.domain.ab98.user_balance_log.dto.UserBalanceLogDTO;
|
||||
import com.agileboot.domain.ab98.user_balance_log.model.UserBalanceLogModel;
|
||||
import com.agileboot.domain.ab98.user_balance_log.model.UserBalanceLogModelFactory;
|
||||
import com.agileboot.domain.ab98.user_balance_log.query.SearchUserBalanceLogQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额变更日志应用服务
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-12-06
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserBalanceLogApplicationService {
|
||||
|
||||
private final UserBalanceLogService userBalanceLogService;
|
||||
private final UserBalanceLogModelFactory userBalanceLogModelFactory;
|
||||
|
||||
/**
|
||||
* 新增用户余额变更日志
|
||||
*
|
||||
* @param command 新增命令
|
||||
* @return 用户余额变更日志DTO
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public UserBalanceLogDTO add(AddUserBalanceLogCommand command) {
|
||||
UserBalanceLogModel model = userBalanceLogModelFactory.create(command);
|
||||
boolean success = model.save();
|
||||
if (!success) {
|
||||
throw new RuntimeException("新增用户余额变更日志失败");
|
||||
}
|
||||
return new UserBalanceLogDTO(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户余额变更日志
|
||||
*
|
||||
* @param command 更新命令
|
||||
* @return 用户余额变更日志DTO
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public UserBalanceLogDTO update(UpdateUserBalanceLogCommand command) {
|
||||
UserBalanceLogModel model = userBalanceLogModelFactory.create(command);
|
||||
boolean success = model.update();
|
||||
if (!success) {
|
||||
throw new RuntimeException("更新用户余额变更日志失败");
|
||||
}
|
||||
return new UserBalanceLogDTO(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID删除用户余额变更日志
|
||||
*
|
||||
* @param logId 主键ID
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(Long logId) {
|
||||
if (logId == null) {
|
||||
throw new IllegalArgumentException("日志ID不能为空");
|
||||
}
|
||||
|
||||
boolean success = userBalanceLogService.removeById(logId);
|
||||
if (!success) {
|
||||
throw new RuntimeException("删除用户余额变更日志失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID查询用户余额变更日志
|
||||
*
|
||||
* @param logId 主键ID
|
||||
* @return 用户余额变更日志DTO
|
||||
*/
|
||||
public UserBalanceLogDTO getById(Long logId) {
|
||||
if (logId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UserBalanceLogEntity entity = userBalanceLogService.getById(logId);
|
||||
return entity != null ? new UserBalanceLogDTO(entity) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户余额变更日志列表
|
||||
*
|
||||
* @param query 查询参数
|
||||
* @return 用户余额变更日志分页DTO
|
||||
*/
|
||||
public PageDTO<UserBalanceLogDTO> getList(SearchUserBalanceLogQuery query) {
|
||||
// 构建查询条件
|
||||
Page<UserBalanceLogEntity> page = query.toPage();
|
||||
UserBalanceLogEntity entity = new UserBalanceLogEntity();
|
||||
BeanUtil.copyProperties(query, entity);
|
||||
|
||||
// 执行查询
|
||||
List<UserBalanceLogEntity> entityList = userBalanceLogService.page(page, query.addQueryCondition()).getRecords();
|
||||
|
||||
// 转换为DTO
|
||||
List<UserBalanceLogDTO> dtoList = entityList.stream()
|
||||
.map(UserBalanceLogDTO::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 获取总数
|
||||
Long total = page.getTotal();
|
||||
|
||||
return new PageDTO<>(dtoList, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除用户余额变更日志
|
||||
*
|
||||
* @param logIds 主键ID列表
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchDelete(List<Long> logIds) {
|
||||
if (CollUtil.isEmpty(logIds)) {
|
||||
throw new IllegalArgumentException("日志ID列表不能为空");
|
||||
}
|
||||
|
||||
boolean success = userBalanceLogService.removeByIds(logIds);
|
||||
if (!success) {
|
||||
throw new RuntimeException("批量删除用户余额变更日志失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户余额ID查询变更日志列表
|
||||
*
|
||||
* @param userBalanceId 用户余额ID
|
||||
* @return 用户余额变更日志DTO列表
|
||||
*/
|
||||
public List<UserBalanceLogDTO> getByUserBalanceId(Long userBalanceId) {
|
||||
if (userBalanceId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<UserBalanceLogEntity> entityList = userBalanceLogService.getByUserBalanceId(userBalanceId);
|
||||
if (CollUtil.isEmpty(entityList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return entityList.stream()
|
||||
.map(UserBalanceLogDTO::new)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单ID查询变更日志列表
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 用户余额变更日志DTO列表
|
||||
*/
|
||||
public List<UserBalanceLogDTO> getByOrderId(Long orderId) {
|
||||
if (orderId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<UserBalanceLogEntity> entityList = userBalanceLogService.getByOrderId(orderId);
|
||||
if (CollUtil.isEmpty(entityList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return entityList.stream()
|
||||
.map(UserBalanceLogDTO::new)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据审批ID查询变更日志列表
|
||||
*
|
||||
* @param approvalId 审批ID
|
||||
* @return 用户余额变更日志DTO列表
|
||||
*/
|
||||
public List<UserBalanceLogDTO> getByApprovalId(Long approvalId) {
|
||||
if (approvalId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<UserBalanceLogEntity> entityList = userBalanceLogService.getByApprovalId(approvalId);
|
||||
if (CollUtil.isEmpty(entityList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return entityList.stream()
|
||||
.map(UserBalanceLogDTO::new)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单商品ID查询变更日志列表
|
||||
*
|
||||
* @param orderGoodsId 订单商品ID
|
||||
* @return 用户余额变更日志DTO列表
|
||||
*/
|
||||
public List<UserBalanceLogDTO> getByOrderGoodsId(Long orderGoodsId) {
|
||||
if (orderGoodsId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<UserBalanceLogEntity> entityList = userBalanceLogService.getByOrderGoodsId(orderGoodsId);
|
||||
if (CollUtil.isEmpty(entityList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return entityList.stream()
|
||||
.map(UserBalanceLogDTO::new)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据变更类型查询变更日志列表
|
||||
*
|
||||
* @param changeType 变更类型
|
||||
* @return 用户余额变更日志DTO列表
|
||||
*/
|
||||
public List<UserBalanceLogDTO> getByChangeType(Integer changeType) {
|
||||
if (changeType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<UserBalanceLogEntity> entityList = userBalanceLogService.getByChangeType(changeType);
|
||||
if (CollUtil.isEmpty(entityList)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return entityList.stream()
|
||||
.map(UserBalanceLogDTO::new)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package com.agileboot.domain.ab98.user_balance_log.command;
|
||||
|
||||
import com.agileboot.domain.ab98.user_balance_log.db.UserBalanceLogEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 新增用户余额变更日志命令
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-12-06
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class AddUserBalanceLogCommand extends UserBalanceLogEntity {
|
||||
|
||||
@NotNull(message = "用户余额ID不能为空")
|
||||
private Long userBalanceId;
|
||||
|
||||
@NotNull(message = "变更类型不能为空")
|
||||
private Integer changeType;
|
||||
|
||||
@NotNull(message = "变更金额不能为空")
|
||||
private Long changeAmount;
|
||||
|
||||
@NotNull(message = "变更前已用余额不能为空")
|
||||
private Long useBalanceBefore;
|
||||
|
||||
@NotNull(message = "变更后已用余额不能为空")
|
||||
private Long useBalanceAfter;
|
||||
|
||||
private Long orderId;
|
||||
|
||||
private Long approvalId;
|
||||
|
||||
private Long orderGoodsId;
|
||||
|
||||
@NotNull(message = "创建者ID不能为空")
|
||||
private Long creatorId;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.agileboot.domain.ab98.user_balance_log.command;
|
||||
|
||||
import com.agileboot.domain.ab98.user_balance_log.db.UserBalanceLogEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 更新用户余额变更日志命令
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-12-06
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class UpdateUserBalanceLogCommand extends AddUserBalanceLogCommand {
|
||||
|
||||
@NotNull(message = "日志ID不能为空")
|
||||
private Long logId;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package com.agileboot.domain.ab98.user_balance_log.db;
|
||||
|
||||
import com.agileboot.common.core.base.BaseEntity;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import java.io.Serializable;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额变更日志表
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-12-06
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("user_balance_log")
|
||||
@ApiModel(value = "UserBalanceLogEntity对象", description = "用户余额变更日志表")
|
||||
public class UserBalanceLogEntity extends BaseEntity<UserBalanceLogEntity> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("主键ID")
|
||||
@TableId(value = "log_id", type = IdType.AUTO)
|
||||
private Long logId;
|
||||
|
||||
@ApiModelProperty("用户余额ID")
|
||||
@TableField("user_balance_id")
|
||||
private Long userBalanceId;
|
||||
|
||||
@ApiModelProperty("变更类型(1-消费 2-审批归还 3-系统调整)")
|
||||
@TableField("change_type")
|
||||
private Integer changeType;
|
||||
|
||||
@ApiModelProperty("变更金额(单位:分,正数表示增加,负数表示减少)")
|
||||
@TableField("change_amount")
|
||||
private Long changeAmount;
|
||||
|
||||
@ApiModelProperty("变更前已用余额")
|
||||
@TableField("use_balance_before")
|
||||
private Long useBalanceBefore;
|
||||
|
||||
@ApiModelProperty("变更后已用余额")
|
||||
@TableField("use_balance_after")
|
||||
private Long useBalanceAfter;
|
||||
|
||||
@ApiModelProperty("关联订单ID")
|
||||
@TableField("order_id")
|
||||
private Long orderId;
|
||||
|
||||
@ApiModelProperty("关联审批ID")
|
||||
@TableField("approval_id")
|
||||
private Long approvalId;
|
||||
|
||||
@ApiModelProperty("关联订单商品ID")
|
||||
@TableField("order_goods_id")
|
||||
private Long orderGoodsId;
|
||||
|
||||
@ApiModelProperty("创建者ID")
|
||||
@TableField("creator_id")
|
||||
private Long creatorId;
|
||||
|
||||
@ApiModelProperty("更新者ID")
|
||||
@TableField("updater_id")
|
||||
private Long updaterId;
|
||||
|
||||
|
||||
@Override
|
||||
public Serializable pkVal() {
|
||||
return this.logId;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package com.agileboot.domain.ab98.user_balance_log.db;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额变更日志表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-12-06
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserBalanceLogMapper extends BaseMapper<UserBalanceLogEntity> {
|
||||
|
||||
/**
|
||||
* 根据用户余额ID查询变更日志列表
|
||||
*
|
||||
* @param userBalanceId 用户余额ID
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
@Select("SELECT * FROM user_balance_log WHERE user_balance_id = #{userBalanceId} ORDER BY create_time DESC")
|
||||
List<UserBalanceLogEntity> selectByUserBalanceId(@Param("userBalanceId") Long userBalanceId);
|
||||
|
||||
/**
|
||||
* 根据订单ID查询变更日志列表
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
@Select("SELECT * FROM user_balance_log WHERE order_id = #{orderId} ORDER BY create_time DESC")
|
||||
List<UserBalanceLogEntity> selectByOrderId(@Param("orderId") Long orderId);
|
||||
|
||||
/**
|
||||
* 根据审批ID查询变更日志列表
|
||||
*
|
||||
* @param approvalId 审批ID
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
@Select("SELECT * FROM user_balance_log WHERE approval_id = #{approvalId} ORDER BY create_time DESC")
|
||||
List<UserBalanceLogEntity> selectByApprovalId(@Param("approvalId") Long approvalId);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package com.agileboot.domain.ab98.user_balance_log.db;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额变更日志表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-12-06
|
||||
*/
|
||||
public interface UserBalanceLogService extends IService<UserBalanceLogEntity> {
|
||||
|
||||
/**
|
||||
* 根据用户余额ID查询变更日志列表
|
||||
*
|
||||
* @param userBalanceId 用户余额ID
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
List<UserBalanceLogEntity> getByUserBalanceId(Long userBalanceId);
|
||||
|
||||
/**
|
||||
* 根据订单ID查询变更日志列表
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
List<UserBalanceLogEntity> getByOrderId(Long orderId);
|
||||
|
||||
/**
|
||||
* 根据审批ID查询变更日志列表
|
||||
*
|
||||
* @param approvalId 审批ID
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
List<UserBalanceLogEntity> getByApprovalId(Long approvalId);
|
||||
|
||||
/**
|
||||
* 根据订单商品ID查询变更日志列表
|
||||
*
|
||||
* @param orderGoodsId 订单商品ID
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
List<UserBalanceLogEntity> getByOrderGoodsId(Long orderGoodsId);
|
||||
|
||||
/**
|
||||
* 根据变更类型查询变更日志列表
|
||||
*
|
||||
* @param changeType 变更类型
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
List<UserBalanceLogEntity> getByChangeType(Integer changeType);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package com.agileboot.domain.ab98.user_balance_log.db;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额变更日志表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-12-06
|
||||
*/
|
||||
@Service
|
||||
public class UserBalanceLogServiceImpl extends ServiceImpl<UserBalanceLogMapper, UserBalanceLogEntity> implements UserBalanceLogService {
|
||||
|
||||
/**
|
||||
* 根据用户余额ID查询变更日志列表
|
||||
*
|
||||
* @param userBalanceId 用户余额ID
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
@Override
|
||||
public List<UserBalanceLogEntity> getByUserBalanceId(Long userBalanceId) {
|
||||
if (userBalanceId == null) {
|
||||
return null;
|
||||
}
|
||||
return baseMapper.selectByUserBalanceId(userBalanceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单ID查询变更日志列表
|
||||
*
|
||||
* @param orderId 订单ID
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
@Override
|
||||
public List<UserBalanceLogEntity> getByOrderId(Long orderId) {
|
||||
if (orderId == null) {
|
||||
return null;
|
||||
}
|
||||
return baseMapper.selectByOrderId(orderId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据审批ID查询变更日志列表
|
||||
*
|
||||
* @param approvalId 审批ID
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
@Override
|
||||
public List<UserBalanceLogEntity> getByApprovalId(Long approvalId) {
|
||||
if (approvalId == null) {
|
||||
return null;
|
||||
}
|
||||
return baseMapper.selectByApprovalId(approvalId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单商品ID查询变更日志列表
|
||||
*
|
||||
* @param orderGoodsId 订单商品ID
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
@Override
|
||||
public List<UserBalanceLogEntity> getByOrderGoodsId(Long orderGoodsId) {
|
||||
if (orderGoodsId == null) {
|
||||
return null;
|
||||
}
|
||||
return lambdaQuery()
|
||||
.eq(UserBalanceLogEntity::getOrderGoodsId, orderGoodsId)
|
||||
.orderByDesc(UserBalanceLogEntity::getCreateTime)
|
||||
.list();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据变更类型查询变更日志列表
|
||||
*
|
||||
* @param changeType 变更类型
|
||||
* @return 变更日志列表
|
||||
*/
|
||||
@Override
|
||||
public List<UserBalanceLogEntity> getByChangeType(Integer changeType) {
|
||||
if (changeType == null) {
|
||||
return null;
|
||||
}
|
||||
return lambdaQuery()
|
||||
.eq(UserBalanceLogEntity::getChangeType, changeType)
|
||||
.orderByDesc(UserBalanceLogEntity::getCreateTime)
|
||||
.list();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package com.agileboot.domain.ab98.user_balance_log.dto;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.agileboot.common.annotation.ExcelColumn;
|
||||
import com.agileboot.common.annotation.ExcelSheet;
|
||||
import com.agileboot.domain.ab98.user_balance_log.db.UserBalanceLogEntity;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额变更日志DTO
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-12-06
|
||||
*/
|
||||
@ExcelSheet(name = "用户余额变更日志")
|
||||
@Data
|
||||
public class UserBalanceLogDTO {
|
||||
|
||||
public UserBalanceLogDTO() {}
|
||||
|
||||
public UserBalanceLogDTO(UserBalanceLogEntity entity) {
|
||||
if (entity != null) {
|
||||
BeanUtil.copyProperties(entity, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ExcelColumn(name = "主键ID")
|
||||
private Long logId;
|
||||
|
||||
@ExcelColumn(name = "用户余额ID")
|
||||
private Long userBalanceId;
|
||||
|
||||
@ExcelColumn(name = "变更类型(1-消费,2-审批归还,3-系统调整)")
|
||||
private Integer changeType;
|
||||
|
||||
@ExcelColumn(name = "变更金额(分)")
|
||||
private Long changeAmount;
|
||||
|
||||
@ExcelColumn(name = "变更前已用余额(分)")
|
||||
private Long useBalanceBefore;
|
||||
|
||||
@ExcelColumn(name = "变更后已用余额(分)")
|
||||
private Long useBalanceAfter;
|
||||
|
||||
@ExcelColumn(name = "关联订单ID")
|
||||
private Long orderId;
|
||||
|
||||
@ExcelColumn(name = "关联审批ID")
|
||||
private Long approvalId;
|
||||
|
||||
@ExcelColumn(name = "关联订单商品ID")
|
||||
private Long orderGoodsId;
|
||||
|
||||
@ExcelColumn(name = "创建者ID")
|
||||
private Long creatorId;
|
||||
|
||||
@ExcelColumn(name = "创建时间")
|
||||
private String createTime;
|
||||
|
||||
@ExcelColumn(name = "更新者ID")
|
||||
private Long updaterId;
|
||||
|
||||
@ExcelColumn(name = "更新时间")
|
||||
private String updateTime;
|
||||
|
||||
@ExcelColumn(name = "删除标志")
|
||||
private Boolean deleted;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
package com.agileboot.domain.ab98.user_balance_log.model;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
import com.agileboot.common.exception.error.ErrorCode;
|
||||
import com.agileboot.domain.ab98.user_balance_log.command.AddUserBalanceLogCommand;
|
||||
import com.agileboot.domain.ab98.user_balance_log.command.UpdateUserBalanceLogCommand;
|
||||
import com.agileboot.domain.ab98.user_balance_log.db.UserBalanceLogEntity;
|
||||
import com.agileboot.domain.ab98.user_balance_log.db.UserBalanceLogService;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额变更日志领域模型
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-12-06
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class UserBalanceLogModel extends UserBalanceLogEntity {
|
||||
|
||||
private UserBalanceLogService userBalanceLogService;
|
||||
|
||||
public UserBalanceLogModel() {}
|
||||
|
||||
public UserBalanceLogModel(UserBalanceLogEntity entity, UserBalanceLogService userBalanceLogService) {
|
||||
this.userBalanceLogService = userBalanceLogService;
|
||||
if (entity != null) {
|
||||
BeanUtil.copyProperties(entity, this);
|
||||
}
|
||||
}
|
||||
|
||||
public UserBalanceLogModel(UserBalanceLogService userBalanceLogService) {
|
||||
this.userBalanceLogService = userBalanceLogService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从新增命令加载数据
|
||||
*
|
||||
* @param command 新增命令
|
||||
*/
|
||||
public void loadAddCommand(AddUserBalanceLogCommand command) {
|
||||
if (command != null) {
|
||||
BeanUtil.copyProperties(command, this, "logId");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从更新命令加载数据
|
||||
*
|
||||
* @param command 更新命令
|
||||
*/
|
||||
public void loadUpdateCommand(UpdateUserBalanceLogCommand command) {
|
||||
if (command != null) {
|
||||
loadAddCommand(command);
|
||||
if (command.getLogId() != null) {
|
||||
this.setLogId(command.getLogId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证变更类型是否有效
|
||||
*
|
||||
* @param changeType 变更类型
|
||||
* @throws ApiException 无效变更类型异常
|
||||
*/
|
||||
public void validateChangeType(Integer changeType) {
|
||||
if (changeType == null || changeType < 1 || changeType > 3) {
|
||||
throw new ApiException(ErrorCode.Business.VALUE_NOT_ALLOWED, "变更类型", "1-消费, 2-审批归还, 3-系统调整");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证变更金额是否有效
|
||||
*
|
||||
* @param changeAmount 变更金额
|
||||
* @throws ApiException 无效变更金额异常
|
||||
*/
|
||||
public void validateChangeAmount(Long changeAmount) {
|
||||
if (changeAmount == null) {
|
||||
throw new ApiException(ErrorCode.Business.VALUE_NOT_ALLOWED, "变更金额", "不能为空");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证变更前后的已用余额
|
||||
*
|
||||
* @param useBalanceBefore 变更前已用余额
|
||||
* @param useBalanceAfter 变更后已用余额
|
||||
* @throws ApiException 已用余额异常
|
||||
*/
|
||||
public void validateUseBalance(Long useBalanceBefore, Long useBalanceAfter) {
|
||||
if (useBalanceBefore == null || useBalanceBefore < 0) {
|
||||
throw new ApiException(ErrorCode.Business.VALUE_NOT_ALLOWED, "变更前已用余额", "不能为空且不能为负数");
|
||||
}
|
||||
|
||||
if (useBalanceAfter == null || useBalanceAfter < 0) {
|
||||
throw new ApiException(ErrorCode.Business.VALUE_NOT_ALLOWED, "变更后已用余额", "不能为空且不能为负数");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存到数据库
|
||||
*
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean save() {
|
||||
return userBalanceLogService.save(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新到数据库
|
||||
*
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean update() {
|
||||
return userBalanceLogService.updateById(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库删除
|
||||
*
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean remove() {
|
||||
return userBalanceLogService.removeById(this.getLogId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.agileboot.domain.ab98.user_balance_log.model;
|
||||
|
||||
import com.agileboot.domain.ab98.user_balance_log.command.AddUserBalanceLogCommand;
|
||||
import com.agileboot.domain.ab98.user_balance_log.command.UpdateUserBalanceLogCommand;
|
||||
import com.agileboot.domain.ab98.user_balance_log.db.UserBalanceLogEntity;
|
||||
import com.agileboot.domain.ab98.user_balance_log.db.UserBalanceLogService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额变更日志领域模型工厂
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-12-06
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class UserBalanceLogModelFactory {
|
||||
|
||||
private final UserBalanceLogService userBalanceLogService;
|
||||
|
||||
/**
|
||||
* 创建空的用户余额变更日志模型
|
||||
*
|
||||
* @return 用户余额变更日志模型
|
||||
*/
|
||||
public UserBalanceLogModel create() {
|
||||
return new UserBalanceLogModel(userBalanceLogService);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据新增命令创建用户余额变更日志模型
|
||||
*
|
||||
* @param command 新增命令
|
||||
* @return 用户余额变更日志模型
|
||||
*/
|
||||
public UserBalanceLogModel create(AddUserBalanceLogCommand command) {
|
||||
UserBalanceLogModel model = create();
|
||||
model.loadAddCommand(command);
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据更新命令创建用户余额变更日志模型
|
||||
*
|
||||
* @param command 更新命令
|
||||
* @return 用户余额变更日志模型
|
||||
*/
|
||||
public UserBalanceLogModel create(UpdateUserBalanceLogCommand command) {
|
||||
UserBalanceLogModel model = create();
|
||||
model.loadUpdateCommand(command);
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据实体创建用户余额变更日志模型
|
||||
*
|
||||
* @param entity 实体
|
||||
* @return 用户余额变更日志模型
|
||||
*/
|
||||
public UserBalanceLogModel create(UserBalanceLogEntity entity) {
|
||||
return new UserBalanceLogModel(entity, userBalanceLogService);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.agileboot.domain.ab98.user_balance_log.query;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.common.core.page.AbstractPageQuery;
|
||||
import com.agileboot.domain.ab98.user_balance_log.db.UserBalanceLogEntity;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额变更日志查询参数
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-12-06
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class SearchUserBalanceLogQuery extends AbstractPageQuery<UserBalanceLogEntity> {
|
||||
|
||||
@ApiModelProperty("用户余额ID")
|
||||
private Long userBalanceId;
|
||||
|
||||
@ApiModelProperty("变更类型(1-消费, 2-审批归还, 3-系统调整)")
|
||||
private Integer changeType;
|
||||
|
||||
@ApiModelProperty("关联订单ID")
|
||||
private Long orderId;
|
||||
|
||||
@ApiModelProperty("关联审批ID")
|
||||
private Long approvalId;
|
||||
|
||||
@ApiModelProperty("关联订单商品ID")
|
||||
private Long orderGoodsId;
|
||||
|
||||
@ApiModelProperty("创建者ID")
|
||||
private Long creatorId;
|
||||
|
||||
@Override
|
||||
public QueryWrapper<UserBalanceLogEntity> addQueryCondition() {
|
||||
QueryWrapper<UserBalanceLogEntity> queryWrapper = new QueryWrapper<>();
|
||||
|
||||
queryWrapper
|
||||
.eq(userBalanceId != null, "user_balance_id", userBalanceId)
|
||||
.eq(changeType != null, "change_type", changeType)
|
||||
.eq(orderId != null, "order_id", orderId)
|
||||
.eq(approvalId != null, "approval_id", approvalId)
|
||||
.eq(orderGoodsId != null, "order_goods_id", orderGoodsId)
|
||||
.eq(creatorId != null, "creator_id", creatorId)
|
||||
.eq("deleted", false);
|
||||
|
||||
this.timeRangeColumn = "create_time";
|
||||
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,6 +7,9 @@ import com.agileboot.common.utils.MoneyUtil;
|
|||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceEntity;
|
||||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceService;
|
||||
import com.agileboot.domain.ab98.user_balance.dto.UserBalanceDTO;
|
||||
import com.agileboot.domain.ab98.user_balance_log.command.AddUserBalanceLogCommand;
|
||||
import com.agileboot.domain.ab98.user_balance_log.model.UserBalanceLogModelFactory;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import com.agileboot.common.constant.UrlConstants;
|
||||
import com.agileboot.common.constant.WeixinConstants;
|
||||
|
|
@ -117,6 +120,7 @@ public class ReturnApprovalApplicationService {
|
|||
private final CabinetCellOperationModelFactory cabinetCellOperationModelFactory;
|
||||
private final MqttService mqttService;
|
||||
private final UserBalanceService userBalanceService;
|
||||
private final UserBalanceLogModelFactory userBalanceLogModelFactory;
|
||||
@Autowired
|
||||
private WxshopConfig wxshopConfig;
|
||||
|
||||
|
|
@ -281,9 +285,33 @@ public class ReturnApprovalApplicationService {
|
|||
if (null == userBalance) {
|
||||
throw new IllegalArgumentException("用户余额不存在");
|
||||
}
|
||||
userBalance.setBalance(userBalance.getBalance() + MoneyUtil.yuanToFen(command.getReturnAmount()));
|
||||
userBalance.setUseBalance(userBalance.getUseBalance() - MoneyUtil.yuanToFen(command.getReturnAmount()));
|
||||
|
||||
// 记录变更前的余额信息
|
||||
Long useBalanceBefore = userBalance.getUseBalance();
|
||||
Long changeAmountFen = MoneyUtil.yuanToFen(command.getReturnAmount());
|
||||
|
||||
// 更新余额
|
||||
userBalance.setBalance(userBalance.getBalance() + changeAmountFen);
|
||||
userBalance.setUseBalance(userBalance.getUseBalance() - changeAmountFen);
|
||||
userBalance.updateById();
|
||||
|
||||
try {
|
||||
// 记录余额变更日志
|
||||
AddUserBalanceLogCommand logCommand = new AddUserBalanceLogCommand();
|
||||
logCommand.setUserBalanceId(userBalance.getUserBalanceId());
|
||||
logCommand.setChangeType(2); // 2-审批归还
|
||||
logCommand.setChangeAmount(-changeAmountFen); // 审批归还为负数
|
||||
logCommand.setUseBalanceBefore(useBalanceBefore);
|
||||
logCommand.setUseBalanceAfter(userBalance.getUseBalance());
|
||||
logCommand.setOrderId(orderModel.getOrderId());
|
||||
logCommand.setApprovalId(model.getApprovalId());
|
||||
logCommand.setOrderGoodsId(orderGoodsModel.getOrderGoodsId());
|
||||
logCommand.initBaseEntity();
|
||||
|
||||
userBalanceLogModelFactory.create(logCommand).insert();
|
||||
} catch (Exception e) {
|
||||
log.error("记录余额变更日志失败", e);
|
||||
}
|
||||
/*if (null != qyUser) {
|
||||
qyUser.setBalance(qyUser.getBalance().add(command.getReturnAmount()));
|
||||
qyUser.setUseBalance(qyUser.getUseBalance().subtract(command.getReturnAmount()));
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import com.agileboot.common.utils.MoneyUtil;
|
|||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceEntity;
|
||||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceService;
|
||||
import com.agileboot.domain.ab98.user_balance.dto.UserBalanceDTO;
|
||||
import com.agileboot.domain.ab98.user_balance_log.command.AddUserBalanceLogCommand;
|
||||
import com.agileboot.domain.ab98.user_balance_log.model.UserBalanceLogModelFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.exception.ApiException;
|
||||
|
|
@ -105,6 +107,7 @@ public class OrderApplicationService {
|
|||
private final Ab98UserService ab98UserService;
|
||||
private final WxUserService wxUserService;
|
||||
private final UserBalanceService userBalanceService;
|
||||
private final UserBalanceLogModelFactory userBalanceLogModelFactory;
|
||||
@Autowired
|
||||
private WxshopConfig wxshopConfig;
|
||||
|
||||
|
|
@ -260,9 +263,28 @@ public class OrderApplicationService {
|
|||
if (userBalance.getBalance().compareTo(MoneyUtil.yuanToFen(orderModel.getTotalAmount())) < 0) {
|
||||
throw new ApiException(ErrorCode.Client.COMMON_REQUEST_PARAMETERS_INVALID, "余额不足");
|
||||
} else {
|
||||
userBalance.setBalance(userBalance.getBalance() - MoneyUtil.yuanToFen(orderModel.getTotalAmount()));
|
||||
userBalance.setUseBalance(userBalance.getUseBalance() + MoneyUtil.yuanToFen(orderModel.getTotalAmount()));
|
||||
// 记录变更前的余额信息
|
||||
Long useBalanceBefore = userBalance.getUseBalance();
|
||||
Long changeAmount = MoneyUtil.yuanToFen(orderModel.getTotalAmount());
|
||||
|
||||
userBalance.setBalance(userBalance.getBalance() - changeAmount);
|
||||
userBalance.setUseBalance(userBalance.getUseBalance() + changeAmount);
|
||||
userBalanceService.updateById(userBalance);
|
||||
|
||||
try {
|
||||
// 记录余额变动日志
|
||||
AddUserBalanceLogCommand logCommand = new AddUserBalanceLogCommand();
|
||||
logCommand.setUserBalanceId(userBalance.getUserBalanceId());
|
||||
logCommand.setChangeType(1); // 1-消费
|
||||
logCommand.setChangeAmount(changeAmount); // 消费为正数
|
||||
logCommand.setUseBalanceBefore(useBalanceBefore);
|
||||
logCommand.setUseBalanceAfter(userBalance.getUseBalance());
|
||||
logCommand.setOrderId(orderModel.getOrderId());
|
||||
logCommand.setCreatorId(orderModel.getCreatorId());
|
||||
userBalanceLogModelFactory.create(logCommand).save();
|
||||
} catch (Exception e) {
|
||||
log.error("记录余额变动日志失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
// 金额转换(元转分)并四舍五入
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
CREATE TABLE `user_balance_log` (
|
||||
`log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志ID',
|
||||
`user_balance_id` bigint NOT NULL COMMENT '用户余额ID',
|
||||
|
||||
-- 余额变更信息
|
||||
`change_type` tinyint NOT NULL COMMENT '变更类型(1-消费 2-审批归还 3-系统调整)',
|
||||
`change_amount` bigint NOT NULL COMMENT '变更金额(单位:分,正数表示增加,负数表示减少)',
|
||||
`use_balance_before` bigint NOT NULL COMMENT '变更前已用余额',
|
||||
`use_balance_after` bigint NOT NULL COMMENT '变更后已用余额',
|
||||
|
||||
-- 关联表信息
|
||||
`order_id` bigint DEFAULT NULL COMMENT '关联订单ID',
|
||||
`approval_id` bigint DEFAULT NULL COMMENT '关联审批ID',
|
||||
`order_goods_id` bigint DEFAULT NULL COMMENT '关联订单商品ID',
|
||||
|
||||
-- 系统字段
|
||||
`creator_id` bigint NOT NULL DEFAULT 0 COMMENT '创建者ID',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater_id` bigint NOT NULL DEFAULT 0 COMMENT '更新者ID',
|
||||
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`deleted` tinyint(1) NOT NULL DEFAULT 0 COMMENT '删除标志(0存在 1删除)',
|
||||
|
||||
PRIMARY KEY (`log_id`),
|
||||
KEY `idx_user_balance` (`user_balance_id`),
|
||||
KEY `idx_order` (`order_id`),
|
||||
KEY `idx_approval` (`approval_id`),
|
||||
KEY `idx_change_type` (`change_type`),
|
||||
KEY `idx_create_time` (`create_time`),
|
||||
KEY `idx_order_goods` (`order_goods_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户余额变更日志表';
|
||||
Loading…
Reference in New Issue