diff --git a/bms-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/ar/ArBankAccountController.java b/bms-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/ar/ArBankAccountController.java new file mode 100644 index 00000000..19bada9c --- /dev/null +++ b/bms-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/ar/ArBankAccountController.java @@ -0,0 +1,33 @@ +package com.ruoyi.web.controller.ar; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.ar.domain.ArBankAccount; +import com.ruoyi.ar.mapper.ArBankAccountMapper; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; + +/** + * 公司收款银行账户(下拉选项,供登记收款等场景选择)。 + */ +@RestController +@RequestMapping("/ar/bank-account") +public class ArBankAccountController extends BaseController { + + @Autowired + private ArBankAccountMapper arBankAccountMapper; + + /** + * 启用账户列表;可按币种过滤,默认账户优先。 + */ + @GetMapping("/options") + public AjaxResult options(@RequestParam(value = "currency", required = false) String currency) { + List list = arBankAccountMapper.selectEnabledList(currency); + return AjaxResult.success(list); + } +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBankAccountMapper.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBankAccountMapper.java index 8a221f13..e0805f0f 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBankAccountMapper.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/mapper/ArBankAccountMapper.java @@ -1,8 +1,16 @@ package com.ruoyi.ar.mapper; +import java.util.List; + import org.apache.ibatis.annotations.Param; import com.ruoyi.ar.domain.ArBankAccount; public interface ArBankAccountMapper { ArBankAccount selectDefaultByCurrency(@Param("currency") String currency); + + /** 按主键查启用账户 */ + ArBankAccount selectEnabledById(@Param("bankAccountId") Long bankAccountId); + + /** 启用账户下拉(currency 为空时查全部),默认账户优先 */ + List selectEnabledList(@Param("currency") String currency); } diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customerinfo/domain/BmsCustomerCompany.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customerinfo/domain/BmsCustomerCompany.java index 8ea932f9..6c519eb5 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customerinfo/domain/BmsCustomerCompany.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customerinfo/domain/BmsCustomerCompany.java @@ -115,8 +115,8 @@ public class BmsCustomerCompany extends BaseEntity /** 注册详细地址 */ private String registeredAddressDetail; - /** 营业执照 oss_id */ - private Long businessLicenseOssId; + /** 营业执照图片URL(当前存服务器本地相对路径,后续可切换对象存储) */ + private String businessLicenseUrl; /** 其他附件 oss_id 逗号分隔 */ private String attachmentIds; diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/CreditUsageCommand.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/CreditUsageCommand.java index b33e270a..bfeff44b 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/CreditUsageCommand.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/CreditUsageCommand.java @@ -51,10 +51,9 @@ public class CreditUsageCommand private String reason; /** - * 占用时是否校验可用额度(授信总额-已用 >= 本次占用额)。 - * true=余额/额度不足直接抛异常(计费开单等新业务场景默认值); - * false=允许超出总额度占用(兼容历史账单确认口径)。 - * 释放场景该参数无意义。 + * 字段保留兼容历史调用,当前计费策略(2026-09-20 起)已不再硬拦截: + * 超额客户计费继续占用信用额度,允许可用额度为负,后续改由超额提醒机制处理。 */ + @Deprecated private Boolean checkAvailable = Boolean.TRUE; } diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/ICustomerAccountApi.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/ICustomerAccountApi.java index aff35aaa..c76cdc52 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/ICustomerAccountApi.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/ICustomerAccountApi.java @@ -60,7 +60,7 @@ public interface ICustomerAccountApi /** * 占用授信额度:used_credit += amount,写 OCCUPY 额度流水(关联来源单据)。 - * 命令中 customerId 与 customerCode 二选一;checkAvailable=true 时可用额度不足抛 ServiceException; + * 命令中 customerId 与 customerCode 二选一;超额不拦截,允许可用额度(总额度-已占用)为负; * CNY账户不存在自动初始化,外币账户不存在时静默跳过(返回null,兼容历史口径)。 * * @return 已落库的额度流水(含ID);账户不存在跳过场景返回null diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/impl/CustomerAccountApiImpl.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/impl/CustomerAccountApiImpl.java index 6f51b299..42929a56 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/impl/CustomerAccountApiImpl.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/api/impl/CustomerAccountApiImpl.java @@ -303,23 +303,8 @@ public class CustomerAccountApiImpl implements ICustomerAccountApi } BigDecimal amount = money(command.getAmount()); BigDecimal beforeUsed = nz(account.getUsedCredit()); - BigDecimal totalAvailable = nz(account.getTotalCredit()).add(nz(account.getExtraCredit())) - .subtract(beforeUsed); - if (Boolean.TRUE.equals(command.getCheckAvailable())) - { - // 已处于超额(欠费)状态:可用额度已为负,任何新增计费一律拦截 - if (totalAvailable.compareTo(BigDecimal.ZERO) < 0) - { - throw new ServiceException("客户已超额(欠费),当前可用额度:" + totalAvailable.toPlainString() - + " " + currency + ",请先回款核销恢复额度后再计费开单"); - } - if (totalAvailable.compareTo(amount) < 0) - { - throw new ServiceException("客户可用额度不足,当前可用额度:" + totalAvailable.toPlainString() - + " " + currency + ",本次需占用:" + amount.toPlainString() - + ",请回款核销或申请调整额度"); - } - } + // 计费策略(2026-09-20 调整):超额客户不拦截计费,继续占用信用额度, + // 允许可用额度(总额度-已占用)为负;后续基于负额度做超额提醒,不做硬拦截。 BigDecimal afterUsed = beforeUsed.add(amount).setScale(MONEY_SCALE, RoundingMode.HALF_UP); account.setUsedCredit(afterUsed); account.setUpdateBy(username); @@ -743,17 +728,17 @@ public class CustomerAccountApiImpl implements ICustomerAccountApi if (disabled && overdue) { vo.setAccountStatus(CustomerAccountStatusVO.STATUS_DISABLED_AND_OVERDUE); - vo.setAccountStatusDesc("客户已停用且可用额度不足(欠费),不可新下单"); + vo.setAccountStatusDesc("客户已停用且已超额(欠费),停用客户不可新计费"); } else if (disabled) { vo.setAccountStatus(CustomerAccountStatusVO.STATUS_DISABLED); - vo.setAccountStatusDesc("客户已停用,不可新下单"); + vo.setAccountStatusDesc("客户已停用,不可新计费"); } else if (overdue) { vo.setAccountStatus(CustomerAccountStatusVO.STATUS_OVERDUE); - vo.setAccountStatusDesc("客户可用额度不足(欠费),需先回款核销恢复额度"); + vo.setAccountStatusDesc("客户已超额(欠费),可继续计费占用额度,请及时催收回款"); } else { diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/domain/CustomerReceipt.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/domain/CustomerReceipt.java index 6f973139..ff60a150 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/domain/CustomerReceipt.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/domain/CustomerReceipt.java @@ -84,6 +84,18 @@ public class CustomerReceipt extends BaseEntity /** 收款方式:BANK_TRANSFER/ALIPAY/WECHAT/CASH/OTHER */ private String payMethod; + /** 收款银行账户ID(ar_bank_account) */ + private Long bankAccountId; + + /** 收款账户户名(登记时快照) */ + private String bankAccountName; + + /** 收款银行账号(登记时快照) */ + private String bankAccountNo; + + /** 开户行名称(登记时快照) */ + private String bankName; + /** 银行流水号/支付平台流水号 */ private String bankTransactionNo; diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/service/impl/CustomerMoneyServiceImpl.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/service/impl/CustomerMoneyServiceImpl.java index ea720031..1a62a234 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/service/impl/CustomerMoneyServiceImpl.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/customer/customermoney/service/impl/CustomerMoneyServiceImpl.java @@ -15,6 +15,8 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.SecurityUtils; +import com.ruoyi.ar.domain.ArBankAccount; +import com.ruoyi.ar.mapper.ArBankAccountMapper; import com.ruoyi.customer.customerinfo.domain.BmsCustomer; import com.ruoyi.customer.customerinfo.domain.BmsCustomerAttachment; import com.ruoyi.customer.customerinfo.mapper.BmsCustomerMapper; @@ -69,6 +71,10 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService @Autowired private ICreditQuotaService creditQuotaService; + /** 公司收款银行账户(登记收款选择并快照) */ + @Autowired + private ArBankAccountMapper arBankAccountMapper; + @Override @Transactional(rollbackFor = Exception.class) public List selectAccountList(Long customerId) @@ -136,6 +142,25 @@ public class CustomerMoneyServiceImpl implements ICustomerMoneyService { receipt.setCurrency(receipt.getCurrency().trim().toUpperCase()); } + // 收款银行账户:以库中启用账户为准回填快照(不信任前端传入的户名/账号/开户行文本), + // 账户后续停用或修改不影响历史单据展示。 + if (receipt.getBankAccountId() != null) + { + ArBankAccount bankAccount = arBankAccountMapper.selectEnabledById(receipt.getBankAccountId()); + if (bankAccount == null) + { + throw new ServiceException("收款银行账户不存在或已停用,请重新选择"); + } + receipt.setBankAccountName(bankAccount.getAccountName()); + receipt.setBankAccountNo(bankAccount.getAccountNo()); + receipt.setBankName(bankAccount.getBankName()); + } + else + { + receipt.setBankAccountName(null); + receipt.setBankAccountNo(null); + receipt.setBankName(null); + } // 汇率与本位币金额:CNY 固定 1:1;外币以收款日即期汇率表为基准,允许页面手工修改。 // 汇率来源由后端权威判定(不信任前端标记):与汇率表一致=RATE_TABLE,不一致/表未配置=MANUAL。 BigDecimal rate = receipt.getExchangeRate(); diff --git a/bms-back/ruoyi-system/src/main/resources/mapper/ar/ArBankAccountMapper.xml b/bms-back/ruoyi-system/src/main/resources/mapper/ar/ArBankAccountMapper.xml index c9f26767..96c2ae6c 100644 --- a/bms-back/ruoyi-system/src/main/resources/mapper/ar/ArBankAccountMapper.xml +++ b/bms-back/ruoyi-system/src/main/resources/mapper/ar/ArBankAccountMapper.xml @@ -36,4 +36,34 @@ and status = '0' order by is_default desc, bank_account_id limit 1 + + + select bank_account_id, + account_name, + account_no, + bank_name, + currency, + is_default, + status, + remark, + create_by, + create_time, + update_by, + update_time + from ar_bank_account + where status = '0' + + + + + diff --git a/bms-back/ruoyi-system/src/main/resources/mapper/customer/BmsCustomerMapper.xml b/bms-back/ruoyi-system/src/main/resources/mapper/customer/BmsCustomerMapper.xml index 7cae5ba2..c4cf81b2 100644 --- a/bms-back/ruoyi-system/src/main/resources/mapper/customer/BmsCustomerMapper.xml +++ b/bms-back/ruoyi-system/src/main/resources/mapper/customer/BmsCustomerMapper.xml @@ -363,7 +363,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - + @@ -374,7 +374,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - select company_id, customer_id, company_name_full, english_name, credit_code, legal_person, legal_person_phone, legal_person_id_card, registered_capital, capital_currency, paid_in_capital, establish_date, business_term_start, business_term_end, business_term_permanent, registration_authority, registration_number, operating_status, business_scope, shareholders, employee_count, company_phone, company_fax, company_website, company_email, registered_province, registered_city, registered_district, registered_address_detail, business_license_oss_id, attachment_ids, remark, create_by, create_time, update_by, update_time, del_flag from bms_customer_company + select company_id, customer_id, company_name_full, english_name, credit_code, legal_person, legal_person_phone, legal_person_id_card, registered_capital, capital_currency, paid_in_capital, establish_date, business_term_start, business_term_end, business_term_permanent, registration_authority, registration_number, operating_status, business_scope, shareholders, employee_count, company_phone, company_fax, company_website, company_email, registered_province, registered_city, registered_district, registered_address_detail, business_license_url, attachment_ids, remark, create_by, create_time, update_by, update_time, del_flag from bms_customer_company