fix(file): allow customs broker receipt files
This commit is contained in:
+1
-1
@@ -19,7 +19,7 @@
|
||||
| 海外异常订单证据 | 通用内部业务文件入口;固定 `businessType=OVERSEAS_EXCEPTION_EVIDENCE`、`tenantId=异常订单所属客户ID`、`businessId=异常订单ID`,File 只校验文件复合归属,异常状态、完成门禁和证据引用归 Lastleg |
|
||||
| 海外换标 PDF 资料 | 通用内部业务文件入口,契约 `src/main/resources/openapi/overseas-relabel-document-v1.yaml`;`OVERSEAS_RELABEL_TOTAL_DOCUMENT` 按 `application.id`、`OVERSEAS_RELABEL_ITEM_DOCUMENT` 按 `item.id` 归属,必须指定明确客户与正数业务 ID;仅非空 PDF、最大 10MiB,校验 MIME 和文件签名。File 按客户、类型、业务 ID、文件 ID 复合校验,Lastleg 校验申请/明细关系、客户归属、权限和业务状态 |
|
||||
| 入库扣货凭证 | 通用内部业务文件入口;固定 `businessType=INBOUND_HOLD_EVIDENCE`、`tenantId=客户ID`、`businessId=入库单ID`,客户作用域单文件最多 10MiB;可见性与历史引用由 Firstleg 校验 |
|
||||
| 报关源文件、完成文件与买单明细导出 | `src/main/resources/openapi/customs-file-and-export-v1.yaml`;文件类别 `LOADING_LIST_CUSTOMS_SOURCE`、`LOADING_LIST_CUSTOMS_RESULT` 均为客户作用域且最多 50MB,异步导出类型 `LOADING_LIST_BUY_DECLARATION_ITEMS` 由 Firstleg Provider 按固定十三列供数 |
|
||||
| 报关源文件、报关行回执、完成文件与买单明细导出 | `src/main/resources/openapi/customs-file-and-export-v1.yaml`;文件类别 `LOADING_LIST_CUSTOMS_SOURCE`、`LOADING_LIST_CUSTOMS_RECEIPT`、`LOADING_LIST_CUSTOMS_RESULT` 均为客户作用域且最多 50MB,异步导出类型 `LOADING_LIST_BUY_DECLARATION_ITEMS` 由 Firstleg Provider 按固定十三列供数 |
|
||||
| 订舱文件 | 通用内部业务文件入口,契约 `src/main/resources/openapi/ocean-booking-file-v1.yaml`;类型固定 `OCEAN_BOOKING_DOCUMENT`、`tenantId=0`(平台专属,客户可选快照不改变文件归属,拒绝客户作用域)、`businessId=oceanBookingId`,任意格式且最多 50MiB,不得绑定拖车;`BOOKING_CONFIRMATION/BILL_OF_LADING` 文档类型及有效状态由 Firstleg 保存 |
|
||||
| 拖车预约附件 | 通用内部业务文件入口;固定 `tenantId=0`、`businessType=TRUCK_APPOINTMENT_ATTACHMENT`、`businessId=appointmentId`,只允许派车单、司机/车辆资料和其他平台附件;提单文件归订舱 `OCEAN_BOOKING_DOCUMENT`,不得复制为拖车附件 |
|
||||
| 存储与实体 | `service/LocalQualificationStorage.java`、`MeasurementImageStorage.java`、`entity/FileObjectEntity.java` |
|
||||
|
||||
@@ -31,6 +31,7 @@ enum BusinessFileCategory {
|
||||
OVERSEAS_RELABEL_ITEM_DOCUMENT(true, FormatPolicy.PDF, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
||||
OVERSEAS_EXCEPTION_EVIDENCE(true, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
||||
LOADING_LIST_CUSTOMS_SOURCE(true, FormatPolicy.ARBITRARY, Limits.CUSTOMS, BusinessIdPolicy.POSITIVE_LONG),
|
||||
LOADING_LIST_CUSTOMS_RECEIPT(true, FormatPolicy.ARBITRARY, Limits.CUSTOMS, BusinessIdPolicy.POSITIVE_LONG),
|
||||
LOADING_LIST_CUSTOMS_RESULT(true, FormatPolicy.ARBITRARY, Limits.CUSTOMS, BusinessIdPolicy.POSITIVE_LONG),
|
||||
ORDER_BATCH_IMPORT_SOURCE(true, FormatPolicy.XLSX, Limits.ORDER_IMPORT, BusinessIdPolicy.ORDER_BATCH_NO),
|
||||
ORDER_BATCH_IMPORT_ERROR_REPORT(true, FormatPolicy.XLSX, Limits.ORDER_IMPORT, BusinessIdPolicy.ORDER_BATCH_NO);
|
||||
|
||||
@@ -5,7 +5,7 @@ info:
|
||||
description: |
|
||||
File 只保存不可变文件对象并生成异步 XLSX,不保存报关状态或业务版本。
|
||||
Firstleg 持有 loadingPlanId、文件版本、完成状态和可见性,并在调用本内部接口前完成 Platform/Client 鉴权。
|
||||
LOADING_LIST_CUSTOMS_SOURCE 与 LOADING_LIST_CUSTOMS_RESULT 均为 CUSTOMER owner scope,tenantId 必须大于 0;
|
||||
LOADING_LIST_CUSTOMS_SOURCE、LOADING_LIST_CUSTOMS_RECEIPT 与 LOADING_LIST_CUSTOMS_RESULT 均为 CUSTOMER owner scope,tenantId 必须大于 0;
|
||||
客户源文件上传/下载由 Firstleg 校验当前客户,结果文件下载还须由 Firstleg 校验整柜完成和结果可见性。
|
||||
用户侧权限冻结为:Platform 上传结果 platform:firstleg:customs:manage,Platform 下载 platform:firstleg:customs:list;
|
||||
Client 上传源文件 merchant:order:edit,Client 下载自身源文件或获准结果 merchant:order:view。
|
||||
@@ -15,7 +15,7 @@ paths:
|
||||
post:
|
||||
summary: 保存报关业务文件对象
|
||||
description: |
|
||||
仅服务令牌可调用。fileCategory 取 LOADING_LIST_CUSTOMS_SOURCE 或 LOADING_LIST_CUSTOMS_RESULT。
|
||||
仅服务令牌可调用。fileCategory 取 LOADING_LIST_CUSTOMS_SOURCE、LOADING_LIST_CUSTOMS_RECEIPT 或 LOADING_LIST_CUSTOMS_RESULT。
|
||||
支持任意文件格式,单文件最多 50MB。operatorId 为已通过 Firstleg 鉴权的实际操作人。
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/InternalToken'
|
||||
@@ -94,7 +94,7 @@ components:
|
||||
InternalToken: {name: X-Internal-Service-Token, in: header, required: true, schema: {type: string}}
|
||||
OperatorId: {name: X-Operator-Id, in: header, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
TenantId: {name: tenantId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}, description: 客户ID;不得使用平台0作用域}
|
||||
FileCategory: {name: fileCategory, in: path, required: true, schema: {type: string, enum: [LOADING_LIST_CUSTOMS_SOURCE, LOADING_LIST_CUSTOMS_RESULT]}}
|
||||
FileCategory: {name: fileCategory, in: path, required: true, schema: {type: string, enum: [LOADING_LIST_CUSTOMS_SOURCE, LOADING_LIST_CUSTOMS_RECEIPT, LOADING_LIST_CUSTOMS_RESULT]}}
|
||||
LoadingPlanId: {name: loadingPlanId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
FileId: {name: fileId, in: path, required: true, schema: {type: integer, format: int64, minimum: 1}}
|
||||
schemas:
|
||||
|
||||
@@ -29,7 +29,7 @@ class CustomsFileExportContractTest {
|
||||
String source = Files.readString(repositoryRoot()
|
||||
.resolve("file/src/main/resources/openapi/customs-file-and-export-v1.yaml"));
|
||||
|
||||
assertThat(source).contains("LOADING_LIST_CUSTOMS_SOURCE", "LOADING_LIST_CUSTOMS_RESULT")
|
||||
assertThat(source).contains("LOADING_LIST_CUSTOMS_SOURCE", "LOADING_LIST_CUSTOMS_RECEIPT", "LOADING_LIST_CUSTOMS_RESULT")
|
||||
.contains("maximum: 52428800", "no-store", "CUSTOMER owner scope", "loadingPlanId")
|
||||
.contains("platform:firstleg:customs:manage", "platform:firstleg:customs:list",
|
||||
"merchant:order:edit", "merchant:order:view")
|
||||
|
||||
@@ -169,14 +169,17 @@ class InternalBusinessFileServiceTest {
|
||||
});
|
||||
|
||||
var source = service.upload(10001L, "LOADING_LIST_CUSTOMS_SOURCE", "51", 7L, file);
|
||||
var receipt = service.upload(10001L, "LOADING_LIST_CUSTOMS_RECEIPT", "51", 7L, file);
|
||||
var result = service.upload(10001L, "LOADING_LIST_CUSTOMS_RESULT", "51", 7L, file);
|
||||
|
||||
assertThat(source).extracting(InternalBusinessFileService.Metadata::tenantId,
|
||||
InternalBusinessFileService.Metadata::businessType,
|
||||
InternalBusinessFileService.Metadata::businessId)
|
||||
.containsExactly(10001L, "LOADING_LIST_CUSTOMS_SOURCE", "51");
|
||||
assertThat(receipt.businessType()).isEqualTo("LOADING_LIST_CUSTOMS_RECEIPT");
|
||||
assertThat(result.businessType()).isEqualTo("LOADING_LIST_CUSTOMS_RESULT");
|
||||
verify(storage).store(10001L, "51", file, BusinessFileCategory.LOADING_LIST_CUSTOMS_SOURCE);
|
||||
verify(storage).store(10001L, "51", file, BusinessFileCategory.LOADING_LIST_CUSTOMS_RECEIPT);
|
||||
verify(storage).store(10001L, "51", file, BusinessFileCategory.LOADING_LIST_CUSTOMS_RESULT);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user