Merge branch 'dev-lyhfive' of http://git.buggoglobal.com/java-project/baiyue-firstleg into dev
This commit is contained in:
+110
-1
@@ -239,6 +239,9 @@ CREATE TABLE IF NOT EXISTS ll_inbound_plan (
|
||||
UNIQUE KEY uk_ll_inbound_plan_container (tenant_id,container_no)
|
||||
) ENGINE=InnoDB COMMENT='尾程入库计划表:每个租户的每个集装箱生成一张入库单';
|
||||
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_inbound_plan' AND column_name='version'), 'SELECT 1', 'ALTER TABLE ll_inbound_plan ADD COLUMN version INT NOT NULL DEFAULT 0 COMMENT ''入库计划乐观锁版本'' AFTER updated_at'));
|
||||
PREPARE ll_inbound_plan_version_ddl FROM @ddl; EXECUTE ll_inbound_plan_version_ddl; DEALLOCATE PREPARE ll_inbound_plan_version_ddl;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_inbound_plan_line (
|
||||
id BIGINT NOT NULL COMMENT '入库计划明细ID(雪花ID)',
|
||||
plan_id BIGINT NOT NULL COMMENT '入库计划ID',
|
||||
@@ -440,6 +443,7 @@ CREATE TABLE IF NOT EXISTS ll_order (
|
||||
relabel_order_no VARCHAR(128) NULL COMMENT '换标单号',
|
||||
relabel_status VARCHAR(32) NULL COMMENT '换标状态',
|
||||
pallet_merge_flag VARCHAR(32) NULL COMMENT '合托标记',
|
||||
pallet_merge_batch_id VARCHAR(64) NULL COMMENT '平台预标记合托分组号',
|
||||
current_status VARCHAR(32) NOT NULL DEFAULT 'PENDING_ASSIGNMENT' COMMENT '当前业务状态',
|
||||
private_remark VARCHAR(1000) NULL COMMENT '备注(仅自己)',
|
||||
customer_remark VARCHAR(1000) NULL COMMENT '备注(客户)',
|
||||
@@ -457,6 +461,9 @@ CREATE TABLE IF NOT EXISTS ll_order (
|
||||
KEY idx_ll_order_list (tenant_id,current_status,created_at)
|
||||
) ENGINE=InnoDB COMMENT='尾程订单主表';
|
||||
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_order' AND column_name='pallet_merge_batch_id'), 'SELECT 1', 'ALTER TABLE ll_order ADD COLUMN pallet_merge_batch_id VARCHAR(64) NULL COMMENT ''平台预标记合托分组号'' AFTER pallet_merge_flag'));
|
||||
PREPARE ll_order_merge_batch_ddl FROM @ddl; EXECUTE ll_order_merge_batch_ddl; DEALLOCATE PREPARE ll_order_merge_batch_ddl;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_order_detail (
|
||||
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '订单明细主键',
|
||||
order_id BIGINT NOT NULL COMMENT '尾程订单ID',
|
||||
@@ -1386,7 +1393,7 @@ CREATE TABLE IF NOT EXISTS ll_overseas_procurement_order (
|
||||
product_specification VARCHAR(500) NULL COMMENT '产品规格', product_url VARCHAR(2000) NULL COMMENT '产品链接', purchase_quantity BIGINT NOT NULL COMMENT '采购数量',
|
||||
budget_unit_price DECIMAL(18,2) NULL COMMENT '预算单价', currency CHAR(3) NOT NULL DEFAULT 'USD' COMMENT '币种', receiving_address VARCHAR(1000) NULL COMMENT '收货地址',
|
||||
contact_name VARCHAR(128) NOT NULL COMMENT '联系人姓名', contact_phone VARCHAR(64) NOT NULL COMMENT '联系人电话', purchase_warehouse_id VARCHAR(128) NULL COMMENT '采购入仓仓库ID',
|
||||
purchase_warehouse_name VARCHAR(255) NULL COMMENT '采购入仓仓库名称', inbound_quantity BIGINT NOT NULL DEFAULT 0 COMMENT '累计入库数量', outbound_quantity BIGINT NOT NULL DEFAULT 0 COMMENT '累计出库数量',
|
||||
purchase_warehouse_name VARCHAR(255) NULL COMMENT '采购入仓仓库名称', inbound_quantity BIGINT NOT NULL DEFAULT 0 COMMENT '累计入库数量', outbound_details JSON NULL COMMENT '出库明细', outbound_quantity BIGINT NOT NULL DEFAULT 0 COMMENT '累计出库数量',
|
||||
domestic_carrier VARCHAR(128) NULL COMMENT '境内承运商', domestic_tracking_no VARCHAR(128) NULL COMMENT '境内物流单号', overseas_carrier VARCHAR(128) NULL COMMENT '海外承运商',
|
||||
overseas_tracking_no VARCHAR(128) NULL COMMENT '海外物流单号', estimated_arrival_at DATETIME(3) NULL COMMENT '预计到达时间', status VARCHAR(32) NOT NULL DEFAULT 'PENDING_REVIEW' COMMENT '业务状态',
|
||||
remark VARCHAR(1000) NULL COMMENT '备注', idempotency_key VARCHAR(255) NOT NULL COMMENT '业务幂等键', request_hash CHAR(64) NOT NULL COMMENT '请求内容哈希',
|
||||
@@ -3195,6 +3202,8 @@ SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE tab
|
||||
PREPARE schema_comments_025 FROM @ddl; EXECUTE schema_comments_025; DEALLOCATE PREPARE schema_comments_025;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_overseas_procurement_order' AND column_name='inbound_quantity' AND COALESCE(column_comment,'') <> '累计入库数量'), 'ALTER TABLE ll_overseas_procurement_order MODIFY COLUMN inbound_quantity BIGINT NOT NULL DEFAULT 0 COMMENT ''累计入库数量''', 'SELECT 1'));
|
||||
PREPARE schema_comments_025 FROM @ddl; EXECUTE schema_comments_025; DEALLOCATE PREPARE schema_comments_025;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_overseas_procurement_order' AND column_name='outbound_details'), 'SELECT 1', 'ALTER TABLE ll_overseas_procurement_order ADD COLUMN outbound_details JSON NULL COMMENT ''出库明细'' AFTER inbound_quantity'));
|
||||
PREPARE schema_comments_025 FROM @ddl; EXECUTE schema_comments_025; DEALLOCATE PREPARE schema_comments_025;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_overseas_procurement_order' AND column_name='outbound_quantity' AND COALESCE(column_comment,'') <> '累计出库数量'), 'ALTER TABLE ll_overseas_procurement_order MODIFY COLUMN outbound_quantity BIGINT NOT NULL DEFAULT 0 COMMENT ''累计出库数量''', 'SELECT 1'));
|
||||
PREPARE schema_comments_025 FROM @ddl; EXECUTE schema_comments_025; DEALLOCATE PREPARE schema_comments_025;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_overseas_procurement_order' AND column_name='domestic_carrier' AND COALESCE(column_comment,'') <> '境内承运商'), 'ALTER TABLE ll_overseas_procurement_order MODIFY COLUMN domestic_carrier VARCHAR(128) NULL COMMENT ''境内承运商''', 'SELECT 1'));
|
||||
@@ -3805,7 +3814,107 @@ SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE tab
|
||||
AND table_name='ll_cargo_discard_application' AND column_name='review_idempotency_key'),
|
||||
'SELECT 1', 'ALTER TABLE ll_cargo_discard_application ADD COLUMN review_idempotency_key VARCHAR(255) NULL COMMENT ''审核幂等键'' AFTER request_hash'));
|
||||
PREPARE phase4_discard_review_stmt FROM @ddl; EXECUTE phase4_discard_review_stmt; DEALLOCATE PREPARE phase4_discard_review_stmt;
|
||||
|
||||
-- 一件代发出库与 PDA 按托盘拣货出库。
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_order' AND column_name='outbound_type'), 'SELECT 1', 'ALTER TABLE ll_outbound_order ADD COLUMN outbound_type VARCHAR(32) NOT NULL DEFAULT ''DISPATCH_DELIVERY'' COMMENT ''出库类型'' AFTER status'));
|
||||
PREPARE dropship_outbound_stmt FROM @ddl; EXECUTE dropship_outbound_stmt; DEALLOCATE PREPARE dropship_outbound_stmt;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_order' AND column_name='recipient_info'), 'SELECT 1', 'ALTER TABLE ll_outbound_order ADD COLUMN recipient_info VARCHAR(1000) NULL COMMENT ''一件代发收件信息'' AFTER outbound_type'));
|
||||
PREPARE dropship_outbound_stmt FROM @ddl; EXECUTE dropship_outbound_stmt; DEALLOCATE PREPARE dropship_outbound_stmt;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_pallet_item' AND column_name='picked_package_count'), 'SELECT 1', 'ALTER TABLE ll_outbound_pallet_item ADD COLUMN picked_package_count INT NOT NULL DEFAULT 0 COMMENT ''已拣箱数'' AFTER package_count'));
|
||||
PREPARE dropship_outbound_stmt FROM @ddl; EXECUTE dropship_outbound_stmt; DEALLOCATE PREPARE dropship_outbound_stmt;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_pallet_item' AND column_name='status'), 'SELECT 1', 'ALTER TABLE ll_outbound_pallet_item ADD COLUMN status VARCHAR(32) NOT NULL DEFAULT ''WAIT_PICK'' COMMENT ''拣货状态'' AFTER picked_package_count'));
|
||||
PREPARE dropship_outbound_stmt FROM @ddl; EXECUTE dropship_outbound_stmt; DEALLOCATE PREPARE dropship_outbound_stmt;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_outbound_pallet_item' AND column_name='sku_code'), 'SELECT 1', 'ALTER TABLE ll_outbound_pallet_item ADD COLUMN sku_code VARCHAR(128) NULL COMMENT ''一件代发SKU'' AFTER status'));
|
||||
PREPARE dropship_outbound_stmt FROM @ddl; EXECUTE dropship_outbound_stmt; DEALLOCATE PREPARE dropship_outbound_stmt;
|
||||
ALTER TABLE ll_outbound_order MODIFY COLUMN dispatch_order_id BIGINT NULL COMMENT '派车单ID,一件代发为空', MODIFY COLUMN dispatch_no VARCHAR(64) NULL COMMENT '派车单号,一件代发为空';
|
||||
CREATE TABLE IF NOT EXISTS ll_outbound_pda_task (id BIGINT NOT NULL COMMENT '主键ID',customer_id VARCHAR(128) NOT NULL COMMENT '客户数据隔离键',outbound_order_id BIGINT NOT NULL COMMENT '出库单ID',task_no VARCHAR(64) NOT NULL COMMENT 'PDA任务号',status VARCHAR(32) NOT NULL DEFAULT 'PENDING' COMMENT '任务状态',pushed_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '推送时间',completed_at DATETIME(3) NULL COMMENT '完成时间',created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',PRIMARY KEY(id),UNIQUE KEY uk_ll_outbound_pda_task_order(customer_id,outbound_order_id),UNIQUE KEY uk_ll_outbound_pda_task_no(customer_id,task_no)) ENGINE=InnoDB COMMENT='一件代发出库PDA拣货任务';
|
||||
CREATE TABLE IF NOT EXISTS ll_outbound_pda_pick (id BIGINT NOT NULL COMMENT '主键ID',customer_id VARCHAR(128) NOT NULL COMMENT '客户数据隔离键',task_id BIGINT NOT NULL COMMENT 'PDA任务ID',outbound_pallet_item_id BIGINT NOT NULL COMMENT '出库托盘明细ID',inventory_position_id BIGINT NOT NULL COMMENT '库存仓位ID',packages BIGINT NOT NULL COMMENT '拣货箱数',idempotency_key VARCHAR(255) NOT NULL COMMENT '拣货幂等键',picked_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '拣货时间',PRIMARY KEY(id),UNIQUE KEY uk_ll_outbound_pda_pick_key(customer_id,idempotency_key)) ENGINE=InnoDB COMMENT='一件代发出库PDA托盘拣货记录';
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE()
|
||||
AND table_name='ll_cargo_discard_application' AND column_name='review_request_hash'),
|
||||
'SELECT 1', 'ALTER TABLE ll_cargo_discard_application ADD COLUMN review_request_hash CHAR(64) NULL COMMENT ''审核请求内容哈希'' AFTER review_idempotency_key'));
|
||||
PREPARE phase4_discard_review_stmt FROM @ddl; EXECUTE phase4_discard_review_stmt; DEALLOCATE PREPARE phase4_discard_review_stmt;
|
||||
CREATE TABLE IF NOT EXISTS ll_order_fee (
|
||||
id BIGINT NOT NULL COMMENT '费用明细主键', customer_id VARCHAR(128) NOT NULL COMMENT '客户数据隔离键',
|
||||
order_id BIGINT NOT NULL COMMENT '尾程订单ID', fee_item VARCHAR(128) NOT NULL COMMENT '费用项目',
|
||||
currency VARCHAR(3) NOT NULL COMMENT '币种代码', amount DECIMAL(18,2) NOT NULL COMMENT '费用金额',
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'PENDING_REVIEW' COMMENT '费用状态:PENDING_REVIEW待审核、APPROVED审核通过、REJECTED已驳回',
|
||||
supplier_description VARCHAR(500) NULL COMMENT '供应商或费用说明', created_by VARCHAR(128) NOT NULL COMMENT '创建操作人',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||
PRIMARY KEY(id), KEY idx_ll_order_fee_customer_order(customer_id,order_id,created_at)
|
||||
) ENGINE=InnoDB COMMENT='尾程订单费用明细';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_order_operation_log (
|
||||
id BIGINT NOT NULL COMMENT '操作记录主键', customer_id VARCHAR(128) NOT NULL COMMENT '客户数据隔离键',
|
||||
order_id BIGINT NOT NULL COMMENT '尾程订单ID', operation_node VARCHAR(64) NOT NULL COMMENT '操作节点',
|
||||
operator_name VARCHAR(128) NOT NULL COMMENT '操作人名称', result VARCHAR(500) NOT NULL COMMENT '处理结果',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '操作时间',
|
||||
PRIMARY KEY(id), KEY idx_ll_order_operation_customer_order(customer_id,order_id,created_at)
|
||||
) ENGINE=InnoDB COMMENT='尾程订单操作记录';
|
||||
|
||||
-- 派送单列表与详情快照、转派送费用及操作记录。
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_delivery_order' AND column_name='overseas_warehouse_name'), 'SELECT 1', 'ALTER TABLE ll_delivery_order ADD COLUMN overseas_warehouse_name VARCHAR(255) NULL COMMENT ''海外仓名称快照'', ADD COLUMN customer_name VARCHAR(255) NULL COMMENT ''客户名称快照'', ADD COLUMN waybill_no VARCHAR(128) NULL COMMENT ''承运运单号'', ADD COLUMN delivery_method VARCHAR(32) NULL COMMENT ''派送方式'', ADD COLUMN carrier_name VARCHAR(255) NULL COMMENT ''派送承运商'', ADD COLUMN pickup_method VARCHAR(64) NULL COMMENT ''提货方式'', ADD COLUMN loading_type VARCHAR(64) NULL COMMENT ''装车类型'', ADD COLUMN vehicle_type VARCHAR(64) NULL COMMENT ''车辆类型'', ADD COLUMN vehicle_size VARCHAR(64) NULL COMMENT ''车辆大小'', ADD COLUMN vehicle_plate VARCHAR(64) NULL COMMENT ''车牌号'', ADD COLUMN driver_name VARCHAR(128) NULL COMMENT ''司机或车队名称'', ADD COLUMN driver_phone VARCHAR(64) NULL COMMENT ''车队联系电话'', ADD COLUMN appointment_account VARCHAR(128) NULL COMMENT ''预约账号'', ADD COLUMN seller_name VARCHAR(128) NULL COMMENT ''卖家姓名'', ADD COLUMN total_weight_kg DECIMAL(18,4) NOT NULL DEFAULT 0 COMMENT ''总重量(千克)'', ADD COLUMN total_volume_cbm DECIMAL(18,4) NOT NULL DEFAULT 0 COMMENT ''总体积(立方米)'', ADD COLUMN planned_delivery_at DATETIME(3) NULL COMMENT ''预计派送时间'', ADD COLUMN dispatched_at DATETIME(3) NULL COMMENT ''实际派送时间'', ADD COLUMN expected_arrival_at DATETIME(3) NULL COMMENT ''预计到达时间'', ADD COLUMN signed_at DATETIME(3) NULL COMMENT ''签收时间'', ADD COLUMN remark VARCHAR(1000) NULL COMMENT ''派送备注'''));
|
||||
PREPARE delivery_detail_stmt FROM @ddl; EXECUTE delivery_detail_stmt; DEALLOCATE PREPARE delivery_detail_stmt;
|
||||
CREATE TABLE IF NOT EXISTS ll_delivery_fee (id BIGINT NOT NULL COMMENT '派送费用主键', customer_id VARCHAR(128) NOT NULL COMMENT '客户数据隔离键', delivery_order_id BIGINT NOT NULL COMMENT '派送单ID', fee_direction VARCHAR(16) NOT NULL DEFAULT 'PAYABLE' COMMENT '应收应付方向', fee_type VARCHAR(64) NOT NULL COMMENT '费用类型', currency VARCHAR(8) NOT NULL COMMENT '币种', amount DECIMAL(18,2) NOT NULL COMMENT '费用金额', remark VARCHAR(500) NULL COMMENT '费用备注', created_by VARCHAR(128) NULL COMMENT '创建人ID', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间', PRIMARY KEY(id), KEY idx_ll_delivery_fee_order(customer_id,delivery_order_id,id)) ENGINE=InnoDB COMMENT='派送单费用明细';
|
||||
CREATE TABLE IF NOT EXISTS ll_delivery_operation (id BIGINT NOT NULL COMMENT '派送操作主键', customer_id VARCHAR(128) NOT NULL COMMENT '客户数据隔离键', delivery_order_id BIGINT NOT NULL COMMENT '派送单ID', operation_node VARCHAR(64) NOT NULL COMMENT '操作节点', operator_id VARCHAR(128) NULL COMMENT '操作人ID', operator_name VARCHAR(128) NULL COMMENT '操作人名称', result VARCHAR(500) NOT NULL COMMENT '处理结果', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '操作时间', PRIMARY KEY(id), KEY idx_ll_delivery_operation_order(customer_id,delivery_order_id,created_at,id)) ENGINE=InnoDB COMMENT='派送单操作记录';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_exception_order (
|
||||
id BIGINT NOT NULL COMMENT '异常订单ID', customer_id VARCHAR(128) NOT NULL COMMENT '客户数据隔离键', exception_no VARCHAR(64) NOT NULL COMMENT '异常订单号',
|
||||
exception_type VARCHAR(32) NOT NULL COMMENT '异常类型', status VARCHAR(32) NOT NULL DEFAULT 'PENDING' COMMENT '异常处理状态', reason VARCHAR(1000) NOT NULL COMMENT '异常原因',
|
||||
last_mile_order_id BIGINT NULL COMMENT '关联尾程订单ID', last_mile_order_no VARCHAR(64) NULL COMMENT '关联尾程订单号', inbound_order_id BIGINT NULL COMMENT '关联入仓单ID', inbound_code VARCHAR(128) NULL COMMENT '关联入仓码',
|
||||
delivery_order_id BIGINT NULL COMMENT '关联派送单ID', delivery_no VARCHAR(64) NULL COMMENT '关联派送单号', outbound_no VARCHAR(64) NULL COMMENT '关联出库单号',
|
||||
customer_name VARCHAR(255) NULL COMMENT '客户名称快照', overseas_warehouse_id VARCHAR(128) NULL COMMENT '海外仓ID快照', overseas_warehouse_name VARCHAR(255) NULL COMMENT '海外仓名称快照',
|
||||
sku_code VARCHAR(128) NULL COMMENT '异常货物SKU', package_count INT NULL COMMENT '异常箱数', return_direction VARCHAR(32) NULL COMMENT '退回方向', return_logistics_no VARCHAR(128) NULL COMMENT '退回物流单号',
|
||||
handling_action VARCHAR(500) NULL COMMENT '异常处理措施', handler_id VARCHAR(128) NULL COMMENT '处理人ID', handler_name VARCHAR(128) NULL COMMENT '处理人名称',
|
||||
source_type VARCHAR(32) NOT NULL DEFAULT 'MANUAL' COMMENT '异常来源类型', created_by VARCHAR(128) NULL COMMENT '创建人ID',
|
||||
exception_at DATETIME(3) NOT NULL COMMENT '异常发生时间', created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||
PRIMARY KEY(id), UNIQUE KEY uk_ll_exception_no(customer_id,exception_no),
|
||||
UNIQUE KEY uk_ll_exception_delivery_return(customer_id,delivery_order_id,exception_type),
|
||||
KEY idx_ll_exception_list(customer_id,status,exception_at), KEY idx_ll_exception_tail(customer_id,last_mile_order_no),
|
||||
KEY idx_ll_exception_inbound(customer_id,inbound_code)
|
||||
) ENGINE=InnoDB COMMENT='海外仓异常订单';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS ll_customer_visit (
|
||||
id BIGINT NOT NULL COMMENT '客户回访记录ID',
|
||||
customer_id VARCHAR(128) NOT NULL COMMENT '客户数据隔离键',
|
||||
delivery_order_id BIGINT NOT NULL COMMENT '关联派送单ID',
|
||||
delivery_no VARCHAR(64) NOT NULL COMMENT '关联派送单号',
|
||||
customer_name VARCHAR(255) NULL COMMENT '客户名称快照',
|
||||
contact_name VARCHAR(128) NULL COMMENT '客户联系人姓名快照',
|
||||
contact_phone VARCHAR(64) NULL COMMENT '客户联系人电话快照',
|
||||
destination VARCHAR(500) NULL COMMENT '派送目的仓编码汇总快照',
|
||||
delivery_completed_at DATETIME(3) NOT NULL COMMENT '派送完成时间',
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'PENDING' COMMENT '回访状态:PENDING待回访或COMPLETED已回访',
|
||||
selected_last_mile_order_id BIGINT NULL COMMENT '本次回访选择的尾程订单ID',
|
||||
selected_last_mile_order_no VARCHAR(64) NULL COMMENT '本次回访选择的尾程订单号',
|
||||
selected_inbound_order_id BIGINT NULL COMMENT '本次回访选择的入仓单ID',
|
||||
selected_inbound_code VARCHAR(128) NULL COMMENT '本次回访选择的入仓码',
|
||||
visit_result VARCHAR(32) NULL COMMENT '最近一次回访结果',
|
||||
customer_feedback VARCHAR(2000) NULL COMMENT '最近一次客户反馈',
|
||||
remark VARCHAR(1000) NULL COMMENT '最近一次回访备注',
|
||||
attachment_json JSON NULL COMMENT '当前回访资料文件元数据列表',
|
||||
visited_by VARCHAR(128) NULL COMMENT '最近一次回访操作人ID',
|
||||
visited_at DATETIME(3) NULL COMMENT '最近一次回访时间',
|
||||
visit_count INT NOT NULL DEFAULT 0 COMMENT '累计保存回访次数',
|
||||
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
|
||||
updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间',
|
||||
PRIMARY KEY(id),
|
||||
UNIQUE KEY uk_ll_customer_visit_delivery(customer_id,delivery_order_id),
|
||||
KEY idx_ll_customer_visit_list(customer_id,status,delivery_completed_at),
|
||||
KEY idx_ll_customer_visit_delivery_no(customer_id,delivery_no)
|
||||
) ENGINE=InnoDB COMMENT='派送单维度客户回访记录';
|
||||
|
||||
-- ============================================================================
|
||||
-- 2026-08-27 / local legacy inventory-ledger cleanup
|
||||
-- ============================================================================
|
||||
USE baiyue_lastleg;
|
||||
|
||||
-- These quantity columns are absent from the current ledger contract. Legacy
|
||||
-- NOT NULL definitions without defaults block package-only ledger writes.
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_inventory_ledger' AND column_name='before_quantity'), 'ALTER TABLE ll_inventory_ledger DROP COLUMN before_quantity', 'SELECT 1'));
|
||||
PREPARE lastleg_ledger_legacy_001 FROM @ddl; EXECUTE lastleg_ledger_legacy_001; DEALLOCATE PREPARE lastleg_ledger_legacy_001;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_inventory_ledger' AND column_name='delta_quantity'), 'ALTER TABLE ll_inventory_ledger DROP COLUMN delta_quantity', 'SELECT 1'));
|
||||
PREPARE lastleg_ledger_legacy_002 FROM @ddl; EXECUTE lastleg_ledger_legacy_002; DEALLOCATE PREPARE lastleg_ledger_legacy_002;
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_inventory_ledger' AND column_name='after_quantity'), 'ALTER TABLE ll_inventory_ledger DROP COLUMN after_quantity', 'SELECT 1'));
|
||||
PREPARE lastleg_ledger_legacy_003 FROM @ddl; EXECUTE lastleg_ledger_legacy_003; DEALLOCATE PREPARE lastleg_ledger_legacy_003;
|
||||
|
||||
@@ -5,6 +5,29 @@ import test from 'node:test'
|
||||
const read = async (path) => (await readFile(new URL(`../${path}`, import.meta.url), 'utf8'))
|
||||
.replaceAll('\r\n', '\n')
|
||||
|
||||
test('local, development and test Nacos publishing remain environment-isolated', async () => {
|
||||
const publisher = await read('scripts/publish-nacos-config.ps1')
|
||||
const local = [
|
||||
await read('config/nacos/local/gateway-overseas.yml'),
|
||||
await read('config/nacos/local/lastleg-service.yml'),
|
||||
await read('config/nacos/local/warehouse-overseas-service.yml'),
|
||||
].join('\n')
|
||||
const remote = [
|
||||
await read('config/nacos/overseas/gateway-overseas.yml'),
|
||||
await read('config/nacos/overseas/lastleg-service.yml'),
|
||||
await read('config/nacos/overseas/warehouse-overseas-service.yml'),
|
||||
].join('\n')
|
||||
|
||||
assert.match(publisher, /ValidateSet\('local', 'dev', 'development', 'test', 'production'\)/)
|
||||
assert.match(publisher, /必须显式指定非 public 的 Nacos namespace/)
|
||||
assert.match(local, /127\.0\.0\.1:9100/)
|
||||
assert.match(local, /127\.0\.0\.1:9303/)
|
||||
assert.doesNotMatch(remote, /127\.0\.0\.1|password:\s*123456/)
|
||||
assert.match(remote, /http:\/\/lastleg-service:9303/)
|
||||
assert.match(remote, /\$\{LASTLEG_DB_URL\}/)
|
||||
assert.match(remote, /\$\{WAREHOUSE_DB_URL\}/)
|
||||
})
|
||||
|
||||
test('Jenkins pipelines recognize all overseas deployable modules', async () => {
|
||||
const controller = await read('Jenkinsfile')
|
||||
const service = await read('Jenkinsfile.service')
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
param(
|
||||
[ValidateSet('local', 'dev', 'development', 'test', 'production')]
|
||||
[string]$Environment,
|
||||
[ValidateSet('cn', 'overseas')]
|
||||
[string]$Region = 'cn',
|
||||
[string]$ServerAddr = '127.0.0.1:8848',
|
||||
[string]$Group = 'BAIYUE',
|
||||
[string]$Namespace
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$projectRoot = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path)
|
||||
|
||||
if ($Environment -eq 'local') {
|
||||
if ($Namespace -and $Namespace -ne 'public') {
|
||||
throw 'local 环境只能发布到 public namespace'
|
||||
}
|
||||
$Namespace = 'public'
|
||||
$configProfile = 'local'
|
||||
} else {
|
||||
if (-not $Namespace -or $Namespace -eq 'public') {
|
||||
throw "$Environment/$Region 必须显式指定非 public 的 Nacos namespace"
|
||||
}
|
||||
$configProfile = $Region
|
||||
}
|
||||
|
||||
$configRoot = (Resolve-Path (Join-Path $projectRoot "config\nacos\$configProfile")).Path
|
||||
$healthUrl = "http://$ServerAddr/nacos/v1/console/health/readiness"
|
||||
$publishUrl = "http://$ServerAddr/nacos/v1/cs/configs"
|
||||
$health = Invoke-WebRequest -UseBasicParsing -Uri $healthUrl -TimeoutSec 5
|
||||
if ($health.StatusCode -ne 200 -or $health.Content.Trim() -ne 'OK') {
|
||||
throw "Nacos not ready: $healthUrl"
|
||||
}
|
||||
|
||||
$files = Get-ChildItem -LiteralPath $configRoot -File -Filter '*.yml' | Sort-Object Name
|
||||
if ($files.Count -eq 0) {
|
||||
throw "No Nacos configuration found: $configRoot"
|
||||
}
|
||||
|
||||
$published = 0
|
||||
foreach ($file in $files) {
|
||||
$resolvedFile = (Resolve-Path -LiteralPath $file.FullName).Path
|
||||
if (-not $resolvedFile.StartsWith($configRoot, [System.StringComparison]::OrdinalIgnoreCase)) {
|
||||
throw "Unexpected config path: $resolvedFile"
|
||||
}
|
||||
$body = @{
|
||||
dataId = $file.Name
|
||||
group = $Group
|
||||
content = Get-Content -LiteralPath $resolvedFile -Raw -Encoding UTF8
|
||||
type = 'yaml'
|
||||
}
|
||||
if ($Namespace -ne 'public') {
|
||||
$body.tenant = $Namespace
|
||||
}
|
||||
$pairs = foreach ($entry in $body.GetEnumerator()) {
|
||||
[uri]::EscapeDataString([string]$entry.Key) + '=' + [uri]::EscapeDataString([string]$entry.Value)
|
||||
}
|
||||
$result = Invoke-RestMethod -Method Post -Uri $publishUrl `
|
||||
-ContentType 'application/x-www-form-urlencoded; charset=UTF-8' `
|
||||
-Body ($pairs -join '&') -TimeoutSec 10
|
||||
if ([string]$result -ne 'true') {
|
||||
throw "Publish failed: $($file.Name), Nacos response: $result"
|
||||
}
|
||||
$published++
|
||||
Write-Host "Published $($file.Name) -> $Namespace / $Group"
|
||||
}
|
||||
|
||||
Write-Host "Published $Environment/$Region Nacos configuration: $published items."
|
||||
@@ -0,0 +1,74 @@
|
||||
param(
|
||||
[ValidateSet('local', 'dev', 'development', 'test')]
|
||||
[string]$Environment,
|
||||
[ValidateSet('cn', 'overseas')]
|
||||
[string]$Region = 'cn',
|
||||
[string]$NacosServerAddr,
|
||||
[string]$NacosNamespace,
|
||||
[string]$NacosUsername,
|
||||
[string]$NacosPassword
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$target = if ($Environment -eq 'development') { 'dev' } else { $Environment }
|
||||
|
||||
$defaults = @{
|
||||
local = @{ Server = '127.0.0.1:8848'; CnNamespace = 'public' }
|
||||
dev = @{ Server = '8.163.49.32:8848'; CnNamespace = $env:DEV_NACOS_NAMESPACE }
|
||||
test = @{ Server = '8.163.30.128:8848'; CnNamespace = 'd99d7998-5bb0-4ffe-a2a0-1a564ce14463' }
|
||||
}
|
||||
$selected = $defaults[$target]
|
||||
$serverAddr = if ($NacosServerAddr) { $NacosServerAddr } else { $selected.Server }
|
||||
$namespace = if ($NacosNamespace) {
|
||||
$NacosNamespace
|
||||
} elseif ($target -eq 'local') {
|
||||
'public'
|
||||
} elseif ($Region -eq 'overseas') {
|
||||
$regionNamespace = [Environment]::GetEnvironmentVariable("$($target.ToUpperInvariant())_OVERSEAS_NACOS_NAMESPACE")
|
||||
if ($regionNamespace) {
|
||||
$regionNamespace
|
||||
} else {
|
||||
[Environment]::GetEnvironmentVariable("$($target.ToUpperInvariant())_NACOS_NAMESPACE")
|
||||
}
|
||||
} else {
|
||||
$selected.CnNamespace
|
||||
}
|
||||
$username = if ($NacosUsername) {
|
||||
$NacosUsername
|
||||
} elseif ([Environment]::GetEnvironmentVariable("$($target.ToUpperInvariant())_NACOS_USERNAME")) {
|
||||
[Environment]::GetEnvironmentVariable("$($target.ToUpperInvariant())_NACOS_USERNAME")
|
||||
} else {
|
||||
'nacos'
|
||||
}
|
||||
$password = if ($NacosPassword) {
|
||||
$NacosPassword
|
||||
} elseif ([Environment]::GetEnvironmentVariable("$($target.ToUpperInvariant())_NACOS_PASSWORD")) {
|
||||
[Environment]::GetEnvironmentVariable("$($target.ToUpperInvariant())_NACOS_PASSWORD")
|
||||
} elseif ($target -eq 'local') {
|
||||
'nacos'
|
||||
} else {
|
||||
$null
|
||||
}
|
||||
|
||||
if (-not $namespace) {
|
||||
throw "$target/$Region 必须通过 -NacosNamespace 或对应的 *_NACOS_NAMESPACE 环境变量指定 namespace"
|
||||
}
|
||||
if (-not $password) {
|
||||
throw "$target 必须通过 -NacosPassword 或 $($target.ToUpperInvariant())_NACOS_PASSWORD 提供 Nacos 密码"
|
||||
}
|
||||
|
||||
$env:NACOS_SERVER_ADDR = $serverAddr
|
||||
$env:NACOS_NAMESPACE = $namespace
|
||||
$env:NACOS_GROUP = 'BAIYUE'
|
||||
$env:NACOS_USERNAME = $username
|
||||
$env:NACOS_PASSWORD = $password
|
||||
$env:SPRING_CLOUD_NACOS_CONFIG_NAMESPACE = $namespace
|
||||
$env:SPRING_CLOUD_NACOS_DISCOVERY_NAMESPACE = $namespace
|
||||
$env:SPRING_PROFILES_ACTIVE = if ($Region -eq 'overseas') { 'overseas' } elseif ($target -eq 'local') { 'dev' } else { 'cn' }
|
||||
$env:BAIYUE_RUNTIME_ENVIRONMENT = $target
|
||||
$env:BAIYUE_RUNTIME_REGION = $Region
|
||||
|
||||
Write-Host "Runtime environment: $target / $Region"
|
||||
Write-Host "Nacos: $serverAddr; namespace: $namespace; group: BAIYUE"
|
||||
Write-Host "Spring profiles: $env:SPRING_PROFILES_ACTIVE"
|
||||
Write-Host 'Nacos password is loaded into the current process and is not printed.'
|
||||
Reference in New Issue
Block a user