支持customerid和customerCode

This commit is contained in:
luojiaquan
2026-09-17 10:55:32 +08:00
parent 85a3752107
commit 72280c86a0
5 changed files with 95 additions and 27 deletions
@@ -11,6 +11,7 @@ import lombok.Data;
* <li>计费订单开单/应收账单确认 -> {@link ICustomerAccountApi#occupyCredit}(已用额度增加)</li>
* <li>账单作废/计费变动核减 -> {@link ICustomerAccountApi#releaseCredit}(已用额度减少)</li>
* </ul>
* 客户标识 customerId / customerCode 二选一,传一个即可。
*
* @author ruoyi
* @date 2026-09-17
@@ -18,9 +19,19 @@ import lombok.Data;
@Data
public class CreditUsageCommand
{
/** 客户ID(必填) */
/**
* 客户ID,与 {@link #customerCode} 二选一(至少传一个)。
* 两者同时传值时以 customerId 为准。
*/
private Long customerId;
/**
* 客户编码,与 {@link #customerId} 二选一(至少传一个)。
* 未传 customerId 时由公共服务按编码解析客户档案(del_flag=0),
* 编码不存在或匹配多条时抛 ServiceException。
*/
private String customerCode;
/** 币种(为空按本位币 CNY 处理) */
private String currency;
@@ -49,8 +49,8 @@ public interface ICustomerAccountApi
/**
* 占用授信额度:used_credit += amount,写 OCCUPY 额度流水(关联来源单据)。
* checkAvailable=true 时可用额度不足抛 ServiceException;CNY账户不存在自动初始化,
* 外币账户不存在时静默跳过(返回null,兼容历史口径)。
* 命令中 customerId 与 customerCode 二选一;checkAvailable=true 时可用额度不足抛 ServiceException;
* CNY账户不存在自动初始化,外币账户不存在时静默跳过(返回null,兼容历史口径)。
*
* @return 已落库的额度流水(含ID);账户不存在跳过场景返回null
*/
@@ -58,7 +58,7 @@ public interface ICustomerAccountApi
/**
* 释放授信额度:used_credit -= amount(不小于0),写 RELEASE 额度流水。
* 账户不存在时静默跳过(返回null)。
* 命令中 customerId 与 customerCode 二选一;账户不存在时静默跳过(返回null)。
*
* @return 已落库的额度流水(含ID);账户不存在跳过场景返回null
*/
@@ -6,6 +6,7 @@ import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -156,10 +157,11 @@ public class CustomerAccountApiImpl implements ICustomerAccountApi
public CustomerCreditFlow occupyCredit(CreditUsageCommand command)
{
validateUsageCommand(command);
Long customerId = resolveCustomerId(command);
String currency = resolveCurrency(command.getCurrency());
String username = SecurityUtils.getUsername();
Long userId = SecurityUtils.getUserId();
CustomerAccount account = lockAccountForUsage(command.getCustomerId(), currency, username);
CustomerAccount account = lockAccountForUsage(customerId, currency, username);
if (account == null)
{
// 外币账户尚未开立时不自动占用,与历史账单口径保持一致(CNY账户会自动初始化)
@@ -190,10 +192,11 @@ public class CustomerAccountApiImpl implements ICustomerAccountApi
public CustomerCreditFlow releaseCredit(CreditUsageCommand command)
{
validateUsageCommand(command);
Long customerId = resolveCustomerId(command);
String currency = resolveCurrency(command.getCurrency());
String username = SecurityUtils.getUsername();
Long userId = SecurityUtils.getUserId();
CustomerAccount account = lockAccountForUsage(command.getCustomerId(), currency, username);
CustomerAccount account = lockAccountForUsage(customerId, currency, username);
if (account == null)
{
return null;
@@ -469,9 +472,9 @@ public class CustomerAccountApiImpl implements ICustomerAccountApi
private void validateUsageCommand(CreditUsageCommand command)
{
if (command == null || command.getCustomerId() == null)
if (command == null || (command.getCustomerId() == null && !StringUtils.hasText(command.getCustomerCode())))
{
throw new ServiceException("客户ID不能为空");
throw new ServiceException("客户ID与客户编码至少传一个");
}
if (!StringUtils.hasText(command.getBizType()))
{
@@ -483,6 +486,34 @@ public class CustomerAccountApiImpl implements ICustomerAccountApi
}
}
/**
* 解析客户标识:customerId 优先;未传时按 customerCode 精确查询有效客户档案。
* 编码不存在或匹配多条时抛异常,避免资金变动落到错误客户。
*/
private Long resolveCustomerId(CreditUsageCommand command)
{
if (command.getCustomerId() != null)
{
return command.getCustomerId();
}
String customerCode = command.getCustomerCode().trim();
BmsCustomer query = new BmsCustomer();
query.setCustomerCode(customerCode);
List<BmsCustomer> customers = bmsCustomerMapper.selectBmsCustomerList(query);
if (customers == null || customers.isEmpty())
{
throw new ServiceException("客户编码不存在:" + customerCode);
}
if (customers.size() > 1)
{
throw new ServiceException("客户编码匹配到多个客户:" + customerCode);
}
Long customerId = customers.get(0).getCustomerId();
// 回填,便于调用方/流水排查时直接取到解析结果
command.setCustomerId(customerId);
return customerId;
}
private void validateBalanceCommand(BalanceChangeCommand command)
{
if (command == null || command.getCustomerId() == null)