✨ 应收账单预览支持大批量单号查询

This commit is contained in:
caojia
2026-10-16 11:02:37 +08:00
parent 132688b9cf
commit 760e3807f3
4 changed files with 41 additions and 6 deletions
@@ -6,6 +6,7 @@ import java.util.Date;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.WebDataBinder;
@@ -120,10 +121,10 @@ public class ArBillController extends BaseController {
* 查询生成账单前的订单计费结果。
*/
@PreAuthorize("@ss.hasPermi('ar:bill:generate')")
@GetMapping("/generate/preview")
public AjaxResult preview(ArBillGenerateQuery query, HttpServletRequest request) {
rejectMultiValueParameter(request, "customerId");
startPage();
@PostMapping("/generate/preview")
public AjaxResult preview(@RequestBody ArBillGenerateQuery query) {
PageHelper.startPage(query == null || query.getPageNum() == null ? 1 : query.getPageNum(),
query == null || query.getPageSize() == null ? 10 : query.getPageSize()).setReasonable(true);
List<PrcOrderBill> list = billService.previewBill(query);
TableDataInfo pageData = getDataTable(list);
AjaxResult result = success();
@@ -1,6 +1,9 @@
package com.bms.ar.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.bms.common.config.serializer.StrictDateDeserializer;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.Data;
@@ -8,11 +11,17 @@ import lombok.Data;
@Data
public class ArBillGenerateQuery
{
private Integer pageNum;
private Integer pageSize;
private Long customerId;
private String customerCode;
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonDeserialize(using = StrictDateDeserializer.class)
private Date billPeriodEnd;
private String currency;
@@ -135,7 +135,10 @@ 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;
private static final int ORDER_IDENTIFIER_LIMIT = 20000;
/** 订单号会分别匹配订单号、运单号和转单号列;预留其他 SQL 参数空间后控制 MySQL 参数总数。 */
private static final int ORDER_IDENTIFIER_SQL_BIND_COUNT = 3;
private static final int MAX_SQL_PARAMETER_COUNT = 65000;
/**
* 模板明细行使用的边框、字体和换行样式;样式定义来自 ar_bill_template.xlsx。
*/
@@ -351,6 +354,9 @@ public class ArBillServiceImpl implements IArBillService {
throw new ServiceException("全选模式最多排除 " + EXCLUDED_SOURCE_ID_LIMIT
+ " 条订单,请缩小查询条件后再生成");
}
validateOrderIdentifierParameterCount(
normalizeOrderIdentifiers(request.getOrderOrTrackingNo()).size(),
allMatched ? excludedSourceBillIds.size() : sourceBillIds.size());
request.setSelectionMode(selectionMode);
String currency = StringUtils.isEmpty(request.getCurrency()) ? "CNY" : request.getCurrency().trim();
@@ -1990,6 +1996,12 @@ public class ArBillServiceImpl implements IArBillService {
|| query.getBillPeriodEnd() == null) {
throw new ServiceException("客户和账单截止日不能为空");
}
int identifierCount = normalizeOrderIdentifiers(query.getOrderOrTrackingNo()).size()
+ normalizeOrderIdentifiers(query.getExcludeOrderOrTrackingNo()).size();
if (identifierCount > ORDER_IDENTIFIER_LIMIT) {
throw new ServiceException("筛选单号和排除单号合计最多输入 " + ORDER_IDENTIFIER_LIMIT + " 个");
}
validateOrderIdentifierParameterCount(identifierCount, 0);
}
/** 可参与本次应收生成的订单状态;PARTIAL 只生成其中仍为 UNBILLED 的费用。 */
@@ -2041,6 +2053,14 @@ public class ArBillServiceImpl implements IArBillService {
return new ArrayList<>(uniqueIdentifiers);
}
/** 校验重复用于三列精确匹配的单号参数及选择/排除订单 ID 不会超过数据库参数预算。 */
private void validateOrderIdentifierParameterCount(int orderIdentifierCount, int billIdCount) {
long parameterCount = (long) orderIdentifierCount * ORDER_IDENTIFIER_SQL_BIND_COUNT + billIdCount;
if (parameterCount > MAX_SQL_PARAMETER_COUNT) {
throw new ServiceException("单号筛选与订单选择/排除条件过多,请减少单号或选择/排除订单数量后重试");
}
}
private long elapsedMillis(long startedAt) {
return (System.nanoTime() - startedAt) / 1_000_000L;
}
+6 -1
View File
@@ -42,7 +42,12 @@ export function retryArBillGenerateTask(taskId) {
}
export function previewArBill(query) {
return request({ url: '/ar/bill/generate/preview', method: 'get', params: query })
return request({
url: '/ar/bill/generate/preview',
method: 'post',
data: query,
timeout: 60000
})
}
export function confirmArBill(arBillId, data = {}) {