diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ProjectApply.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ProjectApply.java index 5526da8e..eb85e2c4 100644 --- a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ProjectApply.java +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/entity/ProjectApply.java @@ -70,10 +70,10 @@ public class ProjectApply extends TenantEntity { @Schema(description = "业务部门") private String businessDeptName; - @Schema(description = "承办部门ID") - private Long undertakeDeptId; + @Schema(description = "平台公司ID,多个逗号分隔") + private String undertakeDeptId; - @Schema(description = "承办部门") + @Schema(description = "平台公司,多个顿号分隔") private String undertakeDeptName; @Schema(description = "项目由来") diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ProjectApplyServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ProjectApplyServiceImpl.java index deb2065f..d0f06ea8 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ProjectApplyServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ProjectApplyServiceImpl.java @@ -338,19 +338,23 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl queryWrapper = Wrappers.lambdaQuery().eq(ProjectApply::getIsDeleted, 0); if (TransportBusinessSupport.isAdministrator()) { - // 超管默认可查看全部未删除数据;仅在明确指定承办组织时按组织精确筛选。 + // 超管默认可查看全部未删除数据;仅在明确指定平台公司时按包含匹配筛选。 if (Objects.equals(projectApply.getAllDept(), 1) && Func.isNotEmpty(projectApply.getUndertakeDeptId())) { - queryWrapper.eq(ProjectApply::getUndertakeDeptId, projectApply.getUndertakeDeptId()); + applyUndertakeDeptContains(queryWrapper, projectApply.getUndertakeDeptId()); } } else if (!Objects.equals(projectApply.getAllDept(), 1)) { Long currentDeptId = TransportBusinessSupport.currentDeptId("项目立项"); Long currentUserId = AuthUtil.getUserId(); - queryWrapper.and(wrapper -> wrapper.eq(ProjectApply::getUndertakeDeptId, currentDeptId) - .or().eq(ProjectApply::getCreateUser, currentUserId) - .or().eq(ProjectApply::getHandlerUserId, currentUserId) - .or().eq(ProjectApply::getPrincipalUserId, currentUserId)); + queryWrapper.and(wrapper -> { + if (currentDeptId != null) { + wrapper.apply("FIND_IN_SET({0}, IFNULL(undertake_dept_id,''))", String.valueOf(currentDeptId)); + } + wrapper.or().eq(ProjectApply::getCreateUser, currentUserId) + .or().eq(ProjectApply::getHandlerUserId, currentUserId) + .or().eq(ProjectApply::getPrincipalUserId, currentUserId); + }); } else if (Func.isNotEmpty(projectApply.getUndertakeDeptId())) { - queryWrapper.eq(ProjectApply::getUndertakeDeptId, projectApply.getUndertakeDeptId()); + applyUndertakeDeptContains(queryWrapper, projectApply.getUndertakeDeptId()); } queryWrapper.like(Func.isNotEmpty(projectApply.getApplyNo()), ProjectApply::getApplyNo, projectApply.getApplyNo()) .like(Func.isNotEmpty(projectApply.getProjectCode()), ProjectApply::getProjectCode, projectApply.getProjectCode()) @@ -464,6 +468,7 @@ public class ProjectApplyServiceImpl extends BaseServiceImpl queryWrapper, String undertakeDeptId) { + if (Func.isBlank(undertakeDeptId) || queryWrapper == null) { + return; + } + List deptIds = Arrays.stream(undertakeDeptId.split("[,,]")) + .map(String::trim) + .filter(Func::isNotEmpty) + .distinct() + .toList(); + if (deptIds.isEmpty()) { + return; + } + queryWrapper.and(wrapper -> { + boolean first = true; + for (String deptId : deptIds) { + if (first) { + wrapper.apply("FIND_IN_SET({0}, IFNULL(undertake_dept_id,''))", deptId); + first = false; + } else { + wrapper.or().apply("FIND_IN_SET({0}, IFNULL(undertake_dept_id,''))", deptId); + } + } + }); + } + + private void normalizeUndertakeDept(ProjectApply projectApply) { + if (projectApply == null) { + return; + } + List deptIds = Arrays.stream(Func.toStr(projectApply.getUndertakeDeptId()).split("[,,]")) + .map(String::trim) + .filter(Func::isNotEmpty) + .filter(id -> !"-1".equals(id)) + .distinct() + .toList(); + projectApply.setUndertakeDeptId(deptIds.isEmpty() ? null : String.join(",", deptIds)); + List deptNames = Arrays.stream(Func.toStr(projectApply.getUndertakeDeptName()).split("[,,、]")) + .map(String::trim) + .filter(Func::isNotEmpty) + .distinct() + .toList(); + projectApply.setUndertakeDeptName(deptNames.isEmpty() ? null : String.join("、", deptNames)); + } + + private Long firstUndertakeDeptId(String undertakeDeptId) { + return Arrays.stream(Func.toStr(undertakeDeptId).split("[,,]")) + .map(String::trim) + .filter(Func::isNotEmpty) + .filter(id -> !"-1".equals(id)) + .map(Func::toLong) + .filter(id -> id != null && id > 0L) + .findFirst() + .orElse(null); + } + + private String firstUndertakeDeptName(String undertakeDeptName) { + return Arrays.stream(Func.toStr(undertakeDeptName).split("[,,、]")) + .map(String::trim) + .filter(Func::isNotEmpty) + .findFirst() + .orElse(null); + } + + private boolean containsUndertakeDept(String undertakeDeptId, Long deptId) { + if (deptId == null || Func.isBlank(undertakeDeptId)) { + return false; + } + String target = String.valueOf(deptId); + return Arrays.stream(undertakeDeptId.split("[,,]")) + .map(String::trim) + .anyMatch(target::equals); + } + } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceivablePayableDetailServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceivablePayableDetailServiceImpl.java index c26eeff0..69e2b6cb 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceivablePayableDetailServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/ReceivablePayableDetailServiceImpl.java @@ -3037,6 +3037,11 @@ public class ReceivablePayableDetailServiceImpl } private String formatQuantity(BigDecimal quantity, String unit) { + // 无有效运输量(空/0/-1)时不展示数值与单位 + if (quantity == null || quantity.compareTo(BigDecimal.ZERO) == 0 + || quantity.compareTo(BigDecimal.valueOf(-1)) == 0) { + return "-"; + } return money(quantity).stripTrailingZeros().toPlainString() + (unit == null ? "" : " " + unit); } diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillImportBatchServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillImportBatchServiceImpl.java index 1a585643..5a40decd 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillImportBatchServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillImportBatchServiceImpl.java @@ -342,10 +342,11 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl queryWrapper, Long carrierId) { + Long normalizedCarrierId = normalizeOptionalId(carrierId); + if (normalizedCarrierId == null) { + return; + } + CustomerArchive carrier = customerArchiveService.getById(normalizedCarrierId); + String carrierName = carrier == null ? null : Func.toStr(carrier.getFullName()).trim(); + queryWrapper.and(wrapper -> { + wrapper.apply("FIND_IN_SET({0}, IFNULL(carrier_ids,''))", String.valueOf(normalizedCarrierId)); + if (Func.isNotEmpty(carrierName)) { + wrapper.or().eq(WaybillImportBatch::getCarrierName, carrierName); + } + }); + } + @Override @Transactional(rollbackFor = Exception.class) public BusinessRemoveResultVO removeBatches(String ids) { @@ -405,8 +424,9 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl carrierIds = resolveCarrierIds(request); + batch.setCarrierIds(joinIds(carrierIds)); + batch.setCarrierName(resolveCarrierNames(carrierIds, request.getCarrierName())); batch.setImportStatus(importStatus); batch.setImportType(IMPORT_TYPE_SETTLEMENT.equals(request.getImportType()) ? IMPORT_TYPE_SETTLEMENT : IMPORT_TYPE_WAYBILL); ProjectApply project = projectApplyService.getById(request.getProjectId()); @@ -586,6 +606,38 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl resolveCarrierIds(WaybillImportBatchRequest request) { + if (request == null) { + return List.of(); + } + List carrierIds = Func.isEmpty(request.getCarrierIds()) + ? new ArrayList<>() + : request.getCarrierIds().stream() + .map(this::normalizeOptionalId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toCollection(ArrayList::new)); + if (Func.isNotEmpty(carrierIds)) { + return carrierIds; + } + Long carrierId = normalizeOptionalId(request.getCarrierId()); + if (carrierId != null) { + return List.of(carrierId); + } + String carrierName = Func.toStr(request.getCarrierName()).trim(); + if (Func.isEmpty(carrierName)) { + return List.of(); + } + CustomerArchive carrier = customerArchiveService.getOne(Wrappers.lambdaQuery() + .eq(CustomerArchive::getFullName, carrierName) + .eq(CustomerArchive::getIsDeleted, 0) + .last("limit 1")); + return carrier == null || carrier.getId() == null ? List.of() : List.of(carrier.getId()); + } + private String resolveCarrierNames(List carrierIds, String carrierName) { if (Func.isNotEmpty(carrierName)) return carrierName; if (Func.isEmpty(carrierIds)) return null; diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillServiceImpl.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillServiceImpl.java index 64c4837e..c850d180 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillServiceImpl.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/service/impl/WaybillServiceImpl.java @@ -1344,21 +1344,15 @@ public class WaybillServiceImpl extends BaseServiceImpl target.setFreightJson(source.getFreightJson()); target.setAttachmentsJson(source.getAttachmentsJson()); target.setRemark(source.getRemark()); - // 复制后业务状态与原运单保持一致 - String sourceBusinessStatus = source.getBusinessStatus(); - target.setBusinessStatus(sourceBusinessStatus); + // 复制新建固定为草稿,不沿用原运单业务状态 + target.setBusinessStatus(STATUS_DRAFT); target.setWaybillNo(nextCode()); clearDriverAcceptRecord(target); fillProjectProcessConfig(target); prepare(target); - applyDriverAcceptBusinessStatus(target); - if (Func.isNotEmpty(sourceBusinessStatus)) { - target.setBusinessStatus(sourceBusinessStatus); - } + target.setBusinessStatus(STATUS_DRAFT); validate(target); save(target); - // 原运单已完成时,复制后按合同系统计费规则生成应收应付明细 - generateReceivablePayableIfCompleted(target); return detail(target.getId()); } diff --git a/doc/sql/transport/blade_project_apply_undertake_dept_multi_20261014.sql b/doc/sql/transport/blade_project_apply_undertake_dept_multi_20261014.sql new file mode 100644 index 00000000..b2d5d222 --- /dev/null +++ b/doc/sql/transport/blade_project_apply_undertake_dept_multi_20261014.sql @@ -0,0 +1,4 @@ +-- 平台公司支持多选:ID 逗号分隔,名称顿号分隔 +ALTER TABLE `blade_project_apply` + MODIFY COLUMN `undertake_dept_id` varchar(500) DEFAULT NULL COMMENT '平台公司ID,多个逗号分隔', + MODIFY COLUMN `undertake_dept_name` varchar(500) DEFAULT NULL COMMENT '平台公司,多个顿号分隔'; diff --git a/doc/sql/transport/blade_project_contract_management.sql b/doc/sql/transport/blade_project_contract_management.sql index b2208fbf..59890b1b 100644 --- a/doc/sql/transport/blade_project_contract_management.sql +++ b/doc/sql/transport/blade_project_contract_management.sql @@ -18,8 +18,8 @@ CREATE TABLE `blade_project_apply` ( `project_type` varchar(50) DEFAULT NULL COMMENT '项目类型', `business_dept_id` bigint(20) DEFAULT NULL COMMENT '业务部门ID', `business_dept_name` varchar(100) DEFAULT NULL COMMENT '业务部门', - `undertake_dept_id` bigint(20) DEFAULT NULL COMMENT '承办部门ID', - `undertake_dept_name` varchar(100) DEFAULT NULL COMMENT '承办部门', + `undertake_dept_id` varchar(500) DEFAULT NULL COMMENT '平台公司ID,多个逗号分隔', + `undertake_dept_name` varchar(500) DEFAULT NULL COMMENT '平台公司,多个顿号分隔', `project_source` varchar(50) DEFAULT NULL COMMENT '项目由来', `source_remark` varchar(500) DEFAULT NULL COMMENT '项目由来说明', `fund_limit` decimal(18,2) DEFAULT NULL COMMENT '项目资金使用额度(万元)', @@ -80,8 +80,8 @@ CREATE TABLE `blade_temporary_credit_limit` ( `project_id` bigint(20) DEFAULT NULL COMMENT '项目ID', `project_code` varchar(100) DEFAULT NULL COMMENT '项目编号', `project_name` varchar(100) DEFAULT NULL COMMENT '项目名称', - `undertake_dept_id` bigint(20) DEFAULT NULL COMMENT '承办部门ID', - `undertake_dept_name` varchar(100) DEFAULT NULL COMMENT '承办部门', + `undertake_dept_id` varchar(500) DEFAULT NULL COMMENT '平台公司ID,多个逗号分隔', + `undertake_dept_name` varchar(500) DEFAULT NULL COMMENT '平台公司,多个顿号分隔', `project_fund_limit` decimal(18,2) DEFAULT NULL COMMENT '项目资金使用额度(万元)', `used_fund_limit` decimal(18,2) DEFAULT NULL COMMENT '已使用项目资金额度(万元)', `remaining_fund_limit` decimal(18,2) DEFAULT NULL COMMENT '剩余项目资金使用额度(万元)',