🐛 改路线时按新地址重推运单站名
- TransportBusinessSupport 新增 deriveRegionName / syncRegionName:按「省+市+区县旗」推导站名, 与库里存量口径一致,县级市只取到地级市,认不出行政区划退回整段地址并截断 100 字 - WaybillServiceImpl.changeRoute(PC 后台改路线)与 ExceptionDisposalServiceImpl.applyWaybillRoute(小程序「同意并修改路线」)写地址时同步写站名; 地址没变保留库里原站名,避免清洗旧的手填站名 - 此前两处都只写 departure_address / arrival_address,站名一直是派单时的旧值, 司机端列表与详情标题改完仍是旧城市 - 补 TransportBusinessSupportRegionNameTest、WaybillChangeRouteStationNameTest 与异常处置站名断言
This commit is contained in:
+4
@@ -863,6 +863,10 @@ public class ExceptionDisposalServiceImpl
|
||||
if (Func.isNotBlank(plan.routeJson())) {
|
||||
waybill.setRouteJson(plan.routeJson());
|
||||
}
|
||||
waybill.setDepartureName(TransportBusinessSupport.syncRegionName(
|
||||
waybill.getDepartureName(), waybill.getDepartureAddress(), plan.departureAddress()));
|
||||
waybill.setArrivalName(TransportBusinessSupport.syncRegionName(
|
||||
waybill.getArrivalName(), waybill.getArrivalAddress(), plan.arrivalAddress()));
|
||||
waybill.setDepartureAddress(plan.departureAddress());
|
||||
waybill.setArrivalAddress(plan.arrivalAddress());
|
||||
waybill.setTaskInfoJson(plan.taskInfoJson());
|
||||
|
||||
+10
@@ -1478,13 +1478,23 @@ public class WaybillServiceImpl extends BaseServiceImpl<WaybillMapper, Waybill>
|
||||
if ("completed".equals(oldRecord.getBusinessStatus()) || "cancelled".equals(oldRecord.getBusinessStatus())) {
|
||||
throw new ServiceException("当前运单状态不允许变更运输路线");
|
||||
}
|
||||
String previousDepartureAddress = oldRecord.getDepartureAddress();
|
||||
String previousArrivalAddress = oldRecord.getArrivalAddress();
|
||||
oldRecord.setRouteJson(TransportBusinessSupport.trimToNull(waybill.getRouteJson()));
|
||||
oldRecord.setDepartureAddress(TransportBusinessSupport.trimToNull(waybill.getDepartureAddress()));
|
||||
oldRecord.setArrivalAddress(TransportBusinessSupport.trimToNull(waybill.getArrivalAddress()));
|
||||
oldRecord.setDepartureName(TransportBusinessSupport.syncRegionName(
|
||||
oldRecord.getDepartureName(), previousDepartureAddress, oldRecord.getDepartureAddress()));
|
||||
oldRecord.setArrivalName(TransportBusinessSupport.syncRegionName(
|
||||
oldRecord.getArrivalName(), previousArrivalAddress, oldRecord.getArrivalAddress()));
|
||||
oldRecord.setTaskInfoJson(TransportBusinessSupport.trimToNull(waybill.getTaskInfoJson()));
|
||||
TransportBusinessSupport.validateLength(oldRecord.getRouteJson(), 8000, "路线信息不能超过8000字");
|
||||
TransportBusinessSupport.validateLength(oldRecord.getDepartureAddress(), 255, "发货地址不能超过255字");
|
||||
TransportBusinessSupport.validateLength(oldRecord.getArrivalAddress(), 255, "收货地址不能超过255字");
|
||||
TransportBusinessSupport.validateLength(oldRecord.getDepartureName(),
|
||||
TransportBusinessSupport.REGION_NAME_MAX_LENGTH, "发货地不能超过100字");
|
||||
TransportBusinessSupport.validateLength(oldRecord.getArrivalName(),
|
||||
TransportBusinessSupport.REGION_NAME_MAX_LENGTH, "收货地不能超过100字");
|
||||
TransportBusinessSupport.validateLength(oldRecord.getTaskInfoJson(), 8000, "任务信息不能超过8000字");
|
||||
return updateById(oldRecord);
|
||||
}
|
||||
|
||||
+71
@@ -37,6 +37,7 @@ import java.time.LocalDate;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
@@ -50,8 +51,18 @@ public final class TransportBusinessSupport {
|
||||
public static final String DATA_SOURCE_MANUAL = "手工创建";
|
||||
public static final String DATA_SOURCE_PLAN_DISPATCH = "计划调度";
|
||||
public static final String DATA_SOURCE_EXTERNAL = "外部系统";
|
||||
/** 站点名(省+市+区县)列宽:blade_waybill.departure_name / arrival_name 为 varchar(100) */
|
||||
public static final int REGION_NAME_MAX_LENGTH = 100;
|
||||
|
||||
private static final Pattern PHONE_PATTERN = Pattern.compile("^(1\\d{10}|0\\d{2,3}-?\\d{7,8})$");
|
||||
/** 省级前缀:主体不含市/区/县,避免把「北京市朝阳区某省道」当省级 */
|
||||
private static final Pattern PROVINCE_PATTERN = Pattern.compile("^[^市区县]{2,10}?(?:省|特别行政区|自治区)");
|
||||
/** 市级:地级市名 2~4 字,「市场」的市不算(地址里常见「农贸市场」「超市」) */
|
||||
private static final Pattern CITY_PATTERN = Pattern.compile("^[^区县旗市]{2,4}?市(?!场)");
|
||||
/** 市级:自治州/地区/盟 的名字可以更长 */
|
||||
private static final Pattern PREFECTURE_PATTERN = Pattern.compile("^[^区县旗市]{2,10}?(?:自治州|地区|盟)");
|
||||
/** 区县:县级市不单独进站名,只取到地级市 */
|
||||
private static final Pattern DISTRICT_PATTERN = Pattern.compile("^[^市县]{2,10}?(?:区|县|旗)");
|
||||
/** 用户档案「数据权限范围」的取值:全部组织,与组织树过滤口径一致 */
|
||||
private static final int DATA_SCOPE_ALL = 2;
|
||||
private static final BigDecimal MIN_LONGITUDE = new BigDecimal("-180");
|
||||
@@ -291,4 +302,64 @@ public final class TransportBusinessSupport {
|
||||
return mileage == null ? null : mileage.stripTrailingZeros().toPlainString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按地址推导站名:省 + 市 + 区/县/旗。
|
||||
* <p>
|
||||
* 库里的站名就是这个口径(如「内蒙古自治区鄂尔多斯市鄂托克旗」「北京市朝阳区」),
|
||||
* 只写地址不写站名会让司机端继续显示旧城市。地址里的「/」是分隔写法,推导时去掉;
|
||||
* 认不出城市的退回整段地址,不拼半截区县名。
|
||||
*/
|
||||
public static String deriveRegionName(String address) {
|
||||
String value = trimToNull(address);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
String rest = value.replace("/", "");
|
||||
String province = matchPrefix(rest, PROVINCE_PATTERN);
|
||||
if (!province.isEmpty()) {
|
||||
rest = rest.substring(province.length());
|
||||
}
|
||||
String city = matchPrefix(rest, CITY_PATTERN);
|
||||
if (city.isEmpty()) {
|
||||
city = matchPrefix(rest, PREFECTURE_PATTERN);
|
||||
}
|
||||
if (city.isEmpty()) {
|
||||
return truncateRegionName(value);
|
||||
}
|
||||
StringBuilder name = new StringBuilder(province).append(city);
|
||||
String district = matchPrefix(rest.substring(city.length()), DISTRICT_PATTERN);
|
||||
if (!district.isEmpty()) {
|
||||
name.append(district);
|
||||
}
|
||||
return truncateRegionName(name.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 地址变了才按新地址重推站名,地址没动保留库里原有的站名。
|
||||
*
|
||||
* @param currentName 库里当前的站名
|
||||
* @param previousAddress 改动前的地址
|
||||
* @param nextAddress 改动后的地址
|
||||
* @return 新地址对应的站名,地址被清空时返回 null
|
||||
*/
|
||||
public static String syncRegionName(String currentName, String previousAddress, String nextAddress) {
|
||||
String next = trimToNull(nextAddress);
|
||||
if (next == null) {
|
||||
return null;
|
||||
}
|
||||
if (Objects.equals(trimToNull(previousAddress), next)) {
|
||||
return trimToNull(currentName);
|
||||
}
|
||||
return deriveRegionName(next);
|
||||
}
|
||||
|
||||
private static String matchPrefix(String text, Pattern pattern) {
|
||||
Matcher matcher = pattern.matcher(text);
|
||||
return matcher.find() ? matcher.group() : "";
|
||||
}
|
||||
|
||||
private static String truncateRegionName(String value) {
|
||||
return value.length() > REGION_NAME_MAX_LENGTH ? value.substring(0, REGION_NAME_MAX_LENGTH) : value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+23
@@ -313,6 +313,8 @@ class ExceptionDisposalRouteAdjustTest {
|
||||
|
||||
assertEquals(START, updated.getDepartureAddress());
|
||||
assertEquals(NEW_END, updated.getArrivalAddress());
|
||||
assertEquals("南宁市邕宁区", updated.getDepartureName(), "站名按新地址重推,不能停在旧城市");
|
||||
assertEquals("成都市新都区", updated.getArrivalName());
|
||||
Map<String, Object> taskInfo = JsonUtil.toMap(updated.getTaskInfoJson());
|
||||
Map<?, ?> latest = (Map<?, ?>) ((List<?>) taskInfo.get("routeChangeRecords")).get(0);
|
||||
assertEquals(routeContent(START, TRANSIT, NEW_END), latest.get("content"));
|
||||
@@ -320,6 +322,27 @@ class ExceptionDisposalRouteAdjustTest {
|
||||
verify(loadingManageMapper, never()).selectOne(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("只改到达地时发货地站名保留库里的原值,改了的到达地按新地址重推")
|
||||
void adjustRouteKeepsDepartureNameWhenAddressUnchanged() {
|
||||
stubPendingDisposal();
|
||||
Waybill waybill = waybill(null, "in_progress", segmentRouteJson());
|
||||
waybill.setDepartureAddress(START);
|
||||
waybill.setDepartureName("南宁市邕宁区");
|
||||
waybill.setArrivalAddress(END);
|
||||
waybill.setArrivalName("成都市双流区");
|
||||
when(waybillService.getById(WAYBILL_ID)).thenReturn(waybill);
|
||||
|
||||
asScheduler(() -> service.adjustRoute(request(
|
||||
node("start", START, null),
|
||||
node("transit", TRANSIT, null),
|
||||
node("end", NEW_END, null))));
|
||||
|
||||
Waybill updated = updatedWaybill();
|
||||
assertEquals("南宁市邕宁区", updated.getDepartureName(), "地址没动,站名不得被改写");
|
||||
assertEquals("成都市新都区", updated.getArrivalName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("运单已关联配载单但配载单查不到时拒绝,不越权改运单")
|
||||
void adjustRouteRejectsWaybillBranchWhenLoadingNoPresent() {
|
||||
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
package org.springblade.transport.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.springblade.core.log.exception.ServiceException;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.transport.mapper.WaybillMapper;
|
||||
import org.springblade.transport.pojo.entity.Waybill;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* 运单「变更运输路线」的站名同步测试。
|
||||
* <p>
|
||||
* 司机端与运单列表读的是 departure_name / arrival_name,PC 后台改路线只提交地址。
|
||||
* 只写地址不写站名,页面上就还是旧城市(YD-VF-ADMIN-R1 改成北京通州后仍显示福建省三明市)。
|
||||
* 站名一律由后端按新地址推导,且只在地址真的变了才重推——地址没动时不得把库里已有的站名写坏。
|
||||
*/
|
||||
class WaybillChangeRouteStationNameTest {
|
||||
|
||||
private static final Long WAYBILL_ID = 7301L;
|
||||
private static final Long DEPT_ID = 100L;
|
||||
private static final String OLD_START = "福建省三明市梅列区列东街道88号";
|
||||
private static final String OLD_END = "福建省三明市三元区江滨路9号";
|
||||
private static final String NEW_END = "北京市通州区西集镇辛集路";
|
||||
|
||||
private WaybillMapper waybillMapper;
|
||||
private WaybillServiceImpl service;
|
||||
|
||||
@BeforeAll
|
||||
static void initTableInfo() {
|
||||
// updateById 判主键、读实体元数据需要 MyBatis-Plus 的缓存
|
||||
MybatisConfiguration configuration = new MybatisConfiguration();
|
||||
MapperBuilderAssistant assistant = new MapperBuilderAssistant(configuration, "");
|
||||
assistant.setCurrentNamespace("test");
|
||||
TableInfoHelper.initTableInfo(assistant, Waybill.class);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() throws Exception {
|
||||
waybillMapper = mock(WaybillMapper.class);
|
||||
service = new WaybillServiceImpl();
|
||||
inject("baseMapper", waybillMapper);
|
||||
when(waybillMapper.updateById(any(Waybill.class))).thenReturn(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("改到达地:地址写新值,到达站名按新地址重推,发货站名原样保留")
|
||||
void changeRouteDerivesArrivalName() {
|
||||
Waybill oldRecord = waybill();
|
||||
oldRecord.setDepartureAddress(OLD_START);
|
||||
oldRecord.setDepartureName("福建省三明市梅列区");
|
||||
oldRecord.setArrivalAddress(OLD_END);
|
||||
oldRecord.setArrivalName("福建省三明市三元区");
|
||||
when(waybillMapper.selectById(WAYBILL_ID)).thenReturn(oldRecord);
|
||||
|
||||
asManager(() -> assertTrue(service.changeRoute(request(OLD_START, NEW_END))));
|
||||
|
||||
Waybill updated = updatedWaybill();
|
||||
assertEquals(NEW_END, updated.getArrivalAddress());
|
||||
assertEquals("北京市通州区", updated.getArrivalName(), "站名不能停在旧城市");
|
||||
assertEquals(OLD_START, updated.getDepartureAddress());
|
||||
assertEquals("福建省三明市梅列区", updated.getDepartureName(), "地址没动,站名不得被改写");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("只改路线节点与任务信息:地址未变,站名一个都不动")
|
||||
void changeRouteKeepsNamesWhenAddressesUnchanged() {
|
||||
Waybill oldRecord = waybill();
|
||||
oldRecord.setDepartureAddress(OLD_START);
|
||||
oldRecord.setDepartureName("福建省三明市梅列区");
|
||||
oldRecord.setArrivalAddress(OLD_END);
|
||||
oldRecord.setArrivalName("福建省三明市三元区");
|
||||
when(waybillMapper.selectById(WAYBILL_ID)).thenReturn(oldRecord);
|
||||
|
||||
asManager(() -> assertTrue(service.changeRoute(request(OLD_START, OLD_END))));
|
||||
|
||||
Waybill updated = updatedWaybill();
|
||||
assertEquals("福建省三明市梅列区", updated.getDepartureName());
|
||||
assertEquals("福建省三明市三元区", updated.getArrivalName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("已配载的运单不允许在这里改路线,站名也不写")
|
||||
void changeRouteRejectsLoadedWaybill() {
|
||||
Waybill oldRecord = waybill();
|
||||
oldRecord.setLoadingNo("PZ-20261024-001");
|
||||
oldRecord.setDepartureAddress(OLD_START);
|
||||
oldRecord.setArrivalAddress(OLD_END);
|
||||
when(waybillMapper.selectById(WAYBILL_ID)).thenReturn(oldRecord);
|
||||
|
||||
ServiceException exception = assertThrows(ServiceException.class,
|
||||
() -> asManager(() -> service.changeRoute(request(OLD_START, NEW_END))));
|
||||
|
||||
assertEquals("运单已关联配载单,请在配载单中修改", exception.getMessage());
|
||||
verify(waybillMapper, never()).updateById(any(Waybill.class));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------ 夹具
|
||||
|
||||
private Waybill waybill() {
|
||||
Waybill waybill = new Waybill();
|
||||
waybill.setId(WAYBILL_ID);
|
||||
waybill.setWaybillNo("YD20261024001");
|
||||
waybill.setBusinessStatus("running");
|
||||
waybill.setDeptId(DEPT_ID);
|
||||
waybill.setDeptName("测试组织");
|
||||
waybill.setIsDeleted(0);
|
||||
return waybill;
|
||||
}
|
||||
|
||||
private Waybill request(String departureAddress, String arrivalAddress) {
|
||||
Waybill request = new Waybill();
|
||||
request.setId(WAYBILL_ID);
|
||||
request.setRouteJson("[{\"address\":\"" + departureAddress + "\"}]");
|
||||
request.setDepartureAddress(departureAddress);
|
||||
request.setArrivalAddress(arrivalAddress);
|
||||
return request;
|
||||
}
|
||||
|
||||
private Waybill updatedWaybill() {
|
||||
ArgumentCaptor<Waybill> captor = ArgumentCaptor.forClass(Waybill.class);
|
||||
verify(waybillMapper).updateById(captor.capture());
|
||||
return captor.getValue();
|
||||
}
|
||||
|
||||
private void asManager(Runnable action) {
|
||||
try (MockedStatic<AuthUtil> authUtil = mockStatic(AuthUtil.class)) {
|
||||
authUtil.when(AuthUtil::getDeptId).thenReturn(String.valueOf(DEPT_ID));
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
|
||||
private void inject(String field, Object value) throws Exception {
|
||||
Class<?> type = service.getClass();
|
||||
while (type != null) {
|
||||
try {
|
||||
Field declared = type.getDeclaredField(field);
|
||||
declared.setAccessible(true);
|
||||
declared.set(service, value);
|
||||
return;
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
type = type.getSuperclass();
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("未找到字段:" + field);
|
||||
}
|
||||
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
package org.springblade.transport.support;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
/**
|
||||
* 站名推导测试。
|
||||
* <p>
|
||||
* 司机端与列表展示的是运单的 departure_name / arrival_name,不是地址;改路线只写地址、
|
||||
* 不写站名,页面上就还是旧城市。库里的站名口径是「省 + 市 + 区/县/旗」,
|
||||
* 例如 内蒙古自治区鄂尔多斯市鄂托克旗、北京市朝阳区、广西壮族自治区北海市合浦县。
|
||||
*/
|
||||
class TransportBusinessSupportRegionNameTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("省+市+区:只取行政区划,街道门牌不进站名")
|
||||
void provinceCityDistrict() {
|
||||
assertEquals("北京市朝阳区",
|
||||
TransportBusinessSupport.deriveRegionName("北京市朝阳区十八里店乡周庄村1号院"));
|
||||
assertEquals("福建省三明市梅列区",
|
||||
TransportBusinessSupport.deriveRegionName("福建省三明市梅列区列东街道88号"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("自治区+市+旗、市+县:旗与县同样算到区县一级")
|
||||
void autonomousRegionCityBanner() {
|
||||
assertEquals("内蒙古自治区鄂尔多斯市鄂托克旗",
|
||||
TransportBusinessSupport.deriveRegionName("内蒙古自治区鄂尔多斯市鄂托克旗棋盘井镇运煤专线"));
|
||||
assertEquals("广西壮族自治区北海市合浦县",
|
||||
TransportBusinessSupport.deriveRegionName("广西壮族自治区北海市合浦县廉州镇还珠大道"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("直辖市与自治州:省这一级可以没有")
|
||||
void municipalityAndAutonomousPrefecture() {
|
||||
assertEquals("天津市北辰区",
|
||||
TransportBusinessSupport.deriveRegionName("天津市北辰区青光镇津围公路"));
|
||||
assertEquals("湖北省恩施土家族苗族自治州",
|
||||
TransportBusinessSupport.deriveRegionName("湖北省恩施土家族苗族自治州恩施市舞阳大道"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("斜杠分隔的地址写法:拼站名时去掉斜杠")
|
||||
void slashSeparatedAddress() {
|
||||
assertEquals("南宁市邕宁区",
|
||||
TransportBusinessSupport.deriveRegionName("南宁市/邕宁区/那赖二路神网数码物流园"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("只到市一级:不硬凑区县")
|
||||
void cityOnly() {
|
||||
assertEquals("贵州省贵阳市", TransportBusinessSupport.deriveRegionName("贵州省贵阳市新店镇农贸市场"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("「市场」「超市」里的市不是城市名,县级市也只取到地级市")
|
||||
void marketNameIsNotACity() {
|
||||
assertEquals("贵州省贵阳市",
|
||||
TransportBusinessSupport.deriveRegionName("贵州省贵阳市城东农贸市场3号门"));
|
||||
assertEquals("江苏省苏州市",
|
||||
TransportBusinessSupport.deriveRegionName("江苏省苏州市昆山市玉山镇紫竹路"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("地址里的「省道」不当省级:仍按市、区推导")
|
||||
void provinceRoadIsNotProvince() {
|
||||
assertEquals("北京市朝阳区", TransportBusinessSupport.deriveRegionName("北京市朝阳区某省道88号"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("认不出城市时退回整段地址,不拼半截区县名")
|
||||
void fallsBackToFullAddress() {
|
||||
assertEquals("新店镇农贸市场3号门", TransportBusinessSupport.deriveRegionName("新店镇农贸市场3号门"));
|
||||
assertEquals("南宁吴圩国际机场货运站", TransportBusinessSupport.deriveRegionName("南宁吴圩国际机场货运站"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("空地址没有站名")
|
||||
void blankAddress() {
|
||||
assertNull(TransportBusinessSupport.deriveRegionName(null));
|
||||
assertNull(TransportBusinessSupport.deriveRegionName(" "));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("站名超出列宽时按 100 字截断")
|
||||
void truncatesToColumnWidth() {
|
||||
String address = "新店镇" + "甲乙丙丁".repeat(30);
|
||||
|
||||
String name = TransportBusinessSupport.deriveRegionName(address);
|
||||
|
||||
assertEquals(TransportBusinessSupport.REGION_NAME_MAX_LENGTH, name.length());
|
||||
assertEquals(address.substring(0, TransportBusinessSupport.REGION_NAME_MAX_LENGTH), name);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("地址没变时保留库里原有的站名")
|
||||
void keepsNameWhenAddressUnchanged() {
|
||||
assertEquals("福建省三明市", TransportBusinessSupport.syncRegionName(
|
||||
"福建省三明市", "福建省三明市梅列区列东街道88号", "福建省三明市梅列区列东街道88号"));
|
||||
assertNull(TransportBusinessSupport.syncRegionName(
|
||||
null, "福建省三明市梅列区列东街道88号", "福建省三明市梅列区列东街道88号"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("地址变了按新地址重推站名,与旧站名无关")
|
||||
void derivesNameWhenAddressChanged() {
|
||||
assertEquals("北京市通州区", TransportBusinessSupport.syncRegionName(
|
||||
"福建省三明市", "福建省三明市梅列区列东街道88号", "北京市通州区西集镇辛集路"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("地址被清空时站名一起清空")
|
||||
void clearsNameWhenAddressCleared() {
|
||||
assertNull(TransportBusinessSupport.syncRegionName(
|
||||
"福建省三明市", "福建省三明市梅列区列东街道88号", null));
|
||||
assertNull(TransportBusinessSupport.syncRegionName(
|
||||
"福建省三明市", "福建省三明市梅列区列东街道88号", " "));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user