手工调账service、controller单元测试完善

This commit is contained in:
gaoqr
2025-10-27 14:57:15 +08:00
parent d3368f89b6
commit 8d6ce2a915
9 changed files with 437 additions and 80 deletions
@@ -2,6 +2,7 @@ package com.cf.imes.module.system.controller.admin.funds.organamount.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@@ -11,6 +12,7 @@ import java.math.BigDecimal;
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OrganRechargeAmountRespVO {
/**
* 可用余额
@@ -3,6 +3,7 @@ package com.cf.imes.module.system.service.funds.incomeandexpense;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.module.system.controller.admin.funds.balancedetails.vo.BalanceDetailsPageReqVO;
import com.cf.imes.module.system.controller.admin.funds.balancedetails.vo.BalanceDetailsRespVO;
import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalancePageReqVO;
import com.cf.imes.module.system.dal.dataobject.incomeandexpense.IncomeExpenseDetailsDO;
/**
@@ -26,4 +27,12 @@ public interface IncomeExpenseService {
* @return
*/
PageResult<BalanceDetailsRespVO> getBalanceDetailsPage(BalanceDetailsPageReqVO pageReqVO);
/**
* 获取手工调账分页
*
* @param pageReqVO
* @return
*/
PageResult<IncomeExpenseDetailsDO> selectAdjustPage(ManualAdjustAccountBalancePageReqVO pageReqVO);
}
@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.module.system.controller.admin.funds.balancedetails.vo.BalanceDetailsPageReqVO;
import com.cf.imes.module.system.controller.admin.funds.balancedetails.vo.BalanceDetailsRespVO;
import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalancePageReqVO;
import com.cf.imes.module.system.dal.dataobject.incomeandexpense.AccountDetailsDO;
import com.cf.imes.module.system.dal.dataobject.incomeandexpense.IncomeExpenseDetailsDO;
import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
@@ -108,4 +109,9 @@ public class IncomeExpenseServiceImpl implements IncomeExpenseService {
});
return new PageResult<>(resultList, pageResult.getTotal());
}
@Override
public PageResult<IncomeExpenseDetailsDO> selectAdjustPage(ManualAdjustAccountBalancePageReqVO pageReqVO) {
return incomeExpenseDetailsMapper.selectAdjustPage(pageReqVO);
}
}
@@ -2,13 +2,11 @@ package com.cf.imes.module.system.service.funds.manualadjust;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.Assert.AssertUtils;
import com.cf.imes.framework.common.util.date.LocalDateTimeUtils;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.id.core.util.SnowflakeSerialNoWorker3rd;
import com.cf.imes.framework.mybatis.core.query.LambdaUpdateWrapperX;
import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalancePageReqVO;
import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalanceRespVO;
import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalanceSaveReqVO;
@@ -17,9 +15,6 @@ import com.cf.imes.module.system.dal.dataobject.funds.organamount.OrganAmountDO;
import com.cf.imes.module.system.dal.dataobject.incomeandexpense.IncomeExpenseDetailsDO;
import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
import com.cf.imes.module.system.dal.dataobject.pay.PayOrderDO;
import com.cf.imes.module.system.dal.mysql.funds.organamount.OrganAmountMapper;
import com.cf.imes.module.system.dal.mysql.incomeandexpense.IncomeExpenseDetailsMapper;
import com.cf.imes.module.system.dal.mysql.pay.PayOrderMapper;
import com.cf.imes.module.system.enums.pay.AdjustTypeEnum;
import com.cf.imes.module.system.enums.pay.IncomeExpenseTypeEnum;
import com.cf.imes.module.system.enums.pay.PayChannelCodeEnum;
@@ -29,6 +24,7 @@ import com.cf.imes.module.system.framework.snowflake.config.MybatisIdProperties;
import com.cf.imes.module.system.service.funds.incomeandexpense.IncomeExpenseService;
import com.cf.imes.module.system.service.funds.organamount.OrganAmountService;
import com.cf.imes.module.system.service.organ.OrganService;
import com.cf.imes.module.system.service.pay.PayOrderService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -40,7 +36,6 @@ import java.util.List;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORGAMOUNT_GIFT_INSUFFICIENT_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORGAMOUNT_RECHARGE_INSUFFICIENT_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORGAN_RECHARGE_AMOUNT_UPDATE_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.RECHARGE_GIFT_MEANWHILE_EMPTY_ERROR;
/**
@@ -57,9 +52,6 @@ public class ManualAdjustAccountBalanceServiceImpl implements ManualAdjustAccoun
@Resource
private OrganAmountService organAmountService;
@Resource
private OrganAmountMapper organAmountMapper;
@Resource
private IncomeExpenseService incomeExpenseService;
@@ -67,10 +59,7 @@ public class ManualAdjustAccountBalanceServiceImpl implements ManualAdjustAccoun
private MybatisIdProperties mybatisIdProperties;
@Resource
private PayOrderMapper payOrderMapper;
@Resource
private IncomeExpenseDetailsMapper incomeExpenseDetailsMapper;
private PayOrderService payOrderService;
@Resource
private SnowflakeSerialNoWorker3rd snowflakeSerialNoWorker3rd;
@@ -94,7 +83,7 @@ public class ManualAdjustAccountBalanceServiceImpl implements ManualAdjustAccoun
switch (AdjustTypeEnum.getByType(saveReqVO.getAdjustType())) {
case INCREASE:
// 调增直接累加
rechargeRespVO = recharge(organAmountDO, rechargeAmount, giftAmount);
rechargeRespVO = organAmountService.recharge(organId, rechargeAmount, giftAmount);
break;
case DECREASE:
incomeExpenseType = IncomeExpenseTypeEnum.EXPENSES.getCode();
@@ -114,21 +103,26 @@ public class ManualAdjustAccountBalanceServiceImpl implements ManualAdjustAccoun
giftAmount = giftAmount.negate();
}
rechargeRespVO = recharge(organAmountDO, rechargeAmount, giftAmount);
rechargeRespVO = organAmountService.recharge(organId, rechargeAmount, giftAmount);
break;
default:
break;
}
// 新增支付单
PayOrderDO payOrderDO = createPayOrder(organId, rechargeAmount);
payOrderMapper.insert(payOrderDO);
String payOrderId = null;
if (ObjectUtil.isNotNull(rechargeAmount)) {
PayOrderDO payOrderDO = createPayOrder(organId, rechargeAmount);
payOrderService.createPayOrder(payOrderDO);
payOrderId = String.valueOf(payOrderDO.getId());
}
// 新增收支明细
IncomeExpenseDetailsDO incomeExpenseDetailsDO = IncomeExpenseDetailsDO.builder()
.organId(organId)
.businessNo(snowflakeSerialNoWorker3rd.nextSerialNo())
.orderNo(String.valueOf(payOrderDO.getId()))
.orderNo(String.valueOf(payOrderId))
.tradeType(TradeTypeEnum.MANUAL_ADJUST.getCode())
.incomeExpenseType(incomeExpenseType)
.cashAmountChange(rechargeAmount)
@@ -153,66 +147,19 @@ public class ManualAdjustAccountBalanceServiceImpl implements ManualAdjustAccoun
Long payOrderId = IdUtil.getSnowflake(mybatisIdProperties.getWorkerId(), mybatisIdProperties.getDatacenterId()).nextId();
payOrderDO.setId(payOrderId);
payOrderDO.setStatus(PayOrderStatusEnum.SUCCESS);
payOrderDO.setPrice(ObjectUtil.isNull(recharge) ? BigDecimal.ZERO : recharge);
payOrderDO.setPrice(recharge);
payOrderDO.setSubject("手工调账");
payOrderDO.setChannelCode(PayChannelCodeEnum.MANUAL_ADJUST);
payOrderDO.setOrganId(organId);
return payOrderDO;
}
/**
* 充值
*
* @param organAmountDO
* @param price
* @param gift
*/
private OrganRechargeAmountRespVO recharge(OrganAmountDO organAmountDO, BigDecimal price, BigDecimal gift) {
Long organId = organAmountDO.getOrganId();
BigDecimal newAmount = organAmountDO.getAmount();
if (ObjectUtil.isNotNull(price)) {
newAmount = organAmountDO.getAmount().add(price);
}
BigDecimal newGift = organAmountDO.getGiftAmount();
if (ObjectUtil.isNotNull(gift)) {
newGift = organAmountDO.getGiftAmount().add(gift);
}
int updated = organAmountMapper.update(new LambdaUpdateWrapperX<OrganAmountDO>()
.eq(OrganAmountDO::getOrganId, organId)
.eq(OrganAmountDO::getVersion, organAmountDO.getVersion())
.set(OrganAmountDO::getGiftAmount, newGift)
.set(OrganAmountDO::getAmount, newAmount)
.set(OrganAmountDO::getVersion, organAmountDO.getVersion() + 1));
// 1. 首次更新失败,认为出现并发,再查一次再更新
if (updated == 0) {
organAmountDO = organAmountMapper.selectOne(new LambdaQueryWrapper<OrganAmountDO>().eq(OrganAmountDO::getOrganId, organId));
newAmount = organAmountDO.getAmount().add(price);
newGift = organAmountDO.getGiftAmount().add(gift);
updated = organAmountMapper.update(new LambdaUpdateWrapperX<OrganAmountDO>()
.eq(OrganAmountDO::getOrganId, organId)
.eq(OrganAmountDO::getVersion, organAmountDO.getVersion())
.set(OrganAmountDO::getGiftAmount, newGift)
.set(OrganAmountDO::getAmount, newAmount)
.set(OrganAmountDO::getVersion, organAmountDO.getVersion() + 1));
// 2. 第二次更新失败,资金表可能不存在
if (updated == 0) {
throw exception(ORGAN_RECHARGE_AMOUNT_UPDATE_ERROR);
} else {
return new OrganRechargeAmountRespVO(newAmount.add(newGift), newAmount, newGift);
}
} else {
return new OrganRechargeAmountRespVO(newAmount.add(newGift), newAmount, newGift);
}
}
@Override
public PageResult<ManualAdjustAccountBalanceRespVO> getPage(ManualAdjustAccountBalancePageReqVO pageReqVO) {
// 时间类型规范为开始0点,结束12点
pageReqVO.setCreateTime(LocalDateTimeUtils.generateTimeSection(pageReqVO.getCreateTime()));
PageResult<IncomeExpenseDetailsDO> incomeExpenseDetailsDOPageResult = incomeExpenseDetailsMapper.selectAdjustPage(pageReqVO);
PageResult<IncomeExpenseDetailsDO> incomeExpenseDetailsDOPageResult = incomeExpenseService.selectAdjustPage(pageReqVO);
List<IncomeExpenseDetailsDO> pageResultList = incomeExpenseDetailsDOPageResult.getList();
List<ManualAdjustAccountBalanceRespVO> resultList = new ArrayList<>();
@@ -73,8 +73,6 @@ public class OrganAmountServiceImpl implements OrganAmountService {
// 常用的字段key
private static final String DATELIST_FIELD_NAME = "dateList";
private static final String SERIES_FIELD_NAME = "series";
private static final String DATE_TIME_FORMATTER_PATTERN_YEAR_MONTH = "yyyy-M";
private static final String DATE_TIME_FORMATTER_PATTERN_YEAR_MONTH_DAY = "yyyy-M-d";
@Override
public OrganAmountDO validOrganAmount(Long organId) {
@@ -85,9 +83,12 @@ public class OrganAmountServiceImpl implements OrganAmountService {
@Override
public OrganRechargeAmountRespVO recharge(Long organId, BigDecimal price, BigDecimal gift) {
OrganAmountDO organAmountDO = organAmountMapper.selectOne(new LambdaQueryWrapper<OrganAmountDO>().eq(OrganAmountDO::getOrganId, organId));
BigDecimal newAmount = organAmountDO.getAmount().add(price);
BigDecimal newGift = null;
OrganAmountDO organAmountDO = validOrganAmount(organId);
BigDecimal newAmount = organAmountDO.getAmount();
if (ObjectUtil.isNotNull(price)) {
newAmount = organAmountDO.getAmount().add(price);
}
BigDecimal newGift = organAmountDO.getGiftAmount();
if (ObjectUtil.isNotNull(gift)) {
newGift = organAmountDO.getGiftAmount().add(gift);
}
@@ -95,7 +96,7 @@ public class OrganAmountServiceImpl implements OrganAmountService {
int updated = organAmountMapper.update(new LambdaUpdateWrapperX<OrganAmountDO>()
.eq(OrganAmountDO::getOrganId, organId)
.eq(OrganAmountDO::getVersion, organAmountDO.getVersion())
.setIfPresent(OrganAmountDO::getGiftAmount, newGift)
.set(OrganAmountDO::getGiftAmount, newGift)
.set(OrganAmountDO::getAmount, newAmount)
.set(OrganAmountDO::getVersion, organAmountDO.getVersion() + 1));
// 1. 首次更新失败,认为出现并发,再查一次再更新
@@ -107,17 +108,17 @@ public class OrganAmountServiceImpl implements OrganAmountService {
updated = organAmountMapper.update(new LambdaUpdateWrapperX<OrganAmountDO>()
.eq(OrganAmountDO::getOrganId, organId)
.eq(OrganAmountDO::getVersion, organAmountDO.getVersion())
.setIfPresent(OrganAmountDO::getGiftAmount, newGift)
.set(OrganAmountDO::getGiftAmount, newGift)
.set(OrganAmountDO::getAmount, newAmount)
.set(OrganAmountDO::getVersion, organAmountDO.getVersion() + 1));
// 2. 第二次更新失败,资金表可能不存在
if (updated == 0) {
throw exception(ORGAN_RECHARGE_AMOUNT_UPDATE_ERROR);
} else {
return new OrganRechargeAmountRespVO(ObjectUtil.isNull(newGift) ? newAmount : newAmount.add(newGift), newAmount, newGift);
return new OrganRechargeAmountRespVO(newAmount.add(newGift), newAmount, newGift);
}
} else {
return new OrganRechargeAmountRespVO(ObjectUtil.isNull(newGift) ? newAmount : newAmount.add(newGift), newAmount, newGift);
return new OrganRechargeAmountRespVO(newAmount.add(newGift), newAmount, newGift);
}
}
@@ -76,4 +76,11 @@ public interface PayOrderService {
* @return
*/
BigDecimal getRechargeTotalAmount();
/**
* 创建支付订单
*
* @param payOrderDO
*/
void createPayOrder(PayOrderDO payOrderDO);
}
@@ -10,13 +10,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
import com.cf.imes.framework.common.util.Assert.AssertUtils;
import com.cf.imes.framework.common.util.json.JsonUtils;
import com.cf.imes.framework.common.util.validation.ValidationUtils;
import com.cf.imes.framework.id.core.util.SnowflakeSerialNoWorker3rd;
import com.cf.imes.framework.organ.core.context.OrganContextHolder;
import com.cf.imes.framework.pay.config.ChenfengAlipayConfig;
import com.cf.imes.framework.pay.config.ChenfengPayConfig;
import com.cf.imes.framework.pay.core.client.dto.order.PayOrderRespDTO;
@@ -234,7 +232,7 @@ public class PayOrderServiceImpl implements PayOrderService {
// 如果有外部支付,发起请求
if (ObjectUtil.isNotNull(payOrder)) {
payOrderMapper.insert(payOrder);
createPayOrder(payOrder);
// 发起渠道方支付
AbstractPayHandler payHandler = payHandlerFactory.getPayHandler(channelCode);
@@ -381,7 +379,7 @@ public class PayOrderServiceImpl implements PayOrderService {
validRechargeActivity(rechargeActivityId, channelCode);
payOrder.setRechargeActivityId(rechargeActivityId);
}
payOrderMapper.insert(payOrder);
createPayOrder(payOrder);
// 发起渠道方支付
PayOrderUnifiedReqDTO payOrderUnifiedReqDTO = null;
@@ -897,4 +895,9 @@ public class PayOrderServiceImpl implements PayOrderService {
public BigDecimal getRechargeTotalAmount() {
return payOrderMapper.getRechargeTotalAmount();
}
@Override
public void createPayOrder(PayOrderDO payOrderDO) {
payOrderMapper.insert(payOrderDO);
}
}
@@ -0,0 +1,87 @@
package com.cf.imes.module.system.controller.admin.funds.manualadjust;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalancePageReqVO;
import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalanceRespVO;
import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalanceSaveReqVO;
import com.cf.imes.module.system.enums.pay.AdjustTypeEnum;
import com.cf.imes.module.system.service.funds.manualadjust.ManualAdjustAccountBalanceService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import java.math.BigDecimal;
import java.util.Collections;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* @author Gqr
* @since 2025/10/27 14:31
*/
@WebMvcTest(controllers = ManualAdjustAccountBalanceController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
public class ManualAdjustAccountBalanceControllerTest {
@Autowired
private MockMvc mockMvc;
@MockitoBean
private ManualAdjustAccountBalanceService manualAdjustAccountBalanceService;
@Autowired
private ObjectMapper objectMapper;
@Test
void testCreateAjustment() throws Exception {
ManualAdjustAccountBalanceSaveReqVO reqVO = new ManualAdjustAccountBalanceSaveReqVO();
reqVO.setOrganId(1L);
reqVO.setAdjustType(1);
reqVO.setRechargeAmount(new BigDecimal("100"));
reqVO.setGiftAmount(new BigDecimal("20"));
when(manualAdjustAccountBalanceService.createAjustment(any())).thenReturn(123L);
mockMvc.perform(put("/system/balance/manualadjust")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(reqVO)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(123));
verify(manualAdjustAccountBalanceService).createAjustment(any());
}
@Test
void testGetAdjustPage() throws Exception {
ManualAdjustAccountBalancePageReqVO pageReqVO = new ManualAdjustAccountBalancePageReqVO();
pageReqVO.setPageNo(1);
pageReqVO.setPageSize(10);
ManualAdjustAccountBalanceRespVO respVO = new ManualAdjustAccountBalanceRespVO();
respVO.setOrganName("测试组织");
respVO.setAdjustType(AdjustTypeEnum.INCREASE.getType());
PageResult<ManualAdjustAccountBalanceRespVO> pageResult = new PageResult<>(
Collections.singletonList(respVO), 1L);
when(manualAdjustAccountBalanceService.getPage(any())).thenReturn(pageResult);
mockMvc.perform(get("/system/balance/manualadjust/page")
.param("pageNo", "1")
.param("pageSize", "10"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.list[0].organName").value("测试组织"))
.andExpect(jsonPath("$.data.total").value(1));
verify(manualAdjustAccountBalanceService).getPage(any());
}
}
@@ -0,0 +1,295 @@
package com.cf.imes.module.system.service.funds.manualadjust;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.id.core.util.SnowflakeSerialNoWorker3rd;
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalancePageReqVO;
import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalanceRespVO;
import com.cf.imes.module.system.controller.admin.funds.manualadjust.vo.ManualAdjustAccountBalanceSaveReqVO;
import com.cf.imes.module.system.controller.admin.funds.organamount.vo.OrganRechargeAmountRespVO;
import com.cf.imes.module.system.dal.dataobject.funds.organamount.OrganAmountDO;
import com.cf.imes.module.system.dal.dataobject.incomeandexpense.IncomeExpenseDetailsDO;
import com.cf.imes.module.system.dal.dataobject.organ.OrganizationDO;
import com.cf.imes.module.system.dal.dataobject.pay.PayOrderDO;
import com.cf.imes.module.system.enums.pay.AdjustTypeEnum;
import com.cf.imes.module.system.framework.snowflake.config.MybatisIdProperties;
import com.cf.imes.module.system.service.funds.incomeandexpense.IncomeExpenseService;
import com.cf.imes.module.system.service.funds.organamount.OrganAmountService;
import com.cf.imes.module.system.service.organ.OrganService;
import com.cf.imes.module.system.service.pay.PayOrderService;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import java.math.BigDecimal;
import java.util.Collections;
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORGAMOUNT_GIFT_INSUFFICIENT_ERROR;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ORGAMOUNT_RECHARGE_INSUFFICIENT_ERROR;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* @author Gqr
* @since 2025/10/27 11:57
*/
@Import(ManualAdjustAccountBalanceServiceImpl.class)
public class ManualAdjustAccountBalanceServiceImplTest extends BaseDbAndRedisUnitTest {
@Resource
private ManualAdjustAccountBalanceService manualAdjustAccountBalanceService;
@MockitoBean
private OrganService organService;
@MockitoBean
private OrganAmountService organAmountService;
@MockitoBean
private IncomeExpenseService incomeExpenseService;
@MockitoBean
private MybatisIdProperties mybatisIdProperties;
@MockitoBean
private PayOrderService payOrderService;
@MockitoBean
private SnowflakeSerialNoWorker3rd snowflakeSerialNoWorker3rd;
@BeforeEach
void setUp() {
when(mybatisIdProperties.getWorkerId()).thenReturn(1L);
when(mybatisIdProperties.getDatacenterId()).thenReturn(1L);
when(snowflakeSerialNoWorker3rd.nextSerialNo()).thenReturn("SN-001");
}
@Test
void testCreateAdjustment_Increase() {
// 模拟请求参数(调增)
ManualAdjustAccountBalanceSaveReqVO reqVO = new ManualAdjustAccountBalanceSaveReqVO();
reqVO.setOrganId(100L);
reqVO.setAdjustType(AdjustTypeEnum.INCREASE.getType());
reqVO.setRechargeAmount(new BigDecimal("100.00"));
reqVO.setGiftAmount(new BigDecimal("20.00"));
reqVO.setRemark("调增测试");
// 模拟依赖返回
OrganAmountDO organAmountDO = new OrganAmountDO();
organAmountDO.setAmount(new BigDecimal("500.00"));
organAmountDO.setGiftAmount(new BigDecimal("100.00"));
when(organAmountService.validOrganAmount(100L)).thenReturn(organAmountDO);
OrganRechargeAmountRespVO rechargeRespVO = new OrganRechargeAmountRespVO();
rechargeRespVO.setAmount(new BigDecimal("600.00"));
rechargeRespVO.setGiftAmount(new BigDecimal("120.00"));
rechargeRespVO.setAvailableAmount(new BigDecimal("720.00"));
when(organAmountService.recharge(eq(100L), any(), any())).thenReturn(rechargeRespVO);
when(incomeExpenseService.createDetail(any())).thenReturn(1L);
// 执行方法
Long result = manualAdjustAccountBalanceService.createAjustment(reqVO);
// 验证逻辑
assertEquals(1L, result);
verify(organService).validOrgan(100L);
verify(payOrderService).createPayOrder(any(PayOrderDO.class));
verify(incomeExpenseService).createDetail(any(IncomeExpenseDetailsDO.class));
}
@Test
void testCreateAdjustment_Decrease() {
// 模拟请求参数(调减)
ManualAdjustAccountBalanceSaveReqVO reqVO = new ManualAdjustAccountBalanceSaveReqVO();
reqVO.setOrganId(200L);
reqVO.setAdjustType(AdjustTypeEnum.DECREASE.getType());
reqVO.setRechargeAmount(new BigDecimal("50.00"));
reqVO.setGiftAmount(new BigDecimal("10.00"));
reqVO.setRemark("调减测试");
// 模拟依赖返回
OrganAmountDO organAmountDO = new OrganAmountDO();
organAmountDO.setAmount(new BigDecimal("500.00"));
organAmountDO.setGiftAmount(new BigDecimal("100.00"));
when(organAmountService.validOrganAmount(200L)).thenReturn(organAmountDO);
OrganRechargeAmountRespVO rechargeRespVO = new OrganRechargeAmountRespVO();
rechargeRespVO.setAmount(new BigDecimal("450.00"));
rechargeRespVO.setGiftAmount(new BigDecimal("90.00"));
rechargeRespVO.setAvailableAmount(new BigDecimal("540.00"));
when(organAmountService.recharge(eq(200L), any(), any())).thenReturn(rechargeRespVO);
when(incomeExpenseService.createDetail(any())).thenReturn(2L);
// 执行方法
Long result = manualAdjustAccountBalanceService.createAjustment(reqVO);
// 验证逻辑
assertEquals(2L, result);
verify(organService).validOrgan(200L);
verify(payOrderService).createPayOrder(any(PayOrderDO.class));
verify(incomeExpenseService).createDetail(any(IncomeExpenseDetailsDO.class));
}
@Test
void testCreateAdjustment_Decrease_RechargeInsufficient() {
// given
ManualAdjustAccountBalanceSaveReqVO reqVO = new ManualAdjustAccountBalanceSaveReqVO();
reqVO.setOrganId(300L);
reqVO.setAdjustType(AdjustTypeEnum.DECREASE.getType());
reqVO.setRechargeAmount(new BigDecimal("200.00")); // 想减200
reqVO.setGiftAmount(null);
OrganAmountDO organAmountDO = new OrganAmountDO();
organAmountDO.setAmount(new BigDecimal("100.00")); // 实际余额只有100,不够减
organAmountDO.setGiftAmount(new BigDecimal("50.00"));
when(organAmountService.validOrganAmount(300L)).thenReturn(organAmountDO);
// 余额不足
assertServiceException(() -> manualAdjustAccountBalanceService.createAjustment(reqVO), ORGAMOUNT_RECHARGE_INSUFFICIENT_ERROR);
}
@Test
void testCreateAdjustment_Decrease_GiftInsufficient() {
// given
ManualAdjustAccountBalanceSaveReqVO reqVO = new ManualAdjustAccountBalanceSaveReqVO();
reqVO.setOrganId(400L);
reqVO.setAdjustType(AdjustTypeEnum.DECREASE.getType());
reqVO.setRechargeAmount(null);
reqVO.setGiftAmount(new BigDecimal("30.00")); // 想减30赠送金
OrganAmountDO organAmountDO = new OrganAmountDO();
organAmountDO.setAmount(new BigDecimal("100.00"));
organAmountDO.setGiftAmount(new BigDecimal("10.00")); // 实际赠送金只有10,不够减
when(organAmountService.validOrganAmount(400L)).thenReturn(organAmountDO);
// 赠送金不足
assertServiceException(() -> manualAdjustAccountBalanceService.createAjustment(reqVO), ORGAMOUNT_GIFT_INSUFFICIENT_ERROR);
}
@Test
void testCreateAdjustment_Decrease_GiftAmountNull() {
// given
ManualAdjustAccountBalanceSaveReqVO reqVO = new ManualAdjustAccountBalanceSaveReqVO();
reqVO.setOrganId(600L);
reqVO.setAdjustType(AdjustTypeEnum.DECREASE.getType());
reqVO.setRechargeAmount(new BigDecimal("50.00")); // 有充值金额
reqVO.setGiftAmount(null); // giftAmount 为 null
OrganAmountDO organAmountDO = new OrganAmountDO();
organAmountDO.setAmount(new BigDecimal("100.00"));
organAmountDO.setGiftAmount(new BigDecimal("100.00"));
when(organAmountService.validOrganAmount(600L)).thenReturn(organAmountDO);
OrganRechargeAmountRespVO respVO = new OrganRechargeAmountRespVO();
respVO.setAmount(new BigDecimal("50.00"));
respVO.setGiftAmount(new BigDecimal("100.00"));
respVO.setAvailableAmount(new BigDecimal("150.00"));
when(organAmountService.recharge(eq(600L), any(), any())).thenReturn(respVO);
when(incomeExpenseService.createDetail(any())).thenReturn(10L);
// when
Long result = manualAdjustAccountBalanceService.createAjustment(reqVO);
// then
assertEquals(10L, result);
verify(payOrderService).createPayOrder(any(PayOrderDO.class));
verify(incomeExpenseService).createDetail(any(IncomeExpenseDetailsDO.class));
}
@Test
void testCreateAdjustment_Decrease_RechargeAmountNull() {
// given
ManualAdjustAccountBalanceSaveReqVO reqVO = new ManualAdjustAccountBalanceSaveReqVO();
reqVO.setOrganId(600L);
reqVO.setAdjustType(AdjustTypeEnum.DECREASE.getType());
reqVO.setRechargeAmount(null); // rechargeAmount 为 null
reqVO.setGiftAmount(new BigDecimal("50.00"));
OrganAmountDO organAmountDO = new OrganAmountDO();
organAmountDO.setAmount(new BigDecimal("100.00"));
organAmountDO.setGiftAmount(new BigDecimal("100.00"));
when(organAmountService.validOrganAmount(600L)).thenReturn(organAmountDO);
OrganRechargeAmountRespVO respVO = new OrganRechargeAmountRespVO();
respVO.setAmount(new BigDecimal("50.00"));
respVO.setGiftAmount(new BigDecimal("100.00"));
respVO.setAvailableAmount(new BigDecimal("150.00"));
when(organAmountService.recharge(eq(600L), any(), any())).thenReturn(respVO);
when(incomeExpenseService.createDetail(any())).thenReturn(10L);
// when
Long result = manualAdjustAccountBalanceService.createAjustment(reqVO);
// then
assertEquals(10L, result);
verify(payOrderService, never()).createPayOrder(any(PayOrderDO.class));
verify(incomeExpenseService).createDetail(any(IncomeExpenseDetailsDO.class));
}
@Test
void testGetPage_WithNonNullOrgan() {
// given
ManualAdjustAccountBalancePageReqVO pageReqVO = new ManualAdjustAccountBalancePageReqVO();
IncomeExpenseDetailsDO detailsDO = new IncomeExpenseDetailsDO();
detailsDO.setIncomeExpenseType(AdjustTypeEnum.INCREASE.getType()); // 假设 1 -> 调增
detailsDO.setOrganId(100L);
PageResult<IncomeExpenseDetailsDO> mockPageResult = new PageResult<>(Collections.singletonList(detailsDO), 1L);
when(incomeExpenseService.selectAdjustPage(pageReqVO)).thenReturn(mockPageResult);
OrganizationDO organ = new OrganizationDO();
organ.setName("测试组织");
when(organService.getOrganWithDeleted(100L)).thenReturn(organ);
// when
PageResult<ManualAdjustAccountBalanceRespVO> result = manualAdjustAccountBalanceService.getPage(pageReqVO);
// then
assertEquals(1, result.getList().size());
ManualAdjustAccountBalanceRespVO respVO = result.getList().get(0);
assertEquals("测试组织", respVO.getOrganName());
assertEquals(AdjustTypeEnum.INCREASE.getType(), respVO.getAdjustType());
verify(incomeExpenseService).selectAdjustPage(pageReqVO);
verify(organService).getOrganWithDeleted(100L);
}
@Test
void testGetPage_WithNullOrgan() {
// given
ManualAdjustAccountBalancePageReqVO pageReqVO = new ManualAdjustAccountBalancePageReqVO();
IncomeExpenseDetailsDO detailsDO = new IncomeExpenseDetailsDO();
detailsDO.setIncomeExpenseType(AdjustTypeEnum.DECREASE.getType()); // 假设 2 -> 调减
detailsDO.setOrganId(200L);
PageResult<IncomeExpenseDetailsDO> mockPageResult = new PageResult<>(Collections.singletonList(detailsDO), 1L);
when(incomeExpenseService.selectAdjustPage(pageReqVO)).thenReturn(mockPageResult);
// 模拟组织为 null,覆盖 if 条件 false
when(organService.getOrganWithDeleted(200L)).thenReturn(null);
// when
PageResult<ManualAdjustAccountBalanceRespVO> result = manualAdjustAccountBalanceService.getPage(pageReqVO);
// then
assertEquals(1, result.getList().size());
ManualAdjustAccountBalanceRespVO respVO = result.getList().get(0);
assertNull(respVO.getOrganName());
assertEquals(AdjustTypeEnum.DECREASE.getType(), respVO.getAdjustType());
verify(incomeExpenseService).selectAdjustPage(pageReqVO);
verify(organService).getOrganWithDeleted(200L);
}
}