二期内容提交
This commit is contained in:
@@ -20,9 +20,19 @@ spring:
|
||||
group: ${NACOS_GROUP:BAIYUE}
|
||||
namespace: ${NACOS_NAMESPACE:public}
|
||||
config.namespace: ${NACOS_NAMESPACE:public}
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 5MB
|
||||
max-request-size: 6MB
|
||||
baiyue:
|
||||
security:
|
||||
jwt-secret: ${JWT_SECRET:change-me-to-at-least-32-bytes-long-before-start}
|
||||
internal-service-token: ${INTERNAL_SERVICE_TOKEN:change-me-to-an-internal-token-at-least-32-bytes-long}
|
||||
clients:
|
||||
order:
|
||||
url: ${ORDER_SERVICE_URL:}
|
||||
file:
|
||||
url: ${FILE_SERVICE_URL:}
|
||||
firstleg:
|
||||
inbound:
|
||||
allow-rejected-measurement: false
|
||||
|
||||
@@ -146,6 +146,7 @@ CREATE TABLE IF NOT EXISTS fl_inbound_measurement (
|
||||
source_type VARCHAR(24) NOT NULL COMMENT '数据来源:THIRD_PARTY或MANUAL',
|
||||
source_code VARCHAR(64) NULL COMMENT '第三方应用或来源编码',
|
||||
external_event_no VARCHAR(128) NULL COMMENT '第三方事件号',
|
||||
external_request_hash CHAR(64) NULL COMMENT '第三方data原文和图片内容联合请求哈希',
|
||||
device_code VARCHAR(64) NULL COMMENT '测量设备编码',
|
||||
warehouse_code VARCHAR(50) NULL COMMENT '第三方回传仓库编码',
|
||||
measured_at DATETIME(3) NULL COMMENT '设备测量时间',
|
||||
@@ -173,6 +174,8 @@ CREATE TABLE IF NOT EXISTS fl_inbound_measurement_item (
|
||||
id BIGINT UNSIGNED NOT NULL COMMENT '测量明细ID',
|
||||
tenant_id BIGINT UNSIGNED NOT NULL COMMENT '数据所属租户ID',
|
||||
measurement_id BIGINT UNSIGNED NOT NULL COMMENT '测量批次ID',
|
||||
inbound_detail_id BIGINT UNSIGNED NULL COMMENT '绑定的订单货物明细ID,平台手工明细可为空',
|
||||
external_detail_no VARCHAR(128) NULL COMMENT '第三方测量明细唯一号,平台手工明细可为空',
|
||||
item_no VARCHAR(32) NOT NULL COMMENT '批次内明细号',
|
||||
box_specification VARCHAR(64) NOT NULL COMMENT '箱规标识',
|
||||
package_count INT UNSIGNED NOT NULL COMMENT '相同箱规箱数',
|
||||
@@ -197,6 +200,7 @@ CREATE TABLE IF NOT EXISTS fl_inbound_measurement_item (
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_measure_item_no (tenant_id, measurement_id, item_no),
|
||||
UNIQUE KEY uk_measure_external_detail (tenant_id, inbound_detail_id, external_detail_no),
|
||||
CONSTRAINT fk_measure_item_batch FOREIGN KEY (measurement_id) REFERENCES fl_inbound_measurement (id)
|
||||
) ENGINE=InnoDB COMMENT='入库长宽高和箱数测量明细';
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
-- 二期第三方单条箱规 + 单张图片绑定增量;可重复执行。
|
||||
USE baiyue_firstleg;
|
||||
|
||||
DROP PROCEDURE IF EXISTS phase2_add_measurement_column;
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE phase2_add_measurement_column(
|
||||
IN p_table VARCHAR(64), IN p_column VARCHAR(64), IN p_definition TEXT)
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = p_table AND COLUMN_NAME = p_column
|
||||
) THEN
|
||||
SET @ddl = CONCAT('ALTER TABLE `', p_table, '` ADD COLUMN `', p_column, '` ', p_definition);
|
||||
PREPARE statement FROM @ddl;
|
||||
EXECUTE statement;
|
||||
DEALLOCATE PREPARE statement;
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
CALL phase2_add_measurement_column(
|
||||
'fl_inbound_measurement', 'external_request_hash',
|
||||
'CHAR(64) NULL COMMENT ''第三方data原文和图片内容联合请求哈希'' AFTER external_event_no');
|
||||
CALL phase2_add_measurement_column(
|
||||
'fl_inbound_measurement_item', 'inbound_detail_id',
|
||||
'BIGINT UNSIGNED NULL COMMENT ''绑定的订单货物明细ID,平台手工明细可为空'' AFTER measurement_id');
|
||||
CALL phase2_add_measurement_column(
|
||||
'fl_inbound_measurement_item', 'external_detail_no',
|
||||
'VARCHAR(128) NULL COMMENT ''第三方测量明细唯一号,平台手工明细可为空'' AFTER inbound_detail_id');
|
||||
|
||||
DROP PROCEDURE IF EXISTS phase2_add_measurement_column;
|
||||
|
||||
SET @has_index = (
|
||||
SELECT COUNT(*) FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'fl_inbound_measurement_item'
|
||||
AND INDEX_NAME = 'uk_measure_external_detail'
|
||||
);
|
||||
SET @ddl = IF(
|
||||
@has_index = 0,
|
||||
'ALTER TABLE fl_inbound_measurement_item ADD UNIQUE KEY uk_measure_external_detail (tenant_id, inbound_detail_id, external_detail_no)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE statement FROM @ddl;
|
||||
EXECUTE statement;
|
||||
DEALLOCATE PREPARE statement;
|
||||
@@ -69,12 +69,13 @@ paths:
|
||||
'403': {description: 无分配权限}
|
||||
/openapi/v1/inbound-measurements:
|
||||
post:
|
||||
summary: 提交第三方长宽高测量结果
|
||||
summary: 提交一条第三方箱规测量结果和一张图片
|
||||
description: >-
|
||||
只写 fl_third_party_call_log、fl_inbound_measurement、fl_inbound_measurement_item
|
||||
和 HTTP 幂等结果,不审核、不计费、不入库,也不改变入库单状态。
|
||||
data 中的 inboundCode 匹配入库单,inboundDetailId 必须匹配该入库单关联订单中的已有货物明细;
|
||||
每次只保存一条箱规明细和一张图片,不审核、不计费、不入库,也不改变入库单状态。
|
||||
签名串依次为 METHOD、原始 PATH、X-Timestamp、X-Nonce、Idempotency-Key、
|
||||
原始 UTF-8 body 的 SHA-256 小写十六进制,六部分使用 LF(\n)连接且末尾不追加换行。
|
||||
签名body的 SHA-256 小写十六进制,六部分使用 LF(\n)连接且末尾不追加换行。
|
||||
签名body = data原始UTF-8文本 + LF + image文件内容SHA-256小写十六进制。
|
||||
三层语义:Nonce 防短时重放;Idempotency-Key 标识一次 HTTP 写操作;
|
||||
appKey + eventNo 标识第三方业务事件。
|
||||
security:
|
||||
@@ -89,8 +90,18 @@ paths:
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: {$ref: '#/components/schemas/InboundMeasurementCallbackRequest'}
|
||||
multipart/form-data:
|
||||
schema:
|
||||
type: object
|
||||
required: [data, image]
|
||||
properties:
|
||||
data:
|
||||
type: string
|
||||
description: InboundMeasurementCallbackRequest 的原始UTF-8 JSON文本
|
||||
image:
|
||||
type: string
|
||||
format: binary
|
||||
description: 当前测量明细唯一对应图片,JPG/PNG/BMP且不超过5MB
|
||||
responses:
|
||||
'200': {description: 成功或业务失败,按响应体字符串 code 判断;非法签名返回 A0401}
|
||||
'413': {description: 请求体超过网关限制}
|
||||
@@ -242,34 +253,31 @@ components:
|
||||
schemas:
|
||||
InboundMeasurementCallbackRequest:
|
||||
type: object
|
||||
required: [eventNo, warehouseCode, inboundCode, deviceCode, measuredAt, items]
|
||||
required: [eventNo, externalDetailNo, warehouseCode, inboundCode, inboundDetailId, deviceCode, measuredAt, boxSpecification, packageCount, lengthCm, widthCm, heightCm]
|
||||
properties:
|
||||
eventNo: {type: string, maxLength: 128, pattern: '^[A-Za-z0-9._:-]+$', example: M202608010001}
|
||||
externalDetailNo: {type: string, maxLength: 128, pattern: '^[A-Za-z0-9._:-]+$', example: BOX-20260801-0001}
|
||||
warehouseCode: {type: string, maxLength: 50, example: CN-YW-01}
|
||||
inboundCode: {type: string, maxLength: 40, example: RK202608010001}
|
||||
inboundDetailId: {type: string, example: '190000000000000001', description: 柏悦订单货物明细ID}
|
||||
deviceCode: {type: string, maxLength: 64, example: DEVICE-01}
|
||||
measuredAt: {type: string, format: date-time, example: '2026-08-01T10:30:00+08:00'}
|
||||
items:
|
||||
type: array
|
||||
minItems: 1
|
||||
maxItems: 500
|
||||
items: {$ref: '#/components/schemas/InboundMeasurementItem'}
|
||||
InboundMeasurementItem:
|
||||
type: object
|
||||
required: [itemNo, boxSpecification, lengthCm, widthCm, heightCm, quantity]
|
||||
properties:
|
||||
itemNo: {type: string, maxLength: 32, example: '001'}
|
||||
boxSpecification: {type: string, maxLength: 64, example: '61.5x42x42cm', description: 入库单绑定的箱规明细}
|
||||
boxSpecification: {type: string, maxLength: 64, example: '40x30x47cm'}
|
||||
lengthCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 50.20}
|
||||
widthCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 40.10}
|
||||
heightCm: {type: number, exclusiveMinimum: true, minimum: 0, example: 30.00}
|
||||
quantity: {type: integer, minimum: 1, maximum: 1000000, example: 5}
|
||||
sourceImageUrl: {type: string, maxLength: 2048, nullable: true, description: 仅随原始报文留档,不直接写文件中心}
|
||||
packageCount: {type: integer, minimum: 1, maximum: 1000000, example: 50}
|
||||
unitWeightKg: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true, example: 20}
|
||||
remark: {type: string, maxLength: 500, nullable: true}
|
||||
InboundMeasurementEventResponse:
|
||||
type: object
|
||||
properties:
|
||||
eventNo: {type: string}
|
||||
inboundCode: {type: string}
|
||||
inboundDetailId: {type: string}
|
||||
measurementId: {type: string}
|
||||
measurementItemId: {type: string}
|
||||
imageFileId: {type: string}
|
||||
accepted: {type: boolean}
|
||||
status: {type: string, enum: [RECEIVED]}
|
||||
receivedAt: {type: string, format: date-time}
|
||||
|
||||
Reference in New Issue
Block a user