From 68fede2caf3da946f5053fd8786108541c00b423 Mon Sep 17 00:00:00 2001 From: b2894lxlx <517289602@qq.com> Date: Sat, 10 Oct 2026 16:20:21 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20=E5=AE=8C=E5=96=84=E6=B8=AF=E5=8F=A3?= =?UTF-8?q?=E7=A0=81=E5=A4=B4/=E9=93=81=E8=B7=AF=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E5=8E=9F=E5=9B=A0=E4=B8=8E=E8=BD=AF=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E6=81=A2=E5=A4=8D=EF=BC=8C=E5=B9=B6=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=BF=90=E5=8D=95=E5=AF=BC=E5=85=A5=E5=88=97=E8=A1=A8=E7=AD=9B?= =?UTF-8?q?=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .../pojo/dto/WaybillImportBatchRequest.java | 6 + .../system/mapper/RailwayStationMapper.java | 5 + .../system/mapper/RailwayStationMapper.xml | 8 + .../service/impl/PortTerminalServiceImpl.java | 247 ++++++++++++++---- .../impl/RailwayStationServiceImpl.java | 13 +- .../controller/WaybillController.java | 28 +- .../impl/WaybillImportBatchServiceImpl.java | 9 + 7 files changed, 260 insertions(+), 56 deletions(-) diff --git a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/WaybillImportBatchRequest.java b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/WaybillImportBatchRequest.java index e445395e..717766fa 100644 --- a/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/WaybillImportBatchRequest.java +++ b/blade-service-api/blade-transport-api/src/main/java/org/springblade/transport/pojo/dto/WaybillImportBatchRequest.java @@ -32,6 +32,12 @@ public class WaybillImportBatchRequest { private Long planId; private String planName; private String remark; + /** 列表筛选:创建人 */ + private Long createUser; + /** 列表筛选:创建时间起(yyyy-MM-dd HH:mm:ss) */ + private String createTimeStart; + /** 列表筛选:创建时间止(yyyy-MM-dd HH:mm:ss) */ + private String createTimeEnd; private List> rows; /** 分批确认导入时,是否追加到已有批次(首批为 false,后续批为 true)。 */ private Boolean append; diff --git a/blade-service/blade-system/src/main/java/org/springblade/system/mapper/RailwayStationMapper.java b/blade-service/blade-system/src/main/java/org/springblade/system/mapper/RailwayStationMapper.java index f06997f6..69c8c24e 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/system/mapper/RailwayStationMapper.java +++ b/blade-service/blade-system/src/main/java/org/springblade/system/mapper/RailwayStationMapper.java @@ -45,6 +45,11 @@ public interface RailwayStationMapper extends BaseMapper { */ RailwayStation selectByCodeIncludingDeleted(@Param("code") String code); + /** + * 按 TMIS 国标编码查询铁路车站(包含逻辑删除记录,用于导入恢复)。 + */ + RailwayStation selectByTmisCodeIncludingDeleted(@Param("tmisCode") String tmisCode); + /** * 恢复逻辑删除铁路车站。 */ diff --git a/blade-service/blade-system/src/main/java/org/springblade/system/mapper/RailwayStationMapper.xml b/blade-service/blade-system/src/main/java/org/springblade/system/mapper/RailwayStationMapper.xml index 54d82bde..72d99a14 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/system/mapper/RailwayStationMapper.xml +++ b/blade-service/blade-system/src/main/java/org/springblade/system/mapper/RailwayStationMapper.xml @@ -36,6 +36,14 @@ SELECT * FROM blade_railway_station WHERE code = #{code} + LIMIT 1 + + + diff --git a/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/PortTerminalServiceImpl.java b/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/PortTerminalServiceImpl.java index 8e96be1d..a9f3fc1c 100644 --- a/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/PortTerminalServiceImpl.java +++ b/blade-service/blade-system/src/main/java/org/springblade/system/service/impl/PortTerminalServiceImpl.java @@ -29,7 +29,8 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.base.BaseServiceImpl; import org.springblade.core.tool.utils.BeanUtil; @@ -44,6 +45,7 @@ import org.springblade.system.pojo.entity.Region; import org.springblade.system.pojo.vo.PortTerminalVO; import org.springblade.system.service.IPortTerminalService; import org.springblade.system.service.IRegionService; +import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -66,8 +68,9 @@ import java.util.regex.Pattern; * * @author Chill */ +@Slf4j @Service -@AllArgsConstructor +@RequiredArgsConstructor public class PortTerminalServiceImpl extends BaseServiceImpl implements IPortTerminalService { private static final String CATEGORY_PORT = "港口"; @@ -76,8 +79,12 @@ public class PortTerminalServiceImpl extends BaseServiceImpl T findCause(Throwable throwable, Class type) { + for (Throwable current = throwable; current != null; current = current.getCause()) { + if (type.isInstance(current)) { + return type.cast(current); + } + if (current.getCause() == current) { + break; + } + } + return null; + } + + private Throwable rootCause(Throwable throwable) { + Throwable root = throwable; + while (root.getCause() != null && root.getCause() != root) { + root = root.getCause(); + } + return root; + } + + private String shortenMessage(String message) { + String value = trimToEmpty(message); + return value.length() > 200 ? value.substring(0, 200) + "..." : value; } @Override @@ -370,6 +441,26 @@ public class PortTerminalServiceImpl extends BaseServiceImpl cityList = regionService.list(Wrappers.lambdaQuery() - .eq(Region::getName, portTerminal.getCity()) - .eq(Region::getRegionLevel, 2)); - for (Region city : cityList) { - district = regionService.getOne(Wrappers.lambdaQuery() - .eq(Region::getParentCode, city.getCode()) - .eq(Region::getName, portTerminal.getDistrictName()), false); - if (Func.isNotEmpty(district)) { - break; - } - } - } - if (Func.isEmpty(district)) { - district = regionService.getOne(Wrappers.lambdaQuery() - .eq(Region::getName, portTerminal.getDistrictName()) - .eq(Region::getRegionLevel, 3), false); - } + district = findRegionByName(portTerminal.getDistrictName(), DISTRICT_REGION_LEVEL, city.getCode()); } if (Func.isEmpty(district)) { throw new ServiceException("请选择区县"); } - Region city = regionService.getById(district.getParentCode()); - if (Func.isEmpty(city)) { - throw new ServiceException("区县所属城市不存在"); - } - if (Func.isNotEmpty(portTerminal.getCity()) && !Objects.equals(portTerminal.getCity(), city.getName())) { - throw new ServiceException("区县与城市不匹配"); + if (!Objects.equals(district.getParentCode(), city.getCode())) { + throw new ServiceException("所属区县与所属城市不匹配"); } + + portTerminal.setProvinceCode(province.getCode()); + portTerminal.setProvinceName(province.getName()); portTerminal.setCity(city.getName()); portTerminal.setDistrictCode(district.getCode()); portTerminal.setDistrictName(district.getName()); portTerminal.setRegionCode(district.getCode()); } + /** + * 按名称查找区划,兼容「福建/福建省」「泉州/泉州市」等简写。 + */ + private Region findRegionByName(String name, int regionLevel, String parentCode) { + String normalized = trimToEmpty(name); + if (Func.isEmpty(normalized)) { + return null; + } + for (String candidate : regionNameCandidates(normalized)) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery() + .eq(Region::getRegionLevel, regionLevel) + .eq(Region::getName, candidate); + if (Func.isNotEmpty(parentCode)) { + queryWrapper.eq(Region::getParentCode, parentCode); + } + Region region = regionService.getOne(queryWrapper, false); + if (Func.isNotEmpty(region)) { + return region; + } + } + return null; + } + + private List regionNameCandidates(String name) { + List candidates = new ArrayList<>(); + candidates.add(name); + if (name.endsWith("省") || name.endsWith("市") || name.endsWith("区") || name.endsWith("县") || name.endsWith("州")) { + String shortName = name.substring(0, name.length() - 1); + if (Func.isNotEmpty(shortName) && !candidates.contains(shortName)) { + candidates.add(shortName); + } + } else { + for (String suffix : List.of("省", "市", "区", "县", "州")) { + String fullName = name + suffix; + if (!candidates.contains(fullName)) { + candidates.add(fullName); + } + } + } + return candidates; + } + private void validate(PortTerminal portTerminal) { if (!CATEGORY_PORT.equals(portTerminal.getCategory()) && !CATEGORY_TERMINAL.equals(portTerminal.getCategory())) { throw new ServiceException("类型只能为港口或码头"); @@ -506,16 +630,17 @@ public class PortTerminalServiceImpl extends BaseServiceImpl option(contract.getId(), "contractName", contract.getContractName(), "projectId", contract.getProjectId())) .toList()); options.put("carriers", customerArchiveService.list().stream() - .filter(customer -> "承运商".equals(customer.getCustomerType()) && Integer.valueOf(1).equals(customer.getStatus())) + .filter(customer -> isCarrierCustomer(customer) && Integer.valueOf(1).equals(customer.getStatus())) .map(customer -> option(customer.getId(), "name", customer.getFullName(), null, null)) .toList()); - options.put("creators", new ArrayList<>()); + // 创建人选项取已有导入批次的创建人,保证筛选项与列表数据可对应。 + Set creatorIds = new LinkedHashSet<>(); + waybillImportBatchService.list(Wrappers.lambdaQuery() + .select(WaybillImportBatch::getCreateUser) + .eq(WaybillImportBatch::getIsDeleted, 0) + .isNotNull(WaybillImportBatch::getCreateUser)) + .stream() + .map(WaybillImportBatch::getCreateUser) + .filter(Objects::nonNull) + .forEach(creatorIds::add); + options.put("creators", creatorIds.stream() + .map(userId -> option(userId, "name", UserCache.getUserRealName(userId), null, null)) + .toList()); options.put("plans", transportPlanService.list().stream() .map(plan -> option(plan.getId(), "planName", plan.getPlanName(), "projectId", plan.getProjectId())) .toList()); @@ -372,6 +390,12 @@ public class WaybillController extends BladeController { return option; } + /** 客商类型支持多选(逗号分隔),包含「承运商」即视为承运商。 */ + private boolean isCarrierCustomer(CustomerArchive customer) { + String type = Func.toStr(customer.getCustomerType()).replace(",", ","); + return Func.toStrList(type).stream().anyMatch("承运商"::equals); + } + private static final class TextColumnStyleHandler implements SheetWriteHandler { private final int[] columnIndexes; 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 a37f242a..1a585643 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 @@ -344,7 +344,16 @@ public class WaybillImportBatchServiceImpl extends BaseServiceImpl entityPage = page(page, queryWrapper); List records = entityPage.getRecords().stream().map(this::toVO).toList(); Page resultPage = new Page<>(entityPage.getCurrent(), entityPage.getSize(), entityPage.getTotal());