feat(用户余额): 新增用户余额管理功能
实现用户余额的增删改查、增加余额、减少余额等核心功能 添加相关DTO、Command、Query、Model等类 提供完整的API接口供前端调用
This commit is contained in:
parent
419cab9048
commit
0e262bd324
|
|
@ -37,7 +37,9 @@
|
|||
"Bash(./mvnw clean compile -pl agileboot-api -am -DskipTests)",
|
||||
"Bash(./mvnw clean compile -pl agileboot-api,agileboot-domain -am -DskipTests)",
|
||||
"Bash(./mvnw clean compile -pl agileboot-domain -am -DskipTests)",
|
||||
"Bash(./mvnw:*)"
|
||||
"Bash(./mvnw:*)",
|
||||
"Bash(tree:*)",
|
||||
"Bash(cat:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
package com.agileboot.admin.controller.ab98;
|
||||
|
||||
import com.agileboot.admin.customize.aop.accessLog.AccessLog;
|
||||
import com.agileboot.common.core.base.BaseController;
|
||||
import com.agileboot.common.core.dto.ResponseDTO;
|
||||
import com.agileboot.common.core.page.PageDTO;
|
||||
import com.agileboot.common.enums.common.BusinessTypeEnum;
|
||||
import com.agileboot.domain.ab98.user_balance.command.AddBalanceCommand;
|
||||
import com.agileboot.domain.ab98.user_balance.command.AddUserBalanceCommand;
|
||||
import com.agileboot.domain.ab98.user_balance.command.SubtractBalanceCommand;
|
||||
import com.agileboot.domain.ab98.user_balance.command.UpdateUserBalanceCommand;
|
||||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceEntity;
|
||||
import com.agileboot.domain.ab98.user_balance.dto.UserBalanceDTO;
|
||||
import com.agileboot.domain.ab98.user_balance.query.SearchUserBalanceQuery;
|
||||
import com.agileboot.domain.ab98.user_balance.UserBalanceApplicationService;
|
||||
import com.agileboot.domain.common.command.BulkOperationCommand;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import java.util.List;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/ab98/balance")
|
||||
@RequiredArgsConstructor
|
||||
@Validated
|
||||
public class UserBalanceController extends BaseController {
|
||||
|
||||
private final UserBalanceApplicationService userBalanceApplicationService;
|
||||
|
||||
@Operation(summary = "用户余额列表")
|
||||
@GetMapping
|
||||
public ResponseDTO<PageDTO<UserBalanceDTO>> list(SearchUserBalanceQuery query) {
|
||||
PageDTO<UserBalanceDTO> page = userBalanceApplicationService.getList(query);
|
||||
return ResponseDTO.ok(page);
|
||||
}
|
||||
|
||||
@Operation(summary = "用户余额详情")
|
||||
@GetMapping("/{id}")
|
||||
public ResponseDTO<UserBalanceDTO> detail(@PathVariable Long id) {
|
||||
UserBalanceDTO userBalanceDTO = userBalanceApplicationService.getById(id);
|
||||
return ResponseDTO.ok(userBalanceDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据企业微信ID和汇邦云用户ID查询用户余额")
|
||||
@GetMapping("/by-corpid-ab98")
|
||||
public ResponseDTO<UserBalanceDTO> getByCorpidAndAb98UserId(String corpid, Long ab98UserId) {
|
||||
UserBalanceDTO userBalanceDTO = userBalanceApplicationService.getByCorpidAndAb98UserId(corpid, ab98UserId);
|
||||
return ResponseDTO.ok(userBalanceDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据openid查询用户余额")
|
||||
@GetMapping("/by-openid")
|
||||
public ResponseDTO<UserBalanceDTO> getByOpenid(String openid) {
|
||||
UserBalanceDTO userBalanceDTO = userBalanceApplicationService.getByOpenid(openid);
|
||||
return ResponseDTO.ok(userBalanceDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "新增用户余额")
|
||||
@AccessLog(title = "用户余额管理", businessType = BusinessTypeEnum.ADD)
|
||||
@PostMapping
|
||||
public ResponseDTO<UserBalanceDTO> add(@Validated @RequestBody AddUserBalanceCommand command) {
|
||||
UserBalanceDTO userBalanceDTO = userBalanceApplicationService.add(command);
|
||||
return ResponseDTO.ok(userBalanceDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "修改用户余额")
|
||||
@AccessLog(title = "用户余额管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PutMapping("/{id}")
|
||||
public ResponseDTO<UserBalanceDTO> edit(@PathVariable Long id, @Validated @RequestBody UpdateUserBalanceCommand command) {
|
||||
command.setUserBalanceId(id);
|
||||
UserBalanceDTO userBalanceDTO = userBalanceApplicationService.update(command);
|
||||
return ResponseDTO.ok(userBalanceDTO);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除用户余额")
|
||||
@AccessLog(title = "用户余额管理", businessType = BusinessTypeEnum.DELETE)
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseDTO<Void> remove(@PathVariable Long id) {
|
||||
userBalanceApplicationService.delete(id);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "批量删除用户余额")
|
||||
@AccessLog(title = "用户余额管理", businessType = BusinessTypeEnum.DELETE)
|
||||
@DeleteMapping("/batch/{ids}")
|
||||
public ResponseDTO<Void> batchRemove(@PathVariable @NotNull List<Long> ids) {
|
||||
userBalanceApplicationService.batchDelete(ids);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "增加用户余额")
|
||||
@AccessLog(title = "用户余额管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PostMapping("/add-balance")
|
||||
public ResponseDTO<String> addBalance(@Validated @RequestBody AddBalanceCommand command) {
|
||||
boolean success = userBalanceApplicationService.addBalance(command);
|
||||
return success ? ResponseDTO.ok("增加用户余额成功") : ResponseDTO.fail("增加用户余额失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "减少用户余额")
|
||||
@AccessLog(title = "用户余额管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PostMapping("/subtract-balance")
|
||||
public ResponseDTO<String> subtractBalance(@Validated @RequestBody SubtractBalanceCommand command) {
|
||||
boolean success = userBalanceApplicationService.subtractBalance(command);
|
||||
return success ? ResponseDTO.ok("减少用户余额成功") : ResponseDTO.fail("减少用户余额失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "插入或更新用户余额")
|
||||
@AccessLog(title = "用户余额管理", businessType = BusinessTypeEnum.MODIFY)
|
||||
@PostMapping("/insert-or-update")
|
||||
public ResponseDTO<UserBalanceDTO> insertOrUpdate(@Validated @RequestBody AddUserBalanceCommand command) {
|
||||
UserBalanceDTO userBalanceDTO = userBalanceApplicationService.insertOrUpdate(command);
|
||||
return ResponseDTO.ok(userBalanceDTO);
|
||||
}
|
||||
}
|
||||
|
|
@ -205,6 +205,10 @@ public enum ErrorCode implements ErrorCodeInterface {
|
|||
USER_ADMIN_CAN_NOT_BE_MODIFY(10515, "管理员不允许做任何修改", "Business.USER_ADMIN_CAN_NOT_BE_MODIFY"),
|
||||
|
||||
COMMON_BAD_REQUEST(10516, "请求参数错误", "Business.COMMON_BAD_REQUEST"),
|
||||
/**
|
||||
* 余额金额无效
|
||||
*/
|
||||
BALANCE_AMOUNT_INVALID(11006, "余额金额无效", "Business.BALANCE_AMOUNT_INVALID"),
|
||||
;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,242 @@
|
|||
package com.agileboot.domain.ab98.user_balance;
|
||||
|
||||
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.command.AddBalanceCommand;
|
||||
import com.agileboot.domain.ab98.user_balance.command.AddUserBalanceCommand;
|
||||
import com.agileboot.domain.ab98.user_balance.command.SubtractBalanceCommand;
|
||||
import com.agileboot.domain.ab98.user_balance.command.UpdateUserBalanceCommand;
|
||||
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.model.UserBalanceModel;
|
||||
import com.agileboot.domain.ab98.user_balance.model.UserBalanceModelFactory;
|
||||
import com.agileboot.domain.ab98.user_balance.query.SearchUserBalanceQuery;
|
||||
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-11-24
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserBalanceApplicationService {
|
||||
|
||||
private final UserBalanceService userBalanceService;
|
||||
private final UserBalanceModelFactory userBalanceModelFactory;
|
||||
|
||||
/**
|
||||
* 新增用户余额
|
||||
*
|
||||
* @param command 新增命令
|
||||
* @return 用户余额DTO
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public UserBalanceDTO add(AddUserBalanceCommand command) {
|
||||
UserBalanceModel model = userBalanceModelFactory.create(command);
|
||||
boolean success = model.save();
|
||||
if (!success) {
|
||||
throw new RuntimeException("新增用户余额失败");
|
||||
}
|
||||
return new UserBalanceDTO(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户余额
|
||||
*
|
||||
* @param command 更新命令
|
||||
* @return 用户余额DTO
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public UserBalanceDTO update(UpdateUserBalanceCommand command) {
|
||||
UserBalanceModel model = userBalanceModelFactory.create(command);
|
||||
boolean success = model.update();
|
||||
if (!success) {
|
||||
throw new RuntimeException("更新用户余额失败");
|
||||
}
|
||||
return new UserBalanceDTO(model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID删除用户余额
|
||||
*
|
||||
* @param userBalanceId 主键ID
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(Long userBalanceId) {
|
||||
if (userBalanceId == null) {
|
||||
throw new IllegalArgumentException("用户余额ID不能为空");
|
||||
}
|
||||
|
||||
boolean success = userBalanceService.removeById(userBalanceId);
|
||||
if (!success) {
|
||||
throw new RuntimeException("删除用户余额失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据ID查询用户余额
|
||||
*
|
||||
* @param userBalanceId 主键ID
|
||||
* @return 用户余额DTO
|
||||
*/
|
||||
public UserBalanceDTO getById(Long userBalanceId) {
|
||||
if (userBalanceId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UserBalanceEntity entity = userBalanceService.getById(userBalanceId);
|
||||
return entity != null ? new UserBalanceDTO(entity) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据企业微信ID和汇邦云用户ID查询用户余额
|
||||
*
|
||||
* @param corpid 企业微信ID
|
||||
* @param ab98UserId 汇邦云用户ID
|
||||
* @return 用户余额DTO
|
||||
*/
|
||||
public UserBalanceDTO getByCorpidAndAb98UserId(String corpid, Long ab98UserId) {
|
||||
if (corpid == null || ab98UserId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UserBalanceEntity entity = userBalanceService.getByCorpidAndAb98UserId(corpid, ab98UserId);
|
||||
return entity != null ? new UserBalanceDTO(entity) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据openid查询用户余额
|
||||
*
|
||||
* @param openid openid
|
||||
* @return 用户余额DTO
|
||||
*/
|
||||
public UserBalanceDTO getByOpenid(String openid) {
|
||||
if (openid == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UserBalanceEntity entity = userBalanceService.getByOpenid(openid);
|
||||
return entity != null ? new UserBalanceDTO(entity) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询用户余额列表
|
||||
*
|
||||
* @param query 查询参数
|
||||
* @return 用户余额分页DTO
|
||||
*/
|
||||
public PageDTO<UserBalanceDTO> getList(SearchUserBalanceQuery query) {
|
||||
// 构建查询条件
|
||||
Page<UserBalanceEntity> page = query.toPage();
|
||||
UserBalanceEntity entity = new UserBalanceEntity();
|
||||
BeanUtil.copyProperties(query, entity);
|
||||
|
||||
// 执行查询
|
||||
List<UserBalanceEntity> entityList = userBalanceService.page(page, query.addQueryCondition()).getRecords();
|
||||
|
||||
// 转换为DTO
|
||||
List<UserBalanceDTO> dtoList = entityList.stream()
|
||||
.map(UserBalanceDTO::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 获取总数
|
||||
Long total = page.getTotal();
|
||||
|
||||
return new PageDTO<>(dtoList, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除用户余额
|
||||
*
|
||||
* @param userBalanceIds 主键ID列表
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void batchDelete(List<Long> userBalanceIds) {
|
||||
if (CollUtil.isEmpty(userBalanceIds)) {
|
||||
throw new IllegalArgumentException("用户余额ID列表不能为空");
|
||||
}
|
||||
|
||||
boolean success = userBalanceService.removeByIds(userBalanceIds);
|
||||
if (!success) {
|
||||
throw new RuntimeException("批量删除用户余额失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加用户余额
|
||||
*
|
||||
* @param corpid 企业微信ID
|
||||
* @param ab98UserId 汇邦云用户ID
|
||||
* @param amount 增加的金额(单位:分)
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean addBalance(String corpid, Long ab98UserId, Long amount) {
|
||||
return userBalanceService.addBalance(corpid, ab98UserId, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少用户余额
|
||||
*
|
||||
* @param corpid 企业微信ID
|
||||
* @param ab98UserId 汇邦云用户ID
|
||||
* @param amount 减少的金额(单位:分)
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean subtractBalance(String corpid, Long ab98UserId, Long amount) {
|
||||
return userBalanceService.subtractBalance(corpid, ab98UserId, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入或更新用户余额
|
||||
*
|
||||
* @param command 用户余额命令
|
||||
* @return 用户余额DTO
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public UserBalanceDTO insertOrUpdate(AddUserBalanceCommand command) {
|
||||
UserBalanceEntity entity = new UserBalanceEntity();
|
||||
BeanUtil.copyProperties(command, entity);
|
||||
boolean success = userBalanceService.insertOrUpdate(entity);
|
||||
if (!success) {
|
||||
throw new RuntimeException("插入或更新用户余额失败");
|
||||
}
|
||||
return new UserBalanceDTO(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加用户余额(使用命令类)
|
||||
*
|
||||
* @param command 增加余额命令
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean addBalance(AddBalanceCommand command) {
|
||||
return userBalanceService.addBalance(command.getCorpid(), command.getAb98UserId(), command.getAmount());
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少用户余额(使用命令类)
|
||||
*
|
||||
* @param command 减少余额命令
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean subtractBalance(SubtractBalanceCommand command) {
|
||||
return userBalanceService.subtractBalance(command.getCorpid(), command.getAb98UserId(), command.getAmount());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.agileboot.domain.ab98.user_balance.command;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 增加用户余额命令
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-11-24
|
||||
*/
|
||||
@Data
|
||||
public class AddBalanceCommand {
|
||||
|
||||
@NotBlank(message = "企业微信ID不能为空")
|
||||
private String corpid;
|
||||
|
||||
@NotNull(message = "汇邦云用户ID不能为空")
|
||||
private Long ab98UserId;
|
||||
|
||||
@NotNull(message = "金额不能为空")
|
||||
private Long amount;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.agileboot.domain.ab98.user_balance.command;
|
||||
|
||||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 新增用户余额命令
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-11-24
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class AddUserBalanceCommand extends UserBalanceEntity {
|
||||
|
||||
@NotBlank(message = "企业微信ID不能为空")
|
||||
private String corpid;
|
||||
|
||||
private String openid;
|
||||
|
||||
@NotNull(message = "汇邦云用户ID不能为空")
|
||||
private Long ab98UserId;
|
||||
|
||||
private Long qyUserId;
|
||||
|
||||
private Long balance;
|
||||
|
||||
private Long useBalance;
|
||||
|
||||
private Long balanceLimit;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.agileboot.domain.ab98.user_balance.command;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 减少用户余额命令
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-11-24
|
||||
*/
|
||||
@Data
|
||||
public class SubtractBalanceCommand {
|
||||
|
||||
@NotBlank(message = "企业微信ID不能为空")
|
||||
private String corpid;
|
||||
|
||||
@NotNull(message = "汇邦云用户ID不能为空")
|
||||
private Long ab98UserId;
|
||||
|
||||
@NotNull(message = "金额不能为空")
|
||||
private Long amount;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.agileboot.domain.ab98.user_balance.command;
|
||||
|
||||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 更新用户余额命令
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-11-24
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class UpdateUserBalanceCommand extends AddUserBalanceCommand {
|
||||
|
||||
@NotNull(message = "主键ID不能为空")
|
||||
private Long userBalanceId;
|
||||
|
||||
@NotBlank(message = "企业微信ID不能为空")
|
||||
private String corpid;
|
||||
|
||||
private String openid;
|
||||
|
||||
@NotNull(message = "汇邦云用户ID不能为空")
|
||||
private Long ab98UserId;
|
||||
|
||||
private Long qyUserId;
|
||||
|
||||
private Long balance;
|
||||
|
||||
private Long useBalance;
|
||||
|
||||
private Long balanceLimit;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package com.agileboot.domain.ab98.user_balance.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-11-24
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@TableName("user_balance")
|
||||
@ApiModel(value = "UserBalanceEntity对象", description = "用户余额表")
|
||||
public class UserBalanceEntity extends BaseEntity<UserBalanceEntity> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("主键ID")
|
||||
@TableId(value = "user_balance_id", type = IdType.AUTO)
|
||||
private Long userBalanceId;
|
||||
|
||||
@ApiModelProperty("企业微信id")
|
||||
@TableField("corpid")
|
||||
private String corpid;
|
||||
|
||||
@ApiModelProperty("openid")
|
||||
@TableField("openid")
|
||||
private String openid;
|
||||
|
||||
@ApiModelProperty("汇邦云用户ID")
|
||||
@TableField("ab98_user_id")
|
||||
private Long ab98UserId;
|
||||
|
||||
@ApiModelProperty("企业用户id")
|
||||
@TableField("qy_user_id")
|
||||
private Long qyUserId;
|
||||
|
||||
@ApiModelProperty("用户余额(单位:分)")
|
||||
@TableField("balance")
|
||||
private Long balance;
|
||||
|
||||
@ApiModelProperty("用户余额(单位:分)")
|
||||
@TableField("use_balance")
|
||||
private Long useBalance;
|
||||
|
||||
@ApiModelProperty("用户余额(单位:分)")
|
||||
@TableField("balance_limit")
|
||||
private Long balanceLimit;
|
||||
|
||||
@ApiModelProperty("创建者ID")
|
||||
@TableField("creator_id")
|
||||
private Long creatorId;
|
||||
|
||||
@ApiModelProperty("更新者ID")
|
||||
@TableField("updater_id")
|
||||
private Long updaterId;
|
||||
|
||||
|
||||
@Override
|
||||
public Serializable pkVal() {
|
||||
return this.userBalanceId;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.agileboot.domain.ab98.user_balance.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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-11-24
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserBalanceMapper extends BaseMapper<UserBalanceEntity> {
|
||||
|
||||
/**
|
||||
* 根据企业微信ID和汇邦云用户ID查询用户余额
|
||||
*
|
||||
* @param corpid 企业微信ID
|
||||
* @param ab98UserId 汇邦云用户ID
|
||||
* @return 用户余额信息
|
||||
*/
|
||||
@Select("SELECT * FROM user_balance WHERE corpid = #{corpid} AND ab98_user_id = #{ab98UserId}")
|
||||
UserBalanceEntity selectByCorpidAndAb98UserId(@Param("corpid") String corpid, @Param("ab98UserId") Long ab98UserId);
|
||||
|
||||
/**
|
||||
* 根据openid查询用户余额
|
||||
*
|
||||
* @param openid openid
|
||||
* @return 用户余额信息
|
||||
*/
|
||||
@Select("SELECT * FROM user_balance WHERE openid = #{openid}")
|
||||
UserBalanceEntity selectByOpenid(@Param("openid") String openid);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package com.agileboot.domain.ab98.user_balance.db;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-11-24
|
||||
*/
|
||||
public interface UserBalanceService extends IService<UserBalanceEntity> {
|
||||
|
||||
/**
|
||||
* 根据企业微信ID和汇邦云用户ID查询用户余额
|
||||
*
|
||||
* @param corpid 企业微信ID
|
||||
* @param ab98UserId 汇邦云用户ID
|
||||
* @return 用户余额信息
|
||||
*/
|
||||
UserBalanceEntity getByCorpidAndAb98UserId(String corpid, Long ab98UserId);
|
||||
|
||||
/**
|
||||
* 根据openid查询用户余额
|
||||
*
|
||||
* @param openid openid
|
||||
* @return 用户余额信息
|
||||
*/
|
||||
UserBalanceEntity getByOpenid(String openid);
|
||||
|
||||
/**
|
||||
* 插入或更新用户余额
|
||||
*
|
||||
* @param entity 用户余额实体
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean insertOrUpdate(UserBalanceEntity entity);
|
||||
|
||||
/**
|
||||
* 增加用户余额
|
||||
*
|
||||
* @param corpid 企业微信ID
|
||||
* @param ab98UserId 汇邦云用户ID
|
||||
* @param amount 增加的金额(单位:分)
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean addBalance(String corpid, Long ab98UserId, Long amount);
|
||||
|
||||
/**
|
||||
* 减少用户余额
|
||||
*
|
||||
* @param corpid 企业微信ID
|
||||
* @param ab98UserId 汇邦云用户ID
|
||||
* @param amount 减少的金额(单位:分)
|
||||
* @return 是否成功
|
||||
*/
|
||||
boolean subtractBalance(String corpid, Long ab98UserId, Long amount);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package com.agileboot.domain.ab98.user_balance.db;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-11-24
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserBalanceServiceImpl extends ServiceImpl<UserBalanceMapper, UserBalanceEntity> implements UserBalanceService {
|
||||
|
||||
private final UserBalanceMapper userBalanceMapper;
|
||||
|
||||
@Override
|
||||
public UserBalanceEntity getByCorpidAndAb98UserId(String corpid, Long ab98UserId) {
|
||||
return userBalanceMapper.selectByCorpidAndAb98UserId(corpid, ab98UserId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserBalanceEntity getByOpenid(String openid) {
|
||||
return userBalanceMapper.selectByOpenid(openid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean insertOrUpdate(UserBalanceEntity entity) {
|
||||
if (entity == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否已存在
|
||||
UserBalanceEntity existing = userBalanceMapper.selectByCorpidAndAb98UserId(entity.getCorpid(), entity.getAb98UserId());
|
||||
if (existing != null) {
|
||||
// 更新
|
||||
entity.setUserBalanceId(existing.getUserBalanceId());
|
||||
return updateById(entity);
|
||||
} else {
|
||||
// 插入
|
||||
return save(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addBalance(String corpid, Long ab98UserId, Long amount) {
|
||||
UserBalanceEntity entity = userBalanceMapper.selectByCorpidAndAb98UserId(corpid, ab98UserId);
|
||||
if (entity == null) {
|
||||
// 如果不存在,则创建
|
||||
entity = new UserBalanceEntity();
|
||||
entity.setCorpid(corpid);
|
||||
entity.setAb98UserId(ab98UserId);
|
||||
entity.setBalance(amount);
|
||||
entity.setUseBalance(0L);
|
||||
entity.setBalanceLimit(0L);
|
||||
return save(entity);
|
||||
}
|
||||
|
||||
// 更新余额
|
||||
Long newBalance = (entity.getBalance() == null ? 0 : entity.getBalance()) + amount;
|
||||
entity.setBalance(newBalance);
|
||||
return updateById(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean subtractBalance(String corpid, Long ab98UserId, Long amount) {
|
||||
UserBalanceEntity entity = userBalanceMapper.selectByCorpidAndAb98UserId(corpid, ab98UserId);
|
||||
if (entity == null || entity.getBalance() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Long currentBalance = entity.getBalance();
|
||||
if (currentBalance < amount) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 更新余额
|
||||
Long newBalance = currentBalance - amount;
|
||||
entity.setBalance(newBalance);
|
||||
return updateById(entity);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.agileboot.domain.ab98.user_balance.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.db.UserBalanceEntity;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额DTO
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-11-24
|
||||
*/
|
||||
@ExcelSheet(name = "用户余额")
|
||||
@Data
|
||||
public class UserBalanceDTO {
|
||||
|
||||
public UserBalanceDTO() {}
|
||||
|
||||
public UserBalanceDTO(UserBalanceEntity entity) {
|
||||
if (entity != null) {
|
||||
BeanUtil.copyProperties(entity, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ExcelColumn(name = "主键ID")
|
||||
private Long userBalanceId;
|
||||
|
||||
@ExcelColumn(name = "企业微信ID")
|
||||
private String corpid;
|
||||
|
||||
@ExcelColumn(name = "openid")
|
||||
private String openid;
|
||||
|
||||
@ExcelColumn(name = "汇邦云用户ID")
|
||||
private Long ab98UserId;
|
||||
|
||||
@ExcelColumn(name = "企业用户ID")
|
||||
private Long qyUserId;
|
||||
|
||||
@ExcelColumn(name = "用户余额(分)")
|
||||
private Long balance;
|
||||
|
||||
@ExcelColumn(name = "可用余额(分)")
|
||||
private Long useBalance;
|
||||
|
||||
@ExcelColumn(name = "余额限制(分)")
|
||||
private Long balanceLimit;
|
||||
|
||||
@ExcelColumn(name = "创建者ID")
|
||||
private Long creatorId;
|
||||
|
||||
@ExcelColumn(name = "更新者ID")
|
||||
private Long updaterId;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
package com.agileboot.domain.ab98.user_balance.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.command.AddUserBalanceCommand;
|
||||
import com.agileboot.domain.ab98.user_balance.command.UpdateUserBalanceCommand;
|
||||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceEntity;
|
||||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceService;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额领域模型
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-11-24
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class UserBalanceModel extends UserBalanceEntity {
|
||||
|
||||
private UserBalanceService userBalanceService;
|
||||
|
||||
public UserBalanceModel() {}
|
||||
|
||||
public UserBalanceModel(UserBalanceEntity entity, UserBalanceService userBalanceService) {
|
||||
this.userBalanceService = userBalanceService;
|
||||
if (entity != null) {
|
||||
BeanUtil.copyProperties(entity, this);
|
||||
}
|
||||
}
|
||||
|
||||
public UserBalanceModel(UserBalanceService userBalanceService) {
|
||||
this.userBalanceService = userBalanceService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从新增命令加载数据
|
||||
*
|
||||
* @param command 新增命令
|
||||
*/
|
||||
public void loadAddCommand(AddUserBalanceCommand command) {
|
||||
if (command != null) {
|
||||
BeanUtil.copyProperties(command, this, "userBalanceId");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从更新命令加载数据
|
||||
*
|
||||
* @param command 更新命令
|
||||
*/
|
||||
public void loadUpdateCommand(UpdateUserBalanceCommand command) {
|
||||
if (command != null) {
|
||||
loadAddCommand(command);
|
||||
if (command.getUserBalanceId() != null) {
|
||||
this.setUserBalanceId(command.getUserBalanceId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证余额是否足够
|
||||
*
|
||||
* @param amount 需要验证的金额(单位:分)
|
||||
* @throws ApiException 余额不足异常
|
||||
*/
|
||||
public void validateBalance(Long amount) {
|
||||
if (amount == null || amount <= 0) {
|
||||
throw new ApiException(ErrorCode.Business.BALANCE_AMOUNT_INVALID);
|
||||
}
|
||||
|
||||
if (this.getBalance() == null || this.getBalance() < amount) {
|
||||
throw new ApiException(ErrorCode.Business.BALANCE_AMOUNT_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加余额
|
||||
*
|
||||
* @param amount 增加的金额(单位:分)
|
||||
*/
|
||||
public void addBalance(Long amount) {
|
||||
if (amount == null || amount <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Long currentBalance = this.getBalance() == null ? 0 : this.getBalance();
|
||||
this.setBalance(currentBalance + amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少余额
|
||||
*
|
||||
* @param amount 减少的金额(单位:分)
|
||||
*/
|
||||
public void subtractBalance(Long amount) {
|
||||
if (amount == null || amount <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
validateBalance(amount);
|
||||
|
||||
Long currentBalance = this.getBalance() == null ? 0 : this.getBalance();
|
||||
this.setBalance(currentBalance - amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存到数据库
|
||||
*
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean save() {
|
||||
return userBalanceService.save(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新到数据库
|
||||
*
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean update() {
|
||||
return userBalanceService.updateById(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数据库删除
|
||||
*
|
||||
* @return 是否成功
|
||||
*/
|
||||
public boolean remove() {
|
||||
return userBalanceService.removeById(this.getUserBalanceId());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.agileboot.domain.ab98.user_balance.model;
|
||||
|
||||
import com.agileboot.domain.ab98.user_balance.command.AddUserBalanceCommand;
|
||||
import com.agileboot.domain.ab98.user_balance.command.UpdateUserBalanceCommand;
|
||||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceEntity;
|
||||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户余额模型工厂
|
||||
* </p>
|
||||
*
|
||||
* @author valarchie
|
||||
* @since 2025-11-24
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class UserBalanceModelFactory {
|
||||
|
||||
private final UserBalanceService userBalanceService;
|
||||
|
||||
/**
|
||||
* 创建新的用户余额模型
|
||||
*
|
||||
* @return 用户余额模型
|
||||
*/
|
||||
public UserBalanceModel create() {
|
||||
return new UserBalanceModel(userBalanceService);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从实体创建用户余额模型
|
||||
*
|
||||
* @param entity 实体
|
||||
* @return 用户余额模型
|
||||
*/
|
||||
public UserBalanceModel create(UserBalanceEntity entity) {
|
||||
return new UserBalanceModel(entity, userBalanceService);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从新增命令创建用户余额模型
|
||||
*
|
||||
* @param command 新增命令
|
||||
* @return 用户余额模型
|
||||
*/
|
||||
public UserBalanceModel create(AddUserBalanceCommand command) {
|
||||
UserBalanceModel model = new UserBalanceModel(userBalanceService);
|
||||
model.loadAddCommand(command);
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从更新命令创建用户余额模型
|
||||
*
|
||||
* @param command 更新命令
|
||||
* @return 用户余额模型
|
||||
*/
|
||||
public UserBalanceModel create(UpdateUserBalanceCommand command) {
|
||||
UserBalanceModel model = new UserBalanceModel(userBalanceService);
|
||||
model.loadUpdateCommand(command);
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.agileboot.domain.ab98.user_balance.query;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.agileboot.common.core.page.AbstractPageQuery;
|
||||
import com.agileboot.domain.ab98.user_balance.db.UserBalanceEntity;
|
||||
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-11-24
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class SearchUserBalanceQuery extends AbstractPageQuery<UserBalanceEntity> {
|
||||
|
||||
@ApiModelProperty("企业微信ID")
|
||||
private String corpid;
|
||||
|
||||
@ApiModelProperty("openid")
|
||||
private String openid;
|
||||
|
||||
@ApiModelProperty("汇邦云用户ID")
|
||||
private Long ab98UserId;
|
||||
|
||||
@ApiModelProperty("企业用户ID")
|
||||
private Long qyUserId;
|
||||
|
||||
@Override
|
||||
public QueryWrapper<UserBalanceEntity> addQueryCondition() {
|
||||
QueryWrapper<UserBalanceEntity> queryWrapper = new QueryWrapper<>();
|
||||
|
||||
queryWrapper
|
||||
.eq(StrUtil.isNotEmpty(corpid), "corpid", corpid)
|
||||
.eq(StrUtil.isNotEmpty(openid), "openid", openid)
|
||||
.eq(ab98UserId != null, "ab98_user_id", ab98UserId)
|
||||
.eq(qyUserId != null, "qy_user_id", qyUserId);
|
||||
|
||||
this.timeRangeColumn = "create_time";
|
||||
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue