fix(lastleg): complete relabel document contract and regression gates
This commit is contained in:
@@ -24,6 +24,8 @@ enum BusinessFileCategory {
|
||||
CONTAINER_PICKUP_ORDER(false, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
||||
OVERSEAS_UNLOAD_PHOTO(true, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
||||
OVERSEAS_RELABEL_PHOTO(true, FormatPolicy.STANDARD, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
||||
OVERSEAS_RELABEL_TOTAL_DOCUMENT(true, FormatPolicy.PDF, Limits.STANDARD, BusinessIdPolicy.POSITIVE_LONG),
|
||||
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_RESULT(true, FormatPolicy.ARBITRARY, Limits.CUSTOMS, BusinessIdPolicy.POSITIVE_LONG),
|
||||
@@ -86,7 +88,7 @@ enum BusinessFileCategory {
|
||||
return Long.toString(value);
|
||||
}
|
||||
|
||||
enum FormatPolicy { STANDARD, ARBITRARY, XLSX }
|
||||
enum FormatPolicy { STANDARD, ARBITRARY, XLSX, PDF }
|
||||
private enum BusinessIdPolicy { POSITIVE_LONG, ORDER_BATCH_NO }
|
||||
private static final class Limits {
|
||||
private static final long STANDARD = 10L * 1024 * 1024;
|
||||
|
||||
@@ -55,6 +55,10 @@ public class BusinessFileStorage {
|
||||
String extension;
|
||||
if (formatPolicy == BusinessFileCategory.FormatPolicy.ARBITRARY) {
|
||||
extension = "";
|
||||
} else if (formatPolicy == BusinessFileCategory.FormatPolicy.PDF) {
|
||||
if (!"application/pdf".equals(type)) throw bad("附件仅支持PDF");
|
||||
verifyContent(file, type);
|
||||
extension = ".pdf";
|
||||
} else if (formatPolicy == BusinessFileCategory.FormatPolicy.XLSX) {
|
||||
if (!XLSX_TYPE.equals(type)) throw bad("附件仅支持XLSX");
|
||||
verifyXlsx(file);
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 海外换标 PDF 文件内部契约
|
||||
version: 1.0.0
|
||||
description: >-
|
||||
File 只保存文件并强制客户、业务类型、业务ID与文件ID复合归属。
|
||||
OVERSEAS_RELABEL_TOTAL_DOCUMENT 的 businessId 为 application.id;
|
||||
OVERSEAS_RELABEL_ITEM_DOCUMENT 的 businessId 为 item.id。
|
||||
Lastleg 必须先校验申请与明细存在、明细所属申请及其客户归属、业务状态和权限。
|
||||
客户归属未知时失败关闭,不得使用平台归属或替代业务ID。
|
||||
security:
|
||||
- InternalServiceToken: []
|
||||
paths:
|
||||
/internal/file/v1/business-files/{tenantId}/{businessType}/{businessId}:
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/TenantId'
|
||||
- $ref: '#/components/parameters/BusinessType'
|
||||
- $ref: '#/components/parameters/BusinessId'
|
||||
post:
|
||||
summary: 上传换标总文件或单品文件
|
||||
description: 非空 PDF,Content-Type 必须为 application/pdf,内容需有 PDF 签名,最大 10MiB(10485760字节,含边界)。
|
||||
parameters:
|
||||
- name: X-Operator-Id
|
||||
in: header
|
||||
required: true
|
||||
schema: {type: integer, format: int64, minimum: 1}
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
required: [file]
|
||||
properties:
|
||||
file: {type: string, format: binary}
|
||||
encoding:
|
||||
file: {contentType: application/pdf}
|
||||
responses:
|
||||
'200':
|
||||
description: 统一响应体;业务失败按 code 判断
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/MetadataEnvelope'}
|
||||
'403': {description: 内部令牌无效}
|
||||
/internal/file/v1/business-files/{tenantId}/{businessType}/{businessId}/{fileId}:
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/TenantId'
|
||||
- $ref: '#/components/parameters/BusinessType'
|
||||
- $ref: '#/components/parameters/BusinessId'
|
||||
- $ref: '#/components/parameters/FileId'
|
||||
get:
|
||||
summary: 校验复合归属并读取元数据
|
||||
responses:
|
||||
'200':
|
||||
description: 仅返回全部归属字段匹配且有效的文件,未匹配按统一业务错误返回
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/MetadataEnvelope'}
|
||||
'403': {description: 内部令牌无效}
|
||||
/internal/file/v1/business-files/{tenantId}/{businessType}/{businessId}/{fileId}/content:
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/TenantId'
|
||||
- $ref: '#/components/parameters/BusinessType'
|
||||
- $ref: '#/components/parameters/BusinessId'
|
||||
- $ref: '#/components/parameters/FileId'
|
||||
get:
|
||||
summary: 校验复合归属并下载 PDF
|
||||
responses:
|
||||
'200':
|
||||
description: 文件内容;Content-Disposition 附件下载,Cache-Control no-store
|
||||
content:
|
||||
application/pdf:
|
||||
schema: {type: string, format: binary}
|
||||
'403': {description: 内部令牌无效}
|
||||
components:
|
||||
schemas:
|
||||
MetadataEnvelope:
|
||||
type: object
|
||||
required: [code, data]
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string, nullable: true}
|
||||
data: {$ref: '#/components/schemas/Metadata'}
|
||||
Metadata:
|
||||
type: object
|
||||
required: [fileId, ownerScope, tenantId, businessType, businessId, fileName, sha256, contentType, sizeBytes]
|
||||
properties:
|
||||
fileId: {type: string, pattern: '^[1-9][0-9]*$'}
|
||||
ownerScope: {type: string, enum: [CUSTOMER]}
|
||||
tenantId: {type: string, pattern: '^[1-9][0-9]*$'}
|
||||
businessType: {type: string, enum: [OVERSEAS_RELABEL_TOTAL_DOCUMENT, OVERSEAS_RELABEL_ITEM_DOCUMENT]}
|
||||
businessId: {type: string, pattern: '^[1-9][0-9]*$'}
|
||||
fileName: {type: string}
|
||||
sha256: {type: string, pattern: '^[0-9a-f]{64}$'}
|
||||
contentType: {type: string, enum: [application/pdf]}
|
||||
sizeBytes: {type: integer, format: int64, minimum: 1, maximum: 10485760}
|
||||
createdAt: {type: string, description: 持久化上传时间LocalDateTime,无时区偏移}
|
||||
securitySchemes:
|
||||
InternalServiceToken:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-Internal-Service-Token
|
||||
parameters:
|
||||
TenantId:
|
||||
name: tenantId
|
||||
in: path
|
||||
required: true
|
||||
schema: {type: integer, format: int64, minimum: 1}
|
||||
BusinessType:
|
||||
name: businessType
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
enum: [OVERSEAS_RELABEL_TOTAL_DOCUMENT, OVERSEAS_RELABEL_ITEM_DOCUMENT]
|
||||
BusinessId:
|
||||
name: businessId
|
||||
in: path
|
||||
required: true
|
||||
schema: {type: string, pattern: '^[1-9][0-9]*$'}
|
||||
FileId:
|
||||
name: fileId
|
||||
in: path
|
||||
required: true
|
||||
schema: {type: integer, format: int64, minimum: 1}
|
||||
Reference in New Issue
Block a user