diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 62b512c83..b0c9364eb 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -192,6 +192,10 @@ public class Constants * 平台内部账户ID */ public static final Long PLATFORM_INTERNAL_ACCOUNT_ID = 1L; + /** + * 平台外部账户ID-支付宝账户 + */ + public static final Long PLATFORM_ALIPAY_EXTERNAL_ACCOUNT_ID = 1L; /** * 排序值1 diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/finance/TransInfo.java b/xkt/src/main/java/com/ruoyi/xkt/dto/finance/TransInfo.java new file mode 100644 index 000000000..ece2fd0ec --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/finance/TransInfo.java @@ -0,0 +1,62 @@ +package com.ruoyi.xkt.dto.finance; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * @author liangyq + * @date 2025-04-09 23:47 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class TransInfo { +// /** +// * 账户ID +// */ +// private Long accountId; + /** + * 来源单据ID + */ + private Long srcBillId; + /** + * 来源单据类型 + * + * @see com.ruoyi.xkt.enums.EFinBillType + */ + private Integer srcBillType; +// /** +// * 借贷方向 +// * +// * @see com.ruoyi.xkt.enums.ELoanDirection +// */ +// private Integer loanDirection; + /** + * 交易金额 + */ + private BigDecimal transAmount; + /** + * 交易时间 + */ + private Date transTime; + /** + * 经办人ID + */ + private Long handlerId; +// /** +// * 入账状态 +// * +// * @see com.ruoyi.xkt.enums.EEntryStatus +// */ +// private Integer entryStatus; + /** + * 备注 + */ + private String remark; +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EAccountStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EAccountStatus.java new file mode 100644 index 000000000..0b6747a50 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EAccountStatus.java @@ -0,0 +1,28 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum EAccountStatus { + + NORMAL(1, "正常"), + FREEZE(2, "冻结"); + + private final Integer value; + private final String label; + + public static EAccountStatus of(Integer value) { + for (EAccountStatus e : EAccountStatus.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EEntryExecuted.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EEntryExecuted.java new file mode 100644 index 000000000..0c7f8f4a4 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EEntryExecuted.java @@ -0,0 +1,28 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum EEntryExecuted { + + FINISH(1, "已执行"), + WAITING(2, "未执行"); + + private final Integer value; + private final String label; + + public static EEntryExecuted of(Integer value) { + for (EEntryExecuted e : EEntryExecuted.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EEntryStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EEntryStatus.java new file mode 100644 index 000000000..cdb72e3f2 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EEntryStatus.java @@ -0,0 +1,28 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum EEntryStatus { + + FINISH(1, "已入账"), + WAITING(2, "待入账"); + + private final Integer value; + private final String label; + + public static EEntryStatus of(Integer value) { + for (EEntryStatus e : EEntryStatus.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/ELoanDirection.java b/xkt/src/main/java/com/ruoyi/xkt/enums/ELoanDirection.java new file mode 100644 index 000000000..9ddff6ce2 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/ELoanDirection.java @@ -0,0 +1,29 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author liangyq + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum ELoanDirection { + + DEBIT(1, "借", "D"), + CREDIT(2, "贷", "C"); + + private final Integer value; + private final String label; + private final String code; + + public static ELoanDirection of(Integer value) { + for (ELoanDirection e : ELoanDirection.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EPayChannel.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EPayChannel.java index 33f41abd5..deec11b8e 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/EPayChannel.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EPayChannel.java @@ -1,5 +1,6 @@ package com.ruoyi.xkt.enums; +import com.ruoyi.common.constant.Constants; import lombok.AllArgsConstructor; import lombok.Getter; @@ -11,10 +12,12 @@ import lombok.Getter; @AllArgsConstructor public enum EPayChannel { - ALI_PAY(1, "支付宝"); + ALI_PAY(1, "支付宝", "ALIPAY_", Constants.PLATFORM_ALIPAY_EXTERNAL_ACCOUNT_ID); private final Integer value; private final String label; + private final String prefix; + private final Long platformExternalAccountId; public static EPayChannel of(Integer value) { for (EPayChannel e : EPayChannel.values()) { diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IExternalAccountService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IExternalAccountService.java new file mode 100644 index 000000000..2e0c31481 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IExternalAccountService.java @@ -0,0 +1,33 @@ +package com.ruoyi.xkt.service; + +import com.ruoyi.xkt.domain.ExternalAccount; +import com.ruoyi.xkt.dto.finance.TransInfo; +import com.ruoyi.xkt.enums.EEntryStatus; +import com.ruoyi.xkt.enums.ELoanDirection; + +/** + * @author liangyq + * @date 2025-04-08 21:14 + */ +public interface IExternalAccountService { + /** + * 通过ID获取外部账户 + * + * @param id + * @return + */ + ExternalAccount getById(Long id); + + /** + * 添加交易明细 + * + * @param externalAccountId + * @param transInfo + * @param loanDirection + * @param entryStatus + * @return + */ + int addTransDetail(Long externalAccountId, TransInfo transInfo, ELoanDirection loanDirection, + EEntryStatus entryStatus); + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IFinanceBillService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IFinanceBillService.java index 88bdd4339..dd89cd9dd 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IFinanceBillService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IFinanceBillService.java @@ -2,6 +2,7 @@ package com.ruoyi.xkt.service; import com.ruoyi.xkt.dto.finance.FinanceBillInfo; import com.ruoyi.xkt.dto.order.StoreOrderInfo; +import com.ruoyi.xkt.enums.EPayChannel; /** * @author liangyq @@ -12,8 +13,9 @@ public interface IFinanceBillService { * 根据订单创建收款单 * * @param orderInfo - * @param srcId + * @param payId + * @param payChannel * @return */ - FinanceBillInfo createCollectionBillAfterOrderPaid(StoreOrderInfo orderInfo, String srcId); + FinanceBillInfo createCollectionBillAfterOrderPaid(StoreOrderInfo orderInfo, Long payId, EPayChannel payChannel); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IInternalAccountService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IInternalAccountService.java index d13d02f5e..05bde1e7b 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IInternalAccountService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IInternalAccountService.java @@ -1,6 +1,9 @@ package com.ruoyi.xkt.service; import com.ruoyi.xkt.domain.InternalAccount; +import com.ruoyi.xkt.dto.finance.TransInfo; +import com.ruoyi.xkt.enums.EEntryStatus; +import com.ruoyi.xkt.enums.ELoanDirection; import java.util.Collection; import java.util.List; @@ -27,4 +30,18 @@ public interface IInternalAccountService { */ List listWithLock(Collection ids); + /** + * 添加交易明细 + * 余额会根据明细更新 + * 调用方法时入参账户必须处于加锁状态! + * + * @param internalAccount + * @param transInfo + * @param loanDirection + * @param entryStatus + * @return + */ + int addTransDetail(InternalAccount internalAccount, TransInfo transInfo, ELoanDirection loanDirection, + EEntryStatus entryStatus); + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/ExternalAccountServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/ExternalAccountServiceImpl.java new file mode 100644 index 000000000..ba2b6b450 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/ExternalAccountServiceImpl.java @@ -0,0 +1,69 @@ +package com.ruoyi.xkt.service.impl; + +import cn.hutool.core.util.NumberUtil; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.bean.BeanValidators; +import com.ruoyi.xkt.domain.ExternalAccount; +import com.ruoyi.xkt.domain.ExternalAccountTransDetail; +import com.ruoyi.xkt.dto.finance.TransInfo; +import com.ruoyi.xkt.enums.EAccountStatus; +import com.ruoyi.xkt.enums.EEntryStatus; +import com.ruoyi.xkt.enums.ELoanDirection; +import com.ruoyi.xkt.mapper.ExternalAccountMapper; +import com.ruoyi.xkt.mapper.ExternalAccountTransDetailMapper; +import com.ruoyi.xkt.service.IExternalAccountService; +import io.jsonwebtoken.lang.Assert; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.math.BigDecimal; + +/** + * @author liangyq + * @date 2025-04-08 21:14 + */ +@Service +public class ExternalAccountServiceImpl implements IExternalAccountService { + + @Autowired + private ExternalAccountMapper externalAccountMapper; + @Autowired + private ExternalAccountTransDetailMapper externalAccountTransDetailMapper; + + @Override + public ExternalAccount getById(Long id) { + Assert.notNull(id); + return externalAccountMapper.selectById(id); + } + + @Transactional + @Override + public int addTransDetail(Long externalAccountId, TransInfo transInfo, ELoanDirection loanDirection, + EEntryStatus entryStatus) { + ExternalAccount account = getById(externalAccountId); + if (!BeanValidators.exists(account)) { + throw new ServiceException("外部账户[" + externalAccountId + "]不存在"); + } + if (!EAccountStatus.NORMAL.getValue().equals(account.getAccountStatus())) { + throw new ServiceException("外部账户[" + externalAccountId + "]已冻结"); + } + ExternalAccountTransDetail transDetail = new ExternalAccountTransDetail(); + transDetail.setExternalAccountId(externalAccountId); + transDetail.setSrcBillId(transInfo.getSrcBillId()); + transDetail.setSrcBillType(transInfo.getSrcBillType()); + transDetail.setLoanDirection(loanDirection.getValue()); + if (NumberUtil.isLess(transInfo.getTransAmount(), BigDecimal.ZERO)) { + throw new ServiceException("交易金额异常"); + } + transDetail.setTransAmount(transInfo.getTransAmount()); + transDetail.setTransTime(transInfo.getTransTime()); + transDetail.setHandlerId(transInfo.getHandlerId()); + transDetail.setEntryStatus(entryStatus.getValue()); + transDetail.setRemark(transInfo.getRemark()); + transDetail.setDelFlag(Constants.UNDELETED); + return externalAccountTransDetailMapper.insert(transDetail); + } + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/FinanceBillServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/FinanceBillServiceImpl.java index f6049d15e..949ae9ced 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/FinanceBillServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/FinanceBillServiceImpl.java @@ -1,17 +1,29 @@ package com.ruoyi.xkt.service.impl; +import cn.hutool.core.util.IdUtil; import com.ruoyi.common.constant.Constants; +import com.ruoyi.xkt.domain.FinanceBill; +import com.ruoyi.xkt.domain.FinanceBillDetail; import com.ruoyi.xkt.domain.InternalAccount; +import com.ruoyi.xkt.domain.StoreOrderDetail; import com.ruoyi.xkt.dto.finance.FinanceBillInfo; +import com.ruoyi.xkt.dto.finance.TransInfo; import com.ruoyi.xkt.dto.order.StoreOrderInfo; +import com.ruoyi.xkt.enums.*; import com.ruoyi.xkt.mapper.FinanceBillDetailMapper; import com.ruoyi.xkt.mapper.FinanceBillMapper; +import com.ruoyi.xkt.service.IExternalAccountService; import com.ruoyi.xkt.service.IFinanceBillService; import com.ruoyi.xkt.service.IInternalAccountService; +import io.jsonwebtoken.lang.Assert; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + /** * @author liangyq * @date 2025-04-08 21:14 @@ -25,12 +37,74 @@ public class FinanceBillServiceImpl implements IFinanceBillService { private FinanceBillDetailMapper financeBillDetailMapper; @Autowired private IInternalAccountService internalAccountService; + @Autowired + private IExternalAccountService externalAccountService; @Transactional @Override - public FinanceBillInfo createCollectionBillAfterOrderPaid(StoreOrderInfo orderInfo, String srcId) { - //获取平台账户并加锁 - InternalAccount ca = internalAccountService.getWithLock(Constants.PLATFORM_INTERNAL_ACCOUNT_ID); - return null; + public FinanceBillInfo createCollectionBillAfterOrderPaid(StoreOrderInfo orderInfo, Long payId, + EPayChannel payChannel) { + Assert.notNull(orderInfo); + Assert.notNull(payId); + Assert.notNull(payChannel); + //获取平台内部账户并加锁 + InternalAccount ia = internalAccountService.getWithLock(Constants.PLATFORM_INTERNAL_ACCOUNT_ID); + FinanceBill bill = new FinanceBill(); + bill.setBillNo(generateBillNo(EFinBillType.COLLECTION)); + bill.setBillType(EFinBillType.COLLECTION.getValue()); + //直接标记成功 + bill.setBillStatus(EFinBillStatus.SUCCESS.getValue()); + bill.setSrcType(EFinBillSrcType.STORE_ORDER_PAID.getValue()); + bill.setSrcId(payId); + bill.setRelType(EFinBillRelType.STORE_ORDER.getValue()); + bill.setRelId(orderInfo.getOrder().getId()); + //支付渠道+回调ID构成业务唯一键,防止重复创建收款单 + String businessUniqueKey = payChannel.getPrefix() + payId; + bill.setBusinessUniqueKey(businessUniqueKey); + bill.setInputInternalAccountId(ia.getId()); + bill.setInputExternalAccountId(payChannel.getPlatformExternalAccountId()); + bill.setBusinessAmount(orderInfo.getOrder().getTotalAmount()); + bill.setTransAmount(orderInfo.getOrder().getRealTotalAmount()); + bill.setVersion(0L); + bill.setDelFlag(Constants.UNDELETED); + financeBillMapper.insert(bill); + List billDetails = new ArrayList<>(orderInfo.getOrderDetails().size()); + for (StoreOrderDetail orderDetail : orderInfo.getOrderDetails()) { + FinanceBillDetail billDetail = new FinanceBillDetail(); + billDetail.setFinanceBillId(bill.getId()); + billDetail.setRelType(EFinBillDetailRelType.STORE_ORDER_DETAIL.getValue()); + billDetail.setRelId(orderDetail.getId()); + billDetail.setBusinessAmount(orderDetail.getTotalAmount()); + billDetail.setTransAmount(orderDetail.getRealTotalAmount()); + billDetail.setDelFlag(Constants.UNDELETED); + financeBillDetailMapper.insert(billDetail); + billDetails.add(billDetail); + } + TransInfo transInfo = TransInfo.builder() + .srcBillId(bill.getId()) + .srcBillType(bill.getBillType()) + .transAmount(bill.getTransAmount()) + .transTime(new Date()) + .handlerId(null) + .remark("订单支付完成") + .build(); + //内部账户 + internalAccountService.addTransDetail(ia, transInfo, ELoanDirection.DEBIT, EEntryStatus.FINISH); + //外部账户 + externalAccountService.addTransDetail(payChannel.getPlatformExternalAccountId(), transInfo, + ELoanDirection.DEBIT, EEntryStatus.FINISH); + return new FinanceBillInfo(bill, billDetails); + } + + + /** + * 生成单号 + * + * @param billType + * @return + */ + public String generateBillNo(EFinBillType billType) { + //未确定规则,暂时用UUID代替 + return IdUtil.simpleUUID(); } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/InternalAccountServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/InternalAccountServiceImpl.java index aed4268ec..146b9875b 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/InternalAccountServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/InternalAccountServiceImpl.java @@ -1,13 +1,24 @@ package com.ruoyi.xkt.service.impl; +import cn.hutool.core.util.NumberUtil; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.bean.BeanValidators; import com.ruoyi.xkt.domain.InternalAccount; +import com.ruoyi.xkt.domain.InternalAccountTransDetail; +import com.ruoyi.xkt.dto.finance.TransInfo; +import com.ruoyi.xkt.enums.EAccountStatus; +import com.ruoyi.xkt.enums.EEntryExecuted; +import com.ruoyi.xkt.enums.EEntryStatus; +import com.ruoyi.xkt.enums.ELoanDirection; import com.ruoyi.xkt.mapper.InternalAccountMapper; import com.ruoyi.xkt.mapper.InternalAccountTransDetailMapper; import com.ruoyi.xkt.service.IInternalAccountService; +import io.jsonwebtoken.lang.Assert; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; import java.util.Collection; import java.util.List; @@ -34,4 +45,101 @@ public class InternalAccountServiceImpl implements IInternalAccountService { public List listWithLock(Collection ids) { return internalAccountMapper.listForUpdate(ids); } + + @Transactional + @Override + public int addTransDetail(InternalAccount internalAccount, TransInfo transInfo, ELoanDirection loanDirection, + EEntryStatus entryStatus) { + Assert.notNull(internalAccount, "内部账户不存在"); + if (!BeanValidators.exists(internalAccount)) { + throw new ServiceException("内部账户[" + internalAccount.getId() + "]不存在"); + } + if (!EAccountStatus.NORMAL.getValue().equals(internalAccount.getAccountStatus())) { + throw new ServiceException("内部账户[" + internalAccount.getId() + "]已冻结"); + } + InternalAccountTransDetail transDetail = new InternalAccountTransDetail(); + transDetail.setInternalAccountId(internalAccount.getId()); + transDetail.setSrcBillId(transInfo.getSrcBillId()); + transDetail.setSrcBillType(transInfo.getSrcBillType()); + transDetail.setLoanDirection(loanDirection.getValue()); + if (less0(transInfo.getTransAmount())) { + throw new ServiceException("交易金额异常"); + } + transDetail.setTransAmount(transInfo.getTransAmount()); + transDetail.setTransTime(transInfo.getTransTime()); + transDetail.setHandlerId(transInfo.getHandlerId()); + transDetail.setEntryStatus(entryStatus.getValue()); + //不考虑热点账户问题,已入账 => 已执行 + transDetail.setEntryExecuted(EEntryStatus.FINISH == entryStatus ? + EEntryExecuted.FINISH.getValue() : EEntryExecuted.WAITING.getValue()); + transDetail.setRemark(transInfo.getRemark()); + switch (loanDirection) { + case DEBIT: + //借 + if (EEntryExecuted.FINISH.getValue().equals(transDetail.getEntryExecuted())) { + //已执行 + //余额 = 余额 + 交易金额 + internalAccount.setBalance(internalAccount.getBalance() + .add(transDetail.getTransAmount())); + //可用余额 = 可用余额 + 交易金额 + internalAccount.setUsableBalance(internalAccount.getUsableBalance() + .add(transDetail.getTransAmount())); + //支付中金额不变 + } else { + //未执行 + //余额不变 + //可用余额不变 + //支付中金额不变 + } + break; + case CREDIT: + //贷 + if (EEntryExecuted.FINISH.getValue().equals(transDetail.getEntryExecuted())) { + //已执行 + //余额 = 余额 - 交易金额 + internalAccount.setBalance(internalAccount.getBalance() + .subtract(transDetail.getTransAmount())); + //可用余额 = 可用余额 - 交易金额 + internalAccount.setUsableBalance(internalAccount.getUsableBalance() + .subtract(transDetail.getTransAmount())); + //支付中金额不变 + } else { + //未执行 + //余额不变 + //可用余额 = 可用余额 - 交易金额 + internalAccount.setUsableBalance(internalAccount.getUsableBalance() + .subtract(transDetail.getTransAmount())); + //支付中金额 = 支付中金额 + 交易金额 + internalAccount.setPaymentAmount(internalAccount.getPaymentAmount() + .add(transDetail.getTransAmount())); + } + break; + default: + throw new ServiceException("未知借贷方向"); + } + //检查账户余额,不允许出现负数 + if (less0(internalAccount.getBalance())) { + throw new ServiceException("账户[" + internalAccount.getId() + "]余额不足"); + } + if (less0(internalAccount.getUsableBalance())) { + throw new ServiceException("账户[" + internalAccount.getId() + "]可用余额不足"); + } + if (less0(internalAccount.getPaymentAmount())) { + throw new ServiceException("账户[" + internalAccount.getId() + "]支付中金额异常"); + } + //更新账户余额 + internalAccountMapper.updateById(internalAccount); + //交易明细 + return internalAccountTransDetailMapper.insert(transDetail); + } + + /** + * 判断数字是否小于0 + * + * @param num + * @return + */ + private boolean less0(BigDecimal num) { + return NumberUtil.isLess(num, BigDecimal.ZERO); + } }