版本: v1.0
来源: 从系统架构总纲文档提取
包含模块: 6.1-6.12 + 11.x 补充能力模块 + 12.x AI Agent 智能运营层
-- 酒店主表
CREATE TABLE hotels (
id BIGSERIAL PRIMARY KEY,
hotel_code VARCHAR(32) NOT NULL UNIQUE, -- 平台统一编码 HPT-XXXXX
name_en VARCHAR(255) NOT NULL, -- 英文名
name_local VARCHAR(255), -- 当地语言名
country_code VARCHAR(3) NOT NULL, -- ISO 3166-1 alpha-3
city_code VARCHAR(8) NOT NULL, -- 城市编码
address TEXT,
latitude DECIMAL(10, 7),
longitude DECIMAL(10, 7),
star_rating SMALLINT CHECK (star_rating BETWEEN 1 AND 5),
chain_code VARCHAR(16), -- 酒店集团编码
geo_info JSONB, -- 扩展地理信息
facilities JSONB, -- {"wifi":true,"pool":true,"parking":false}
images JSONB, -- 图片URL列表
check_in_time TIME DEFAULT '14:00:00',
check_out_time TIME DEFAULT '12:00:00',
contact_info JSONB, -- 电话、邮箱、网站
status VARCHAR(20) DEFAULT 'active', -- active/inactive/pending
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
source VARCHAR(32) DEFAULT 'manual' -- manual/api/import
);
CREATE INDEX idx_hotels_geo ON hotels USING GIST (
ll_to_earth(latitude, longitude)
);
CREATE INDEX idx_hotels_city ON hotels (city_code);
CREATE INDEX idx_hotels_status ON hotels (status);
CREATE INDEX idx_hotels_facilities ON hotels USING GIN (facilities);
CREATE INDEX idx_hotels_chain ON hotels (chain_code);
-- 标准房型表
CREATE TABLE room_types (
id BIGSERIAL PRIMARY KEY,
room_code VARCHAR(32) NOT NULL UNIQUE, -- 平台统一编码
hotel_id BIGINT REFERENCES hotels(id) ON DELETE CASCADE,
name_en VARCHAR(128) NOT NULL,
name_local VARCHAR(128),
bed_type VARCHAR(64), -- Double/Twin/King/Sofa
max_adults SMALLINT DEFAULT 2,
max_children SMALLINT DEFAULT 0,
room_size_sqm DECIMAL(6, 1),
floor VARCHAR(32),
bed_count SMALLINT DEFAULT 1,
facilities JSONB, -- 房间设施
description TEXT,
images JSONB,
status VARCHAR(20) DEFAULT 'active',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_room_types_hotel ON room_types (hotel_id);
-- 供应商酒店映射源数据表
CREATE TABLE supplier_hotels (
id BIGSERIAL PRIMARY KEY,
supplier_code VARCHAR(32) NOT NULL, -- 供应商编码
supplier_hotel_id VARCHAR(64) NOT NULL, -- 供应商侧酒店ID
hotel_id BIGINT REFERENCES hotels(id), -- 映射到平台酒店(可为空=待匹配)
raw_data JSONB NOT NULL, -- 原始数据快照
name VARCHAR(255), -- 供应商侧名称
city_code VARCHAR(8),
star_rating SMALLINT,
latitude DECIMAL(10, 7),
longitude DECIMAL(10, 7),
last_synced_at TIMESTAMPTZ,
connection_mode VARCHAR(32) DEFAULT 'direct_connect', -- direct_connect/direct_procure(供应商-酒店级别)
sync_interval_minutes INT DEFAULT 120, -- 直采拉取间隔
sync_validity_minutes INT DEFAULT 120, -- 直采价格有效期
sync_max_failures INT DEFAULT 3, -- 降级阈值
sync_suspend_threshold INT DEFAULT 10, -- 暂停阈值
sync_status VARCHAR(20) DEFAULT 'normal', -- normal/degraded/suspended
sync_fail_count INT DEFAULT 0,
match_status VARCHAR(20) DEFAULT 'pending', -- pending/matched/unmatched/manual_review
match_confidence DECIMAL(5, 2), -- 匹配置信度 0-100
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(supplier_code, supplier_hotel_id)
);
CREATE INDEX idx_supplier_hotels_match ON supplier_hotels (match_status);
CREATE INDEX idx_supplier_hotels_supplier ON supplier_hotels (supplier_code);
-- 供应商房型映射源数据表
CREATE TABLE supplier_room_types (
id BIGSERIAL PRIMARY KEY,
supplier_code VARCHAR(32) NOT NULL,
supplier_room_code VARCHAR(64) NOT NULL,
supplier_hotel_id VARCHAR(64) NOT NULL,
room_type_id BIGINT REFERENCES room_types(id), -- 映射到平台房型
raw_data JSONB NOT NULL,
name VARCHAR(255),
match_status VARCHAR(20) DEFAULT 'pending',
match_confidence DECIMAL(5, 2),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(supplier_code, supplier_room_code, supplier_hotel_id)
);
-- 城市字典表
CREATE TABLE cities (
code VARCHAR(8) PRIMARY KEY,
name_en VARCHAR(128) NOT NULL,
name_local VARCHAR(128),
country_code VARCHAR(3) NOT NULL,
latitude DECIMAL(10, 7),
longitude DECIMAL(10, 7),
timezone VARCHAR(32),
status VARCHAR(20) DEFAULT 'active'
);
-- 设施字典表
CREATE TABLE facility_dict (
id SERIAL PRIMARY KEY,
category VARCHAR(32) NOT NULL, -- general/room/dining/sports/business
code VARCHAR(32) NOT NULL UNIQUE, -- wifi/pool/gym/spa/parking
name_en VARCHAR(64) NOT NULL,
name_local VARCHAR(128),
icon VARCHAR(64)
);
-- 匹配规则表
CREATE TABLE match_rules (
id SERIAL PRIMARY KEY,
supplier_code VARCHAR(32) NOT NULL,
rule_type VARCHAR(32) NOT NULL, -- hotel/room_type
field_name VARCHAR(64) NOT NULL, -- name/lat_lng/address/star
algorithm VARCHAR(64) NOT NULL, -- levenshtein/haversine/exact/regex
weight DECIMAL(3, 2) NOT NULL, -- 权重 0.00-1.00
threshold DECIMAL(5, 2), -- 单字段阈值
params JSONB, -- 算法参数
priority SMALLINT DEFAULT 0,
enabled BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 匹配任务表
CREATE TABLE match_tasks (
id BIGSERIAL PRIMARY KEY,
task_type VARCHAR(32) NOT NULL, -- hotel/room_type
supplier_code VARCHAR(32) NOT NULL,
total_count INT DEFAULT 0,
matched_count INT DEFAULT 0,
pending_count INT DEFAULT 0,
failed_count INT DEFAULT 0,
status VARCHAR(20) DEFAULT 'pending', -- pending/running/completed/failed
started_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
created_by VARCHAR(64),
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 匹配历史表(审计)
CREATE TABLE match_history (
id BIGSERIAL PRIMARY KEY,
task_id BIGINT REFERENCES match_tasks(id),
supplier_code VARCHAR(32),
match_type VARCHAR(32), -- hotel/room_type
supplier_id VARCHAR(64) NOT NULL,
platform_id BIGINT, -- 匹配到的平台ID
confidence DECIMAL(5, 2),
match_method VARCHAR(32), -- auto/manual/unmatched
old_platform_id BIGINT, -- 变更前的映射(如重新匹配)
details JSONB, -- 各维度得分明细
operator VARCHAR(64), -- 操作人(auto/manual)
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_match_history_task ON match_history (task_id);
CREATE INDEX idx_match_history_supplier ON match_history (supplier_code);
-- 查价请求日志表(写入 ClickHouse 用于分析,PG 做短期热数据)
CREATE TABLE price_search_logs (
id BIGSERIAL PRIMARY KEY,
trace_id VARCHAR(64) NOT NULL, -- 链路追踪ID
agent_code VARCHAR(32) NOT NULL, -- 代理商编码
channel_code VARCHAR(32), -- 渠道编码
hotel_id BIGINT, -- 平台酒店ID
check_in DATE NOT NULL,
check_out DATE NOT NULL,
adults SMALLINT DEFAULT 2,
children SMALLINT DEFAULT 0,
room_count SMALLINT DEFAULT 1,
currency VARCHAR(3) DEFAULT 'CNY',
supplier_codes VARCHAR(255), -- 查询了哪些供应商
result_count INT DEFAULT 0, -- 返回结果数量
min_price DECIMAL(12, 2), -- 最低价
cache_hit BOOLEAN DEFAULT false, -- 是否命中缓存
response_ms INT, -- 响应耗时
error_code VARCHAR(32), -- 错误码
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_search_logs_hotel_date ON price_search_logs (hotel_id, check_in, check_out);
CREATE INDEX idx_search_logs_agent ON price_search_logs (agent_code, created_at);
-- Redis 缓存 Key 设计
-- 查价缓存: price:search:{hotel_id}:{check_in}:{check_out}:{adults}:{children}:{room_count}:{currency}
-- TTL: 300s (5min)
-- Value: JSON数组,每个元素包含供应商、房型、价格、库存等
-- 订单主表
CREATE TABLE orders (
id BIGSERIAL PRIMARY KEY,
order_no VARCHAR(32) NOT NULL UNIQUE, -- 平台订单号 PLT-YYYYMMDD-XXXXXX
agent_code VARCHAR(32) NOT NULL, -- 代理商编码
channel_code VARCHAR(32), -- 渠道编码
supplier_code VARCHAR(32) NOT NULL, -- 供应商编码
supplier_order_no VARCHAR(64), -- 供应商侧订单号
-- 酒店信息快照
hotel_id BIGINT NOT NULL,
hotel_name VARCHAR(255) NOT NULL, -- 下单时快照
hotel_code VARCHAR(32), -- 供应商侧酒店编码
-- 房型信息快照
room_type_code VARCHAR(32) NOT NULL,
room_type_name VARCHAR(128) NOT NULL,
meal_plan VARCHAR(16) DEFAULT 'BB',
-- 入住信息
check_in DATE NOT NULL,
check_out DATE NOT NULL,
nights SMALLINT GENERATED ALWAYS AS (check_out - check_in) STORED,
adults SMALLINT DEFAULT 2,
children SMALLINT DEFAULT 0,
room_count SMALLINT DEFAULT 1,
-- 住客信息
guest_name VARCHAR(128),
guest_email VARCHAR(128),
guest_phone VARCHAR(32),
special_requests TEXT,
-- 价格信息快照
gross_price DECIMAL(12, 2) NOT NULL, -- 售价
net_price DECIMAL(12, 2) NOT NULL, -- 采购价
commission DECIMAL(12, 2), -- 佣金
currency VARCHAR(3) DEFAULT 'CNY',
-- 取消政策
cancellation_policy JSONB,
cancellation_deadline TIMESTAMPTZ,
-- 状态
status VARCHAR(32) NOT NULL DEFAULT 'CREATED',
-- 代理商侧引用号
client_ref VARCHAR(64),
-- 内部信息
internal_remarks TEXT,
operator VARCHAR(64),
-- 时间戳
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
confirmed_at TIMESTAMPTZ,
cancelled_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
expired_at TIMESTAMPTZ
);
CREATE INDEX idx_orders_agent ON orders (agent_code, created_at DESC);
CREATE INDEX idx_orders_supplier ON orders (supplier_code, status);
CREATE INDEX idx_orders_hotel_date ON orders (hotel_id, check_in);
CREATE INDEX idx_orders_status ON orders (status, created_at DESC);
CREATE INDEX idx_orders_no ON orders (order_no);
-- 订单状态变更历史表
CREATE TABLE order_status_logs (
id BIGSERIAL PRIMARY KEY,
order_id BIGINT NOT NULL REFERENCES orders(id),
from_status VARCHAR(32),
to_status VARCHAR(32) NOT NULL,
reason TEXT,
operator VARCHAR(64), -- system/agent_name/manual
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_order_status_logs_order ON order_status_logs (order_id);
-- 订单备注表
CREATE TABLE order_remarks (
id BIGSERIAL PRIMARY KEY,
order_id BIGINT NOT NULL REFERENCES orders(id),
content TEXT NOT NULL,
remark_type VARCHAR(16) DEFAULT 'internal', -- internal/agent/supplier
creator VARCHAR(64),
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 供应商订单关联表(一笔平台订单可能对应多笔供应商订单)
CREATE TABLE supplier_orders (
id BIGSERIAL PRIMARY KEY,
platform_order_id BIGINT NOT NULL REFERENCES orders(id),
supplier_code VARCHAR(32) NOT NULL,
supplier_order_no VARCHAR(64),
supplier_status VARCHAR(32), -- 供应商侧状态
raw_response JSONB, -- 供应商原始响应
error_message TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 代理商表
CREATE TABLE agents (
id BIGSERIAL PRIMARY KEY,
agent_code VARCHAR(32) NOT NULL UNIQUE, -- AGT-XXXXX
company_name VARCHAR(255) NOT NULL,
contact_name VARCHAR(64),
contact_email VARCHAR(64) NOT NULL UNIQUE,
contact_phone VARCHAR(32),
country_code VARCHAR(3) DEFAULT 'CN',
city VARCHAR(64),
address TEXT,
business_license VARCHAR(128), -- 营业执照号
credit_limit DECIMAL(12, 2) DEFAULT 0, -- 信用额度
credit_used DECIMAL(12, 2) DEFAULT 0, -- 已用额度
level VARCHAR(16) DEFAULT 'standard', -- standard/silver/gold/platinum
status VARCHAR(20) DEFAULT 'pending', -- pending/active/suspended/closed
api_key_hash VARCHAR(128), -- API Key 哈希
api_secret_hash VARCHAR(128),
webhook_url VARCHAR(512),
contract_id BIGINT, -- 关联合同
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 供应商表
CREATE TABLE suppliers (
id BIGSERIAL PRIMARY KEY,
supplier_code VARCHAR(32) NOT NULL UNIQUE, -- SUP-XXXXX
company_name VARCHAR(255) NOT NULL,
supplier_type VARCHAR(32) NOT NULL, -- wholesaler/chain_hotel/independent_hotel
contact_name VARCHAR(64),
contact_email VARCHAR(64) NOT NULL,
contact_phone VARCHAR(32),
country_code VARCHAR(3),
api_endpoint VARCHAR(512), -- 供应商API地址
api_auth_type VARCHAR(32), -- api_key/oauth2/basic
api_credentials JSONB, -- 加密存储
webhook_url VARCHAR(512), -- 回调地址
status VARCHAR(20) DEFAULT 'pending', -- pending/active/suspended/closed
connection_mode VARCHAR(32) NOT NULL DEFAULT 'direct_connect', -- direct_connect(直连:实时查价,有价即有房) / direct_procure(直采:预采购库存,平台持有)
priority SMALLINT DEFAULT 0, -- 查价优先级
avg_response_ms INT, -- 平均响应时间
availability DECIMAL(5, 2), -- 可用率百分比
contract_id BIGINT,
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 渠道表
CREATE TABLE channels (
id SERIAL PRIMARY KEY,
channel_code VARCHAR(32) NOT NULL UNIQUE, -- CHN-XXXXX
channel_name VARCHAR(128) NOT NULL,
channel_type VARCHAR(32) NOT NULL, -- direct/ota/wholesale/corporate
description TEXT,
commission_rate DECIMAL(5, 2) DEFAULT 0, -- 默认佣金率 %
markup_type VARCHAR(16) DEFAULT 'percentage',-- percentage/fixed
markup_value DECIMAL(8, 2) DEFAULT 0, -- 加价值
status VARCHAR(20) DEFAULT 'active',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 合同表
CREATE TABLE contracts (
id BIGSERIAL PRIMARY KEY,
contract_no VARCHAR(32) NOT NULL UNIQUE,
contract_type VARCHAR(32) NOT NULL, -- supplier/agent/channel
party_code VARCHAR(32) NOT NULL, -- 对方编码(供应商/代理商)
party_name VARCHAR(255) NOT NULL,
start_date DATE NOT NULL,
end_date DATE,
status VARCHAR(20) DEFAULT 'draft', -- draft/active/expired/terminated
-- 商务条款
payment_terms VARCHAR(64) DEFAULT 'prepaid', -- prepaid/postpaid/credit
credit_days SMALLINT DEFAULT 0, -- 账期天数
commission_rate DECIMAL(5, 2) DEFAULT 0,
cancellation_policy JSONB,
special_terms JSONB,
-- 合同文件
file_url VARCHAR(512),
-- SLA
sla_response_time_ms INT DEFAULT 3000,
sla_availability DECIMAL(5, 2) DEFAULT 99.5,
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 渠道可见性规则表
CREATE TABLE channel_visibility (
id BIGSERIAL PRIMARY KEY,
agent_id BIGINT NOT NULL REFERENCES agents(id),
supplier_id BIGINT NOT NULL REFERENCES suppliers(id),
hotel_id BIGINT REFERENCES hotels(id), -- NULL = 该供应商下所有酒店
country_code VARCHAR(3), -- NULL = 不限国家
visibility_type VARCHAR(16) NOT NULL DEFAULT 'whitelist', -- whitelist/blacklist
priority SMALLINT DEFAULT 0, -- 规则优先级,数值越大优先级越高
effective_date DATE DEFAULT CURRENT_DATE,
expire_date DATE, -- NULL = 永久有效
created_by VARCHAR(64) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_visibility_agent ON channel_visibility (agent_id, visibility_type, effective_date, expire_date);
CREATE INDEX idx_visibility_supplier ON channel_visibility (supplier_id, visibility_type);
-- 熔断记录表
CREATE TABLE circuit_breaker (
id BIGSERIAL PRIMARY KEY,
party_type VARCHAR(16) NOT NULL, -- agent/supplier
party_id BIGINT NOT NULL, -- agents.id 或 suppliers.id
reason VARCHAR(128) NOT NULL, -- 触发原因
status VARCHAR(16) NOT NULL DEFAULT 'open', -- open(熔断中)/ half_open(半开)/ closed(正常)
triggered_at TIMESTAMPTZ NOT NULL, -- 熔断触发时间
recovered_at TIMESTAMPTZ, -- 恢复时间
config JSONB NOT NULL DEFAULT '{}', -- 熔断配置(阈值、恢复策略等)
operated_by VARCHAR(64) NOT NULL, -- 操作人(system/manual)
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_cb_party ON circuit_breaker (party_type, party_id, status);
CREATE INDEX idx_cb_status ON circuit_breaker (status, triggered_at);
-- 准入审核记录表
CREATE TABLE onboarding_reviews (
id BIGSERIAL PRIMARY KEY,
party_type VARCHAR(16) NOT NULL, -- agent/supplier
party_id BIGINT NOT NULL,
review_type VARCHAR(32) NOT NULL, -- tech_verify/commercial_review/trial_upgrade
reviewer VARCHAR(64) NOT NULL,
result VARCHAR(16) NOT NULL, -- approved/rejected/pending
comments TEXT,
metadata JSONB DEFAULT '{}', -- 审核元数据
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 信用额度变更记录表
CREATE TABLE credit_ledger (
id BIGSERIAL PRIMARY KEY,
agent_id BIGINT NOT NULL REFERENCES agents(id),
amount DECIMAL(12, 2) NOT NULL, -- 正数=充值/释放,负数=扣减/冻结
balance_after DECIMAL(12, 2) NOT NULL, -- 变更后余额
transaction_type VARCHAR(32) NOT NULL, -- recharge/freeze/unfreeze/deduct/refund/adjust
reference_id BIGINT, -- 关联单据(订单号/充值单号等)
reference_type VARCHAR(32), -- order/recharge/adjustment
description TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_credit_ledger_agent ON credit_ledger (agent_id, created_at DESC);
-- 额度预警记录表
CREATE TABLE credit_alerts (
id BIGSERIAL PRIMARY KEY,
agent_id BIGINT NOT NULL REFERENCES agents(id),
alert_level VARCHAR(8) NOT NULL, -- warning(80%)/critical(90%)/exhausted(100%)
usage_rate DECIMAL(5, 2) NOT NULL, -- 使用率百分比
credit_limit DECIMAL(12, 2) NOT NULL,
credit_used DECIMAL(12, 2) NOT NULL,
is_resolved BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_credit_alerts_agent ON credit_alerts (agent_id, is_resolved);
-- 币种与汇率表
CREATE TABLE currencies (
code VARCHAR(3) PRIMARY KEY, -- ISO 4217
name VARCHAR(64) NOT NULL,
symbol VARCHAR(8),
exchange_rate DECIMAL(12, 6) NOT NULL, -- 相对基准货币(CNY)
base_currency VARCHAR(3) DEFAULT 'CNY',
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 汇率历史表
CREATE TABLE exchange_rate_history (
id BIGSERIAL PRIMARY KEY,
from_currency VARCHAR(3) NOT NULL,
to_currency VARCHAR(3) NOT NULL,
rate DECIMAL(12, 6) NOT NULL,
source VARCHAR(32) DEFAULT 'manual', -- manual/api/exchangerate
effective_at TIMESTAMPTZ NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 加价策略表
CREATE TABLE markup_rules (
id BIGSERIAL PRIMARY KEY,
rule_name VARCHAR(128) NOT NULL,
priority SMALLINT NOT NULL DEFAULT 0, -- 数字越大优先级越高
-- 匹配条件 (可为空,表示不限制)
agent_code VARCHAR(32), -- 限定代理商
channel_code VARCHAR(32), -- 限定渠道
supplier_code VARCHAR(32), -- 限定供应商
hotel_id BIGINT, -- 限定酒店
country_code VARCHAR(3), -- 限定国家
city_code VARCHAR(8), -- 限定城市
date_from DATE, -- 有效期起
date_to DATE, -- 有效期止
meal_plan VARCHAR(16), -- 限定餐型
rate_plan VARCHAR(32), -- 限定价格计划
-- 加价规则
markup_type VARCHAR(16) NOT NULL, -- percentage/fixed/mixed
markup_value DECIMAL(8, 4) NOT NULL, -- 百分比(如 0.15=15%) 或固定金额
min_markup DECIMAL(8, 2) DEFAULT 0, -- 最低加价
max_markup DECIMAL(8, 2), -- 最高加价
-- 含税/不含税处理
tax_inclusive BOOLEAN DEFAULT false,
status VARCHAR(20) DEFAULT 'active',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_markup_rules_priority ON markup_rules (priority DESC);
-- 价格合规规则表 (最低售价限制)
CREATE TABLE price_compliance_rules (
id BIGSERIAL PRIMARY KEY,
supplier_code VARCHAR(32) NOT NULL,
hotel_id BIGINT,
room_type_code VARCHAR(32),
rate_plan VARCHAR(32),
min_gross_rate DECIMAL(12, 2), -- 最低售价要求
map_policy VARCHAR(32) DEFAULT 'soft', -- soft(警告)/hard(拦截)
date_from DATE,
date_to DATE,
status VARCHAR(20) DEFAULT 'active',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 特殊日期价格调整表
CREATE TABLE special_dates (
id BIGSERIAL PRIMARY KEY,
date DATE NOT NULL,
date_type VARCHAR(32) NOT NULL, -- holiday/event/low_season
name VARCHAR(128),
country_code VARCHAR(3),
city_code VARCHAR(8),
markup_adjust DECIMAL(8, 4) DEFAULT 0, -- 额外加价(正数=加价)
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(date, country_code, city_code)
);
-- 结算单表
CREATE TABLE settlement_bills (
id BIGSERIAL PRIMARY KEY,
bill_no VARCHAR(32) NOT NULL UNIQUE, -- SET-YYYYMMDD-XXXXX
bill_type VARCHAR(32) NOT NULL, -- payable(应付)/receivable(应收)
party_code VARCHAR(32) NOT NULL, -- 供应商/代理商编码
party_name VARCHAR(255) NOT NULL,
period_start DATE NOT NULL,
period_end DATE NOT NULL,
order_count INT DEFAULT 0,
total_amount DECIMAL(14, 2) DEFAULT 0,
commission DECIMAL(14, 2) DEFAULT 0,
net_amount DECIMAL(14, 2) DEFAULT 0, -- 实际结算金额
currency VARCHAR(3) DEFAULT 'CNY',
status VARCHAR(20) DEFAULT 'draft', -- draft/pending_approval/approved/paid/cancelled
approved_by VARCHAR(64),
approved_at TIMESTAMPTZ,
paid_at TIMESTAMPTZ,
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 结算明细表(每笔订单的结算记录)
CREATE TABLE settlement_items (
id BIGSERIAL PRIMARY KEY,
bill_id BIGINT REFERENCES settlement_bills(id),
order_id BIGINT NOT NULL REFERENCES orders(id),
order_no VARCHAR(32) NOT NULL,
hotel_name VARCHAR(255),
check_in DATE,
check_out DATE,
nights SMALLINT,
gross_amount DECIMAL(12, 2) NOT NULL, -- 应收金额
net_amount DECIMAL(12, 2) NOT NULL, -- 应付金额
commission DECIMAL(12, 2), -- 佣金
currency VARCHAR(3) DEFAULT 'CNY',
reconciliation_status VARCHAR(20) DEFAULT 'matched', -- matched/unmatched/disputed
dispute_reason TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_settlement_items_bill ON settlement_items (bill_id);
CREATE INDEX idx_settlement_items_order ON settlement_items (order_id);
-- 发票表
CREATE TABLE invoices (
id BIGSERIAL PRIMARY KEY,
invoice_no VARCHAR(32) NOT NULL UNIQUE, -- INV-YYYYMMDD-XXXXX
bill_id BIGINT REFERENCES settlement_bills(id),
party_code VARCHAR(32) NOT NULL,
party_name VARCHAR(255) NOT NULL,
invoice_type VARCHAR(32) NOT NULL, -- sales(销售发票)/purchase(采购发票)
amount DECIMAL(14, 2) NOT NULL,
tax_amount DECIMAL(14, 2) DEFAULT 0,
total_amount DECIMAL(14, 2) NOT NULL,
currency VARCHAR(3) DEFAULT 'CNY',
-- 发票信息
invoice_title VARCHAR(255), -- 发票抬头
tax_number VARCHAR(32), -- 税号
status VARCHAR(20) DEFAULT 'pending', -- pending/issued/cancelled
file_url VARCHAR(512), -- 发票文件URL
issued_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 付款记录表
CREATE TABLE payments (
id BIGSERIAL PRIMARY KEY,
payment_no VARCHAR(32) NOT NULL UNIQUE, -- PAY-YYYYMMDD-XXXXX
bill_id BIGINT REFERENCES settlement_bills(id),
party_code VARCHAR(32) NOT NULL,
amount DECIMAL(14, 2) NOT NULL,
currency VARCHAR(3) DEFAULT 'CNY',
payment_method VARCHAR(32), -- bank_transfer/credit/alipay
payment_ref VARCHAR(128), -- 付款参考号/银行流水号
status VARCHAR(20) DEFAULT 'pending', -- pending/processing/completed/failed
paid_at TIMESTAMPTZ,
confirmed_by VARCHAR(64),
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 实时库存表(热数据,频繁更新)
CREATE TABLE inventory_snapshots (
id BIGSERIAL PRIMARY KEY,
supplier_code VARCHAR(32) NOT NULL,
supplier_hotel_id VARCHAR(64) NOT NULL,
room_type_code VARCHAR(32) NOT NULL,
stay_date DATE NOT NULL, -- 入住日期
total_rooms INT DEFAULT 0, -- 总房量
sold_rooms INT DEFAULT 0, -- 已售
blocked_rooms INT DEFAULT 0, -- 关停房
available_rooms INT, -- 可用房量(NULL=有价即有房不限量;有值=真实库存数售完为止)
last_synced_at TIMESTAMPTZ,
sync_source VARCHAR(32) DEFAULT 'pull', -- pull/push/manual
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(supplier_code, supplier_hotel_id, room_type_code, stay_date)
);
CREATE INDEX idx_inventory_date ON inventory_snapshots (supplier_code, stay_date);
-- 库存预占记录表
CREATE TABLE inventory_holds (
id BIGSERIAL PRIMARY KEY,
order_id BIGINT NOT NULL REFERENCES orders(id),
supplier_code VARCHAR(32) NOT NULL,
supplier_hotel_id VARCHAR(64) NOT NULL,
room_type_code VARCHAR(32) NOT NULL,
stay_date DATE NOT NULL,
room_count SMALLINT NOT NULL DEFAULT 1,
status VARCHAR(20) DEFAULT 'active', -- active/confirmed/released/expired
expires_at TIMESTAMPTZ NOT NULL, -- 预占过期时间
released_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_inventory_holds_order ON inventory_holds (order_id);
CREATE INDEX idx_inventory_holds_status ON inventory_holds (status, expires_at);
CREATE INDEX idx_inventory_holds_expire ON inventory_holds (status, expires_at)
WHERE status = 'active';
-- 关停房日期表
CREATE TABLE stop_sells (
id BIGSERIAL PRIMARY KEY,
supplier_code VARCHAR(32) NOT NULL,
supplier_hotel_id VARCHAR(64) NOT NULL,
room_type_code VARCHAR(32), -- 空=整个酒店
start_date DATE NOT NULL,
end_date DATE NOT NULL,
reason VARCHAR(128),
source VARCHAR(32) DEFAULT 'supplier', -- supplier/manual
created_at TIMESTAMPTZ DEFAULT NOW(),
created_by VARCHAR(64)
);
-- 房量配额分配表
CREATE TABLE inventory_allocations (
id BIGSERIAL PRIMARY KEY,
supplier_code VARCHAR(32) NOT NULL,
supplier_hotel_id VARCHAR(64) NOT NULL,
room_type_code VARCHAR(32) NOT NULL,
stay_date DATE NOT NULL,
agent_code VARCHAR(32), -- 分配给特定代理商
channel_code VARCHAR(32), -- 或分配给渠道
allocated_rooms INT NOT NULL DEFAULT 0, -- 分配房量
used_rooms INT NOT NULL DEFAULT 0, -- 已用房量
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(supplier_code, supplier_hotel_id, room_type_code, stay_date,
COALESCE(agent_code, ''), COALESCE(channel_code, ''))
);
CREATE TABLE sell_date_range (
id BIGSERIAL PRIMARY KEY,
supplier_id BIGINT NOT NULL REFERENCES suppliers(id),
hotel_id BIGINT NOT NULL,
room_type_id BIGINT, -- NULL = 该酒店所有房型
channel_id BIGINT REFERENCES channels(id), -- NULL = 全局默认
agent_id BIGINT REFERENCES agents(id), -- NULL = 不限代理商(配合 channel_id 使用)
sell_from DATE NOT NULL, -- 可售开始日期
sell_to DATE NOT NULL, -- 可售结束日期
overwrite_global BOOLEAN DEFAULT FALSE, -- true = 覆盖全局设置
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_sdr_supplier_hotel ON sell_date_range (supplier_id, hotel_id, room_type_id);
CREATE INDEX idx_sdr_channel ON sell_date_range (channel_id, sell_from, sell_to);
CREATE TABLE booking_window (
id BIGSERIAL PRIMARY KEY,
supplier_id BIGINT NOT NULL REFERENCES suppliers(id),
hotel_id BIGINT NOT NULL,
room_type_id BIGINT, -- NULL = 该酒店所有房型
channel_id BIGINT REFERENCES channels(id), -- NULL = 全局默认
agent_id BIGINT REFERENCES agents(id), -- NULL = 不限代理商
min_advance SMALLINT NOT NULL DEFAULT 1, -- 最少提前天数(如 1 = 当天不能订)
max_advance SMALLINT NOT NULL DEFAULT 365, -- 最远可订天数
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_bw_supplier_hotel ON booking_window (supplier_id, hotel_id, room_type_id);
CREATE INDEX idx_bw_channel ON booking_window (channel_id);
CREATE TABLE los_rule (
id BIGSERIAL PRIMARY KEY,
supplier_id BIGINT NOT NULL REFERENCES suppliers(id),
hotel_id BIGINT NOT NULL,
room_type_id BIGINT, -- NULL = 该酒店所有房型
channel_id BIGINT REFERENCES channels(id), -- NULL = 全局默认
agent_id BIGINT REFERENCES agents(id), -- NULL = 不限代理商
min_los SMALLINT NOT NULL DEFAULT 1, -- 最少入住天数
max_los SMALLINT, -- NULL = 不限最多天数
discount_type VARCHAR(16), -- percentage/fixed/none
discount_value DECIMAL(8, 2) DEFAULT 0, -- 折扣值(百分比或固定金额)
effective_from DATE NOT NULL DEFAULT CURRENT_DATE,
effective_to DATE, -- NULL = 长期有效
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_los_supplier_hotel ON los_rule (supplier_id, hotel_id, room_type_id);
CREATE INDEX idx_los_channel ON los_rule (channel_id, effective_from, effective_to);
CREATE TABLE allocation (
id BIGSERIAL PRIMARY KEY,
supplier_id BIGINT NOT NULL REFERENCES suppliers(id),
hotel_id BIGINT NOT NULL,
room_type_id BIGINT NOT NULL,
date DATE NOT NULL,
channel_id BIGINT, -- NULL = 共用池(overbooking)
agent_id BIGINT REFERENCES agents(id), -- NULL = 不限代理商(配合 channel_id)
allocated_qty INT NOT NULL DEFAULT 0, -- 分配房量
sold_qty INT NOT NULL DEFAULT 0, -- 已售房量
released_at TIMESTAMPTZ, -- 释放时间(售罄时间)
status VARCHAR(16) DEFAULT 'active', -- active/exhausted/released
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(supplier_id, hotel_id, room_type_id, date, COALESCE(channel_id, 0))
);
CREATE INDEX idx_alloc_date ON allocation (supplier_id, hotel_id, room_type_id, date);
CREATE INDEX idx_alloc_channel ON allocation (channel_id, date, status);
CREATE TABLE stop_sell_v2 (
id BIGSERIAL PRIMARY KEY,
supplier_id BIGINT NOT NULL REFERENCES suppliers(id),
hotel_id BIGINT NOT NULL,
room_type_id BIGINT, -- NULL = 整个酒店关停
channel_id BIGINT REFERENCES channels(id), -- NULL = 所有渠道关停
stop_from DATE NOT NULL, -- 关停开始日期
stop_to DATE NOT NULL, -- 关停结束日期
reason VARCHAR(128) NOT NULL, -- maintenance/full/event/seasonal/other
reason_detail TEXT, -- 详细说明
status VARCHAR(16) DEFAULT 'active', -- active/cancelled/expired
created_by VARCHAR(64) NOT NULL, -- 创建人
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_ss_v2_hotel_date ON stop_sell_v2 (supplier_id, hotel_id, room_type_id, stop_from, stop_to);
CREATE INDEX idx_ss_v2_channel ON stop_sell_v2 (channel_id, status, stop_from, stop_to);
CREATE INDEX idx_ss_v2_status ON stop_sell_v2 (status, stop_from, stop_to);
-- 风控规则表
CREATE TABLE risk_rules (
id SERIAL PRIMARY KEY,
rule_name VARCHAR(128) NOT NULL,
rule_type VARCHAR(32) NOT NULL, -- price_anomaly/traffic/credit/blacklist
condition JSONB NOT NULL, -- 规则条件配置
action VARCHAR(32) NOT NULL, -- block/alert/log/verify
severity VARCHAR(16) DEFAULT 'medium', -- low/medium/high/critical
enabled BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 风控事件日志表
CREATE TABLE risk_events (
id BIGSERIAL PRIMARY KEY,
event_type VARCHAR(32) NOT NULL,
rule_id INT REFERENCES risk_rules(id),
agent_code VARCHAR(32),
ip_address VARCHAR(45),
request_path VARCHAR(256),
detail JSONB, -- 详细信息
action_taken VARCHAR(32), -- block/alert/passed
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_risk_events_type ON risk_events (event_type, created_at DESC);
CREATE INDEX idx_risk_events_agent ON risk_events (agent_code);
-- IP 黑名单表
CREATE TABLE ip_blacklist (
id SERIAL PRIMARY KEY,
ip_address VARCHAR(45) NOT NULL UNIQUE,
reason VARCHAR(255),
blocked_by VARCHAR(64),
expires_at TIMESTAMPTZ, -- 空=永久
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 风险告警记录表
CREATE TABLE risk_alerts (
id BIGSERIAL PRIMARY KEY,
alert_type VARCHAR(64) NOT NULL,
severity VARCHAR(16) NOT NULL,
title VARCHAR(255) NOT NULL,
detail JSONB,
status VARCHAR(20) DEFAULT 'open', -- open/acknowledged/resolved
acknowledged_by VARCHAR(64),
resolved_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_risk_alerts_status ON risk_alerts (status, created_at DESC);
-- 信用额度变更记录
CREATE TABLE credit_log (
id BIGSERIAL PRIMARY KEY,
agent_code VARCHAR(32) NOT NULL,
change_type VARCHAR(32) NOT NULL, -- order_hold/order_release/settlement/adjust
amount DECIMAL(12, 2) NOT NULL, -- 正=增加使用,负=释放
balance_before DECIMAL(12, 2),
balance_after DECIMAL(12, 2),
reference_no VARCHAR(64), -- 关联订单号或结算单号
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_credit_log_agent ON credit_log (agent_code, created_at DESC);
-- 以下表主要在 ClickHouse 中创建,PG 中保留简化版本
-- ClickHouse: 每日聚合统计表
-- CREATE TABLE daily_stats (date Date, metric String, dimension String, value Int64, amount Float64)
-- ENGINE = SummingMergeTree() ORDER BY (date, metric, dimension)
-- 供应商评分表 (PG)
CREATE TABLE supplier_scores (
id BIGSERIAL PRIMARY KEY,
supplier_code VARCHAR(32) NOT NULL,
period_date DATE NOT NULL,
availability_score DECIMAL(5, 2), -- 可用率评分
price_score DECIMAL(5, 2), -- 价格竞争力评分
response_score DECIMAL(5, 2), -- 响应速度评分
quality_score DECIMAL(5, 2), -- 综合质量评分
booking_rate DECIMAL(5, 2), -- 预订成功率
cancellation_rate DECIMAL(5, 2), -- 取消率
total_bookings INT DEFAULT 0,
total_revenue DECIMAL(14, 2) DEFAULT 0,
rank INT, -- 排名
calculated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(supplier_code, period_date)
);
-- 代理商评分表
CREATE TABLE agent_scores (
id BIGSERIAL PRIMARY KEY,
agent_code VARCHAR(32) NOT NULL,
period_date DATE NOT NULL,
booking_score DECIMAL(5, 2), -- 预订量评分
revenue_score DECIMAL(5, 2), -- 营收贡献评分
payment_score DECIMAL(5, 2), -- 付款及时性评分
cancellation_score DECIMAL(5, 2), -- 取消率评分(低好)
overall_score DECIMAL(5, 2), -- 综合评分
total_bookings INT DEFAULT 0,
total_revenue DECIMAL(14, 2) DEFAULT 0,
avg_booking_value DECIMAL(10, 2),
calculated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(agent_code, period_date)
);
-- 需求预测表
CREATE TABLE demand_forecasts (
id BIGSERIAL PRIMARY KEY,
hotel_id BIGINT NOT NULL,
stay_date DATE NOT NULL,
predicted_demand INT, -- 预测需求热度 1-100
confidence DECIMAL(5, 2), -- 预测置信度
model_version VARCHAR(16),
actual_demand INT, -- 实际值(事后回填)
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(hotel_id, stay_date)
);
-- 报表配置表
CREATE TABLE report_configs (
id SERIAL PRIMARY KEY,
report_name VARCHAR(128) NOT NULL,
report_type VARCHAR(32) NOT NULL, -- daily/weekly/monthly/custom
schedule_cron VARCHAR(64), -- 定时表达式
recipients JSONB, -- 接收人列表
config JSONB, -- 报表参数
enabled BOOLEAN DEFAULT true,
last_run_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- API 密钥表 (关联 agents 表)
CREATE TABLE api_keys (
id BIGSERIAL PRIMARY KEY,
agent_code VARCHAR(32) NOT NULL REFERENCES agents(agent_code),
key_id VARCHAR(32) NOT NULL UNIQUE, -- 可公开的 Key ID
key_secret_hash VARCHAR(128) NOT NULL, -- 密钥哈希(不可逆)
rate_limit_rpm INT DEFAULT 60, -- 每分钟请求限制
rate_limit_rpd INT DEFAULT 10000, -- 每天请求限制
allowed_apis JSONB DEFAULT '["*"]', -- 允许访问的 API 列表
ip_whitelist JSONB, -- IP 白名单
status VARCHAR(20) DEFAULT 'active', -- active/suspended/revoked
last_used_at TIMESTAMPTZ,
expires_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
revoked_at TIMESTAMPTZ
);
-- 请求日志表 (ClickHouse 或 PG)
CREATE TABLE request_logs (
id BIGSERIAL PRIMARY KEY,
trace_id VARCHAR(64) NOT NULL,
request_method VARCHAR(16) NOT NULL,
request_path VARCHAR(512) NOT NULL,
query_params TEXT,
request_body TEXT, -- 脱敏后
client_ip VARCHAR(45),
user_agent VARCHAR(512),
agent_code VARCHAR(32),
api_key_id VARCHAR(32),
response_status SMALLINT NOT NULL,
response_ms INT NOT NULL,
error_message TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 限流配置表
CREATE TABLE rate_limits (
id SERIAL PRIMARY KEY,
limit_type VARCHAR(32) NOT NULL, -- global/ip/agent/api
limit_key VARCHAR(64) NOT NULL, -- 具体限流对象
requests_per_minute INT NOT NULL,
requests_per_day INT,
burst_size INT DEFAULT 10, -- 突发容量
enabled BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT NOW()
);
管理后台为前端模块,无独立数据表,调用后端各模块 API 进行操作。 请参见 6.5-6.11 各模块数据表。
CREATE TABLE dynamic_pricing_rule (
id SERIAL PRIMARY KEY,
supplier_id BIGINT,
hotel_id BIGINT,
room_type_id BIGINT,
channel_id BIGINT,
rule_type VARCHAR(32) NOT NULL, -- holiday/advance/last_minute/custom
trigger_condition JSONB NOT NULL, -- 触发条件,如 {"advance_days_gte": 30}
adjustment_type VARCHAR(16) NOT NULL, -- percentage / fixed
adjustment_value DECIMAL(10, 2) NOT NULL, -- 百分比值或固定金额
effective_from DATE NOT NULL,
effective_to DATE NOT NULL,
priority SMALLINT DEFAULT 0,
status VARCHAR(16) DEFAULT 'active',
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_dpr_hotel ON dynamic_pricing_rule (hotel_id, room_type_id, status, effective_from);
CREATE TABLE rate_parity_alert (
id SERIAL PRIMARY KEY,
hotel_id BIGINT NOT NULL,
room_type_id BIGINT,
check_in_date DATE NOT NULL,
channel_a VARCHAR(64) NOT NULL,
channel_b VARCHAR(64) NOT NULL,
price_a DECIMAL(10, 2) NOT NULL,
price_b DECIMAL(10, 2) NOT NULL,
deviation_pct DECIMAL(5, 2) NOT NULL, -- 偏差百分比
alert_level VARCHAR(16) DEFAULT 'warning', -- warning / critical
status VARCHAR(16) DEFAULT 'open', -- open / acknowledged / resolved
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_rpa_hotel_date ON rate_parity_alert (hotel_id, check_in_date, status);
CREATE TABLE promotion (
id SERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL,
type VARCHAR(32) NOT NULL, -- flash / early_bird / package / custom
supplier_id BIGINT,
hotel_ids INT[] DEFAULT '{}',
channel_ids INT[] DEFAULT '{}',
discount_type VARCHAR(16) NOT NULL, -- percentage / fixed / free_night
discount_value DECIMAL(10, 2) NOT NULL,
start_time TIMESTAMPTZ NOT NULL,
end_time TIMESTAMPTZ NOT NULL,
quota INT DEFAULT 0, -- 0=不限量
used_quota INT DEFAULT 0,
conditions JSONB, -- 如 {"min_stay": 3, "min_amount": 1000}
status VARCHAR(16) DEFAULT 'draft',
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_promotion_time ON promotion (start_time, end_time, status);
CREATE TABLE exchange_rate (
id SERIAL PRIMARY KEY,
currency_from VARCHAR(3) NOT NULL, -- ISO 4217
currency_to VARCHAR(3) NOT NULL,
rate DECIMAL(18, 8) NOT NULL, -- 1 unit of currency_from = ? currency_to
effective_at TIMESTAMPTZ NOT NULL,
source VARCHAR(32) NOT NULL, -- ecb / open_exchange_rates / manual
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE UNIQUE INDEX idx_er_pair_time ON exchange_rate (currency_from, currency_to, effective_at DESC);
-- orders 表新增字段
ALTER TABLE orders ADD COLUMN parent_order_id BIGINT REFERENCES orders(id);
ALTER TABLE orders ADD COLUMN split_sequence SMALLINT DEFAULT 0;
CREATE TABLE consolidation (
id SERIAL PRIMARY KEY,
agent_id BIGINT NOT NULL,
period_start DATE NOT NULL,
period_end DATE NOT NULL,
order_ids BIGINT[] NOT NULL,
total_amount DECIMAL(12, 2) NOT NULL,
currency VARCHAR(3) DEFAULT 'CNY',
status VARCHAR(16) DEFAULT 'pending', -- pending / confirmed / settled
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE payment_rule (
id SERIAL PRIMARY KEY,
supplier_id BIGINT NOT NULL,
channel_id BIGINT,
hotel_id BIGINT,
payment_type VARCHAR(16) NOT NULL, -- guarantee / prepay / postpay
guarantee_amount DECIMAL(10, 2), -- 担保金额(NULL=全额担保)
prepay_days INT, -- 提前 N 天预付(NULL=立即预付)
payment_methods JSONB, -- 支持的支付方式,如 ["credit_card", "bank_transfer"]
effective_from DATE NOT NULL,
effective_to DATE NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- orders 表新增字段
ALTER TABLE orders ADD COLUMN confirmed_at TIMESTAMPTZ;
ALTER TABLE orders ADD COLUMN paid_at TIMESTAMPTZ;
CREATE TABLE order_timeout_config (
id SERIAL PRIMARY KEY,
channel_id BIGINT,
supplier_id BIGINT,
confirm_timeout_min INT NOT NULL DEFAULT 30, -- 确认超时(分钟)
payment_timeout_min INT NOT NULL DEFAULT 60, -- 支付超时(分钟)
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE hotel_content_i18n (
hotel_id BIGINT NOT NULL REFERENCES hotels(id),
language VARCHAR(5) NOT NULL, -- zh-CN / en / ja
name VARCHAR(256),
description TEXT,
address VARCHAR(512),
amenities JSONB,
PRIMARY KEY (hotel_id, language)
);
CREATE TABLE room_type_content_i18n (
room_type_id BIGINT NOT NULL REFERENCES room_types(id),
language VARCHAR(5) NOT NULL,
name VARCHAR(256),
description TEXT,
bed_type VARCHAR(64),
PRIMARY KEY (room_type_id, language)
);
CREATE TABLE media (
id SERIAL PRIMARY KEY,
entity_type VARCHAR(16) NOT NULL, -- hotel / room_type / facility
entity_id BIGINT NOT NULL,
url VARCHAR(512) NOT NULL, -- 原图 CDN 地址
thumbnail_url VARCHAR(512), -- 缩略图 CDN 地址
category VARCHAR(32), -- exterior / room / amenity / facility
sort_order SMALLINT DEFAULT 0,
uploaded_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_media_entity ON media (entity_type, entity_id, sort_order);
CREATE TABLE hotel_policy (
id SERIAL PRIMARY KEY,
hotel_id BIGINT NOT NULL REFERENCES hotels(id),
policy_type VARCHAR(32) NOT NULL, -- check_in / children / pet / payment / general
content JSONB NOT NULL, -- 政策内容,如 {"check_in_from": "14:00", "check_out_by": "12:00"}
language VARCHAR(5) DEFAULT 'zh-CN',
effective_from DATE NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_hp_hotel_type ON hotel_policy (hotel_id, policy_type, language);
CREATE TABLE reconciliation (
id SERIAL PRIMARY KEY,
period VARCHAR(7) NOT NULL, -- 对账周期,如 2024-01
agent_id BIGINT NOT NULL,
supplier_id BIGINT NOT NULL,
our_amount DECIMAL(12, 2) NOT NULL, -- 我方金额
their_amount DECIMAL(12, 2) NOT NULL, -- 对方金额
diff_amount DECIMAL(12, 2) NOT NULL, -- 差异金额
status VARCHAR(16) DEFAULT 'pending', -- pending / auto_resolved / resolved / disputed
resolution JSONB, -- 解决方案,如 {"type": "adjustment", "note": "..."}
resolved_by VARCHAR(64),
resolved_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_recon_period ON reconciliation (period, status);
CREATE TABLE supplier_rating (
id SERIAL PRIMARY KEY,
supplier_id BIGINT NOT NULL REFERENCES suppliers(id),
period VARCHAR(7) NOT NULL, -- 评分周期,如 2024-01
score_overall DECIMAL(4, 2) NOT NULL, -- 综合评分 0-100
score_response_time DECIMAL(4, 2),
score_price DECIMAL(4, 2),
score_inventory_accuracy DECIMAL(4, 2),
score_cancel_rate DECIMAL(4, 2),
calc_details JSONB, -- 各指标原始值和计算过程
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE UNIQUE INDEX idx_sr_supplier_period ON supplier_rating (supplier_id, period);
CREATE TABLE agent_tier (
id SERIAL PRIMARY KEY,
tier_name VARCHAR(32) NOT NULL UNIQUE, -- bronze / silver / gold / platinum
min_monthly_volume INT NOT NULL, -- 最低月交易单数
price_discount_pct DECIMAL(4, 2) DEFAULT 0, -- 价格折扣百分比
inventory_priority SMALLINT DEFAULT 0, -- 库存优先级,越高越优先
settlement_days INT DEFAULT 30, -- 结算天数
support_level VARCHAR(16) DEFAULT 'standard',
benefits JSONB, -- 其他权益描述
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- agents 表新增字段
ALTER TABLE agents ADD COLUMN tier_id BIGINT REFERENCES agent_tier(id);
ALTER TABLE agents ADD COLUMN tier_evaluated_at TIMESTAMPTZ;
CREATE TABLE notification (
id SERIAL PRIMARY KEY,
party_type VARCHAR(16) NOT NULL, -- agent / supplier / admin
party_id BIGINT NOT NULL,
type VARCHAR(32) NOT NULL, -- order_status / inventory_alert / price_change / ...
title VARCHAR(256) NOT NULL,
content JSONB NOT NULL, -- 通知内容,结构因 type 而异
channel VARCHAR(16) NOT NULL, -- email / webhook / in_app
status VARCHAR(16) DEFAULT 'pending', -- pending / sent / failed
sent_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_notif_party ON notification (party_type, party_id, status, created_at DESC);
CREATE TABLE audit_log (
id BIGSERIAL PRIMARY KEY,
operator_type VARCHAR(16) NOT NULL, -- admin / agent / supplier / system
operator_id BIGINT,
action VARCHAR(32) NOT NULL, -- create / update / delete / login / ...
entity_type VARCHAR(32) NOT NULL, -- hotel / order / supplier / ...
entity_id BIGINT,
detail JSONB, -- 变更详情,如 {"before": {...}, "after": {...}}
ip VARCHAR(45),
user_agent VARCHAR(256),
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_audit_entity ON audit_log (entity_type, entity_id, created_at DESC);
CREATE INDEX idx_audit_operator ON audit_log (operator_type, operator_id, created_at DESC);
CREATE TABLE tenants (
id SERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL,
domain VARCHAR(128) UNIQUE, -- 租户域名,如 hotel.example.com
config JSONB DEFAULT '{}', -- 租户自定义配置
status VARCHAR(16) DEFAULT 'active',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- 所有业务表新增租户字段(示例)
ALTER TABLE hotels ADD COLUMN tenant_id BIGINT REFERENCES tenants(id);
ALTER TABLE agents ADD COLUMN tenant_id BIGINT REFERENCES tenants(id);
ALTER TABLE suppliers ADD COLUMN tenant_id BIGINT REFERENCES tenants(id);
CREATE TABLE insight_rules (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(128) NOT NULL,
description TEXT,
metric_source VARCHAR(64) NOT NULL, -- 指标来源(如 supplier_price_competitiveness)
condition JSONB NOT NULL, -- 触发条件(如 {"change_pct": -10, "window_days": 3})
suggestion TEXT NOT NULL, -- 建议方案模板
severity VARCHAR(16) DEFAULT 'info', -- info/warning/critical
action_type VARCHAR(32), -- recommend/auto_execute/notify_only
enabled BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE insight_events (
id BIGSERIAL PRIMARY KEY,
rule_id BIGINT REFERENCES insight_rules(id),
triggered_at TIMESTAMPTZ NOT NULL,
metric_data JSONB NOT NULL, -- 触发时的指标快照
suggestion_text TEXT NOT NULL,
channel VARCHAR(32) DEFAULT 'feishu',
status VARCHAR(16) DEFAULT 'pending', -- pending/accepted/ignored/executed
user_feedback VARCHAR(16), -- 用户的反馈
processed_at TIMESTAMPTZ
);
CREATE TABLE permission_policy (
id BIGSERIAL PRIMARY KEY,
action_category VARCHAR(64) NOT NULL, -- restart_service/cleanup_logs/supplier_circuit_break/...
action_name VARCHAR(128) NOT NULL,
level VARCHAR(8) NOT NULL, -- L1/L2/L3
description TEXT,
conditions JSONB, -- 额外条件(如 L2 级操作在非工作时间升级为 L3)
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE execution_log (
id BIGSERIAL PRIMARY KEY,
action_category VARCHAR(64) NOT NULL,
action_name VARCHAR(128) NOT NULL,
level VARCHAR(8) NOT NULL,
status VARCHAR(16) NOT NULL, -- approved/executed/rejected/timeout
approval_status VARCHAR(16), -- null(L1)/auto(L2)/pending/manual(L3)
result JSONB,
executed_at TIMESTAMPTZ,
approved_by VARCHAR(64),
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE supplier_onboarding (
id BIGSERIAL PRIMARY KEY,
supplier_id BIGINT REFERENCES suppliers(id),
status VARCHAR(32) DEFAULT 'pending',
-- pending/adapter_dev/mock_test/integration_test/staging/production/failed
api_doc_url VARCHAR(512),
test_credentials JSONB,
adapter_code TEXT,
test_results JSONB,
staging_config JSONB,
production_config JSONB,
health_score DECIMAL(5,2),
started_at TIMESTAMPTZ,
completed_at TIMESTAMPTZ,
notes TEXT
);
CREATE TABLE supplier_test_suite (
id BIGSERIAL PRIMARY KEY,
onboarding_id BIGINT REFERENCES supplier_onboarding(id),
test_type VARCHAR(32) NOT NULL, -- mock/integration/regression
test_name VARCHAR(128) NOT NULL,
status VARCHAR(16), -- passed/failed/skipped
duration_ms INT,
error_detail TEXT,
executed_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE tickets (
id BIGSERIAL PRIMARY KEY,
ticket_no VARCHAR(32) NOT NULL UNIQUE, -- TK-20260415-001
title VARCHAR(256) NOT NULL,
description TEXT NOT NULL,
source VARCHAR(32) NOT NULL, -- agent/manual/monitor
priority VARCHAR(8) NOT NULL, -- P0/P1/P2/P3
status VARCHAR(32) DEFAULT 'open',
-- open/diagnosing/pending_approval/resolved/closed
related_type VARCHAR(32), -- order/hotel/supplier/agent
related_id VARCHAR(64),
diagnosis JSONB, -- AI 自动诊断结果
suggestion TEXT, -- AI 建议
resolution TEXT,
assigned_to VARCHAR(64),
created_by VARCHAR(64),
created_at TIMESTAMPTZ DEFAULT now(),
resolved_at TIMESTAMPTZ,
closed_at TIMESTAMPTZ
);
CREATE TABLE ticket_timeline (
id BIGSERIAL PRIMARY KEY,
ticket_id BIGINT REFERENCES tickets(id),
action VARCHAR(64) NOT NULL, -- created/diagnosed/suggested/replied/resolved
operator_type VARCHAR(16), -- ai/human/system
operator_id VARCHAR(64),
content JSONB NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE knowledge_base (
id BIGSERIAL PRIMARY KEY,
category VARCHAR(32) NOT NULL, -- supplier/operation/technical
title VARCHAR(256) NOT NULL,
content TEXT NOT NULL,
tags VARCHAR(256)[], -- 数组标签
related_type VARCHAR(32), -- supplier_id/agent_id/incident_id
related_id VARCHAR(64),
source VARCHAR(32) NOT NULL, -- manual/auto_decision/auto_incident/auto_config
confidence DECIMAL(3,2) DEFAULT 1.0,
reference_count INT DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE knowledge_references (
id BIGSERIAL PRIMARY KEY,
knowledge_id BIGINT REFERENCES knowledge_base(id),
ref_type VARCHAR(32), -- ticket/incident/decision/config_change
ref_id VARCHAR(64),
context TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE financial_metrics (
id BIGSERIAL PRIMARY KEY,
metric_date DATE NOT NULL,
metric_type VARCHAR(64) NOT NULL, -- daily_commission/supplier_contribution/agent_revenue
dimension_key VARCHAR(128), -- supplier_id/agent_id
dimension_value VARCHAR(128),
amount DECIMAL(14,2) NOT NULL,
change_pct DECIMAL(5,2),
change_reason TEXT,
calculated_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE financial_alerts (
id BIGSERIAL PRIMARY KEY,
alert_type VARCHAR(64) NOT NULL, -- revenue_drop/overdue_payment/credit_limit
entity_type VARCHAR(32), -- supplier/agent
entity_id VARCHAR(64),
current_value DECIMAL(14,2),
threshold_value DECIMAL(14,2),
suggestion TEXT,
status VARCHAR(16) DEFAULT 'pending',
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE trace_events (
id BIGSERIAL PRIMARY KEY,
trace_id VARCHAR(64) NOT NULL, -- 链路追踪 ID
span_id VARCHAR(64) NOT NULL, -- 当前环节 ID
parent_span_id VARCHAR(64), -- 父环节 ID
event_type VARCHAR(64) NOT NULL, -- search/cache_hit/supplier_query/trial/book/confirm/settle
service VARCHAR(32) NOT NULL, -- api_gateway/query_engine/supplier_adapter/...
related_type VARCHAR(32), -- order/supplier/agent/hotel
related_id VARCHAR(64),
request_data JSONB,
response_data JSONB,
duration_ms INT,
status VARCHAR(16) NOT NULL, -- success/error/timeout
error_detail TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_trace_trace_id ON trace_events(trace_id);
CREATE INDEX idx_trace_related ON trace_events(related_type, related_id);
CREATE INDEX idx_trace_created ON trace_events(created_at);
文档结束
本文档为 B2B2B 酒店分销平台完整数据模型设计,共计 75+ 张数据表(含 3 张 ClickHouse 表),覆盖所有业务模块。