diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/vo/ArBillGenerateQuery.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/vo/ArBillGenerateQuery.java index e2901755..1b565e23 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/vo/ArBillGenerateQuery.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/vo/ArBillGenerateQuery.java @@ -17,7 +17,7 @@ public class ArBillGenerateQuery private String currency; - /** 订单号、运单号或转单号关键词,按 OR 条件模糊查询。 */ + /** 订单号、运单号或转单号;支持换行、逗号、分号或空格分隔多个号码。 */ private String orderOrTrackingNo; /** 全选模式下,排除弹窗使用的附加订单号、运单号或转单号关键词。 */ diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/vo/ArBillGenerateRequest.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/vo/ArBillGenerateRequest.java index 65a86ffb..595728c3 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/vo/ArBillGenerateRequest.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/domain/vo/ArBillGenerateRequest.java @@ -36,7 +36,7 @@ public class ArBillGenerateRequest @JsonDeserialize(using = StrictDateDeserializer.class) private Date billDate; private String currency = "CNY"; - /** 订单号、运单号或转单号关键词,生成时用于再次校验筛选条件。 */ + /** 订单号、运单号或转单号原始输入,生成时会拆分并再次校验筛选条件。 */ private String orderOrTrackingNo; private String bankAccountName; private String bankAccountNo; diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillServiceImpl.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillServiceImpl.java index 5e664083..382c0190 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillServiceImpl.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/ar/service/impl/ArBillServiceImpl.java @@ -114,6 +114,8 @@ public class ArBillServiceImpl implements IArBillService { */ private static final int EXPLICIT_SOURCE_ID_LIMIT = 10000; private static final int EXCLUDED_SOURCE_ID_LIMIT = 10000; + /** 单次生成查询最多接收的订单号、运单号或转单号数量。 */ + private static final int ORDER_IDENTIFIER_LIMIT = 2000; /** * 模板明细行使用的边框、字体和换行样式;样式定义来自 ar_bill_template.xlsx。 */ @@ -216,13 +218,14 @@ public class ArBillServiceImpl implements IArBillService { } /** - * 分页预览可生成订单;订单号和运单号关键字在 SQL 中使用 OR 条件。 + * 分页预览可生成订单;多个订单号、运单号或转单号按 OR 条件精确匹配。 */ @Override public List previewBill(ArBillGenerateQuery query) { validatePreviewQuery(query); + List orderIdentifiers = normalizeOrderIdentifiers(query.getOrderOrTrackingNo()); return sourceBillMapper.selectPrcOrderBillByCustomerPeriod(query.getCustomerId(), - query.getCustomerCode(), StringUtils.trim(query.getOrderOrTrackingNo()), + query.getCustomerCode(), orderIdentifiers, StringUtils.trim(query.getExcludeOrderOrTrackingNo()), query.getBillPeriodEnd(), query.getCurrency(), eligibleOrderBillStatuses(), ArIncomeBillFeeStatus.UNBILLED.getCode(), null); } @@ -233,8 +236,9 @@ public class ArBillServiceImpl implements IArBillService { @Override public BigDecimal sumPreviewBill(ArBillGenerateQuery query) { validatePreviewQuery(query); + List orderIdentifiers = normalizeOrderIdentifiers(query.getOrderOrTrackingNo()); return nvl(sourceBillMapper.sumPrcOrderBillIncomeByCustomerPeriod(query.getCustomerId(), - query.getCustomerCode(), StringUtils.trim(query.getOrderOrTrackingNo()), + query.getCustomerCode(), orderIdentifiers, StringUtils.trim(query.getExcludeOrderOrTrackingNo()), query.getBillPeriodEnd(), query.getCurrency(), eligibleOrderBillStatuses(), ArIncomeBillFeeStatus.UNBILLED.getCode())); } @@ -422,7 +426,8 @@ public class ArBillServiceImpl implements IArBillService { if (task.getTotalCount() == null || task.getTotalCount() < 0) { log.info("开始统计应收账单生成范围,taskId={}", taskId); int totalCount = sourceBillMapper.countPrcOrderBillByCustomerPeriod( - request.getCustomerId(), request.getCustomerCode(), StringUtils.trim(request.getOrderOrTrackingNo()), + request.getCustomerId(), request.getCustomerCode(), + normalizeOrderIdentifiers(request.getOrderOrTrackingNo()), request.getBillPeriodEnd(), request.getCurrency(), eligibleOrderBillStatuses(), ArIncomeBillFeeStatus.UNBILLED.getCode(), task.getSnapshotCreateTime(), null, excludedSourceBillIds); @@ -546,7 +551,8 @@ public class ArBillServiceImpl implements IArBillService { List explicitIds = selectionMode == ArBillSelectionMode.EXPLICIT ? sourceBillIds : null; List sources = sourceBillMapper.selectPrcOrderBillByCustomerPeriodCursor( - request.getCustomerId(), request.getCustomerCode(), StringUtils.trim(request.getOrderOrTrackingNo()), + request.getCustomerId(), request.getCustomerCode(), + normalizeOrderIdentifiers(request.getOrderOrTrackingNo()), request.getBillPeriodEnd(), StringUtils.isEmpty(request.getCurrency()) ? "CNY" : request.getCurrency(), eligibleOrderBillStatuses(), ArIncomeBillFeeStatus.UNBILLED.getCode(), task.getSnapshotCreateTime(), task.getLastSourceBillId(), @@ -1661,6 +1667,8 @@ public class ArBillServiceImpl implements IArBillService { if (StringUtils.isNotEmpty(request.getRemark()) && request.getRemark().trim().length() > 500) { throw new ServiceException("备注不能超过500个字符"); } + // 生成任务会保存原始请求快照,先在入任务前校验号码数量,避免后台任务创建后才失败。 + normalizeOrderIdentifiers(request.getOrderOrTrackingNo()); } private void validatePreviewQuery(ArBillGenerateQuery query) { @@ -1696,4 +1704,26 @@ public class ArBillServiceImpl implements IArBillService { } return new ArrayList<>(uniqueIds); } + + /** + * 将前端多行输入的订单号、运单号和转单号拆分为去重列表。 + * 支持换行、空格、英文/中文逗号和英文/中文分号作为分隔符。 + */ + private List normalizeOrderIdentifiers(String rawIdentifiers) { + LinkedHashSet uniqueIdentifiers = new LinkedHashSet<>(); + if (StringUtils.isEmpty(rawIdentifiers)) { + return new ArrayList<>(); + } + String[] identifiers = rawIdentifiers.split("[\\s,,;;]+"); + for (String identifier : identifiers) { + String value = StringUtils.trim(identifier); + if (!StringUtils.isEmpty(value)) { + uniqueIdentifiers.add(value); + } + } + if (uniqueIdentifiers.size() > ORDER_IDENTIFIER_LIMIT) { + throw new ServiceException("单号最多输入 " + ORDER_IDENTIFIER_LIMIT + " 个"); + } + return new ArrayList<>(uniqueIdentifiers); + } } diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/mapper/PrcOrderBillMapper.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/mapper/PrcOrderBillMapper.java index e7c9edc5..65bcd7cc 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/mapper/PrcOrderBillMapper.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/mapper/PrcOrderBillMapper.java @@ -31,7 +31,7 @@ public interface PrcOrderBillMapper /** 应收账单生成读取指定客户截止日期前仍存在未出账费用的订单计费快照。 */ public List selectPrcOrderBillByCustomerPeriod(@Param("customerId") Long customerId, - @Param("customerCode") String customerCode, @Param("orderOrTrackingNo") String orderOrTrackingNo, + @Param("customerCode") String customerCode, @Param("orderIdentifiers") List orderIdentifiers, @Param("excludeOrderOrTrackingNo") String excludeOrderOrTrackingNo, @Param("cutoffDate") Date cutoffDate, @Param("currency") String currency, @Param("arBillStatuses") List arBillStatuses, @Param("feeArBillStatus") String feeArBillStatus, @@ -39,14 +39,14 @@ public interface PrcOrderBillMapper /** 统计应收账单预览结果金额,供全选模式展示。 */ BigDecimal sumPrcOrderBillIncomeByCustomerPeriod(@Param("customerId") Long customerId, - @Param("customerCode") String customerCode, @Param("orderOrTrackingNo") String orderOrTrackingNo, + @Param("customerCode") String customerCode, @Param("orderIdentifiers") List orderIdentifiers, @Param("excludeOrderOrTrackingNo") String excludeOrderOrTrackingNo, @Param("cutoffDate") Date cutoffDate, @Param("currency") String currency, @Param("arBillStatuses") List arBillStatuses, @Param("feeArBillStatus") String feeArBillStatus); /** 异步生成账单按 bill_id 游标读取一批来源订单。 */ List selectPrcOrderBillByCustomerPeriodCursor(@Param("customerId") Long customerId, - @Param("customerCode") String customerCode, @Param("orderOrTrackingNo") String orderOrTrackingNo, + @Param("customerCode") String customerCode, @Param("orderIdentifiers") List orderIdentifiers, @Param("cutoffDate") Date cutoffDate, @Param("currency") String currency, @Param("arBillStatuses") List arBillStatuses, @Param("feeArBillStatus") String feeArBillStatus, @Param("snapshotCreateTime") Date snapshotCreateTime, @@ -54,7 +54,7 @@ public interface PrcOrderBillMapper @Param("excludedBillIds") List excludedBillIds, @Param("limit") int limit); int countPrcOrderBillByCustomerPeriod(@Param("customerId") Long customerId, - @Param("customerCode") String customerCode, @Param("orderOrTrackingNo") String orderOrTrackingNo, + @Param("customerCode") String customerCode, @Param("orderIdentifiers") List orderIdentifiers, @Param("cutoffDate") Date cutoffDate, @Param("currency") String currency, @Param("arBillStatuses") List arBillStatuses, @Param("feeArBillStatus") String feeArBillStatus, @Param("snapshotCreateTime") Date snapshotCreateTime, @@ -62,7 +62,7 @@ public interface PrcOrderBillMapper /** 按生成账单时用户勾选的订单读取,并再次校验账单筛选条件。 */ public List selectPrcOrderBillByCustomerCutoffAndIds(@Param("customerId") Long customerId, - @Param("customerCode") String customerCode, @Param("orderOrTrackingNo") String orderOrTrackingNo, + @Param("customerCode") String customerCode, @Param("orderIdentifiers") List orderIdentifiers, @Param("cutoffDate") Date cutoffDate, @Param("currency") String currency, @Param("billIds") List billIds, @Param("arBillStatuses") List arBillStatuses, @Param("feeArBillStatus") String feeArBillStatus); diff --git a/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcOrderBillMapper.xml b/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcOrderBillMapper.xml index eaef285d..922afc96 100644 --- a/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcOrderBillMapper.xml +++ b/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcOrderBillMapper.xml @@ -267,17 +267,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + and ( + p.order_no in + + #{identifier} + + or p.tracking_no in + + #{identifier} + + or p.transfer_no in + + #{identifier} + + ) + + +