优化
This commit is contained in:
@@ -4788,7 +4788,8 @@ CREATE TABLE IF NOT EXISTS fl_container_booking (
|
|||||||
destination_warehouse_name VARCHAR(128) NULL COMMENT '目的仓名称快照',
|
destination_warehouse_name VARCHAR(128) NULL COMMENT '目的仓名称快照',
|
||||||
capacity_cbm DECIMAL(18,4) NULL COMMENT '货柜容量m3',
|
capacity_cbm DECIMAL(18,4) NULL COMMENT '货柜容量m3',
|
||||||
max_weight_kg DECIMAL(18,3) NULL COMMENT '货柜最大承重kg',
|
max_weight_kg DECIMAL(18,3) NULL COMMENT '货柜最大承重kg',
|
||||||
terminal_trucking_company VARCHAR(128) NULL COMMENT '码头拖车公司',
|
terminal_trucking_company_id BIGINT UNSIGNED NULL COMMENT '码头拖车Supplier逻辑ID快照;历史数据无法推导时为空',
|
||||||
|
terminal_trucking_company VARCHAR(128) NULL COMMENT '码头拖车公司名称快照',
|
||||||
loading_at DATETIME(3) NULL COMMENT '计划或实际装柜时间',
|
loading_at DATETIME(3) NULL COMMENT '计划或实际装柜时间',
|
||||||
estimated_sailing_at DATETIME(3) NULL COMMENT '预计开船时间',
|
estimated_sailing_at DATETIME(3) NULL COMMENT '预计开船时间',
|
||||||
actual_sailing_at DATETIME(3) NULL COMMENT '实际开船时间',
|
actual_sailing_at DATETIME(3) NULL COMMENT '实际开船时间',
|
||||||
@@ -9507,7 +9508,7 @@ CREATE TABLE IF NOT EXISTS fl_customs_supplement_request (
|
|||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS fl_customs_submission_batch (
|
CREATE TABLE IF NOT EXISTS fl_customs_submission_batch (
|
||||||
id BIGINT UNSIGNED NOT NULL COMMENT '报关代理提交批次逻辑ID', customs_case_id BIGINT UNSIGNED NOT NULL COMMENT '所属报关协同单ID', batch_no VARCHAR(40) NOT NULL COMMENT '全局唯一代理提交批次号',
|
id BIGINT UNSIGNED NOT NULL COMMENT '报关代理提交批次逻辑ID', customs_case_id BIGINT UNSIGNED NOT NULL COMMENT '所属报关协同单ID', batch_no VARCHAR(40) NOT NULL COMMENT '全局唯一代理提交批次号',
|
||||||
batch_version INT UNSIGNED NOT NULL COMMENT '同一报关协同单内的提交批次版本序号', customs_agent_name VARCHAR(128) NOT NULL COMMENT '本批次接收报关资料的报关代理名称快照', external_reference VARCHAR(128) NULL COMMENT '报关代理或外部系统返回的业务参考号',
|
batch_version INT UNSIGNED NOT NULL COMMENT '同一报关协同单内的提交批次版本序号', customs_agent_id BIGINT UNSIGNED NULL COMMENT '本批次报关代理Supplier逻辑ID快照;历史数据无法推导时为空', customs_agent_name VARCHAR(128) NOT NULL COMMENT '本批次接收报关资料的报关代理名称快照', external_reference VARCHAR(128) NULL COMMENT '报关代理或外部系统返回的业务参考号',
|
||||||
file_snapshot_json JSON NOT NULL COMMENT '提交时冻结的已审核资料数组;元素包含documentId、fileId、itemCode、documentVersion和fileHash', status VARCHAR(16) NOT NULL DEFAULT 'SUBMITTED' COMMENT '代理提交状态:SUBMITTED已提交、ACKNOWLEDGED代理已确认、REJECTED代理已拒绝、COMPLETED代理处理完成', note VARCHAR(500) NULL COMMENT '提交报关代理时的平台备注',
|
file_snapshot_json JSON NOT NULL COMMENT '提交时冻结的已审核资料数组;元素包含documentId、fileId、itemCode、documentVersion和fileHash', status VARCHAR(16) NOT NULL DEFAULT 'SUBMITTED' COMMENT '代理提交状态:SUBMITTED已提交、ACKNOWLEDGED代理已确认、REJECTED代理已拒绝、COMPLETED代理处理完成', note VARCHAR(500) NULL COMMENT '提交报关代理时的平台备注',
|
||||||
submitted_by BIGINT UNSIGNED NOT NULL COMMENT '提交报关代理的平台操作人ID', submitted_by_name VARCHAR(64) NULL COMMENT '提交时的平台操作人名称快照',
|
submitted_by BIGINT UNSIGNED NOT NULL COMMENT '提交报关代理的平台操作人ID', submitted_by_name VARCHAR(64) NULL COMMENT '提交时的平台操作人名称快照',
|
||||||
submitted_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '提交报关代理时间', PRIMARY KEY (id),
|
submitted_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '提交报关代理时间', PRIMARY KEY (id),
|
||||||
@@ -9516,6 +9517,26 @@ CREATE TABLE IF NOT EXISTS fl_customs_submission_batch (
|
|||||||
CONSTRAINT chk_customs_batch_status CHECK (status IN ('SUBMITTED','ACKNOWLEDGED','REJECTED','COMPLETED'))
|
CONSTRAINT chk_customs_batch_status CHECK (status IN ('SUBMITTED','ACKNOWLEDGED','REJECTED','COMPLETED'))
|
||||||
) ENGINE=InnoDB COMMENT='报关代理提交批次及冻结文件版本';
|
) ENGINE=InnoDB COMMENT='报关代理提交批次及冻结文件版本';
|
||||||
|
|
||||||
|
-- 供应商引用快照收敛:历史名称无法反推Supplier ID,保留为空;新写入由Firstleg服务校验并持久化。
|
||||||
|
DROP PROCEDURE IF EXISTS phase3_supplier_snapshot_add_columns;
|
||||||
|
DELIMITER $$
|
||||||
|
CREATE PROCEDURE phase3_supplier_snapshot_add_columns()
|
||||||
|
BEGIN
|
||||||
|
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name='fl_container_booking')
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_container_booking' AND column_name='terminal_trucking_company_id') THEN
|
||||||
|
ALTER TABLE fl_container_booking
|
||||||
|
ADD COLUMN terminal_trucking_company_id BIGINT UNSIGNED NULL COMMENT '码头拖车Supplier逻辑ID快照;历史数据无法推导时为空' AFTER max_weight_kg;
|
||||||
|
END IF;
|
||||||
|
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name='fl_customs_submission_batch')
|
||||||
|
AND NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='fl_customs_submission_batch' AND column_name='customs_agent_id') THEN
|
||||||
|
ALTER TABLE fl_customs_submission_batch
|
||||||
|
ADD COLUMN customs_agent_id BIGINT UNSIGNED NULL COMMENT '本批次报关代理Supplier逻辑ID快照;历史数据无法推导时为空' AFTER batch_version;
|
||||||
|
END IF;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
CALL phase3_supplier_snapshot_add_columns();
|
||||||
|
DROP PROCEDURE phase3_supplier_snapshot_add_columns;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS fl_customs_receipt (
|
CREATE TABLE IF NOT EXISTS fl_customs_receipt (
|
||||||
id BIGINT UNSIGNED NOT NULL COMMENT '报关回执文件版本逻辑ID', customs_case_id BIGINT UNSIGNED NOT NULL COMMENT '所属报关协同单ID', submission_batch_id BIGINT UNSIGNED NOT NULL COMMENT '产生本回执的报关代理提交批次ID',
|
id BIGINT UNSIGNED NOT NULL COMMENT '报关回执文件版本逻辑ID', customs_case_id BIGINT UNSIGNED NOT NULL COMMENT '所属报关协同单ID', submission_batch_id BIGINT UNSIGNED NOT NULL COMMENT '产生本回执的报关代理提交批次ID',
|
||||||
receipt_type VARCHAR(16) NOT NULL COMMENT '回执类型:RECEIVED已收件、DECLARED已申报、REJECTED已拒绝、INSPECTION查验通知、RELEASED放行回执、OTHER其他回执', file_id BIGINT UNSIGNED NOT NULL COMMENT 'File服务回执文件逻辑ID;跨库不建立外键', receipt_version INT UNSIGNED NOT NULL COMMENT '同一提交批次和回执类型下的版本序号',
|
receipt_type VARCHAR(16) NOT NULL COMMENT '回执类型:RECEIVED已收件、DECLARED已申报、REJECTED已拒绝、INSPECTION查验通知、RELEASED放行回执、OTHER其他回执', file_id BIGINT UNSIGNED NOT NULL COMMENT 'File服务回执文件逻辑ID;跨库不建立外键', receipt_version INT UNSIGNED NOT NULL COMMENT '同一提交批次和回执类型下的版本序号',
|
||||||
@@ -11998,6 +12019,7 @@ CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'max_weight
|
|||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'shipping_company_id', '船司ID快照');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'shipping_company_id', '船司ID快照');
|
||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'shipping_company_name', '船司名称快照');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'shipping_company_name', '船司名称快照');
|
||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'terminal_trucking_company', '码头拖车公司');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'terminal_trucking_company', '码头拖车公司');
|
||||||
|
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'terminal_trucking_company_id', '码头拖车Supplier逻辑ID快照;历史数据无法推导时为空');
|
||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'updated_at', '货柜资料最后更新时间');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'updated_at', '货柜资料最后更新时间');
|
||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'updated_by', '最后修改人ID');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'updated_by', '最后修改人ID');
|
||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'updated_by_name', '最后修改人名称快照');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_container_booking', 'updated_by_name', '最后修改人名称快照');
|
||||||
@@ -12167,6 +12189,7 @@ CALL queue_column_comment('baiyue_firstleg', 'fl_customs_receipt', 'visibility',
|
|||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'batch_no', '全局唯一代理提交批次号');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'batch_no', '全局唯一代理提交批次号');
|
||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'batch_version', '同一报关协同单内的提交批次版本序号');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'batch_version', '同一报关协同单内的提交批次版本序号');
|
||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'customs_agent_name', '本批次接收报关资料的报关代理名称快照');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'customs_agent_name', '本批次接收报关资料的报关代理名称快照');
|
||||||
|
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'customs_agent_id', '本批次报关代理Supplier逻辑ID快照;历史数据无法推导时为空');
|
||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'customs_case_id', '所属报关协同单ID');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'customs_case_id', '所属报关协同单ID');
|
||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'external_reference', '报关代理或外部系统返回的业务参考号');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'external_reference', '报关代理或外部系统返回的业务参考号');
|
||||||
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'file_snapshot_json', '提交时冻结的已审核资料数组;元素包含documentId、fileId、itemCode、documentVersion和fileHash');
|
CALL queue_column_comment('baiyue_firstleg', 'fl_customs_submission_batch', 'file_snapshot_json', '提交时冻结的已审核资料数组;元素包含documentId、fileId、itemCode、documentVersion和fileHash');
|
||||||
|
|||||||
+1
@@ -11,6 +11,7 @@ public class CustomsSubmissionBatchEntity {
|
|||||||
private Long customsCaseId;
|
private Long customsCaseId;
|
||||||
private String batchNo;
|
private String batchNo;
|
||||||
private Integer batchVersion;
|
private Integer batchVersion;
|
||||||
|
private Long customsAgentId;
|
||||||
private String customsAgentName;
|
private String customsAgentName;
|
||||||
private String externalReference;
|
private String externalReference;
|
||||||
private String fileSnapshotJson;
|
private String fileSnapshotJson;
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ public class CustomsService {
|
|||||||
batch.setId(IdWorker.getId()); batch.setCustomsCaseId(caseId); batch.setBatchVersion(repository.batches(caseId).size() + 1);
|
batch.setId(IdWorker.getId()); batch.setCustomsCaseId(caseId); batch.setBatchVersion(repository.batches(caseId).size() + 1);
|
||||||
batch.setBatchNo("CB" + batch.getId());
|
batch.setBatchNo("CB" + batch.getId());
|
||||||
var customsAgent = suppliers.customs(request.customsAgentId(), request.customsAgentName());
|
var customsAgent = suppliers.customs(request.customsAgentId(), request.customsAgentName());
|
||||||
|
batch.setCustomsAgentId(customsAgent == null ? null : customsAgent.supplierId());
|
||||||
batch.setCustomsAgentName(customsAgent == null ? null : customsAgent.name());
|
batch.setCustomsAgentName(customsAgent == null ? null : customsAgent.name());
|
||||||
batch.setExternalReference(trim(request.externalReference())); batch.setFileSnapshotJson(json(current.stream()
|
batch.setExternalReference(trim(request.externalReference())); batch.setFileSnapshotJson(json(current.stream()
|
||||||
.map(v -> Map.of("documentId", v.getId(), "fileId", v.getFileId(), "itemCode", v.getChecklistItemCode(),
|
.map(v -> Map.of("documentId", v.getId(), "fileId", v.getFileId(), "itemCode", v.getChecklistItemCode(),
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ public final class ContainerDtos {
|
|||||||
@Size(max = 128) String destinationWarehouseName,
|
@Size(max = 128) String destinationWarehouseName,
|
||||||
@DecimalMin(value = "0", inclusive = false) BigDecimal capacityCbm,
|
@DecimalMin(value = "0", inclusive = false) BigDecimal capacityCbm,
|
||||||
@DecimalMin(value = "0", inclusive = false) BigDecimal maxWeightKg,
|
@DecimalMin(value = "0", inclusive = false) BigDecimal maxWeightKg,
|
||||||
|
@Positive Long terminalTruckingCompanyId,
|
||||||
@Size(max = 128) String terminalTruckingCompany,
|
@Size(max = 128) String terminalTruckingCompany,
|
||||||
LocalDateTime loadingAt,
|
LocalDateTime loadingAt,
|
||||||
LocalDateTime estimatedSailingAt,
|
LocalDateTime estimatedSailingAt,
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public class ContainerBookingEntity {
|
|||||||
private String destinationWarehouseName;
|
private String destinationWarehouseName;
|
||||||
private BigDecimal capacityCbm;
|
private BigDecimal capacityCbm;
|
||||||
private BigDecimal maxWeightKg;
|
private BigDecimal maxWeightKg;
|
||||||
|
private Long terminalTruckingCompanyId;
|
||||||
private String terminalTruckingCompany;
|
private String terminalTruckingCompany;
|
||||||
private LocalDateTime loadingAt;
|
private LocalDateTime loadingAt;
|
||||||
private LocalDateTime estimatedSailingAt;
|
private LocalDateTime estimatedSailingAt;
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ public interface ContainerBookingMapper extends BaseMapper<ContainerBookingEntit
|
|||||||
departure_port_name=#{value.departurePortName}, destination_port_code=#{value.destinationPortCode},
|
departure_port_name=#{value.departurePortName}, destination_port_code=#{value.destinationPortCode},
|
||||||
destination_port_name=#{value.destinationPortName}, destination_warehouse_code=#{value.destinationWarehouseCode},
|
destination_port_name=#{value.destinationPortName}, destination_warehouse_code=#{value.destinationWarehouseCode},
|
||||||
destination_warehouse_name=#{value.destinationWarehouseName}, capacity_cbm=#{value.capacityCbm},
|
destination_warehouse_name=#{value.destinationWarehouseName}, capacity_cbm=#{value.capacityCbm},
|
||||||
max_weight_kg=#{value.maxWeightKg}, terminal_trucking_company=#{value.terminalTruckingCompany},
|
max_weight_kg=#{value.maxWeightKg}, terminal_trucking_company_id=#{value.terminalTruckingCompanyId},
|
||||||
|
terminal_trucking_company=#{value.terminalTruckingCompany},
|
||||||
loading_at=#{value.loadingAt}, estimated_sailing_at=#{value.estimatedSailingAt},
|
loading_at=#{value.loadingAt}, estimated_sailing_at=#{value.estimatedSailingAt},
|
||||||
actual_sailing_at=#{value.actualSailingAt}, estimated_port_arrival_at=#{value.estimatedPortArrivalAt},
|
actual_sailing_at=#{value.actualSailingAt}, estimated_port_arrival_at=#{value.estimatedPortArrivalAt},
|
||||||
actual_port_arrival_at=#{value.actualPortArrivalAt},
|
actual_port_arrival_at=#{value.actualPortArrivalAt},
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ public class ContainerService {
|
|||||||
@Resource private LoadingPickService loadingPickService;
|
@Resource private LoadingPickService loadingPickService;
|
||||||
@Resource private PriceBookQueryRepository priceBooks;
|
@Resource private PriceBookQueryRepository priceBooks;
|
||||||
@Resource private OceanBookingRepository oceanBookings;
|
@Resource private OceanBookingRepository oceanBookings;
|
||||||
|
@Resource private WarehouseSupplierSnapshotService suppliers;
|
||||||
@Autowired(required = false) private ContainerTransportHistoryMapper transportHistories;
|
@Autowired(required = false) private ContainerTransportHistoryMapper transportHistories;
|
||||||
@Value("${baiyue.security.internal-service-token:}") private String internalToken;
|
@Value("${baiyue.security.internal-service-token:}") private String internalToken;
|
||||||
@Value("${baiyue.warehouse.public-tenant-id:0}") private long publicWarehouseTenantId;
|
@Value("${baiyue.warehouse.public-tenant-id:0}") private long publicWarehouseTenantId;
|
||||||
@@ -130,9 +131,12 @@ public class ContainerService {
|
|||||||
}
|
}
|
||||||
validateSchedule(request.data());
|
validateSchedule(request.data());
|
||||||
WarehouseMasterDataClient.Warehouse warehouse = requireDomesticTransitWarehouse(request.data().warehouseId());
|
WarehouseMasterDataClient.Warehouse warehouse = requireDomesticTransitWarehouse(request.data().warehouseId());
|
||||||
|
var trucking = suppliers.trucking(request.data().terminalTruckingCompanyId(), request.data().terminalTruckingCompany());
|
||||||
ensureUnique(trim(request.data().containerNo()), request.data().cabinetNo().trim(), id);
|
ensureUnique(trim(request.data().containerNo()), request.data().cabinetNo().trim(), id);
|
||||||
copy(current, request.data());
|
copy(current, request.data());
|
||||||
current.setWarehouseId(warehouse.id()); current.setWarehouseName(warehouse.warehouseName());
|
current.setWarehouseId(warehouse.id()); current.setWarehouseName(warehouse.warehouseName());
|
||||||
|
current.setTerminalTruckingCompanyId(trucking == null ? null : trucking.supplierId());
|
||||||
|
current.setTerminalTruckingCompany(trucking == null ? null : trucking.name());
|
||||||
try {
|
try {
|
||||||
if (repository.updateDraft(current, request.version(), operatorId, operatorName) != 1) {
|
if (repository.updateDraft(current, request.version(), operatorId, operatorName) != 1) {
|
||||||
throw conflict("货柜状态或版本已变化,请刷新后重试");
|
throw conflict("货柜状态或版本已变化,请刷新后重试");
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ CREATE TABLE IF NOT EXISTS fl_customs_submission_batch (
|
|||||||
customs_case_id BIGINT UNSIGNED NOT NULL COMMENT '所属报关协同单ID',
|
customs_case_id BIGINT UNSIGNED NOT NULL COMMENT '所属报关协同单ID',
|
||||||
batch_no VARCHAR(40) NOT NULL COMMENT '全局唯一代理提交批次号',
|
batch_no VARCHAR(40) NOT NULL COMMENT '全局唯一代理提交批次号',
|
||||||
batch_version INT UNSIGNED NOT NULL COMMENT '同一报关协同单内的提交批次版本序号',
|
batch_version INT UNSIGNED NOT NULL COMMENT '同一报关协同单内的提交批次版本序号',
|
||||||
|
customs_agent_id BIGINT UNSIGNED NULL COMMENT '本批次报关代理Supplier逻辑ID快照;历史数据无法推导时为空',
|
||||||
customs_agent_name VARCHAR(128) NOT NULL COMMENT '本批次接收报关资料的报关代理名称快照',
|
customs_agent_name VARCHAR(128) NOT NULL COMMENT '本批次接收报关资料的报关代理名称快照',
|
||||||
external_reference VARCHAR(128) NULL COMMENT '报关代理或外部系统返回的业务参考号',
|
external_reference VARCHAR(128) NULL COMMENT '报关代理或外部系统返回的业务参考号',
|
||||||
file_snapshot_json JSON NOT NULL COMMENT '提交时冻结的已审核资料数组;元素包含documentId、fileId、itemCode、documentVersion和fileHash',
|
file_snapshot_json JSON NOT NULL COMMENT '提交时冻结的已审核资料数组;元素包含documentId、fileId、itemCode、documentVersion和fileHash',
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ CREATE TABLE IF NOT EXISTS fl_container_booking (
|
|||||||
destination_warehouse_name VARCHAR(128) NULL COMMENT '目的仓名称快照',
|
destination_warehouse_name VARCHAR(128) NULL COMMENT '目的仓名称快照',
|
||||||
capacity_cbm DECIMAL(18,4) NULL COMMENT '货柜容量m3',
|
capacity_cbm DECIMAL(18,4) NULL COMMENT '货柜容量m3',
|
||||||
max_weight_kg DECIMAL(18,3) NULL COMMENT '货柜最大承重kg',
|
max_weight_kg DECIMAL(18,3) NULL COMMENT '货柜最大承重kg',
|
||||||
terminal_trucking_company VARCHAR(128) NULL COMMENT '码头拖车公司',
|
terminal_trucking_company_id BIGINT UNSIGNED NULL COMMENT '码头拖车Supplier逻辑ID快照;历史数据无法推导时为空',
|
||||||
|
terminal_trucking_company VARCHAR(128) NULL COMMENT '码头拖车公司名称快照',
|
||||||
loading_at DATETIME(3) NULL COMMENT '计划或实际装柜时间',
|
loading_at DATETIME(3) NULL COMMENT '计划或实际装柜时间',
|
||||||
estimated_sailing_at DATETIME(3) NULL COMMENT '预计开船时间',
|
estimated_sailing_at DATETIME(3) NULL COMMENT '预计开船时间',
|
||||||
actual_sailing_at DATETIME(3) NULL COMMENT '实际开船时间',
|
actual_sailing_at DATETIME(3) NULL COMMENT '实际开船时间',
|
||||||
|
|||||||
@@ -57,7 +57,12 @@ paths:
|
|||||||
summary: Submit to customs agent and freeze approved file versions in a batch snapshot
|
summary: Submit to customs agent and freeze approved file versions in a batch snapshot
|
||||||
description: customsAgentId must identify an ACTIVE Warehouse supplier in category CUSTOMS; the persisted agent name is resolved server-side and free text cannot bypass supplier validation.
|
description: customsAgentId must identify an ACTIVE Warehouse supplier in category CUSTOMS; the persisted agent name is resolved server-side and free text cannot bypass supplier validation.
|
||||||
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/SubmitBatchRequest'}}}}
|
requestBody: {required: true, content: {application/json: {schema: {$ref: '#/components/schemas/SubmitBatchRequest'}}}}
|
||||||
responses: {'200': {description: Submission batch}}
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Submission batch
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema: {$ref: '#/components/schemas/CustomsSubmissionBatch'}
|
||||||
/api/platform/v1/customs/submission-batches/{batchId}/receipts:
|
/api/platform/v1/customs/submission-batches/{batchId}/receipts:
|
||||||
parameters:
|
parameters:
|
||||||
- {name: batchId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
- {name: batchId, in: path, required: true, schema: {type: string, pattern: '^[1-9][0-9]*$'}}
|
||||||
@@ -103,3 +108,20 @@ components:
|
|||||||
externalReference: {type: string, maxLength: 128, nullable: true}
|
externalReference: {type: string, maxLength: 128, nullable: true}
|
||||||
note: {type: string, maxLength: 500, nullable: true}
|
note: {type: string, maxLength: 500, nullable: true}
|
||||||
expectedVersion: {type: integer, minimum: 0}
|
expectedVersion: {type: integer, minimum: 0}
|
||||||
|
CustomsSubmissionBatch:
|
||||||
|
type: object
|
||||||
|
required: [id, customsCaseId, batchNo, batchVersion, customsAgentName, status, submittedBy, submittedAt]
|
||||||
|
properties:
|
||||||
|
id: {type: string, pattern: '^[1-9][0-9]*$'}
|
||||||
|
customsCaseId: {type: string, pattern: '^[1-9][0-9]*$'}
|
||||||
|
batchNo: {type: string, maxLength: 40}
|
||||||
|
batchVersion: {type: integer, minimum: 1}
|
||||||
|
customsAgentId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: Server-validated CUSTOMS supplier ID snapshot; null only for non-migrated historical rows.}
|
||||||
|
customsAgentName: {type: string, maxLength: 128, description: Server-frozen Warehouse supplier name snapshot.}
|
||||||
|
externalReference: {type: string, maxLength: 128, nullable: true}
|
||||||
|
fileSnapshotJson: {type: string}
|
||||||
|
status: {type: string, enum: [SUBMITTED, ACKNOWLEDGED, REJECTED, COMPLETED]}
|
||||||
|
note: {type: string, maxLength: 500, nullable: true}
|
||||||
|
submittedBy: {type: string, pattern: '^[1-9][0-9]*$'}
|
||||||
|
submittedByName: {type: string, maxLength: 64, nullable: true}
|
||||||
|
submittedAt: {type: string, format: date-time}
|
||||||
|
|||||||
@@ -1234,7 +1234,8 @@ components:
|
|||||||
destinationWarehouseName: {type: string, maxLength: 128, nullable: true}
|
destinationWarehouseName: {type: string, maxLength: 128, nullable: true}
|
||||||
capacityCbm: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true}
|
capacityCbm: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true}
|
||||||
maxWeightKg: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true}
|
maxWeightKg: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true}
|
||||||
terminalTruckingCompany: {type: string, maxLength: 128, nullable: true}
|
terminalTruckingCompanyId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: ACTIVE Warehouse Supplier ID validated as TRUCKING}
|
||||||
|
terminalTruckingCompany: {type: string, maxLength: 128, nullable: true, description: Server-frozen Warehouse supplier name snapshot}
|
||||||
loadingAt: {type: string, format: date-time, nullable: true}
|
loadingAt: {type: string, format: date-time, nullable: true}
|
||||||
estimatedSailingAt: {type: string, format: date-time, nullable: true}
|
estimatedSailingAt: {type: string, format: date-time, nullable: true}
|
||||||
actualSailingAt: {type: string, format: date-time, nullable: true}
|
actualSailingAt: {type: string, format: date-time, nullable: true}
|
||||||
@@ -1266,7 +1267,8 @@ components:
|
|||||||
destinationWarehouseName: {type: string, maxLength: 128, nullable: true}
|
destinationWarehouseName: {type: string, maxLength: 128, nullable: true}
|
||||||
capacityCbm: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true}
|
capacityCbm: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true}
|
||||||
maxWeightKg: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true}
|
maxWeightKg: {type: number, exclusiveMinimum: true, minimum: 0, nullable: true}
|
||||||
terminalTruckingCompany: {type: string, maxLength: 128, nullable: true}
|
terminalTruckingCompanyId: {type: string, pattern: '^[1-9][0-9]*$', nullable: true, description: ACTIVE Warehouse Supplier ID validated as TRUCKING}
|
||||||
|
terminalTruckingCompany: {type: string, maxLength: 128, nullable: true, description: Optional consistency hint; persisted name always comes from Warehouse and cannot replace the ID}
|
||||||
loadingAt: {type: string, format: date-time, nullable: true}
|
loadingAt: {type: string, format: date-time, nullable: true}
|
||||||
estimatedSailingAt: {type: string, format: date-time, nullable: true}
|
estimatedSailingAt: {type: string, format: date-time, nullable: true}
|
||||||
actualSailingAt: {type: string, format: date-time, nullable: true}
|
actualSailingAt: {type: string, format: date-time, nullable: true}
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ class CustomsServiceTest {
|
|||||||
new SubmitBatchRequest(88L, "线下报关代理", "EXT-1", "提交", 4));
|
new SubmitBatchRequest(88L, "线下报关代理", "EXT-1", "提交", 4));
|
||||||
|
|
||||||
assertThat(result.getFileSnapshotJson()).contains("documentVersion").contains("INVOICE");
|
assertThat(result.getFileSnapshotJson()).contains("documentVersion").contains("INVOICE");
|
||||||
|
assertThat(result.getCustomsAgentId()).isEqualTo(88L);
|
||||||
|
assertThat(result.getCustomsAgentName()).isEqualTo("线下报关代理");
|
||||||
verify(repository).freeze(51L);
|
verify(repository).freeze(51L);
|
||||||
verify(repository).insert(any(CustomsSubmissionBatchEntity.class));
|
verify(repository).insert(any(CustomsSubmissionBatchEntity.class));
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -30,6 +30,9 @@ class Phase3FinalUnifiedSqlContractTest {
|
|||||||
.contains("CREATE TABLE IF NOT EXISTS fl_customs_case")
|
.contains("CREATE TABLE IF NOT EXISTS fl_customs_case")
|
||||||
.contains("CREATE TABLE IF NOT EXISTS fl_customs_document")
|
.contains("CREATE TABLE IF NOT EXISTS fl_customs_document")
|
||||||
.contains("CREATE TABLE IF NOT EXISTS fl_customs_submission_batch")
|
.contains("CREATE TABLE IF NOT EXISTS fl_customs_submission_batch")
|
||||||
|
.contains("customs_agent_id BIGINT UNSIGNED NULL")
|
||||||
|
.contains("terminal_trucking_company_id BIGINT UNSIGNED NULL")
|
||||||
|
.contains("phase3_supplier_snapshot_add_columns")
|
||||||
.contains("CREATE TABLE IF NOT EXISTS fl_customs_receipt")
|
.contains("CREATE TABLE IF NOT EXISTS fl_customs_receipt")
|
||||||
.contains("CREATE TABLE IF NOT EXISTS fl_port_schedule")
|
.contains("CREATE TABLE IF NOT EXISTS fl_port_schedule")
|
||||||
.contains("CREATE TABLE IF NOT EXISTS fl_port_schedule_history")
|
.contains("CREATE TABLE IF NOT EXISTS fl_port_schedule_history")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.baiyue.firstleg.service;
|
|||||||
import com.baiyue.common.core.api.ApiResponse;
|
import com.baiyue.common.core.api.ApiResponse;
|
||||||
import com.baiyue.common.core.exception.BizException;
|
import com.baiyue.common.core.exception.BizException;
|
||||||
import com.baiyue.firstleg.client.WarehouseMasterDataClient;
|
import com.baiyue.firstleg.client.WarehouseMasterDataClient;
|
||||||
|
import com.baiyue.firstleg.client.WarehouseSupplierClient;
|
||||||
import com.baiyue.firstleg.dto.ContainerDtos.FullUpdateRequest;
|
import com.baiyue.firstleg.dto.ContainerDtos.FullUpdateRequest;
|
||||||
import com.baiyue.firstleg.dto.ContainerDtos.SaveRequest;
|
import com.baiyue.firstleg.dto.ContainerDtos.SaveRequest;
|
||||||
import com.baiyue.firstleg.dto.ContainerDtos.SimulationCreateRequest;
|
import com.baiyue.firstleg.dto.ContainerDtos.SimulationCreateRequest;
|
||||||
@@ -51,6 +52,7 @@ class ContainerServiceTest {
|
|||||||
@MockBean private LoadingPickService loadingPickService;
|
@MockBean private LoadingPickService loadingPickService;
|
||||||
@MockBean private PriceBookQueryRepository priceBooks;
|
@MockBean private PriceBookQueryRepository priceBooks;
|
||||||
@MockBean private OceanBookingRepository oceanBookings;
|
@MockBean private OceanBookingRepository oceanBookings;
|
||||||
|
@MockBean private WarehouseSupplierSnapshotService suppliers;
|
||||||
@MockBean private ContainerTransportHistoryMapper transportHistories;
|
@MockBean private ContainerTransportHistoryMapper transportHistories;
|
||||||
@Resource private ContainerService service;
|
@Resource private ContainerService service;
|
||||||
|
|
||||||
@@ -58,6 +60,8 @@ class ContainerServiceTest {
|
|||||||
void setUpWarehouse() {
|
void setUpWarehouse() {
|
||||||
when(warehouses.active(anyString(), anyLong(), anyLong())).thenAnswer(invocation ->
|
when(warehouses.active(anyString(), anyLong(), anyLong())).thenAnswer(invocation ->
|
||||||
activeWarehouse(invocation.getArgument(2, Long.class), "DOMESTIC", "上海中转仓"));
|
activeWarehouse(invocation.getArgument(2, Long.class), "DOMESTIC", "上海中转仓"));
|
||||||
|
when(suppliers.trucking(202L, "拖车公司A"))
|
||||||
|
.thenReturn(new WarehouseSupplierClient.Snapshot(202L, "拖车公司A", "TRUCKING", null, "ACTIVE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -320,7 +324,7 @@ class ContainerServiceTest {
|
|||||||
private static SaveRequest request(String cabinetNo) {
|
private static SaveRequest request(String cabinetNo) {
|
||||||
return new SaveRequest("MSCU1234567", cabinetNo, 101L, "上海仓", "BOL-001", "柏悦轮",
|
return new SaveRequest("MSCU1234567", cabinetNo, 101L, "上海仓", "BOL-001", "柏悦轮",
|
||||||
"V001", "40HQ", 201L, "船司A", "CNSHA", "上海港", "USLAX", "洛杉矶港",
|
"V001", "40HQ", 201L, "船司A", "CNSHA", "上海港", "USLAX", "洛杉矶港",
|
||||||
"ONT8", "ONT8", new BigDecimal("68.0000"), new BigDecimal("26000.000"), "拖车公司A",
|
"ONT8", "ONT8", new BigDecimal("68.0000"), new BigDecimal("26000.000"), 202L, "拖车公司A",
|
||||||
LocalDateTime.of(2026, 8, 10, 8, 0), LocalDateTime.of(2026, 8, 12, 8, 0), null,
|
LocalDateTime.of(2026, 8, 10, 8, 0), LocalDateTime.of(2026, 8, 12, 8, 0), null,
|
||||||
LocalDateTime.of(2026, 8, 25, 8, 0), null,
|
LocalDateTime.of(2026, 8, 25, 8, 0), null,
|
||||||
LocalDateTime.of(2026, 8, 27, 8, 0), null);
|
LocalDateTime.of(2026, 8, 27, 8, 0), null);
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
- 负责头程订单主数据、货物明细、快照、状态编排、幂等、Outbox 和内部货物查询。
|
- 负责头程订单主数据、货物明细、快照、状态编排、幂等、Outbox 和内部货物查询。
|
||||||
- 订单交易状态归本模块;履约/入库状态归 `firstleg/`,仓储资源归 `warehouse/`,不得跨库读取。
|
- 订单交易状态归本模块;履约/入库状态归 `firstleg/`,仓储资源归 `warehouse/`,不得跨库读取。
|
||||||
- `tenant_id` 是客户隔离键;`customer_id` 是业务客户/往来单位快照,不能替代前者。
|
- `tenant_id` 是客户隔离键;`customer_id` 是客户/企业账号 ID,商户下单时固定来自认证上下文,不得指向 Warehouse 往来单位。发货单位、收货单位只保存为订单 Party 引用与业务快照。
|
||||||
|
|
||||||
## 模块入口
|
## 模块入口
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
package com.baiyue.order.client;
|
|
||||||
|
|
||||||
import com.baiyue.common.core.api.ApiResponse;
|
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@FeignClient(name="warehouse-service", contextId="warehousePartnerClient",
|
|
||||||
url="${baiyue.clients.warehouse.url:}", path="/internal/warehouse-partners")
|
|
||||||
public interface PartnerClient {
|
|
||||||
@GetMapping("/{tenantId}/{id}/active")
|
|
||||||
ApiResponse<Partner> active(@RequestHeader("X-Internal-Service-Token") String token,
|
|
||||||
@PathVariable("tenantId") long tenantId, @PathVariable("id") long id);
|
|
||||||
record Partner(Long id, Long tenantId, String partnerName, String status,
|
|
||||||
String partnerType, List<String> types) { }
|
|
||||||
}
|
|
||||||
@@ -28,7 +28,8 @@ public final class OrderRequests {
|
|||||||
|
|
||||||
@Schema(name = "FirstLegOrderSaveRequest", description = "First-leg order create or update request / 头程订单新增或更新请求")
|
@Schema(name = "FirstLegOrderSaveRequest", description = "First-leg order create or update request / 头程订单新增或更新请求")
|
||||||
public record SaveRequest(
|
public record SaveRequest(
|
||||||
@Schema(description = "Customer ID / 客户 ID", example = "30001") Long customerId,
|
@Schema(description = "Deprecated and ignored. Customer ID is always taken from authenticated enterprise context / 已废弃并忽略,客户 ID 固定取认证企业上下文", deprecated = true)
|
||||||
|
Long customerId,
|
||||||
@Schema(description = "Customer name / 客户名称", example = "Shenzhen Example Trading Co., Ltd. / 深圳示例贸易有限公司", maxLength = 128, requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "Customer name / 客户名称", example = "Shenzhen Example Trading Co., Ltd. / 深圳示例贸易有限公司", maxLength = 128, requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
@NotBlank @Size(max = 128) String customerName,
|
@NotBlank @Size(max = 128) String customerName,
|
||||||
@Schema(description = "Transport mode / 运输方式", example = "SEA", allowableValues = {"SEA", "AIR", "RAIL", "TRUCK"}, requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "Transport mode / 运输方式", example = "SEA", allowableValues = {"SEA", "AIR", "RAIL", "TRUCK"}, requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
|||||||
@@ -590,7 +590,8 @@ components:
|
|||||||
items: {$ref: '#/components/schemas/FirstLegOrderCargo'}
|
items: {$ref: '#/components/schemas/FirstLegOrderCargo'}
|
||||||
description: >-
|
description: >-
|
||||||
订单保存请求中的完整字段以服务端 FirstLegOrderSaveRequest 为准;pricingTaxMode
|
订单保存请求中的完整字段以服务端 FirstLegOrderSaveRequest 为准;pricingTaxMode
|
||||||
是新建和编辑订单的必填报价维度;历史存量订单的响应字段仍允许为空。
|
是新建和编辑订单的必填报价维度;customerId 不接受客户端指定,服务端始终使用认证企业 ID;
|
||||||
|
发货单位和收货单位仅通过 sender/receiver 保存业务快照。历史存量订单的响应字段仍允许为空。
|
||||||
FirstLegBatchDraftItem:
|
FirstLegBatchDraftItem:
|
||||||
type: object
|
type: object
|
||||||
required: [clientRowId, draft]
|
required: [clientRowId, draft]
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
class WarehouseFeignContractTest {
|
class WarehouseFeignContractTest {
|
||||||
@Test void clientsUseNacosServiceNameAndInternalPathsByDefault() throws Exception {
|
@Test void clientsUseNacosServiceNameAndInternalPathsByDefault() throws Exception {
|
||||||
assertClient(WarehouseClient.class, "/internal/warehouses");
|
assertClient(WarehouseClient.class, "/internal/warehouses");
|
||||||
assertClient(PartnerClient.class, "/internal/warehouse-partners");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertClient(Class<?> type, String expectedPath) throws Exception {
|
private void assertClient(Class<?> type, String expectedPath) throws Exception {
|
||||||
|
|||||||
@@ -363,7 +363,7 @@ class OrderApplicationServiceStateTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void publicDestinationCanBeSavedWithoutPartnerSenderOrReceiver() {
|
void publicDestinationUsesAuthenticatedEnterpriseAsCustomerWithoutPartySnapshots() {
|
||||||
OrderRepository repository = mock(OrderRepository.class);
|
OrderRepository repository = mock(OrderRepository.class);
|
||||||
OrderEligibilityGuard eligibility = mock(OrderEligibilityGuard.class);
|
OrderEligibilityGuard eligibility = mock(OrderEligibilityGuard.class);
|
||||||
OrderMasterDataGuard masterData = mock(OrderMasterDataGuard.class);
|
OrderMasterDataGuard masterData = mock(OrderMasterDataGuard.class);
|
||||||
@@ -374,7 +374,7 @@ class OrderApplicationServiceStateTest {
|
|||||||
service(repository, eligibility, masterData)
|
service(repository, eligibility, masterData)
|
||||||
.createDraft(20002L, 2L, request, "public-destination-no-parties");
|
.createDraft(20002L, 2L, request, "public-destination-no-parties");
|
||||||
|
|
||||||
verify(repository).insertOrder(argThat(order -> order.getCustomerId() == null
|
verify(repository).insertOrder(argThat(order -> Long.valueOf(20002L).equals(order.getCustomerId())
|
||||||
&& "当前企业".equals(order.getCustomerName())));
|
&& "当前企业".equals(order.getCustomerName())));
|
||||||
verify(repository, never()).insertParty(any());
|
verify(repository, never()).insertParty(any());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class OrderMasterDataGuardTest {
|
|||||||
"CN", null, "深圳", null, "地址", null);
|
"CN", null, "深圳", null, "地址", null);
|
||||||
var cargo = new OrderRequests.Cargo("货物", null, "CARTON", 1, BigDecimal.ONE, BigDecimal.ONE,
|
var cargo = new OrderRequests.Cargo("货物", null, "CARTON", 1, BigDecimal.ONE, BigDecimal.ONE,
|
||||||
null, null, null, null, null, false, null, null, null, null, null, null, null, null,
|
null, null, null, null, null, false, null, null, null, null, null, null, null, null,
|
||||||
null, null, null, null, null, null, null, null, null, null);
|
null, null, null, null, null, null, null, null, null, null, null);
|
||||||
return new OrderRequests.SaveRequest(null, "当前企业", "SEA", null, "CN", destinationWarehouseId,
|
return new OrderRequests.SaveRequest(null, "当前企业", "SEA", null, "CN", destinationWarehouseId,
|
||||||
"目的仓", null, null, party, party, List.of(cargo), "PICKUP", receivingWarehouseId,
|
"目的仓", null, null, party, party, List.of(cargo), "PICKUP", receivingWarehouseId,
|
||||||
"收货仓", "CH", "渠道", null, null, "BUY_DECLARATION", null, "LCL", false,
|
"收货仓", "CH", "渠道", null, null, "BUY_DECLARATION", null, "LCL", false,
|
||||||
|
|||||||
+12
-1
@@ -28,7 +28,10 @@ class WarehouseSchemaContractTest {
|
|||||||
"contact_phone", "contact_email", "country_code", "province", "city", "district", "address_line",
|
"contact_phone", "contact_email", "country_code", "province", "city", "district", "address_line",
|
||||||
"postal_code", "status", "remark");
|
"postal_code", "status", "remark");
|
||||||
assertThat(sql).contains("CREATE TABLE IF NOT EXISTS wh_partner_type")
|
assertThat(sql).contains("CREATE TABLE IF NOT EXISTS wh_partner_type")
|
||||||
.contains("idx_wh_partner_type_scope");
|
.contains("idx_wh_partner_type_scope")
|
||||||
|
.contains("chk_wh_partner_type CHECK (partner_type IN ('CUSTOMER','CARRIER','SHIPPER','CONSIGNEE'))")
|
||||||
|
.contains("chk_wh_partner_type_value CHECK (partner_type IN ('CUSTOMER','CARRIER','SHIPPER','CONSIGNEE'))")
|
||||||
|
.doesNotContain("CUSTOMS_BROKER", "SUPPLIER或BOTH");
|
||||||
assertBaseColumns(sql);
|
assertBaseColumns(sql);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +141,14 @@ class WarehouseSchemaContractTest {
|
|||||||
.contains("库位活动预占或占用唯一约束不完整");
|
.contains("库位活动预占或占用唯一约束不完整");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void unifiedSqlUsesOnlyNonSupplierPartnerTypes() throws IOException {
|
||||||
|
String unified = Files.readString(Path.of("..", "deploy", "sql", "头程数据库统一增量-MySQL8.sql"));
|
||||||
|
assertThat(tableDefinition(unified, "wh_partner"))
|
||||||
|
.contains("chk_wh_partner_type CHECK (partner_type IN ('CUSTOMER','CARRIER','SHIPPER','CONSIGNEE'))")
|
||||||
|
.doesNotContain("CUSTOMS_BROKER", "SUPPLIER或BOTH");
|
||||||
|
}
|
||||||
|
|
||||||
private static String read(String file) throws IOException {
|
private static String read(String file) throws IOException {
|
||||||
return Files.readString(Path.of("src/main/resources/db", file));
|
return Files.readString(Path.of("src/main/resources/db", file));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user