From e5b8ff5d4ce6b51e2425b4bd89e380d2447ebb23 Mon Sep 17 00:00:00 2001 From: b2894lxlx <517289602@qq.com> Date: Wed, 2 Sep 2026 03:22:22 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E4=B8=9A=E5=8A=A1=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/InvoiceApplicationSaveRequest.java | 2 + .../pojo/entity/InvoiceApplicationLine.java | 2 + .../pojo/entity/PreSettlementDetailFee.java | 5 ++ .../controller/BillLedgerController.java | 13 +++- .../controller/WaybillController.java | 33 ++++++---- .../transport/service/IBillLedgerService.java | 1 + .../transport/service/IWaybillService.java | 1 + .../service/impl/BillLedgerServiceImpl.java | 21 ++++++- .../impl/InvoiceApplicationServiceImpl.java | 45 ++++++++++---- .../impl/LoadingManageServiceImpl.java | 1 + .../service/impl/MasterOrderServiceImpl.java | 17 ++++-- .../impl/PaymentApplicationServiceImpl.java | 28 ++------- .../impl/PreSettlementServiceImpl.java | 13 +++- .../impl/TransportPlanServiceImpl.java | 2 +- .../service/impl/WaybillServiceImpl.java | 17 +++++- .../support/TransportBusinessSupport.java | 23 +++++++ .../wrapper/TransportPlanWrapper.java | 2 + .../blade_invoice_application_20260821.sql | 6 +- ...e_invoice_application_amounts_20260901.sql | 61 +++++++++++++++++++ doc/sql/transport/blade_tms_business.sql | 2 +- ...de_transport_plan_data_source_20260902.sql | 17 ++++++ 21 files changed, 249 insertions(+), 63 deletions(-) create mode 100644 doc/sql/transport/blade_invoice_application_amounts_20260901.sql create mode 100644 doc/sql/transport/blade_transport_plan_data_source_20260902.sql diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationSaveRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationSaveRequest.java index b6b5274..207879c 100644 --- a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationSaveRequest.java +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/InvoiceApplicationSaveRequest.java @@ -74,9 +74,11 @@ public class InvoiceApplicationSaveRequest implements Serializable { private String unit; private BigDecimal quantity; private BigDecimal unitPriceNoTax; + private BigDecimal amountNoTax; private BigDecimal amountWithTax; private BigDecimal taxRate; private BigDecimal taxAmount; + private BigDecimal totalAmount; private String remark; } } diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationLine.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationLine.java index 1615453..30ded9f 100644 --- a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationLine.java +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/InvoiceApplicationLine.java @@ -51,8 +51,10 @@ public class InvoiceApplicationLine extends TenantEntity { private String unit; private BigDecimal quantity; private BigDecimal unitPriceNoTax; + private BigDecimal amountNoTax; private BigDecimal amountWithTax; private BigDecimal taxRate; private BigDecimal taxAmount; + private BigDecimal totalAmount; private String remark; } diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PreSettlementDetailFee.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PreSettlementDetailFee.java index 3d9dc3b..ea2e0da 100644 --- a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PreSettlementDetailFee.java +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/PreSettlementDetailFee.java @@ -9,6 +9,7 @@ */ package org.springblade.transport.pojo.entity; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -65,6 +66,10 @@ public class PreSettlementDetailFee extends TenantEntity { @Schema(description = "费用项JSON") private String feeItemsJson; + @Schema(description = "命中计费规则JSON") + @TableField(exist = false) + private String billingRulesJson; + @Schema(description = "原金额") private BigDecimal originalAmount; diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillLedgerController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillLedgerController.java index c699cdb..24d695c 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillLedgerController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/BillLedgerController.java @@ -65,15 +65,24 @@ public class BillLedgerController extends BladeController { return R.data(billLedgerService.availableOptions(keyword, deptId, selectedId)); } - @PostMapping("/submit") + @GetMapping("/available-page") @ApiOperationSupport(order = 5) + @Operation(summary = "付款申请可用汇票分页") + public R> availablePage(Query pageQuery, + @RequestParam(required = false) String keyword, @RequestParam(required = false) Long deptId, + @RequestParam(required = false) Long selectedId) { + return R.data(billLedgerService.availablePage(Condition.getPage(pageQuery), keyword, deptId, selectedId)); + } + + @PostMapping("/submit") + @ApiOperationSupport(order = 6) @Operation(summary = "新增或编辑汇票台账") public R submit(@RequestBody BillLedgerSaveRequest request) { return R.data(billLedgerService.submit(request)); } @PostMapping("/remove") - @ApiOperationSupport(order = 6) + @ApiOperationSupport(order = 7) @Operation(summary = "删除汇票台账") public R remove(@RequestParam Long id) { billLedgerService.removeLedger(id); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/WaybillController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/WaybillController.java index a21f338..b06c278 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/WaybillController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/WaybillController.java @@ -174,15 +174,22 @@ public class WaybillController extends BladeController { return R.status(waybillService.submit(waybill)); } - @PostMapping("/remove") + @PostMapping("/save-draft") @ApiOperationSupport(order = 10) + @Operation(summary = "保存草稿", description = "传入waybill") + public R saveDraft(@RequestBody Waybill waybill) { + return R.status(waybillService.saveDraft(waybill)); + } + + @PostMapping("/remove") + @ApiOperationSupport(order = 11) @Operation(summary = "逻辑删除", description = "传入ids") public R remove(@Parameter(description = "主键集合", required = true) @RequestParam String ids) { return R.data(waybillService.removeWaybill(ids)); } @GetMapping("/export-waybill-manage") - @ApiOperationSupport(order = 11) + @ApiOperationSupport(order = 12) @Operation(summary = "导出运单管理") public void exportWaybill(WaybillVO waybill, @RequestParam(required = false) String ids, HttpServletResponse response) { List list = waybillService.exportWaybill(waybill, ids); @@ -190,7 +197,7 @@ public class WaybillController extends BladeController { } @PostMapping("/import-waybill-manage") - @ApiOperationSupport(order = 12) + @ApiOperationSupport(order = 13) @Operation(summary = "导入运单管理", description = "传入excel") public R importWaybill(MultipartFile file, HttpServletResponse response) { List failureList = waybillService.importWaybill(ExcelUtil.read(file, WaybillExcel.class)); @@ -202,14 +209,14 @@ public class WaybillController extends BladeController { } @GetMapping("/export-template") - @ApiOperationSupport(order = 13) + @ApiOperationSupport(order = 14) @Operation(summary = "导出模板") public void exportTemplate(HttpServletResponse response) { ExcelUtil.export(response, "运单管理模板", "运单管理导入模板", new ArrayList(), WaybillExcel.class); } @GetMapping("/import-batch/export-template") - @ApiOperationSupport(order = 14) + @ApiOperationSupport(order = 15) @Operation(summary = "导出运单批量导入模板") public void exportImportBatchTemplate(HttpServletResponse response) { ExcelUtil.export( @@ -223,56 +230,56 @@ public class WaybillController extends BladeController { } @PostMapping("/copy") - @ApiOperationSupport(order = 15) + @ApiOperationSupport(order = 16) @Operation(summary = "复制", description = "传入id") public R copy(@Parameter(description = "主键", required = true) @RequestParam Long id) { return R.data(waybillService.copy(id)); } @PostMapping("/change-route") - @ApiOperationSupport(order = 16) + @ApiOperationSupport(order = 17) @Operation(summary = "变更运输路线", description = "传入运单路线与变更记录") public R changeRoute(@RequestBody Waybill waybill) { return R.status(waybillService.changeRoute(waybill)); } @PostMapping("/maintain-mileage") - @ApiOperationSupport(order = 17) + @ApiOperationSupport(order = 18) @Operation(summary = "维护里程", description = "仅已完成且未生成结算单的运单允许维护") public R maintainMileage(@RequestBody WaybillMileageRequest request) { return R.status(waybillService.maintainMileage(request)); } @PostMapping("/cancel") - @ApiOperationSupport(order = 18) + @ApiOperationSupport(order = 19) @Operation(summary = "取消", description = "传入id") public R cancel(@Parameter(description = "主键", required = true) @RequestParam Long id) { return R.status(waybillService.cancel(id)); } @PostMapping("/reassign") - @ApiOperationSupport(order = 19) + @ApiOperationSupport(order = 20) @Operation(summary = "重新派单", description = "传入id") public R reassign(@Parameter(description = "主键", required = true) @RequestParam Long id) { return R.status(waybillService.reassign(id)); } @PostMapping("/complete") - @ApiOperationSupport(order = 20) + @ApiOperationSupport(order = 21) @Operation(summary = "完成", description = "传入id") public R complete(@Parameter(description = "主键", required = true) @RequestParam Long id) { return R.status(waybillService.complete(id)); } @PostMapping("/batch-complete") - @ApiOperationSupport(order = 21) + @ApiOperationSupport(order = 22) @Operation(summary = "批量完成", description = "传入ids") public R batchComplete(@Parameter(description = "主键集合", required = true) @RequestParam String ids) { return R.data(waybillService.batchComplete(ids)); } @PostMapping("/road-loading") - @ApiOperationSupport(order = 22) + @ApiOperationSupport(order = 23) @Operation(summary = "公路配载", description = "传入ids") public R roadLoading(@Parameter(description = "主键集合", required = true) @RequestParam String ids) { return R.data(waybillService.roadLoading(ids)); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillLedgerService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillLedgerService.java index c31abd0..abd6e5d 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillLedgerService.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IBillLedgerService.java @@ -19,6 +19,7 @@ public interface IBillLedgerService extends BaseService { BillLedgerVO detail(Long id); Map expiryCounts(); List availableOptions(String keyword, Long deptId, Long selectedId); + IPage availablePage(IPage page, String keyword, Long deptId, Long selectedId); Long submit(BillLedgerSaveRequest request); void removeLedger(Long id); } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IWaybillService.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IWaybillService.java index 791d1fc..a152079 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IWaybillService.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/IWaybillService.java @@ -43,6 +43,7 @@ public interface IWaybillService extends BaseService { IPage selectWaybillPage(IPage page, WaybillVO waybill); WaybillVO detail(Long id); boolean submit(Waybill waybill); + boolean saveDraft(Waybill waybill); BusinessRemoveResultVO removeWaybill(String ids); List exportWaybill(WaybillVO waybill, String ids); List importWaybill(List data); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillLedgerServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillLedgerServiceImpl.java index 64f7119..0e08c8a 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillLedgerServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/BillLedgerServiceImpl.java @@ -7,6 +7,7 @@ package org.springblade.transport.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.RequiredArgsConstructor; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.base.BaseServiceImpl; @@ -86,6 +87,23 @@ public class BillLedgerServiceImpl extends BaseServiceImpl availableOptions(String keyword, Long deptId, Long selectedId) { + return availableList(keyword, deptId, selectedId); + } + + @Override + public IPage availablePage(IPage page, String keyword, Long deptId, + Long selectedId) { + List available = availableList(keyword, deptId, selectedId); + long current = Math.max(page.getCurrent(), 1); + long size = Math.max(page.getSize(), 1); + long from = Math.min((current - 1) * size, available.size()); + long to = Math.min(from + size, available.size()); + Page result = new Page<>(current, size, available.size()); + result.setRecords(available.subList((int) from, (int) to)); + return result; + } + + private List availableList(String keyword, Long deptId, Long selectedId) { return list(Wrappers.lambdaQuery() .and(Func.isNotEmpty(keyword), wrapper -> wrapper.like(BillLedger::getBillNo, keyword) .or().like(BillLedger::getIssuerName, keyword) @@ -94,8 +112,7 @@ public class BillLedgerServiceImpl extends BaseServiceImpl child.eq(BillLedger::getId, selectedId))) .orderByAsc(BillLedger::getMaturityDate) - .orderByDesc(BillLedger::getCreateTime) - .last("limit 200")).stream() + .orderByDesc(BillLedger::getCreateTime)).stream() .filter(item -> selectedId != null && Objects.equals(item.getId(), selectedId) || departmentAvailable(item, deptId)) .map(item -> BillLedgerWrapper.build().entityVO(item)) diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java index b3edd8c..b787034 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/InvoiceApplicationServiceImpl.java @@ -47,6 +47,7 @@ import org.springblade.transport.mapper.InvoiceApplicationMapper; import org.springblade.transport.mapper.InvoiceApplicationRecordMapper; import org.springblade.transport.mapper.InvoiceApplicationSettlementMapper; import org.springblade.transport.mapper.InvoiceApplicationSheetMapper; +import org.springblade.transport.mapper.WaybillMapper; import org.springblade.transport.pojo.dto.InvoiceApplicationSaveRequest; import org.springblade.transport.pojo.dto.InvoiceApplicationStatusRequest; import org.springblade.transport.pojo.entity.CustomerArchive; @@ -61,6 +62,7 @@ import org.springblade.transport.pojo.entity.InvoiceApplicationLine; import org.springblade.transport.pojo.entity.InvoiceApplicationRecord; import org.springblade.transport.pojo.entity.InvoiceApplicationSettlement; import org.springblade.transport.pojo.entity.InvoiceApplicationSheet; +import org.springblade.transport.pojo.entity.Waybill; import org.springblade.transport.pojo.vo.InvoiceApplicationSheetVO; import org.springblade.transport.pojo.vo.InvoiceApplicationVO; import org.springblade.transport.service.IInvoiceApplicationService; @@ -100,6 +102,7 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl ids = distinctIds(settlementIds); if (ids.isEmpty()) return List.of(); assertCompatible(ids.stream().map(this::availableSettlement).toList()); - return formalSettlementDetailMapper.selectList(Wrappers.lambdaQuery() - .in(FormalSettlementDetail::getFormalSettlementId, ids).orderByAsc(FormalSettlementDetail::getLineNo)); + List details = formalSettlementDetailMapper.selectList( + Wrappers.lambdaQuery() + .in(FormalSettlementDetail::getFormalSettlementId, ids) + .orderByAsc(FormalSettlementDetail::getLineNo)); + List waybillIds = details.stream().map(FormalSettlementDetail::getWaybillId) + .filter(Objects::nonNull).distinct().toList(); + if (!waybillIds.isEmpty()) { + Map waybillMap = waybillMapper.selectBatchIds(waybillIds).stream() + .collect(Collectors.toMap(Waybill::getId, Function.identity(), (first, duplicate) -> first)); + details.forEach(detail -> { + Waybill waybill = waybillMap.get(detail.getWaybillId()); + if (waybill == null) return; + if (waybill.getStartDate() != null) detail.setActualDepartureTime(waybill.getStartDate().atStartOfDay()); + if (waybill.getEndDate() != null) detail.setActualCompletionTime(waybill.getEndDate().atStartOfDay()); + }); + } + return details; } @Override @@ -455,14 +473,21 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl 0) throw new ServiceException("税率必须在0-100之间"); - line.setTaxAmount(calculateTax(amount, taxRate)); + BigDecimal taxAmount = calculateTax(amountNoTax, taxRate); + BigDecimal totalAmount = amountNoTax.add(taxAmount).setScale(2, RoundingMode.HALF_UP); + line.setAmountNoTax(amountNoTax); + line.setTaxAmount(taxAmount); + line.setTotalAmount(totalAmount); + line.setAmountWithTax(totalAmount); line.setRemark(limit(line.getRemark(), 200, "商品行备注")); - total = total.add(amount); + total = total.add(totalAmount); } } return total.setScale(2, RoundingMode.HALF_UP); @@ -534,7 +559,7 @@ public class InvoiceApplicationServiceImpl extends BaseServiceImpl { + waybill.setEndDate(LocalDate.now()); + waybillService.updateById(waybill); + }); receivablePayableDetailService.generateForClosedMasterOrder(masterOrder); } return updated; @@ -369,8 +373,7 @@ public class MasterOrderServiceImpl extends BaseServiceImpl files)) return false; - return files.stream().anyMatch(file -> file instanceof Map fields - && (attachmentType == null || Objects.equals(attachmentType, fields.get("attachmentType"))) - && List.of("url", "link", "fileUrl", "downloadUrl", "src", "domain").stream() - .anyMatch(key -> Func.isNotEmpty(fields.get(key)))); - } catch (Exception exception) { - return false; + if (!"承运商合同".equals(contract.getContractCategory())) { + throw new ServiceException("付款申请只能选择承运商合同"); } } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PreSettlementServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PreSettlementServiceImpl.java index ff45ce7..0cc9081 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PreSettlementServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/PreSettlementServiceImpl.java @@ -235,6 +235,7 @@ public class PreSettlementServiceImpl extends BaseServiceImpllambdaQuery() + List fees = detailFeeMapper.selectList(Wrappers.lambdaQuery() .eq(PreSettlementDetailFee::getPreSettlementDetailId, detailId) .eq(PreSettlementDetailFee::getIsDeleted, 0) .orderByAsc(PreSettlementDetailFee::getCreateTime)); + List sourceFeeIds = fees.stream().map(PreSettlementDetailFee::getSourceFeeId) + .filter(Objects::nonNull).toList(); + if (sourceFeeIds.isEmpty()) return fees; + Map sourceFeeMap = sourceFeeMapper.selectBatchIds(sourceFeeIds).stream() + .collect(Collectors.toMap(ReceivablePayableCargoFee::getId, Function.identity(), (left, right) -> left)); + fees.forEach(fee -> { + ReceivablePayableCargoFee sourceFee = sourceFeeMap.get(fee.getSourceFeeId()); + if (sourceFee != null) fee.setBillingRulesJson(sourceFee.getBillingRulesJson()); + }); + return fees; } @Override diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/TransportPlanServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/TransportPlanServiceImpl.java index 5deb1a5..856c3d0 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/TransportPlanServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/TransportPlanServiceImpl.java @@ -462,7 +462,7 @@ public class TransportPlanServiceImpl extends BaseServiceImpl @Override @Transactional(rollbackFor = Exception.class) public boolean submit(Waybill waybill) { + prepareForSave(waybill); + validate(waybill); + return saveOrUpdate(waybill); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean saveDraft(Waybill waybill) { + prepareForSave(waybill); + waybill.setBusinessStatus(STATUS_DRAFT); + return saveOrUpdate(waybill); + } + + private void prepareForSave(Waybill waybill) { boolean created = Func.isEmpty(waybill.getId()); if (!created) { Waybill oldRecord = loadEditable(waybill.getId(), true); @@ -124,8 +138,6 @@ public class WaybillServiceImpl extends BaseServiceImpl if (created && Func.isEmpty(waybill.getWaybillNo())) { waybill.setWaybillNo(nextCode()); } - validate(waybill); - return saveOrUpdate(waybill); } private void fillProjectProcessConfig(Waybill waybill) { @@ -372,6 +384,7 @@ public class WaybillServiceImpl extends BaseServiceImpl throw new ServiceException("当前状态不允许完成"); } waybill.setBusinessStatus("completed"); + waybill.setEndDate(LocalDate.now()); boolean updated = updateById(waybill); if (updated) { receivablePayableDetailService.generateForCompletedWaybills(List.of(waybill.getId())); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/TransportBusinessSupport.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/TransportBusinessSupport.java index 4ccfe8c..54bf8eb 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/support/TransportBusinessSupport.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/support/TransportBusinessSupport.java @@ -41,6 +41,10 @@ import java.util.regex.Pattern; */ public final class TransportBusinessSupport { + public static final String DATA_SOURCE_BATCH_IMPORT = "批量导入"; + public static final String DATA_SOURCE_MANUAL = "手工创建"; + public static final String DATA_SOURCE_EXTERNAL = "外部系统"; + private static final Pattern PHONE_PATTERN = Pattern.compile("^(1\\d{10}|0\\d{2,3}-?\\d{7,8})$"); private static final BigDecimal MIN_LONGITUDE = new BigDecimal("-180"); private static final BigDecimal MAX_LONGITUDE = new BigDecimal("180"); @@ -87,6 +91,25 @@ public final class TransportBusinessSupport { return trimValue.isEmpty() ? null : trimValue; } + /** + * 归一化运输计划数据来源,保证列表只出现约定的三种来源。 + * + * @param value 原始数据来源 + * @return 批量导入、手工创建或外部系统 + */ + public static String normalizeTransportPlanDataSource(String value) { + String source = trimToNull(value); + if (Func.isEmpty(source)) { + return DATA_SOURCE_MANUAL; + } + return switch (source) { + case DATA_SOURCE_BATCH_IMPORT -> DATA_SOURCE_BATCH_IMPORT; + case DATA_SOURCE_MANUAL, "手动创建", "手动录入", "手工录入", "手动", "模板生成", "计划调度", "多联总单调度" -> DATA_SOURCE_MANUAL; + case DATA_SOURCE_EXTERNAL -> DATA_SOURCE_EXTERNAL; + default -> DATA_SOURCE_EXTERNAL; + }; + } + public static void validateRequired(String value, String message) { if (Func.isEmpty(trimToNull(value))) { throw new ServiceException(message); diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/TransportPlanWrapper.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/TransportPlanWrapper.java index 4f91630..4dbbad9 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/TransportPlanWrapper.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/wrapper/TransportPlanWrapper.java @@ -29,6 +29,7 @@ import org.springblade.core.tool.utils.Func; import org.springblade.system.cache.UserCache; import org.springblade.transport.pojo.entity.TransportPlan; import org.springblade.transport.pojo.vo.TransportPlanVO; +import org.springblade.transport.support.TransportBusinessSupport; import java.util.Objects; @@ -48,6 +49,7 @@ public class TransportPlanWrapper extends BaseEntityWrapper 0, + 'ALTER TABLE `blade_invoice_application_line` MODIFY COLUMN `unit_price_no_tax` decimal(18,2) DEFAULT NULL', + 'SELECT 1' + ) + FROM information_schema.columns + WHERE table_schema = @invoice_line_schema + AND table_name = 'blade_invoice_application_line' + AND column_name = 'unit_price_no_tax' + AND (numeric_precision <> 18 OR numeric_scale <> 2) +); +PREPARE invoice_line_stmt FROM @invoice_line_sql; +EXECUTE invoice_line_stmt; +DEALLOCATE PREPARE invoice_line_stmt; + +SET @invoice_line_sql = ( + SELECT IF( + COUNT(*) = 0, + 'ALTER TABLE `blade_invoice_application_line` ADD COLUMN `amount_no_tax` decimal(18,2) NOT NULL DEFAULT ''0.00'' COMMENT ''不含税金额'' AFTER `unit_price_no_tax`', + 'SELECT 1' + ) + FROM information_schema.columns + WHERE table_schema = @invoice_line_schema + AND table_name = 'blade_invoice_application_line' + AND column_name = 'amount_no_tax' +); +PREPARE invoice_line_stmt FROM @invoice_line_sql; +EXECUTE invoice_line_stmt; +DEALLOCATE PREPARE invoice_line_stmt; + +SET @invoice_line_sql = ( + SELECT IF( + COUNT(*) = 0, + 'ALTER TABLE `blade_invoice_application_line` ADD COLUMN `total_amount` decimal(18,2) NOT NULL DEFAULT ''0.00'' COMMENT ''含税合计'' AFTER `tax_amount`', + 'SELECT 1' + ) + FROM information_schema.columns + WHERE table_schema = @invoice_line_schema + AND table_name = 'blade_invoice_application_line' + AND column_name = 'total_amount' +); +PREPARE invoice_line_stmt FROM @invoice_line_sql; +EXECUTE invoice_line_stmt; +DEALLOCATE PREPARE invoice_line_stmt; + +UPDATE `blade_invoice_application_line` +SET `amount_no_tax` = ROUND( + `amount_with_tax` / (1 + `tax_rate` / 100), + 2 +) +WHERE `amount_no_tax` = 0 + AND `amount_with_tax` > 0; + +UPDATE `blade_invoice_application_line` +SET `total_amount` = ROUND(`amount_no_tax` + `tax_amount`, 2), + `amount_with_tax` = ROUND(`amount_no_tax` + `tax_amount`, 2); diff --git a/doc/sql/transport/blade_tms_business.sql b/doc/sql/transport/blade_tms_business.sql index 92632b8..2c9d133 100644 --- a/doc/sql/transport/blade_tms_business.sql +++ b/doc/sql/transport/blade_tms_business.sql @@ -196,7 +196,7 @@ CREATE TABLE `blade_transport_plan` ( `goods_json` text DEFAULT NULL COMMENT '货物信息', `freight_json` text DEFAULT NULL COMMENT '费用信息', `attachments_json` text DEFAULT NULL COMMENT '附件', - `data_source` varchar(100) DEFAULT NULL COMMENT '数据来源', + `data_source` varchar(100) DEFAULT '手工创建' COMMENT '数据来源', `business_status` varchar(100) DEFAULT NULL COMMENT '业务状态', `dispatcher_user_id` bigint(20) DEFAULT NULL COMMENT '调度人ID', `dispatcher_user_name` varchar(100) DEFAULT NULL COMMENT '调度人姓名', diff --git a/doc/sql/transport/blade_transport_plan_data_source_20260902.sql b/doc/sql/transport/blade_transport_plan_data_source_20260902.sql new file mode 100644 index 0000000..4a2421b --- /dev/null +++ b/doc/sql/transport/blade_transport_plan_data_source_20260902.sql @@ -0,0 +1,17 @@ +-- 运输计划数据来源统一为:批量导入、手工创建、外部系统 +ALTER TABLE `blade_transport_plan` + MODIFY COLUMN `data_source` varchar(100) DEFAULT '手工创建' COMMENT '数据来源'; + +UPDATE `blade_transport_plan` +SET `data_source` = CASE + WHEN TRIM(COALESCE(`data_source`, '')) = '批量导入' THEN '批量导入' + WHEN TRIM(COALESCE(`data_source`, '')) IN ( + '手工创建', '手动创建', '手动录入', '手工录入', '手动', + '模板生成', '计划调度', '多联总单调度' + ) THEN '手工创建' + WHEN TRIM(COALESCE(`data_source`, '')) = '外部系统' THEN '外部系统' + ELSE '外部系统' +END +WHERE `data_source` IS NULL + OR TRIM(`data_source`) = '' + OR TRIM(`data_source`) NOT IN ('批量导入', '手工创建', '外部系统');