fix(warehouse): reject invalid import files with validation code

This commit is contained in:
2026-08-08 15:54:31 +08:00
parent 931009a518
commit d49b4128bc
6 changed files with 46 additions and 3 deletions
@@ -94,7 +94,11 @@ public class PlatformExpressCompanyController {
requirePlatform(user);
requirePlatformScope(tenantId);
try {
return ApiResponse.success(importService.importFile(tenantId, file.getOriginalFilename(), file.getBytes()));
ExpressCompanyImportResult result = importService.importFile(tenantId, file.getOriginalFilename(), file.getBytes());
if (!result.success()) {
throw new BizException(ResultCode.VALIDATION_FAILED, "快递公司导入文件校验失败");
}
return ApiResponse.success(result);
} catch (IOException exception) {
throw new BizException(ResultCode.BAD_REQUEST, "导入文件读取失败");
}
@@ -75,7 +75,11 @@ public class PlatformPartnerController {
requirePlatform(user);
requirePlatformScope(tenantId);
try {
return ApiResponse.success(importService.importFile(0L, file.getOriginalFilename(), file.getBytes()));
PartnerImportResult result = importService.importFile(0L, file.getOriginalFilename(), file.getBytes());
if (!result.success()) {
throw new BizException(ResultCode.VALIDATION_FAILED, "往来单位导入文件校验失败");
}
return ApiResponse.success(result);
} catch (IOException exception) {
throw new BizException(ResultCode.BAD_REQUEST, "导入文件读取失败");
}
@@ -163,7 +163,11 @@ public class PlatformWarehouseController {
requireImportPermission(user, mode);
if (tenantId != null) requireTenant(tenantId);
try {
return ApiResponse.success(importService.importFile(0L, file.getOriginalFilename(), file.getBytes(), mode, dryRun));
WarehouseImportResult result = importService.importFile(0L, file.getOriginalFilename(), file.getBytes(), mode, dryRun);
if (!result.success()) {
throw new BizException(ResultCode.VALIDATION_FAILED, "仓库导入文件校验失败");
}
return ApiResponse.success(result);
} catch (IOException exception) {
throw new BizException(ResultCode.BAD_REQUEST, "导入文件读取失败");
}
@@ -23,6 +23,16 @@ import static org.mockito.Mockito.verify;
class ExpressCompanyImportServiceTest {
@MockBean private ExpressCompanyRepository repository;
@Resource private ExpressCompanyImportService service;
@Test
@DisplayName("空文件或错误扩展名整批拒绝且不写入")
void shouldRejectMalformedWorkbookWithoutWrites() {
var empty = service.importFile(0L, "express.xlsx", new byte[0]);
var wrongExtension = service.importFile(0L, "express.xls", new byte[] {1, 2, 3});
assertThat(empty.success()).isFalse();
assertThat(wrongExtension.success()).isFalse();
verify(repository, never()).insert(any());
}
@Test
@DisplayName("标准模板通过整批校验后写入全部数据")
void shouldImportValidWorkbookAfterFullValidation() throws Exception {
@@ -25,6 +25,16 @@ import static org.mockito.Mockito.verify;
class PartnerImportServiceTest {
@MockBean private PartnerRepository repository;
@Resource private PartnerImportService service;
@Test
@DisplayName("空文件或非 XLSX 整批拒绝且不写入")
void shouldRejectMalformedWorkbookWithoutWrites() {
PartnerImportResult empty = service.importFile(0L, "partners.xlsx", new byte[0]);
PartnerImportResult nonXlsx = service.importFile(0L, "partners.csv", new byte[] {1, 2, 3});
assertThat(empty.success()).isFalse();
assertThat(nonXlsx.success()).isFalse();
verify(repository, never()).insert(any());
}
@Test
@DisplayName("标准模板支持多类型并写入服务端数据范围")
void shouldImportValidMultiTypeRow() throws Exception {
@@ -31,6 +31,17 @@ class WarehouseImportServiceTest {
@MockBean private WarehouseApplicationService warehouseService;
@Resource private WarehouseImportService service;
@Test
@DisplayName("空文件或损坏 XLSX 整批拒绝且不写入")
void shouldRejectMalformedWorkbookWithoutWrites() {
WarehouseImportResult empty = service.importFile(0L, "warehouses.xlsx", new byte[0], null);
WarehouseImportResult corrupt = service.importFile(0L, "warehouses.xlsx", new byte[] {1, 2, 3}, null);
assertThat(empty.success()).isFalse();
assertThat(corrupt.success()).isFalse();
verify(warehouseService, never()).create(any());
verify(warehouseService, never()).update(org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.anyLong(), any());
}
@Test
@DisplayName("默认 CREATE_ONLY 只新增新仓库并返回预检分类")
void shouldCreateOnlyNewWarehousesByDefault() throws Exception {