实现V4数据库目录与Lookup接口

This commit is contained in:
andy
2026-07-19 14:36:11 +07:00
parent 145511620c
commit 88f98a0eb6
39 changed files with 2075 additions and 167 deletions

View File

@@ -0,0 +1,185 @@
CREATE TABLE workflow_reservation_catalog_account (
id BIGINT NOT NULL COMMENT 'Reservation 目录 Account ID',
hotel_id VARCHAR(64) NOT NULL COMMENT '酒店 ID',
account_code VARCHAR(64) NOT NULL COMMENT 'Account 稳定代码,前端和 SuperAgent 使用该代码提交',
account_name VARCHAR(255) NOT NULL COMMENT 'Account 显示名称',
market_code VARCHAR(64) NOT NULL COMMENT 'Account 关联 Market 代码',
source_code VARCHAR(64) NOT NULL COMMENT 'Account 关联 Source 代码',
status VARCHAR(32) NOT NULL COMMENT '目录状态ACTIVE、DISABLED',
source_system VARCHAR(32) NOT NULL COMMENT '目录来源FIXED_SEED_IMPORT、SYSTEM_MANAGED、PMS_SYNC',
external_account_id VARCHAR(128) NULL COMMENT '外部系统 Account ID未接 PMS 时为空',
catalog_version VARCHAR(64) NOT NULL COMMENT '目录版本,用于前端缓存和排查目录来源',
last_synced_at DATETIME(6) NULL COMMENT '最近同步 UTC 时间,固定种子导入时为空',
metadata_json LONGTEXT NULL COMMENT 'Account 扩展属性 JSON第一版不参与业务校验',
version BIGINT NOT NULL DEFAULT 0 COMMENT '乐观锁版本',
created_at DATETIME(6) NOT NULL COMMENT '记录创建 UTC 时间',
updated_at DATETIME(6) NOT NULL COMMENT '记录更新 UTC 时间',
logic_deleted_at DATETIME(6) NULL COMMENT '逻辑删除 UTC 时间',
logic_deleted_reason VARCHAR(512) NULL COMMENT '逻辑删除原因',
PRIMARY KEY (id),
UNIQUE KEY uk_reservation_catalog_account_code (hotel_id, account_code),
KEY idx_reservation_catalog_account_status (hotel_id, status, account_code),
KEY idx_reservation_catalog_account_name (hotel_id, account_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='Reservation V4 Account 目录表';
CREATE TABLE workflow_reservation_catalog_code (
id BIGINT NOT NULL COMMENT 'Reservation 通用代码目录 ID',
hotel_id VARCHAR(64) NOT NULL COMMENT '酒店 ID',
catalog_type VARCHAR(32) NOT NULL COMMENT '目录类型ROOM_TYPE、RATE_CODE、MARKET、SOURCE',
code VARCHAR(64) NOT NULL COMMENT '目录稳定代码,前端和 SuperAgent 使用该代码提交',
display_name VARCHAR(255) NOT NULL COMMENT '目录显示名称',
status VARCHAR(32) NOT NULL COMMENT '目录状态ACTIVE、DISABLED',
source_system VARCHAR(32) NOT NULL COMMENT '目录来源FIXED_SEED_IMPORT、SYSTEM_MANAGED、PMS_SYNC',
external_id VARCHAR(128) NULL COMMENT '外部系统目录 ID未接 PMS 时为空',
sort_order INT NOT NULL DEFAULT 0 COMMENT '目录展示排序',
catalog_version VARCHAR(64) NOT NULL COMMENT '目录版本,用于前端缓存和排查目录来源',
last_synced_at DATETIME(6) NULL COMMENT '最近同步 UTC 时间,固定种子导入时为空',
metadata_json LONGTEXT NULL COMMENT '目录扩展属性 JSON例如房型人数、Rate Code 价格能力',
version BIGINT NOT NULL DEFAULT 0 COMMENT '乐观锁版本',
created_at DATETIME(6) NOT NULL COMMENT '记录创建 UTC 时间',
updated_at DATETIME(6) NOT NULL COMMENT '记录更新 UTC 时间',
logic_deleted_at DATETIME(6) NULL COMMENT '逻辑删除 UTC 时间',
logic_deleted_reason VARCHAR(512) NULL COMMENT '逻辑删除原因',
PRIMARY KEY (id),
UNIQUE KEY uk_reservation_catalog_code (hotel_id, catalog_type, code),
KEY idx_reservation_catalog_code_status (hotel_id, catalog_type, status, sort_order),
KEY idx_reservation_catalog_code_name (hotel_id, catalog_type, display_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='Reservation V4 通用代码目录表';
INSERT INTO workflow_reservation_catalog_account (
id, hotel_id, account_code, account_name, market_code, source_code, status, source_system,
external_account_id, catalog_version, last_synced_at, metadata_json, version, created_at, updated_at,
logic_deleted_at, logic_deleted_reason
) VALUES
(240000000001, 'HOTEL-TEST', 'QBD_TRAVEL', 'Q.B.D. TRAVEL GROUP CO., LTD', 'LEISURE', 'TRAVEL_AGENT', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 'seed-20260719-v1', NULL, NULL, 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000000002, 'HOTEL-TEST', 'LIAN_TAI', 'LIAN TAI TRAVEL (THAILAND) CO., LTD.', 'LEISURE', 'TRAVEL_AGENT', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 'seed-20260719-v1', NULL, NULL, 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000000003, 'HOTEL-TEST', 'HANATOUR_TD', 'HANATOUR TD CO., LTD.', 'LEISURE', 'TRAVEL_AGENT', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 'seed-20260719-v1', NULL, NULL, 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000001001, 'HOTEL-DEV', 'QBD_TRAVEL', 'Q.B.D. TRAVEL GROUP CO., LTD', 'LEISURE', 'TRAVEL_AGENT', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 'seed-20260719-v1', NULL, NULL, 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000001002, 'HOTEL-DEV', 'LIAN_TAI', 'LIAN TAI TRAVEL (THAILAND) CO., LTD.', 'LEISURE', 'TRAVEL_AGENT', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 'seed-20260719-v1', NULL, NULL, 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000001003, 'HOTEL-DEV', 'HANATOUR_TD', 'HANATOUR TD CO., LTD.', 'LEISURE', 'TRAVEL_AGENT', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 'seed-20260719-v1', NULL, NULL, 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL);
INSERT INTO workflow_reservation_catalog_code (
id, hotel_id, catalog_type, code, display_name, status, source_system, external_id, sort_order,
catalog_version, last_synced_at, metadata_json, version, created_at, updated_at, logic_deleted_at,
logic_deleted_reason
) VALUES
(240000010101, 'HOTEL-TEST', 'ROOM_TYPE', 'TWN', 'TWN', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 10, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010102, 'HOTEL-TEST', 'ROOM_TYPE', 'KING', 'KING', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 20, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010103, 'HOTEL-TEST', 'ROOM_TYPE', 'DBL', 'DBL', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 30, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010104, 'HOTEL-TEST', 'ROOM_TYPE', 'SGL', 'SGL', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 40, 'seed-20260719-v1', NULL, '{"adult_capacity":1}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010105, 'HOTEL-TEST', 'ROOM_TYPE', 'TRP', 'TRP', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 50, 'seed-20260719-v1', NULL, '{"adult_capacity":3}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010106, 'HOTEL-TEST', 'ROOM_TYPE', 'RM1', 'RM1', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 60, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010107, 'HOTEL-TEST', 'ROOM_TYPE', 'RM2', 'RM2', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 70, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010108, 'HOTEL-TEST', 'ROOM_TYPE', 'RM3', 'RM3', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 80, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010201, 'HOTEL-TEST', 'RATE_CODE', 'BAR', 'BAR', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 10, 'seed-20260719-v1', NULL, '{"pricing_available":false}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010202, 'HOTEL-TEST', 'RATE_CODE', 'RACK', 'RACK', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 20, 'seed-20260719-v1', NULL, '{"pricing_available":false}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010203, 'HOTEL-TEST', 'RATE_CODE', 'PACKAGE', 'PACKAGE', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 30, 'seed-20260719-v1', NULL, '{"pricing_available":false}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010204, 'HOTEL-TEST', 'RATE_CODE', 'GROUP', 'GROUP', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 40, 'seed-20260719-v1', NULL, '{"pricing_available":false}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010205, 'HOTEL-TEST', 'RATE_CODE', 'FIT', 'FIT', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 50, 'seed-20260719-v1', NULL, '{"pricing_available":false}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010301, 'HOTEL-TEST', 'MARKET', 'LEISURE', 'LEISURE', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 10, 'seed-20260719-v1', NULL, NULL, 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000010401, 'HOTEL-TEST', 'SOURCE', 'TRAVEL_AGENT', 'TRAVEL_AGENT', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 10, 'seed-20260719-v1', NULL, NULL, 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020101, 'HOTEL-DEV', 'ROOM_TYPE', 'TWN', 'TWN', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 10, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020102, 'HOTEL-DEV', 'ROOM_TYPE', 'KING', 'KING', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 20, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020103, 'HOTEL-DEV', 'ROOM_TYPE', 'DBL', 'DBL', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 30, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020104, 'HOTEL-DEV', 'ROOM_TYPE', 'SGL', 'SGL', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 40, 'seed-20260719-v1', NULL, '{"adult_capacity":1}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020105, 'HOTEL-DEV', 'ROOM_TYPE', 'TRP', 'TRP', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 50, 'seed-20260719-v1', NULL, '{"adult_capacity":3}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020106, 'HOTEL-DEV', 'ROOM_TYPE', 'RM1', 'RM1', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 60, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020107, 'HOTEL-DEV', 'ROOM_TYPE', 'RM2', 'RM2', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 70, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020108, 'HOTEL-DEV', 'ROOM_TYPE', 'RM3', 'RM3', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 80, 'seed-20260719-v1', NULL, '{"adult_capacity":2}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020201, 'HOTEL-DEV', 'RATE_CODE', 'BAR', 'BAR', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 10, 'seed-20260719-v1', NULL, '{"pricing_available":false}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020202, 'HOTEL-DEV', 'RATE_CODE', 'RACK', 'RACK', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 20, 'seed-20260719-v1', NULL, '{"pricing_available":false}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020203, 'HOTEL-DEV', 'RATE_CODE', 'PACKAGE', 'PACKAGE', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 30, 'seed-20260719-v1', NULL, '{"pricing_available":false}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020204, 'HOTEL-DEV', 'RATE_CODE', 'GROUP', 'GROUP', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 40, 'seed-20260719-v1', NULL, '{"pricing_available":false}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020205, 'HOTEL-DEV', 'RATE_CODE', 'FIT', 'FIT', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 50, 'seed-20260719-v1', NULL, '{"pricing_available":false}', 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020301, 'HOTEL-DEV', 'MARKET', 'LEISURE', 'LEISURE', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 10, 'seed-20260719-v1', NULL, NULL, 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL),
(240000020401, 'HOTEL-DEV', 'SOURCE', 'TRAVEL_AGENT', 'TRAVEL_AGENT', 'ACTIVE', 'FIXED_SEED_IMPORT', NULL, 10, 'seed-20260719-v1', NULL, NULL, 0, '2026-07-19 00:00:00.000000', '2026-07-19 00:00:00.000000', NULL, NULL);
-- 如果迁移执行时平台酒店已经存在,则给当前 ACTIVE 酒店也导入一份固定种子,避免非 HOTEL-TEST/DEV 环境 lookup 全空。
INSERT INTO workflow_reservation_catalog_account (
id, hotel_id, account_code, account_name, market_code, source_code, status, source_system,
external_account_id, catalog_version, last_synced_at, metadata_json, version, created_at, updated_at,
logic_deleted_at, logic_deleted_reason
)
SELECT
1000000000000000 + MOD(h.id, 1000000000) * 1000 + seed.seed_offset,
h.hotel_id,
seed.account_code,
seed.account_name,
'LEISURE',
'TRAVEL_AGENT',
'ACTIVE',
'FIXED_SEED_IMPORT',
NULL,
'seed-20260719-v1',
NULL,
NULL,
0,
'2026-07-19 00:00:00.000000',
'2026-07-19 00:00:00.000000',
NULL,
NULL
FROM platform_hotel h
JOIN (
SELECT 1 AS seed_offset, 'QBD_TRAVEL' AS account_code, 'Q.B.D. TRAVEL GROUP CO., LTD' AS account_name
UNION ALL SELECT 2, 'LIAN_TAI', 'LIAN TAI TRAVEL (THAILAND) CO., LTD.'
UNION ALL SELECT 3, 'HANATOUR_TD', 'HANATOUR TD CO., LTD.'
) seed ON 1 = 1
WHERE h.hotel_status = 'ACTIVE'
AND h.hotel_id NOT IN ('HOTEL-TEST', 'HOTEL-DEV')
AND NOT EXISTS (
SELECT 1
FROM workflow_reservation_catalog_account existing
WHERE existing.hotel_id = h.hotel_id
AND existing.account_code = seed.account_code
);
INSERT INTO workflow_reservation_catalog_code (
id, hotel_id, catalog_type, code, display_name, status, source_system, external_id, sort_order,
catalog_version, last_synced_at, metadata_json, version, created_at, updated_at, logic_deleted_at,
logic_deleted_reason
)
SELECT
1000001000000000 + MOD(h.id, 1000000000) * 1000 + seed.seed_offset,
h.hotel_id,
seed.catalog_type,
seed.code,
seed.display_name,
'ACTIVE',
'FIXED_SEED_IMPORT',
NULL,
seed.sort_order,
'seed-20260719-v1',
NULL,
seed.metadata_json,
0,
'2026-07-19 00:00:00.000000',
'2026-07-19 00:00:00.000000',
NULL,
NULL
FROM platform_hotel h
JOIN (
SELECT 101 AS seed_offset, 'ROOM_TYPE' AS catalog_type, 'TWN' AS code, 'TWN' AS display_name, 10 AS sort_order, '{"adult_capacity":2}' AS metadata_json
UNION ALL SELECT 102, 'ROOM_TYPE', 'KING', 'KING', 20, '{"adult_capacity":2}'
UNION ALL SELECT 103, 'ROOM_TYPE', 'DBL', 'DBL', 30, '{"adult_capacity":2}'
UNION ALL SELECT 104, 'ROOM_TYPE', 'SGL', 'SGL', 40, '{"adult_capacity":1}'
UNION ALL SELECT 105, 'ROOM_TYPE', 'TRP', 'TRP', 50, '{"adult_capacity":3}'
UNION ALL SELECT 106, 'ROOM_TYPE', 'RM1', 'RM1', 60, '{"adult_capacity":2}'
UNION ALL SELECT 107, 'ROOM_TYPE', 'RM2', 'RM2', 70, '{"adult_capacity":2}'
UNION ALL SELECT 108, 'ROOM_TYPE', 'RM3', 'RM3', 80, '{"adult_capacity":2}'
UNION ALL SELECT 201, 'RATE_CODE', 'BAR', 'BAR', 10, '{"pricing_available":false}'
UNION ALL SELECT 202, 'RATE_CODE', 'RACK', 'RACK', 20, '{"pricing_available":false}'
UNION ALL SELECT 203, 'RATE_CODE', 'PACKAGE', 'PACKAGE', 30, '{"pricing_available":false}'
UNION ALL SELECT 204, 'RATE_CODE', 'GROUP', 'GROUP', 40, '{"pricing_available":false}'
UNION ALL SELECT 205, 'RATE_CODE', 'FIT', 'FIT', 50, '{"pricing_available":false}'
UNION ALL SELECT 301, 'MARKET', 'LEISURE', 'LEISURE', 10, NULL
UNION ALL SELECT 401, 'SOURCE', 'TRAVEL_AGENT', 'TRAVEL_AGENT', 10, NULL
) seed ON 1 = 1
WHERE h.hotel_status = 'ACTIVE'
AND h.hotel_id NOT IN ('HOTEL-TEST', 'HOTEL-DEV')
AND NOT EXISTS (
SELECT 1
FROM workflow_reservation_catalog_code existing
WHERE existing.hotel_id = h.hotel_id
AND existing.catalog_type = seed.catalog_type
AND existing.code = seed.code
);