wujianwei
2026-03-20 b2e717310b8a177b435e0a3532f520839ec26402
service/src/main/java/com/ruoyi/cwgl/service/impl/FundFlowClaimDetailServiceImpl.java
@@ -21,8 +21,19 @@
import com.ruoyi.cwgl.mapper.FundFlowMapper;
import com.ruoyi.cwgl.domain.FundFlowClaimDetail;
import com.ruoyi.cwgl.domain.FundFlow;
import com.ruoyi.cwgl.domain.FundFlowLog;
import com.ruoyi.cwgl.domain.ReceivableBillSettlementDetail;
import com.ruoyi.cwgl.domain.PayableBillSettlementDetail;
import com.ruoyi.cwgl.domain.ReceivableBillManagement;
import com.ruoyi.cwgl.domain.PayableBillManagement;
import com.ruoyi.cwgl.service.IFundFlowClaimDetailService;
import com.ruoyi.cwgl.service.IFundFlowLogService;
import com.ruoyi.cwgl.service.IReceivableBillSettlementDetailService;
import com.ruoyi.cwgl.service.IPayableBillSettlementDetailService;
import com.ruoyi.cwgl.service.IReceivableBillManagementService;
import com.ruoyi.cwgl.service.IPayableBillManagementService;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.SecurityUtils;
import java.math.BigDecimal;
/**
@@ -41,6 +52,21 @@
    
    @Resource
    private FundFlowMapper fundFlowMapper;
    @Resource
    private IReceivableBillSettlementDetailService receivableBillSettlementDetailService;
    @Resource
    private IPayableBillSettlementDetailService payableBillSettlementDetailService;
    @Resource
    private IReceivableBillManagementService receivableBillManagementService;
    @Resource
    private IPayableBillManagementService payableBillManagementService;
    @Resource
    private IFundFlowLogService fundFlowLogService;
    /**
@@ -160,6 +186,7 @@
    @Override
    public int deleteFundFlowClaimDetailByIds(String ids)
    {
        return deleteFundFlowClaimDetailByIds(Convert.toIntArray(ids));
    }
@@ -173,7 +200,65 @@
    @Override
    public int deleteFundFlowClaimDetailByIds(Integer[] ids)
    {
        return fundFlowClaimDetailMapper.deleteFundFlowClaimDetailByIds(ids);
        if (ids == null || ids.length == 0) {
            throw new RuntimeException("删除的认领明细ID不能为空");
        }
        // 由于删除只会有一条记录,取第一条进行处理
        Integer id = ids[0];
        FundFlowClaimDetail claimDetail = fundFlowClaimDetailMapper.selectFundFlowClaimDetailById(id);
        if (claimDetail == null) {
            throw new RuntimeException("未找到要删除的认领明细记录,ID: " + id);
        }
        Integer fundFlowId = claimDetail.getFundFlowId();
        BigDecimal deleteAmount = claimDetail.getClaimAmount();
        // 查询资金流水信息
        FundFlow fundFlow = fundFlowMapper.selectFundFlowById(fundFlowId);
        if (fundFlow == null) {
            throw new RuntimeException("资金流水不存在,ID: " + fundFlowId);
        }
        // 更新资金流水的已认领金额
        BigDecimal newClaimedAmount = fundFlow.getClaimedAmount().subtract(deleteAmount);
        if (newClaimedAmount.compareTo(BigDecimal.ZERO) < 0) {
            newClaimedAmount = BigDecimal.ZERO;
        }
        // 根据新的认领金额设置状态
        String newStatus =fundFlow.getStatus();
        if (newClaimedAmount.compareTo(BigDecimal.ZERO) == 0) {
            // 已认领金额为0,状态改为1(未认领)
            newStatus = "1";
        } else if (newClaimedAmount.compareTo(fundFlow.getTransactionAmount()) < 0) {
            // 已认领金额小于交易金额,状态改为2(部分认领)
            newStatus = "2";
        }
        // 更新资金流水状态和已认领金额
        fundFlow.setStatus(newStatus);
        fundFlow.setClaimedAmount(newClaimedAmount);
        fundFlow.setUpdateTime(DateUtils.getNowDate());
        int updateResult = fundFlowMapper.updateFundFlow(fundFlow);
        if (updateResult <= 0) {
            throw new RuntimeException("更新资金流水状态失败,ID: " + fundFlowId);
        }
        // 删除结算明细并更新账单状态
        deleteSettlementDetailsAndUpdateBillStatus(claimDetail,fundFlow);
        int result = fundFlowClaimDetailMapper.deleteFundFlowClaimDetailByIds(ids);
        // 记录操作日志
        if (result > 0) {
            FundFlowLog log = new FundFlowLog();
            log.setFlowId(fundFlowId);
            log.setOperation("删除账单认领明细,账单编号:" + claimDetail.getBillNo() + ",认领金额:" + deleteAmount + ",资金流水号:" + fundFlow.getBankFlowNo());
            fundFlowLogService.insertFundFlowLog(log);
        }
        return result;
    }
    /**
@@ -185,6 +270,7 @@
    @Override
    public int deleteFundFlowClaimDetailById(Integer id)
    {
        return fundFlowClaimDetailMapper.deleteFundFlowClaimDetailById(id);
    }
@@ -196,80 +282,87 @@
     * @return 结果
     */
    @Override
    public int claimBill(Integer fundFlowId, List<FundFlowClaimDetail> claimDetails)
    public int claimBill(Integer fundFlowId, FundFlowClaimDetail claimDetail)
    {
        if (fundFlowId == null) {
            throw new RuntimeException("资金流水ID不能为空");
        }
        
        if (claimDetails == null || claimDetails.isEmpty()) {
        if (claimDetail == null ) {
            throw new RuntimeException("认领明细列表不能为空");
        }
        // 计算总认领金额
        BigDecimal totalClaimAmount = BigDecimal.ZERO;
        // 验证认领明细的必填字段
        for (FundFlowClaimDetail claimDetail : claimDetails) {
            if (claimDetail.getClaimAmount() == null || claimDetail.getClaimAmount().compareTo(BigDecimal.ZERO) <= 0) {
        //金额
        BigDecimal claimAmount = claimDetail.getClaimAmount();
        if (claimAmount == null || claimAmount.compareTo(BigDecimal.ZERO) <= 0) {
                throw new RuntimeException("认领金额必须大于0");
            }
            totalClaimAmount = totalClaimAmount.add(claimDetail.getClaimAmount());
        }
        
        // 查询资金流水信息
        FundFlow fundFlow = fundFlowMapper.selectFundFlowById(fundFlowId);
        
        // 根据总认领金额与交易金额的比较设置状态
        String newStatus = getString(fundFlowId, claimDetails, fundFlow);
        String newStatus = getString(fundFlowId, claimDetail, fundFlow);
        // 更新资金流水状态和已认领金额
        fundFlow.setStatus(newStatus);
        fundFlow.setClaimedAmount(totalClaimAmount); // 设置已认领金额
        fundFlow.setClaimedAmount(fundFlow.getClaimedAmount().add(claimAmount)); // 设置已认领金额
        fundFlow.setUpdateTime(DateUtils.getNowDate());
        int updateResult = fundFlowMapper.updateFundFlow(fundFlow);
        if (updateResult <= 0) {
            throw new RuntimeException("更新资金流水状态失败,ID: " + fundFlowId);
        }
        
        // 先删除该资金流水ID下的所有认领明细(避免重复认领)
        fundFlowClaimDetailMapper.deleteFundFlowClaimDetailByFundFlowId(fundFlowId);
        // 批量保存所有账单认领明细
        for (FundFlowClaimDetail claimDetail : claimDetails) {
            // 设置资金流水ID
            claimDetail.setFundFlowId(fundFlowId);
            // 设置认领日期
            claimDetail.setClaimDate(DateUtils.getNowDate());
            // 设置创建时间
            claimDetail.setCreateTime(DateUtils.getNowDate());
        int insertResult = fundFlowClaimDetailMapper.insertFundFlowClaimDetail(claimDetail);
        // 新增:创建结算明细并更新账单状态
        if (insertResult > 0) {
            createSettlementDetailsAndUpdateBillStatus(claimDetail, fundFlow);
            // 记录操作日志
            FundFlowLog log = new FundFlowLog();
            log.setFlowId(fundFlowId);
            log.setOperation("新增账单认领明细,账单编号:" + claimDetail.getBillNo() + ",认领金额:" + claimAmount + ",资金流水号:" + fundFlow.getBankFlowNo());
            fundFlowLogService.insertFundFlowLog(log);
        }
        
        int insertResult = fundFlowClaimDetailMapper.insertFundFlowClaimDetailBatch(claimDetails);
        return insertResult;
    }
/**
 * 根据资金流水ID、认领详情列表和资金流水对象获取状态字符串
 * @param fundFlowId 资金流水ID,用于标识特定的资金流水记录
 * @param claimDetails 认领详情列表,包含所有认领金额信息
 * @param claimDetail 认领详情列表,包含所有认领金额信息
 * @param fundFlow 资金流水对象,包含交易金额等关键信息
 * @return 返回处理后的状态字符串
 * @throws RuntimeException 当资金流水对象为null时抛出异常
 */
    private static @NonNull String getString(Integer fundFlowId, List<FundFlowClaimDetail> claimDetails, FundFlow fundFlow) {
    private static @NonNull String getString(Integer fundFlowId, FundFlowClaimDetail claimDetail, FundFlow fundFlow) {
    // 检查资金流水对象是否为空,如果为空则抛出异常
        if (fundFlow == null) {
            throw new RuntimeException("资金流水不存在,ID: " + fundFlowId);
        }
        // 计算总认领金额
        BigDecimal totalClaimAmount = BigDecimal.ZERO;
        for (FundFlowClaimDetail claimDetail : claimDetails) {
            totalClaimAmount = totalClaimAmount.add(claimDetail.getClaimAmount());
        }
        BigDecimal totalClaimAmount = claimDetail.getClaimAmount();
        // 验证总认领金额不能超过交易金额
        String newStatus = getString(fundFlow, totalClaimAmount);
        return newStatus;
        return  getString(fundFlow, totalClaimAmount);
    }
    private static @NonNull String getString(FundFlow fundFlow, BigDecimal totalClaimAmount) {
@@ -289,4 +382,173 @@
        }
        return newStatus;
    }
    /**
     * 创建结算明细并更新账单状态
     */
    private void createSettlementDetailsAndUpdateBillStatus(FundFlowClaimDetail claimDetail, FundFlow fundFlow) {
            String billNo = claimDetail.getBillNo();
            BigDecimal claimAmount = claimDetail.getClaimAmount();
            Integer claimDetailId = claimDetail.getId();
            // 根据收支标识借贷标志判断是应收账单还是应付账单
            if (fundFlow.getIncomeExpenseFlag().equals(0)) {
                // 应收账单
                createReceivableSettlementDetail(billNo, claimAmount, fundFlow, claimDetailId);
            } else  {
                // 应付账单
                createPayableSettlementDetail(billNo, claimAmount, fundFlow, claimDetailId);
        }
    }
    /**
     * 创建应收账单结算明细
     */
    private void createReceivableSettlementDetail(String billNo, BigDecimal claimAmount, FundFlow fundFlow, Integer claimDetailId) {
        try {
            // 根据账单编号查询应收账单
            ReceivableBillManagement bill = receivableBillManagementService.selectReceivableBillManagementBySystemNo(billNo);
            if (bill != null) {
                // 创建结算明细
                ReceivableBillSettlementDetail settlementDetail = new ReceivableBillSettlementDetail();
                settlementDetail.setBillId(bill.getId());
                settlementDetail.setClaimDetailId(claimDetailId); // 设置认领明细ID
                settlementDetail.setReceiptAmount(claimAmount);
                settlementDetail.setReceiptDate(fundFlow.getTransactionDate());
                settlementDetail.setSettlementMethod("0"); // 根据实际情况设置
                // 设置银行账户信息
                settlementDetail.setCustomerBank(fundFlow.getOurBankName()); // 客户开户行(本方账户开户行)
                settlementDetail.setCustomerBankAccount(fundFlow.getOurAccount()); // 客户银行账号(本方账号)
                settlementDetail.setReceivingBank(fundFlow.getCounterpartyName()); // 收款账户开户行(对方户名)
                settlementDetail.setReceivingBankAccount(fundFlow.getCounterpartyAccount()); // 收款银行账号(对方账号)
                settlementDetail.setCreateBy(SecurityUtils.getUsername());
                settlementDetail.setCreateTime(DateUtils.getNowDate());
                // 插入结算明细(会自动更新账单状态)
                receivableBillSettlementDetailService.insertReceivableBillSettlementDetail(settlementDetail);
                logger.info("成功创建应收账单结算明细,账单编号:{},金额:{},认领明细ID:{}", billNo, claimAmount, claimDetailId);
            } else {
                logger.warn("未找到对应的应收账单,账单编号:{}", billNo);
            }
        } catch (Exception e) {
            logger.error("创建应收账单结算明细失败,账单编号:{}", billNo, e);
            // 这里可以选择抛出异常或记录日志,但不中断整个认领流程
        }
    }
    /**
     * 创建应付账单结算明细
     */
    private void createPayableSettlementDetail(String billNo, BigDecimal claimAmount, FundFlow fundFlow, Integer claimDetailId) {
        try {
            // 根据账单编号查询应付账单
            PayableBillManagement bill = payableBillManagementService.selectPayableBillManagementBySystemNo(billNo);
            if (bill != null) {
                // 创建结算明细
                PayableBillSettlementDetail settlementDetail = new PayableBillSettlementDetail();
                settlementDetail.setBillId(bill.getId());
                settlementDetail.setClaimDetailId(claimDetailId); // 设置认领明细ID
                settlementDetail.setPaymentAmount(claimAmount);
                settlementDetail.setPaymentDate(fundFlow.getTransactionDate());
                settlementDetail.setSettlementMethod("0"); // 根据实际情况设置
                // 设置银行账户信息
                settlementDetail.setPaymentBank(fundFlow.getOurBankName()); // 付款账户开户行(本方账户开户行)
                settlementDetail.setPaymentBankAccount(fundFlow.getOurAccount()); // 付款账户银行账号(本方账号)
                settlementDetail.setSupplierReceivingBank(fundFlow.getCounterpartyName()); // 供应商收款账户开户行(对方户名)
                settlementDetail.setSupplierReceivingAccount(fundFlow.getCounterpartyAccount()); // 供应商收款银行账户(对方账号)
                settlementDetail.setCreateBy(SecurityUtils.getUsername());
                settlementDetail.setCreateTime(DateUtils.getNowDate());
                // 插入结算明细(会自动更新账单状态)
                payableBillSettlementDetailService.insertPayableBillSettlementDetail(settlementDetail);
                logger.info("成功创建应付账单结算明细,账单编号:{},金额:{},认领明细ID:{}", billNo, claimAmount, claimDetailId);
            } else {
                logger.warn("未找到对应的应付账单,账单编号:{}", billNo);
            }
        } catch (Exception e) {
            logger.error("创建应付账单结算明细失败,账单编号:{}", billNo, e);
            // 这里可以选择抛出异常或记录日志,但不中断整个认领流程
        }
    }
    /**
     * 删除结算明细并更新账单状态
     */
    private void deleteSettlementDetailsAndUpdateBillStatus(FundFlowClaimDetail claimDetail, FundFlow fundFlow) {
        String billNo = claimDetail.getBillNo();
        Integer claimDetailId = claimDetail.getId();
        try {
            // 根据收支标识借贷标志判断是应收账单还是应付账单
            if (fundFlow.getIncomeExpenseFlag().equals(0)) {
                // 应收账单
                deleteReceivableSettlementDetail(claimDetailId);
            } else {
                // 应付账单
                deletePayableSettlementDetail(claimDetailId);
            }
            logger.info("成功删除结算明细,认领明细ID:{}", claimDetailId);
        } catch (Exception e) {
            logger.error("删除结算明细失败,认领明细ID:{}", claimDetailId, e);
            // 这里可以选择抛出异常或记录日志,但不中断整个删除流程
        }
    }
    /**
     * 删除应收账单结算明细
     */
    private void deleteReceivableSettlementDetail(Integer claimDetailId) {
        try {
            // 根据认领明细ID查询应收账单结算明细
            ReceivableBillSettlementDetail receivableQuery = new ReceivableBillSettlementDetail();
            receivableQuery.setClaimDetailId(claimDetailId);
            List<ReceivableBillSettlementDetail> receivableDetails = receivableBillSettlementDetailService.selectReceivableBillSettlementDetailList(receivableQuery);
            if (!receivableDetails.isEmpty()) {
                Integer[] receivableIds = receivableDetails.stream()
                        .map(ReceivableBillSettlementDetail::getId)
                        .toArray(Integer[]::new);
                receivableBillSettlementDetailService.deleteReceivableBillSettlementDetailByIds(receivableIds);
                logger.info("成功删除应收账单结算明细,认领明细ID:{}", claimDetailId);
            }
        } catch (Exception e) {
            logger.error("删除应收账单结算明细失败,认领明细ID:{}", claimDetailId, e);
            throw e;
        }
    }
    /**
     * 删除应付账单结算明细
     */
    private void deletePayableSettlementDetail(Integer claimDetailId) {
        try {
            // 根据认领明细ID查询应付账单结算明细
            PayableBillSettlementDetail payableQuery = new PayableBillSettlementDetail();
            payableQuery.setClaimDetailId(claimDetailId);
            List<PayableBillSettlementDetail> payableDetails = payableBillSettlementDetailService.selectPayableBillSettlementDetailList(payableQuery);
            if (!payableDetails.isEmpty()) {
                Integer[] payableIds = payableDetails.stream()
                        .map(PayableBillSettlementDetail::getId)
                        .toArray(Integer[]::new);
                payableBillSettlementDetailService.deletePayableBillSettlementDetailByIds(payableIds);
                logger.info("成功删除应付账单结算明细,认领明细ID:{}", claimDetailId);
            }
        } catch (Exception e) {
            logger.error("删除应付账单结算明细失败,认领明细ID:{}", claimDetailId, e);
            throw e;
        }
    }
}