chore: 文档与 IDE 配置整理
- .kiro/specs/ → docs/specs/(41 个历史需求 spec 迁移,移除 .config.kiro) - CLAUDE.md 三层拆分:根文件精简 + apps/backend/CLAUDE.md + .claude/commands/ - 新增 /spec-close、/pre-change 两个工作流命令 - DDL 基线刷新(从测试库重新导出 11 个文件,dws 35→38 表,biz 18→21 表) - BD_Manual → BD_manual 命名统一(48 个文件) - 修复 3 处文档与数据库不一致(auth.users.status 默认值、scheduled_tasks 字段、RLS 视图数) - 新增 BD_manual_public_rbac_tables.md(public schema 8 张 RBAC/工作流表) - 合并 biz.trigger_jobs 文档(10→12 字段,归档独立文档) - docs/database/README.md 索引更新 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
-- =============================================================================
|
||||
-- etl_feiqiu / app(RLS 视图层)
|
||||
-- 生成日期:2026-03-15
|
||||
-- 生成日期:2026-04-05
|
||||
-- 来源:测试库(通过脚本自动导出)
|
||||
-- =============================================================================
|
||||
|
||||
@@ -39,6 +39,17 @@ SELECT id,
|
||||
FROM dws.dws_assistant_daily_detail d;
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_cfg_area_category AS
|
||||
SELECT DISTINCT category_code,
|
||||
category_name,
|
||||
display_name,
|
||||
short_name,
|
||||
sort_order
|
||||
FROM dws.cfg_area_category
|
||||
WHERE ((is_active = true) AND ((category_code)::text <> ALL ((ARRAY['SPECIAL'::character varying, 'OTHER'::character varying])::text[])))
|
||||
ORDER BY sort_order;
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_cfg_assistant_level_price AS
|
||||
SELECT price_id,
|
||||
level_code,
|
||||
@@ -104,19 +115,6 @@ SELECT tier_id,
|
||||
FROM dws.cfg_performance_tier;
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_cfg_area_category AS
|
||||
SELECT DISTINCT
|
||||
category_code,
|
||||
category_name,
|
||||
display_name,
|
||||
short_name,
|
||||
sort_order
|
||||
FROM dws.cfg_area_category
|
||||
WHERE is_active = TRUE
|
||||
AND category_code NOT IN ('SPECIAL', 'OTHER')
|
||||
ORDER BY sort_order;
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dim_assistant AS
|
||||
SELECT assistant_id,
|
||||
user_id,
|
||||
@@ -606,6 +604,26 @@ SELECT contribution_id,
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_assistant_project_tag AS
|
||||
SELECT id,
|
||||
site_id,
|
||||
tenant_id,
|
||||
assistant_id,
|
||||
time_window,
|
||||
category_code,
|
||||
category_name,
|
||||
short_name,
|
||||
duration_seconds,
|
||||
total_seconds,
|
||||
percentage,
|
||||
is_tagged,
|
||||
computed_at,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM dws.dws_assistant_project_tag
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_assistant_recharge_commission AS
|
||||
SELECT id,
|
||||
site_id,
|
||||
@@ -671,6 +689,92 @@ SELECT id,
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_coach_area_hours AS
|
||||
SELECT id,
|
||||
site_id,
|
||||
tenant_id,
|
||||
stat_month,
|
||||
assistant_id,
|
||||
area_code,
|
||||
base_hours,
|
||||
bonus_hours,
|
||||
room_hours,
|
||||
effective_hours,
|
||||
trashed_hours,
|
||||
base_service_count,
|
||||
bonus_service_count,
|
||||
room_service_count,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM dws.dws_coach_area_hours
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_finance_area_daily AS
|
||||
SELECT id,
|
||||
site_id,
|
||||
tenant_id,
|
||||
stat_date,
|
||||
area_code,
|
||||
table_fee_amount,
|
||||
goods_amount,
|
||||
assistant_pd_amount,
|
||||
assistant_cx_amount,
|
||||
gross_amount,
|
||||
discount_groupbuy,
|
||||
discount_vip,
|
||||
discount_manual,
|
||||
discount_gift_card,
|
||||
discount_rounding,
|
||||
discount_other,
|
||||
discount_total,
|
||||
confirmed_income,
|
||||
cash_pay_amount,
|
||||
cash_paper_amount,
|
||||
scan_pay_amount,
|
||||
groupbuy_pay_amount,
|
||||
recharge_cash_inflow,
|
||||
cash_inflow_total,
|
||||
cash_outflow_total,
|
||||
cash_balance_change,
|
||||
card_consume_total,
|
||||
recharge_card_consume,
|
||||
gift_card_consume,
|
||||
recharge_cash,
|
||||
first_recharge_cash,
|
||||
renewal_cash,
|
||||
order_count,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM dws.dws_finance_area_daily
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_finance_board_cache AS
|
||||
SELECT id,
|
||||
site_id,
|
||||
time_range,
|
||||
area_code,
|
||||
start_date,
|
||||
end_date,
|
||||
prev_start_date,
|
||||
prev_end_date,
|
||||
occurrence,
|
||||
discount,
|
||||
discount_rate,
|
||||
confirmed_revenue,
|
||||
cash_in,
|
||||
cash_out,
|
||||
cash_balance,
|
||||
balance_rate,
|
||||
data_fingerprint,
|
||||
computed_at,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM dws.dws_finance_board_cache
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_finance_daily_summary AS
|
||||
SELECT id,
|
||||
site_id,
|
||||
@@ -691,6 +795,8 @@ SELECT id,
|
||||
confirmed_income,
|
||||
cash_inflow_total,
|
||||
cash_pay_amount,
|
||||
cash_paper_amount,
|
||||
scan_pay_amount,
|
||||
groupbuy_pay_amount,
|
||||
platform_settlement_amount,
|
||||
platform_fee_amount,
|
||||
@@ -963,7 +1069,54 @@ SELECT newconv_id,
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_project_tag AS
|
||||
SELECT id,
|
||||
site_id,
|
||||
tenant_id,
|
||||
member_id,
|
||||
time_window,
|
||||
category_code,
|
||||
category_name,
|
||||
short_name,
|
||||
duration_seconds,
|
||||
total_seconds,
|
||||
percentage,
|
||||
is_tagged,
|
||||
computed_at,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM dws.dws_member_project_tag
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_spending_power_index AS
|
||||
SELECT spi_id,
|
||||
site_id,
|
||||
member_id,
|
||||
spend_30,
|
||||
spend_90,
|
||||
recharge_90,
|
||||
orders_30,
|
||||
orders_90,
|
||||
visit_days_30,
|
||||
visit_days_90,
|
||||
avg_ticket_90,
|
||||
active_weeks_90,
|
||||
daily_spend_ewma_90,
|
||||
score_level_raw,
|
||||
score_speed_raw,
|
||||
score_stability_raw,
|
||||
score_level_display,
|
||||
score_speed_display,
|
||||
score_stability_display,
|
||||
raw_score,
|
||||
display_score,
|
||||
calc_time,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM dws.dws_member_spending_power_index
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_visit_detail AS
|
||||
SELECT id,
|
||||
@@ -1182,34 +1335,3 @@ SELECT site_id,
|
||||
FROM core.dim_site s;
|
||||
;
|
||||
|
||||
|
||||
-- 2026-03-19 新增:BOARD 看板所需的 3 个 RLS 视图
|
||||
-- 迁移脚本:db/etl_feiqiu/migrations/2026-03-19_add_board_rls_views.sql
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_assistant_project_tag AS
|
||||
SELECT id, site_id, tenant_id, assistant_id, time_window,
|
||||
category_code, category_name, short_name,
|
||||
duration_seconds, total_seconds, percentage, is_tagged,
|
||||
computed_at, created_at, updated_at
|
||||
FROM dws.dws_assistant_project_tag
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_project_tag AS
|
||||
SELECT id, site_id, tenant_id, member_id, time_window,
|
||||
category_code, category_name, short_name,
|
||||
duration_seconds, total_seconds, percentage, is_tagged,
|
||||
computed_at, created_at, updated_at
|
||||
FROM dws.dws_member_project_tag
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
CREATE OR REPLACE VIEW app.v_dws_member_spending_power_index AS
|
||||
SELECT spi_id, site_id, member_id,
|
||||
spend_30, spend_90, recharge_90,
|
||||
orders_30, orders_90, visit_days_30, visit_days_90,
|
||||
avg_ticket_90, active_weeks_90, daily_spend_ewma_90,
|
||||
score_level_raw, score_speed_raw, score_stability_raw,
|
||||
score_level_display, score_speed_display, score_stability_display,
|
||||
raw_score, display_score,
|
||||
calc_time, created_at, updated_at
|
||||
FROM dws.dws_member_spending_power_index
|
||||
WHERE site_id = current_setting('app.current_site_id')::bigint;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- =============================================================================
|
||||
-- etl_feiqiu / core(跨门店标准化维度/事实)
|
||||
-- 生成日期:2026-03-15
|
||||
-- 生成日期:2026-04-05
|
||||
-- 来源:测试库(通过脚本自动导出)
|
||||
-- =============================================================================
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- =============================================================================
|
||||
-- etl_feiqiu / dwd(明细数据层)
|
||||
-- 生成日期:2026-03-15
|
||||
-- 生成日期:2026-04-05
|
||||
-- 来源:测试库(通过脚本自动导出)
|
||||
-- =============================================================================
|
||||
|
||||
@@ -284,7 +284,11 @@ CREATE TABLE dwd.dim_member_ex (
|
||||
scd2_start_time timestamp with time zone NOT NULL,
|
||||
scd2_end_time timestamp with time zone,
|
||||
scd2_is_current integer,
|
||||
scd2_version integer
|
||||
scd2_version integer,
|
||||
other_pay_money_sum numeric(18,2),
|
||||
last_consume_time timestamp with time zone,
|
||||
non_consume_day_num integer,
|
||||
first_consumption integer
|
||||
);
|
||||
|
||||
CREATE TABLE dwd.dim_site (
|
||||
@@ -617,7 +621,9 @@ CREATE TABLE dwd.dwd_assistant_service_log_ex (
|
||||
composite_grade_time timestamp with time zone,
|
||||
assistant_team_name text,
|
||||
operator_id bigint,
|
||||
operator_name text
|
||||
operator_name text,
|
||||
deduct_leave_seconds integer DEFAULT 0,
|
||||
order_from integer
|
||||
);
|
||||
|
||||
CREATE TABLE dwd.dwd_goods_stock_movement (
|
||||
@@ -660,7 +666,8 @@ CREATE TABLE dwd.dwd_goods_stock_summary (
|
||||
current_stock numeric(18,4),
|
||||
site_id bigint,
|
||||
tenant_id bigint,
|
||||
fetched_at timestamp with time zone NOT NULL
|
||||
fetched_at timestamp with time zone NOT NULL,
|
||||
create_time timestamp with time zone
|
||||
);
|
||||
|
||||
CREATE TABLE dwd.dwd_groupbuy_redemption (
|
||||
@@ -986,7 +993,8 @@ CREATE TABLE dwd.dwd_settlement_head_ex (
|
||||
salesman_name character varying(100),
|
||||
order_remark character varying(255),
|
||||
operator_id bigint,
|
||||
salesman_user_id bigint
|
||||
salesman_user_id bigint,
|
||||
order_from integer
|
||||
);
|
||||
|
||||
CREATE TABLE dwd.dwd_store_goods_sale (
|
||||
@@ -1045,7 +1053,10 @@ CREATE TABLE dwd.dwd_store_goods_sale_ex (
|
||||
push_money numeric(18,2),
|
||||
is_single_order integer,
|
||||
sales_type integer,
|
||||
operator_id bigint
|
||||
operator_id bigint,
|
||||
activity_amount numeric(18,2) DEFAULT 0,
|
||||
activity_id bigint DEFAULT 0,
|
||||
order_from integer
|
||||
);
|
||||
|
||||
CREATE TABLE dwd.dwd_table_fee_adjust (
|
||||
@@ -1128,7 +1139,8 @@ CREATE TABLE dwd.dwd_table_fee_log_ex (
|
||||
operator_id bigint,
|
||||
salesman_user_id bigint,
|
||||
salesman_org_id bigint,
|
||||
order_consumption_type integer
|
||||
order_consumption_type integer,
|
||||
order_from integer
|
||||
);
|
||||
|
||||
-- 约束(主键 / 唯一 / 外键)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- =============================================================================
|
||||
-- etl_feiqiu / dws(汇总数据层)
|
||||
-- 生成日期:2026-03-15
|
||||
-- 生成日期:2026-04-05
|
||||
-- 来源:测试库(通过脚本自动导出)
|
||||
-- =============================================================================
|
||||
|
||||
@@ -21,6 +21,9 @@ CREATE SEQUENCE IF NOT EXISTS dws.dws_assistant_order_contribution_contribution_
|
||||
CREATE SEQUENCE IF NOT EXISTS dws.dws_assistant_project_tag_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS dws.dws_assistant_recharge_commission_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS dws.dws_assistant_salary_calc_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS dws.dws_coach_area_hours_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS dws.dws_finance_area_daily_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS dws.dws_finance_board_cache_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS dws.dws_finance_daily_summary_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS dws.dws_finance_discount_detail_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS dws.dws_finance_expense_summary_id_seq AS bigint;
|
||||
@@ -364,6 +367,86 @@ CREATE TABLE dws.dws_assistant_salary_calc (
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE dws.dws_coach_area_hours (
|
||||
id bigint DEFAULT nextval('dws.dws_coach_area_hours_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
tenant_id bigint NOT NULL,
|
||||
stat_month date NOT NULL,
|
||||
assistant_id bigint NOT NULL,
|
||||
area_code character varying(20) NOT NULL,
|
||||
base_hours numeric(10,2) DEFAULT 0 NOT NULL,
|
||||
bonus_hours numeric(10,2) DEFAULT 0 NOT NULL,
|
||||
room_hours numeric(10,2) DEFAULT 0 NOT NULL,
|
||||
effective_hours numeric(10,2) DEFAULT 0 NOT NULL,
|
||||
trashed_hours numeric(10,2) DEFAULT 0 NOT NULL,
|
||||
base_service_count integer DEFAULT 0 NOT NULL,
|
||||
bonus_service_count integer DEFAULT 0 NOT NULL,
|
||||
room_service_count integer DEFAULT 0 NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE dws.dws_finance_area_daily (
|
||||
id bigint DEFAULT nextval('dws.dws_finance_area_daily_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
tenant_id bigint NOT NULL,
|
||||
stat_date date NOT NULL,
|
||||
area_code character varying(20) NOT NULL,
|
||||
table_fee_amount numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
goods_amount numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
assistant_pd_amount numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
assistant_cx_amount numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
gross_amount numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
discount_groupbuy numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
discount_vip numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
discount_manual numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
discount_gift_card numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
discount_rounding numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
discount_other numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
discount_total numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
confirmed_income numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
cash_pay_amount numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
cash_paper_amount numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
scan_pay_amount numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
groupbuy_pay_amount numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
recharge_cash_inflow numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
cash_inflow_total numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
cash_outflow_total numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
cash_balance_change numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
card_consume_total numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
recharge_card_consume numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
gift_card_consume numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
recharge_cash numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
first_recharge_cash numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
renewal_cash numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
order_count integer DEFAULT 0 NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE dws.dws_finance_board_cache (
|
||||
id bigint DEFAULT nextval('dws.dws_finance_board_cache_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
time_range character varying(20) NOT NULL,
|
||||
area_code character varying(20) NOT NULL,
|
||||
start_date date NOT NULL,
|
||||
end_date date NOT NULL,
|
||||
prev_start_date date,
|
||||
prev_end_date date,
|
||||
occurrence numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
discount numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
discount_rate numeric(8,4) DEFAULT 0 NOT NULL,
|
||||
confirmed_revenue numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
cash_in numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
cash_out numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
cash_balance numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
balance_rate numeric(8,4) DEFAULT 0 NOT NULL,
|
||||
data_fingerprint character varying(64),
|
||||
computed_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE dws.dws_finance_daily_summary (
|
||||
id bigint DEFAULT nextval('dws.dws_finance_daily_summary_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
@@ -406,7 +489,9 @@ CREATE TABLE dws.dws_finance_daily_summary (
|
||||
guest_order_count integer DEFAULT 0 NOT NULL,
|
||||
avg_order_amount numeric(12,2) DEFAULT 0 NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
cash_paper_amount numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
scan_pay_amount numeric(14,2) DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE dws.dws_finance_discount_detail (
|
||||
@@ -481,14 +566,14 @@ CREATE TABLE dws.dws_finance_recharge_summary (
|
||||
total_card_balance numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
cash_card_balance numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
gift_card_balance numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
gift_liquor_balance numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
gift_table_fee_balance numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
gift_voucher_balance numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
gift_liquor_recharge numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
gift_table_fee_recharge numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
gift_voucher_recharge numeric(14,2) DEFAULT 0 NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
gift_voucher_recharge numeric(14,2) DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE dws.dws_goods_stock_daily_summary (
|
||||
@@ -631,7 +716,13 @@ CREATE TABLE dws.dws_member_assistant_relation_index (
|
||||
ml_display numeric(4,2) DEFAULT 0 NOT NULL,
|
||||
calc_time timestamp with time zone DEFAULT now() NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
recall_created_total integer DEFAULT 0 NOT NULL,
|
||||
recall_completed_total integer DEFAULT 0 NOT NULL,
|
||||
follow_up_created_total integer DEFAULT 0 NOT NULL,
|
||||
follow_up_completed_total integer DEFAULT 0 NOT NULL,
|
||||
total_created integer DEFAULT 0 NOT NULL,
|
||||
total_completed integer DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE dws.dws_member_consumption_summary (
|
||||
@@ -976,6 +1067,12 @@ ALTER TABLE dws.dws_assistant_project_tag ADD CONSTRAINT uk_dws_assistant_projec
|
||||
ALTER TABLE dws.dws_assistant_recharge_commission ADD CONSTRAINT dws_assistant_recharge_commission_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE dws.dws_assistant_salary_calc ADD CONSTRAINT dws_assistant_salary_calc_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE dws.dws_assistant_salary_calc ADD CONSTRAINT uk_dws_assistant_salary UNIQUE (site_id, assistant_id, salary_month, assistant_level_code);
|
||||
ALTER TABLE dws.dws_coach_area_hours ADD CONSTRAINT dws_coach_area_hours_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE dws.dws_coach_area_hours ADD CONSTRAINT dws_coach_area_hours_site_id_stat_month_assistant_id_area_c_key UNIQUE (site_id, stat_month, assistant_id, area_code);
|
||||
ALTER TABLE dws.dws_finance_area_daily ADD CONSTRAINT dws_finance_area_daily_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE dws.dws_finance_area_daily ADD CONSTRAINT dws_finance_area_daily_site_id_stat_date_area_code_key UNIQUE (site_id, stat_date, area_code);
|
||||
ALTER TABLE dws.dws_finance_board_cache ADD CONSTRAINT dws_finance_board_cache_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE dws.dws_finance_board_cache ADD CONSTRAINT dws_finance_board_cache_site_id_time_range_area_code_key UNIQUE (site_id, time_range, area_code);
|
||||
ALTER TABLE dws.dws_finance_daily_summary ADD CONSTRAINT dws_finance_daily_summary_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE dws.dws_finance_daily_summary ADD CONSTRAINT uk_dws_finance_daily UNIQUE (site_id, stat_date);
|
||||
ALTER TABLE dws.dws_finance_discount_detail ADD CONSTRAINT dws_finance_discount_detail_pkey PRIMARY KEY (id);
|
||||
@@ -1099,6 +1196,92 @@ CREATE INDEX idx_mv_finance_daily_l3 ON dws.mv_dws_finance_daily_summary_l3 USIN
|
||||
CREATE INDEX idx_mv_finance_daily_l4 ON dws.mv_dws_finance_daily_summary_l4 USING btree (site_id, stat_date);
|
||||
|
||||
-- 视图
|
||||
CREATE OR REPLACE VIEW dws.v_dws_coach_area_hours AS
|
||||
SELECT id,
|
||||
site_id,
|
||||
tenant_id,
|
||||
stat_month,
|
||||
assistant_id,
|
||||
area_code,
|
||||
base_hours,
|
||||
bonus_hours,
|
||||
room_hours,
|
||||
effective_hours,
|
||||
trashed_hours,
|
||||
base_service_count,
|
||||
bonus_service_count,
|
||||
room_service_count,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM dws.dws_coach_area_hours
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW dws.v_dws_finance_area_daily AS
|
||||
SELECT id,
|
||||
site_id,
|
||||
tenant_id,
|
||||
stat_date,
|
||||
area_code,
|
||||
table_fee_amount,
|
||||
goods_amount,
|
||||
assistant_pd_amount,
|
||||
assistant_cx_amount,
|
||||
gross_amount,
|
||||
discount_groupbuy,
|
||||
discount_vip,
|
||||
discount_manual,
|
||||
discount_gift_card,
|
||||
discount_rounding,
|
||||
discount_other,
|
||||
discount_total,
|
||||
confirmed_income,
|
||||
cash_pay_amount,
|
||||
cash_paper_amount,
|
||||
scan_pay_amount,
|
||||
groupbuy_pay_amount,
|
||||
recharge_cash_inflow,
|
||||
cash_inflow_total,
|
||||
cash_outflow_total,
|
||||
cash_balance_change,
|
||||
card_consume_total,
|
||||
recharge_card_consume,
|
||||
gift_card_consume,
|
||||
recharge_cash,
|
||||
first_recharge_cash,
|
||||
renewal_cash,
|
||||
order_count,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM dws.dws_finance_area_daily
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW dws.v_dws_finance_board_cache AS
|
||||
SELECT id,
|
||||
site_id,
|
||||
time_range,
|
||||
area_code,
|
||||
start_date,
|
||||
end_date,
|
||||
prev_start_date,
|
||||
prev_end_date,
|
||||
occurrence,
|
||||
discount,
|
||||
discount_rate,
|
||||
confirmed_revenue,
|
||||
cash_in,
|
||||
cash_out,
|
||||
cash_balance,
|
||||
balance_rate,
|
||||
data_fingerprint,
|
||||
computed_at,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM dws.dws_finance_board_cache
|
||||
WHERE (site_id = (current_setting('app.current_site_id'::text))::bigint);
|
||||
;
|
||||
|
||||
CREATE OR REPLACE VIEW dws.v_member_recall_priority AS
|
||||
SELECT dws_member_winback_index.site_id,
|
||||
dws_member_winback_index.tenant_id,
|
||||
@@ -1510,625 +1693,3 @@ CREATE INDEX idx_mv_finance_daily_l2 ON dws.mv_dws_finance_daily_summary_l2 USIN
|
||||
CREATE INDEX idx_mv_finance_daily_l3 ON dws.mv_dws_finance_daily_summary_l3 USING btree (site_id, stat_date);
|
||||
CREATE INDEX idx_mv_finance_daily_l4 ON dws.mv_dws_finance_daily_summary_l4 USING btree (site_id, stat_date);
|
||||
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 种子数据:DWS 配置表初始数据(绩效档位、等级定价、奖金规则、区域分类、技能映射)
|
||||
-- =============================================================================
|
||||
|
||||
-- =============================================================================
|
||||
-- DWS 配置表初始数据
|
||||
-- 版本: v4.0
|
||||
-- 创建日期: 2026-02-01
|
||||
-- 更新日期: 2026-02-21
|
||||
-- AI_CHANGELOG [2026-02-21] 取消全文注释,数据已写入 test_etl_feiqiu;
|
||||
-- 新增 2025-01-01~2026-02-28 统一提成档位(基础课18元/小时,打赏课40%);
|
||||
-- 新增 GUARANTEE 保底奖金规则(按等级:初级12000/中级16000/高级18000/星级23000);
|
||||
-- 历史分档口径截止日期调整为 2024-12-31
|
||||
-- 描述: 初始化配置表数据,包含绩效档位、等级定价、奖金规则、区域分类、技能映射
|
||||
-- =============================================================================
|
||||
|
||||
-- =============================================================================
|
||||
-- 1. cfg_performance_tier - 绩效档位配置(含历史口径)
|
||||
-- 数据来源:DWS 数据库处理需求.md
|
||||
-- 三段时间线:
|
||||
-- 2000-01-01 ~ 2024-12-31: 旧方案(6档阶梯抽成)
|
||||
-- 2025-01-01 ~ 2026-02-28: 统一提成(不分档,基础课18元/小时,打赏课40%)
|
||||
-- 2026-03-01 ~ 9999-12-31: 新方案(5档阶梯抽成)
|
||||
-- =============================================================================
|
||||
TRUNCATE TABLE dws.cfg_performance_tier RESTART IDENTITY CASCADE;
|
||||
|
||||
INSERT INTO dws.cfg_performance_tier (
|
||||
tier_code, tier_name, tier_level,
|
||||
min_hours, max_hours,
|
||||
base_deduction, bonus_deduction_ratio, vacation_days, vacation_unlimited,
|
||||
is_new_hire_tier, effective_from, effective_to, description
|
||||
) VALUES
|
||||
-- 旧方案(至2024-12-31)
|
||||
('T0', '0档-淘汰压力', 0,
|
||||
0, 100,
|
||||
28.00, 0.50, 3, FALSE,
|
||||
FALSE, '2000-01-01', '2024-12-31',
|
||||
'旧方案:H<100,专业课抽成28元/小时,打赏课抽成50%,休假3天'),
|
||||
('T1', '1档-及格档', 1,
|
||||
100, 130,
|
||||
18.00, 0.40, 4, FALSE,
|
||||
FALSE, '2000-01-01', '2024-12-31',
|
||||
'旧方案:100≤H<130,专业课抽成18元/小时,打赏课抽成40%,休假4天'),
|
||||
('T2', '2档-良好档', 2,
|
||||
130, 160,
|
||||
15.00, 0.38, 4, FALSE,
|
||||
FALSE, '2000-01-01', '2024-12-31',
|
||||
'旧方案:130≤H<160,专业课抽成15元/小时,打赏课抽成38%,休假4天'),
|
||||
('T3', '3档-优秀档', 3,
|
||||
160, 190,
|
||||
13.00, 0.35, 5, FALSE,
|
||||
FALSE, '2000-01-01', '2024-12-31',
|
||||
'旧方案:160≤H<190,专业课抽成13元/小时,打赏课抽成35%,休假5天'),
|
||||
('T4', '4档-卓越加速档', 4,
|
||||
190, 220,
|
||||
10.00, 0.33, 6, FALSE,
|
||||
FALSE, '2000-01-01', '2024-12-31',
|
||||
'旧方案:190≤H<220,专业课抽成10元/小时,打赏课抽成33%,休假6天'),
|
||||
('T5', '5档-冠军加速档', 5,
|
||||
220, NULL,
|
||||
8.00, 0.30, 0, TRUE,
|
||||
FALSE, '2000-01-01', '2024-12-31',
|
||||
'旧方案:H≥220,专业课抽成8元/小时,打赏课抽成30%,休假自由'),
|
||||
|
||||
-- 2025-01-01 ~ 2026-02-28: 统一提成(不分档,所有助教统一规则)
|
||||
-- CHANGE 2026-02-21 | 新增统一提成档位,基础课球房提成18元/小时,打赏课球房提成40%
|
||||
('T0', '统一档', 0,
|
||||
0, NULL,
|
||||
18.00, 0.40, 0, FALSE,
|
||||
FALSE, '2025-01-01', '2026-02-28',
|
||||
'2025-01-01~2026-02-28统一规则:基础课球房提成18元/小时,打赏课球房提成40%,不分档位'),
|
||||
|
||||
-- 新方案(2026-03-01起)
|
||||
('T0', '0档-淘汰压力', 0,
|
||||
0, 120,
|
||||
28.00, 0.50, 3, FALSE,
|
||||
FALSE, '2026-03-01', '9999-12-31',
|
||||
'新方案:H<120,专业课抽成28元/小时,打赏课抽成50%,休假3天'),
|
||||
('T1', '1档-及格档', 1,
|
||||
120, 150,
|
||||
18.00, 0.40, 4, FALSE,
|
||||
FALSE, '2026-03-01', '9999-12-31',
|
||||
'新方案:120≤H<150,专业课抽成18元/小时,打赏课抽成40%,休假4天'),
|
||||
('T2', '2档-良好档', 2,
|
||||
150, 180,
|
||||
13.00, 0.35, 5, FALSE,
|
||||
FALSE, '2026-03-01', '9999-12-31',
|
||||
'新方案:150≤H<180,专业课抽成13元/小时,打赏课抽成35%,休假5天'),
|
||||
('T3', '3档-优秀档', 3,
|
||||
180, 210,
|
||||
10.00, 0.30, 6, FALSE,
|
||||
FALSE, '2026-03-01', '9999-12-31',
|
||||
'新方案:180≤H<210,专业课抽成10元/小时,打赏课抽成30%,休假6天'),
|
||||
('T4', '4档-销冠竞争', 4,
|
||||
210, NULL,
|
||||
8.00, 0.25, 0, TRUE,
|
||||
FALSE, '2026-03-01', '9999-12-31',
|
||||
'新方案:H≥210,专业课抽成8元/小时,打赏课抽成25%,休假自由');
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 2. cfg_assistant_level_price - 助教等级定价
|
||||
-- 说明:
|
||||
-- - level_code 来自 dim_assistant.assistant_level
|
||||
-- - 8=助教管理, 10=初级, 20=中级, 30=高级, 40=星级
|
||||
-- - 价格为客户支付价格(对外价格),助教收入=客户支付-档位抽成
|
||||
-- - 包厢课基础课统一138元/小时(不随等级变化)
|
||||
-- =============================================================================
|
||||
TRUNCATE TABLE dws.cfg_assistant_level_price RESTART IDENTITY CASCADE;
|
||||
|
||||
INSERT INTO dws.cfg_assistant_level_price (
|
||||
level_code, level_name,
|
||||
base_course_price, bonus_course_price,
|
||||
effective_from, effective_to, description
|
||||
) VALUES
|
||||
(10, '初级',
|
||||
98.00, 190.00,
|
||||
'2000-01-01', '9999-12-31',
|
||||
'初级助教:基础课98元/时,附加课190元/时(客户支付价格)'),
|
||||
(20, '中级',
|
||||
108.00, 190.00,
|
||||
'2000-01-01', '9999-12-31',
|
||||
'中级助教:基础课108元/时,附加课190元/时(客户支付价格)'),
|
||||
(30, '高级',
|
||||
118.00, 190.00,
|
||||
'2000-01-01', '9999-12-31',
|
||||
'高级助教:基础课118元/时,附加课190元/时(客户支付价格)'),
|
||||
(40, '星级',
|
||||
138.00, 190.00,
|
||||
'2000-01-01', '9999-12-31',
|
||||
'星级助教:基础课138元/时,附加课190元/时(客户支付价格)'),
|
||||
(8, '助教管理',
|
||||
98.00, 190.00,
|
||||
'2000-01-01', '9999-12-31',
|
||||
'助教管理:不参与客户服务计费,默认按初级价格');
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 3. cfg_bonus_rules - 奖金规则配置
|
||||
-- 说明:
|
||||
-- - SPRINT: 冲刺奖金(历史口径,至2024-12-31)
|
||||
-- - GUARANTEE: 保底月薪线(2025-01-01~2026-02-28,按等级区分)
|
||||
-- * 保底规则:总课时达标 + 打赏课≥10小时 → 触发保底月薪线
|
||||
-- * 保底含义:实发 = MAX(课时收入+奖金, 保底金额),非额外奖金
|
||||
-- * rule_code 中 LV10/LV20/LV30/LV40 对应 level_code
|
||||
-- - TOP_RANK: Top3排名奖金(2026-03-01起)
|
||||
-- CHANGE 2026-02-21 | 新增 GUARANTEE 保底奖金规则
|
||||
-- =============================================================================
|
||||
TRUNCATE TABLE dws.cfg_bonus_rules RESTART IDENTITY CASCADE;
|
||||
|
||||
INSERT INTO dws.cfg_bonus_rules (
|
||||
rule_type, rule_code, rule_name,
|
||||
threshold_hours, rank_position, bonus_amount,
|
||||
is_cumulative, priority,
|
||||
effective_from, effective_to, description
|
||||
) VALUES
|
||||
-- 冲刺奖金(历史口径,至2024-12-31)
|
||||
('SPRINT', 'SPRINT_190', '冲刺奖金190',
|
||||
190.00, NULL, 300.00,
|
||||
FALSE, 1,
|
||||
'2000-01-01', '2024-12-31',
|
||||
'历史口径:业绩≥190小时,获得300元冲刺奖金(不累计)'),
|
||||
('SPRINT', 'SPRINT_220', '冲刺奖金220',
|
||||
220.00, NULL, 800.00,
|
||||
FALSE, 2,
|
||||
'2000-01-01', '2024-12-31',
|
||||
'历史口径:业绩≥220小时,获得800元冲刺奖金(覆盖190档)'),
|
||||
|
||||
-- 保底奖金(2025-01-01 ~ 2026-02-28)
|
||||
-- 按助教等级区分,需同时满足总课时和打赏课最低时数(≥10小时)
|
||||
('GUARANTEE', 'GUAR_LV10', '初级保底奖金',
|
||||
130.00, NULL, 12000.00,
|
||||
FALSE, 10,
|
||||
'2025-01-01', '2026-02-28',
|
||||
'初级保底:完成130小时课程(含≥10小时打赏课),保底月薪线12000元(实发=MAX(课时收入+奖金, 12000))'),
|
||||
('GUARANTEE', 'GUAR_LV20', '中级保底奖金',
|
||||
150.00, NULL, 16000.00,
|
||||
FALSE, 20,
|
||||
'2025-01-01', '2026-02-28',
|
||||
'中级保底:完成150小时课程(含≥10小时打赏课),保底月薪线16000元(实发=MAX(课时收入+奖金, 16000))'),
|
||||
('GUARANTEE', 'GUAR_LV30', '高级保底奖金',
|
||||
160.00, NULL, 18000.00,
|
||||
FALSE, 30,
|
||||
'2025-01-01', '2026-02-28',
|
||||
'高级保底:完成160小时课程(含≥10小时打赏课),保底月薪线18000元(实发=MAX(课时收入+奖金, 18000))'),
|
||||
('GUARANTEE', 'GUAR_LV40', '星级保底奖金',
|
||||
170.00, NULL, 23000.00,
|
||||
FALSE, 40,
|
||||
'2025-01-01', '2026-02-28',
|
||||
'星级保底:完成170小时课程(含≥10小时打赏课),保底月薪线23000元(实发=MAX(课时收入+奖金, 23000))'),
|
||||
|
||||
-- Top排名奖金(2026-03-01起)
|
||||
('TOP_RANK', 'TOP_1', 'Top1排名奖金',
|
||||
NULL, 1, 1000.00,
|
||||
FALSE, 0,
|
||||
'2026-03-01', '9999-12-31',
|
||||
'月度排名第一,获得1000元(并列都算)'),
|
||||
('TOP_RANK', 'TOP_2', 'Top2排名奖金',
|
||||
NULL, 2, 600.00,
|
||||
FALSE, 0,
|
||||
'2026-03-01', '9999-12-31',
|
||||
'月度排名第二,获得600元(并列都算)'),
|
||||
('TOP_RANK', 'TOP_3', 'Top3排名奖金',
|
||||
NULL, 3, 400.00,
|
||||
FALSE, 0,
|
||||
'2026-03-01', '9999-12-31',
|
||||
'月度排名第三,获得400元(并列都算)');
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 4. cfg_area_category - 台区分类映射(纯台桌级精确映射)
|
||||
-- 说明:
|
||||
-- - 每台桌一行精确映射,source_area_name=区域, source_table_name=台桌名
|
||||
-- - 不使用 LIKE 模糊匹配,仅 EXACT + DEFAULT 兜底
|
||||
-- - 数据来源: 用户提供的完整台桌清单(2026-03-09)
|
||||
-- =============================================================================
|
||||
TRUNCATE TABLE dws.cfg_area_category RESTART IDENTITY CASCADE;
|
||||
|
||||
INSERT INTO dws.cfg_area_category (
|
||||
source_area_name, source_table_name, category_code, category_name,
|
||||
display_name, short_name,
|
||||
match_type, match_priority, is_active, description, sort_order
|
||||
) VALUES
|
||||
-- ============ BILLIARD 🎱 中式/追分 (sort_order=10) ============
|
||||
-- A区(18台)
|
||||
('A区', 'A1', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A1', 10),
|
||||
('A区', 'A2', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A2', 10),
|
||||
('A区', 'A3', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A3', 10),
|
||||
('A区', 'A4', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A4', 10),
|
||||
('A区', 'A5', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A5', 10),
|
||||
('A区', 'A6', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A6', 10),
|
||||
('A区', 'A7', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A7', 10),
|
||||
('A区', 'A8', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A8', 10),
|
||||
('A区', 'A9', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A9', 10),
|
||||
('A区', 'A10', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A10', 10),
|
||||
('A区', 'A11', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A11', 10),
|
||||
('A区', 'A12', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A12', 10),
|
||||
('A区', 'A13', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A13', 10),
|
||||
('A区', 'A14', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A14', 10),
|
||||
('A区', 'A15', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A15', 10),
|
||||
('A区', 'A16', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A16', 10),
|
||||
('A区', 'A17', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A17', 10),
|
||||
('A区', 'A18', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'A区-A18', 10),
|
||||
-- B区(15台)
|
||||
('B区', 'B1', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B1', 10),
|
||||
('B区', 'B2', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B2', 10),
|
||||
('B区', 'B3', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B3', 10),
|
||||
('B区', 'B4', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B4', 10),
|
||||
('B区', 'B5', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B5', 10),
|
||||
('B区', 'B6', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B6', 10),
|
||||
('B区', 'B7', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B7', 10),
|
||||
('B区', 'B8', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B8', 10),
|
||||
('B区', 'B9', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B9', 10),
|
||||
('B区', 'B10', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B10', 10),
|
||||
('B区', 'B11', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B11', 10),
|
||||
('B区', 'B12', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B12', 10),
|
||||
('B区', 'B13', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B13', 10),
|
||||
('B区', 'B14', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B14', 10),
|
||||
('B区', 'B15', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'B区-B15', 10),
|
||||
-- C区(6台)
|
||||
('C区', 'C1', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C1', 10),
|
||||
('C区', 'C2', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C2', 10),
|
||||
('C区', 'C3', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C3', 10),
|
||||
('C区', 'C4', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C4', 10),
|
||||
('C区', 'C5', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C5', 10),
|
||||
('C区', 'C6', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'C区-C6', 10),
|
||||
-- VIP包厢 BILLIARD(3台)
|
||||
('VIP包厢', 'VIP1', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'VIP包厢-VIP1', 10),
|
||||
('VIP包厢', 'VIP2', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'VIP包厢-VIP2', 10),
|
||||
('VIP包厢', 'VIP3', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'VIP包厢-VIP3', 10),
|
||||
-- TV台(1台)
|
||||
('TV台', 'TV', 'BILLIARD', '🎱 中式/追分', '🎱 中式/追分', '🎱', 'EXACT', 10, TRUE, 'TV台-TV', 10),
|
||||
-- ============ SNOOKER 斯诺克 ============
|
||||
('VIP包厢', 'VIP5', 'SNOOKER', '斯诺克', '斯诺克', '斯', 'EXACT', 10, TRUE, 'VIP包厢-VIP5→斯诺克', 20),
|
||||
('斯诺克区', 'S1', 'SNOOKER', '斯诺克', '斯诺克', '斯', 'EXACT', 10, TRUE, '斯诺克区-S1', 20),
|
||||
('斯诺克区', 'S2', 'SNOOKER', '斯诺克', '斯诺克', '斯', 'EXACT', 10, TRUE, '斯诺克区-S2', 20),
|
||||
('斯诺克区', 'S3', 'SNOOKER', '斯诺克', '斯诺克', '斯', 'EXACT', 10, TRUE, '斯诺克区-S3', 20),
|
||||
('斯诺克区', 'S4', 'SNOOKER', '斯诺克', '斯诺克', '斯', 'EXACT', 10, TRUE, '斯诺克区-S4', 20),
|
||||
-- ============ MAHJONG 🀄 麻将/棋牌 ============
|
||||
('666', '董事办', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '666-董事办', 30),
|
||||
('666', '666', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '666-666', 30),
|
||||
('麻将房', 'M1', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '麻将房-M1', 30),
|
||||
('麻将房', 'M2', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '麻将房-M2', 30),
|
||||
('麻将房', 'M3', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '麻将房-M3', 30),
|
||||
('麻将房', 'M4', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '麻将房-M4', 30),
|
||||
('麻将房', 'M5', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '麻将房-M5', 30),
|
||||
('M7', 'M7', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, 'M7-M7', 30),
|
||||
('M7', '大包麻将房', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, 'M7-大包麻将房', 30),
|
||||
('M8', 'M8', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, 'M8-M8', 30),
|
||||
('发财', '发财', 'MAHJONG', '🀄 麻将/棋牌', '🀄 麻将/棋牌', '🀄', 'EXACT', 10, TRUE, '发财-发财', 30),
|
||||
-- ============ KTV 🎤 团建/K歌 ============
|
||||
('K包', '常乐', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'K包-常乐', 40),
|
||||
('K包', '幸会(纯k)', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'K包-幸会(纯k)', 40),
|
||||
('K包', '虚拟188', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'K包-虚拟188', 40),
|
||||
('K包', '888', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'K包-888', 40),
|
||||
('k包活动区', '大包', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'k包活动区-大包', 40),
|
||||
('k包活动区', '小包', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, 'k包活动区-小包', 40),
|
||||
('幸会158', '纯k', 'KTV', '🎤 团建/K歌', '🎤 团建/K歌', '🎤', 'EXACT', 10, TRUE, '幸会158-纯k', 40),
|
||||
-- ============ SPECIAL 补时长/虚拟台 ============
|
||||
('补时长', '补时长', 'SPECIAL', '补时长', '补时长', '补', 'EXACT', 10, TRUE, '补时长-补时长', 900),
|
||||
('补时长', '补时长2', 'SPECIAL', '补时长', '补时长', '补', 'EXACT', 10, TRUE, '补时长-补时长2', 900),
|
||||
('补时长', '补时长3', 'SPECIAL', '补时长', '补时长', '补', 'EXACT', 10, TRUE, '补时长-补时长3', 900),
|
||||
('补时长', '补时长4', 'SPECIAL', '补时长', '补时长', '补', 'EXACT', 10, TRUE, '补时长-补时长4', 900),
|
||||
('补时长', '补时长5', 'SPECIAL', '补时长', '补时长', '补', 'EXACT', 10, TRUE, '补时长-补时长5', 900),
|
||||
('补时长', '补时长6', 'SPECIAL', '补时长', '补时长', '补', 'EXACT', 10, TRUE, '补时长-补时长6', 900),
|
||||
('补时长', '补时长7', 'SPECIAL', '补时长', '补时长', '补', 'EXACT', 10, TRUE, '补时长-补时长7', 900),
|
||||
('虚拟台', '虚拟台1号', 'SPECIAL', '补时长', '补时长', '补', 'EXACT', 10, TRUE, '虚拟台-虚拟台1号', 900),
|
||||
-- ============ OTHER 兜底 ============
|
||||
('DEFAULT', NULL, 'OTHER', '其他', '其他', '他', 'DEFAULT', 999, TRUE, '兜底规则:无法匹配的归入其他', 999);
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 5. cfg_skill_type - 技能→课程类型映射
|
||||
-- 说明:
|
||||
-- - 将 skill_id 映射到课程类型
|
||||
-- - 基础课/陪打: skill_id = 2791903611396869
|
||||
-- - 附加课/超休: skill_id = 2807440316432197
|
||||
-- - 避免依赖 skill_name 文本匹配
|
||||
-- =============================================================================
|
||||
TRUNCATE TABLE dws.cfg_skill_type RESTART IDENTITY CASCADE;
|
||||
|
||||
INSERT INTO dws.cfg_skill_type (
|
||||
skill_id, skill_name,
|
||||
course_type_code, course_type_name,
|
||||
is_active, description
|
||||
) VALUES
|
||||
(2791903611396869, '台球基础陪打',
|
||||
'BASE', '基础课',
|
||||
TRUE, '基础课:陪打服务,按助教等级计价'),
|
||||
(2807440316432197, '台球超休服务',
|
||||
'BONUS', '附加课',
|
||||
TRUE, '附加课:超休/激励课,固定190元/小时'),
|
||||
(2807440316432198, '包厢服务',
|
||||
'BASE', '基础课',
|
||||
TRUE, '包厢服务:归入基础课统计,统一按138元/小时计价');
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 6~8. 优惠类型/支出类型/平台类型 — 作为代码常量使用,不单独建表
|
||||
-- =============================================================================
|
||||
-- 优惠类型: GROUPBUY/VIP/GIFT_CARD/MANUAL/ROUNDING/BIG_CUSTOMER/OTHER
|
||||
-- 支出类型: RENT/UTILITY/PROPERTY/SALARY/REIMBURSE/PLATFORM_FEE/OTHER
|
||||
-- 平台类型: MEITUAN/DOUYIN/DIANPING/OTHER
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 验证数据插入
|
||||
-- =============================================================================
|
||||
DO $
|
||||
DECLARE
|
||||
v_tier_count INTEGER;
|
||||
v_price_count INTEGER;
|
||||
v_bonus_count INTEGER;
|
||||
v_area_count INTEGER;
|
||||
v_skill_count INTEGER;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO v_tier_count FROM dws.cfg_performance_tier;
|
||||
SELECT COUNT(*) INTO v_price_count FROM dws.cfg_assistant_level_price;
|
||||
SELECT COUNT(*) INTO v_bonus_count FROM dws.cfg_bonus_rules;
|
||||
SELECT COUNT(*) INTO v_area_count FROM dws.cfg_area_category;
|
||||
SELECT COUNT(*) INTO v_skill_count FROM dws.cfg_skill_type;
|
||||
|
||||
RAISE NOTICE '配置数据初始化完成:';
|
||||
RAISE NOTICE ' - cfg_performance_tier: % 条', v_tier_count;
|
||||
RAISE NOTICE ' - cfg_assistant_level_price: % 条', v_price_count;
|
||||
RAISE NOTICE ' - cfg_bonus_rules: % 条', v_bonus_count;
|
||||
RAISE NOTICE ' - cfg_area_category: % 条', v_area_count;
|
||||
RAISE NOTICE ' - cfg_skill_type: % 条', v_skill_count;
|
||||
END;
|
||||
$;
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 种子数据:指数算法参数(NCI/WBI/RS/OS/MS/ML/SPI)
|
||||
-- =============================================================================
|
||||
|
||||
-- =============================================================================
|
||||
-- 指数算法参数初始化脚本
|
||||
-- 版本: v3.0
|
||||
-- 创建日期: 2026-02-13
|
||||
-- 描述: 仅保留 RS / OS / MS / ML / NCI / WBI 指数参数(已移除 RECALL / INTIMACY)
|
||||
-- AI_CHANGELOG [2026-02-13] 移除 RECALL/INTIMACY 参数及 ML 废弃参数(source_mode/recharge_attribute_hours)
|
||||
-- =============================================================================
|
||||
|
||||
-- 清理旧版指数参数
|
||||
DELETE FROM dws.cfg_index_parameters WHERE index_type IN ('RECALL', 'INTIMACY');
|
||||
-- 清理 ML 已废弃参数
|
||||
DELETE FROM dws.cfg_index_parameters WHERE index_type = 'ML' AND param_name IN ('source_mode', 'recharge_attribute_hours');
|
||||
|
||||
INSERT INTO dws.cfg_index_parameters
|
||||
(index_type, param_name, param_value, description, effective_from)
|
||||
VALUES
|
||||
('NCI', 'active_new_penalty', 0.200000, 'active-new suppression multiplier', DATE '2026-02-06'),
|
||||
('NCI', 'active_new_recency_days', 7.000000, 'active-new recency window (days)', DATE '2026-02-06'),
|
||||
('NCI', 'active_new_visit_threshold_14d', 2.000000, 'active-new threshold in 14d visits', DATE '2026-02-06'),
|
||||
('NCI', 'amount_base_M0', 300.000000, 'spend log base M0', DATE '2026-02-06'),
|
||||
('NCI', 'balance_base_B0', 500.000000, 'balance log base B0', DATE '2026-02-06'),
|
||||
('NCI', 'compression_mode', 0.000000, 'compression mode', DATE '2026-02-06'),
|
||||
('NCI', 'enable_stop_high_balance_exception', 0.000000, 'enable high-balance STOP exception', DATE '2026-02-06'),
|
||||
('NCI', 'ewma_alpha', 0.200000, 'EWMA alpha', DATE '2026-02-06'),
|
||||
('NCI', 'h_recharge', 7.000000, 'recharge decay half-life (days)', DATE '2026-02-06'),
|
||||
('NCI', 'high_balance_threshold', 1000.000000, 'high-balance threshold', DATE '2026-02-06'),
|
||||
('NCI', 'lookback_days_recency', 60.000000, 'recency lookback window (days)', DATE '2026-02-06'),
|
||||
('NCI', 'new_days_threshold', 30.000000, 'new member days threshold', DATE '2026-02-06'),
|
||||
('NCI', 'new_recharge_max_visits', 10.000000, 'max visits for new-recharge grouping', DATE '2026-02-06'),
|
||||
('NCI', 'new_visit_threshold', 2.000000, 'new member visit threshold', DATE '2026-02-06'),
|
||||
('NCI', 'no_touch_days_new', 3.000000, 'no-touch threshold (days)', DATE '2026-02-06'),
|
||||
('NCI', 'percentile_lower', 5.000000, 'lower percentile', DATE '2026-02-06'),
|
||||
('NCI', 'percentile_upper', 95.000000, 'upper percentile', DATE '2026-02-06'),
|
||||
('NCI', 'recharge_recent_days', 14.000000, 'recent recharge window (days)', DATE '2026-02-06'),
|
||||
('NCI', 'salvage_end', 60.000000, 'salvage decay end day', DATE '2026-02-06'),
|
||||
('NCI', 'salvage_start', 30.000000, 'salvage decay start day', DATE '2026-02-06'),
|
||||
('NCI', 't2_target_days', 7.000000, 'second-visit target window (days)', DATE '2026-02-06'),
|
||||
('NCI', 'use_smoothing', 1.000000, 'enable smoothing', DATE '2026-02-06'),
|
||||
('NCI', 'value_w_bal', 0.800000, 'value weight for balance', DATE '2026-02-06'),
|
||||
('NCI', 'value_w_spend', 1.000000, 'value weight for spend', DATE '2026-02-06'),
|
||||
('NCI', 'visit_lookback_days', 180.000000, 'visit history lookback (days)', DATE '2026-02-06'),
|
||||
('NCI', 'w_need', 1.600000, 'need weight', DATE '2026-02-06'),
|
||||
('NCI', 'w_re', 0.800000, 'recharge pressure weight', DATE '2026-02-06'),
|
||||
('NCI', 'w_value', 1.000000, 'value weight', DATE '2026-02-06'),
|
||||
('NCI', 'w_welcome', 1.000000, 'welcome-stage weight', DATE '2026-02-06'),
|
||||
('NCI', 'welcome_window_days', 3.000000, 'welcome outreach window for first touch (days)', DATE '2026-02-06'),
|
||||
('WBI', 'amount_base_M0', 300.000000, 'spend log base M0', DATE '2026-02-06'),
|
||||
('WBI', 'balance_base_B0', 500.000000, 'balance log base B0', DATE '2026-02-06'),
|
||||
('WBI', 'compression_mode', 0.000000, 'compression mode', DATE '2026-02-06'),
|
||||
('WBI', 'enable_stop_high_balance_exception', 0.000000, 'enable high-balance STOP exception', DATE '2026-02-06'),
|
||||
('WBI', 'ewma_alpha', 0.200000, 'EWMA alpha', DATE '2026-02-06'),
|
||||
('WBI', 'h_recharge', 7.000000, 'recharge decay half-life (days)', DATE '2026-02-06'),
|
||||
('WBI', 'high_balance_threshold', 1000.000000, 'high-balance threshold', DATE '2026-02-06'),
|
||||
('WBI', 'lookback_days_recency', 60.000000, 'recency lookback window (days)', DATE '2026-02-06'),
|
||||
('WBI', 'new_days_threshold', 30.000000, 'new member days threshold', DATE '2026-02-06'),
|
||||
('WBI', 'new_recharge_max_visits', 10.000000, 'max visits for new-recharge grouping', DATE '2026-02-06'),
|
||||
('WBI', 'new_visit_threshold', 2.000000, 'new member visit threshold', DATE '2026-02-06'),
|
||||
('WBI', 'overdue_alpha', 2.000000, 'overdue fallback alpha', DATE '2026-02-06'),
|
||||
('WBI', 'overdue_weight_blend_min_samples', 8.000000, 'minimum samples to fully trust weighted overdue CDF', DATE '2026-02-07'),
|
||||
('WBI', 'overdue_weight_halflife_days', 30.000000, 'overdue weighted-CDF interval half-life (days)', DATE '2026-02-07'),
|
||||
('WBI', 'percentile_lower', 5.000000, 'lower percentile', DATE '2026-02-06'),
|
||||
('WBI', 'percentile_upper', 95.000000, 'upper percentile', DATE '2026-02-06'),
|
||||
('WBI', 'recency_gate_days', 14.000000, 'recency suppression gate center (days)', DATE '2026-02-06'),
|
||||
('WBI', 'recency_gate_slope_days', 3.000000, 'recency suppression slope (days)', DATE '2026-02-06'),
|
||||
('WBI', 'recency_hard_floor_days', 14.000000, 'hard floor for winback recency (days)', DATE '2026-02-06'),
|
||||
('WBI', 'recharge_recent_days', 14.000000, 'recent recharge window (days)', DATE '2026-02-06'),
|
||||
('WBI', 'use_smoothing', 1.000000, 'enable smoothing', DATE '2026-02-06'),
|
||||
('WBI', 'value_w_bal', 1.000000, 'value weight for balance', DATE '2026-02-06'),
|
||||
('WBI', 'value_w_spend', 1.000000, 'value weight for spend', DATE '2026-02-06'),
|
||||
('WBI', 'visit_lookback_days', 180.000000, 'visit history lookback (days)', DATE '2026-02-06'),
|
||||
('WBI', 'w_drop', 1.000000, 'drop weight', DATE '2026-02-06'),
|
||||
('WBI', 'w_over', 2.000000, 'overdue weight', DATE '2026-02-06'),
|
||||
('WBI', 'w_re', 0.400000, 'recharge pressure weight', DATE '2026-02-06'),
|
||||
('WBI', 'w_value', 1.200000, 'value weight', DATE '2026-02-06')
|
||||
ON CONFLICT (index_type, param_name, effective_from) DO UPDATE SET
|
||||
param_value = EXCLUDED.param_value,
|
||||
description = EXCLUDED.description,
|
||||
updated_at = NOW();
|
||||
|
||||
-- =============================================================================
|
||||
-- 关系指数(RS/OS/MS/ML)参数
|
||||
-- 生效时间:北京时间 2026-01-01(按数据库日期管理)
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO dws.cfg_index_parameters
|
||||
(index_type, param_name, param_value, description, effective_from)
|
||||
VALUES
|
||||
-- RS(关系强度)
|
||||
('RS', 'lookback_days', 60.000000, '服务行为回溯窗口(天)', DATE '2026-01-01'),
|
||||
('RS', 'session_merge_hours', 4.000000, '会话合并阈值(小时)', DATE '2026-01-01'),
|
||||
('RS', 'incentive_weight', 1.500000, '激励课权重', DATE '2026-01-01'),
|
||||
('RS', 'halflife_session', 14.000000, '会话半衰期(天)', DATE '2026-01-01'),
|
||||
('RS', 'halflife_last', 10.000000, '最近一次服务半衰期(天)', DATE '2026-01-01'),
|
||||
('RS', 'weight_f', 1.000000, '频次项权重', DATE '2026-01-01'),
|
||||
('RS', 'weight_d', 0.700000, '时长项权重', DATE '2026-01-01'),
|
||||
('RS', 'gate_alpha', 0.600000, '最近服务门控指数', DATE '2026-01-01'),
|
||||
('RS', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-01-01'),
|
||||
('RS', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-01-01'),
|
||||
('RS', 'compression_mode', 1.000000, '压缩模式:0=none,1=log1p,2=asinh', DATE '2026-01-01'),
|
||||
('RS', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-01-01'),
|
||||
('RS', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-01-01'),
|
||||
|
||||
-- OS(归属份额)
|
||||
('OS', 'min_rs_raw_for_ownership', 0.050000, '参与归属计算的最小RS_raw', DATE '2026-01-01'),
|
||||
('OS', 'min_total_rs_raw', 0.100000, '形成稳定归属的最小sum_rs', DATE '2026-01-01'),
|
||||
('OS', 'ownership_main_threshold', 0.600000, '主责阈值', DATE '2026-01-01'),
|
||||
('OS', 'ownership_comanage_threshold', 0.350000, '共管阈值', DATE '2026-01-01'),
|
||||
('OS', 'ownership_gap_threshold', 0.150000, '主责与次席份额差阈值', DATE '2026-01-01'),
|
||||
('OS', 'eps', 0.000001, '数值稳定项', DATE '2026-01-01'),
|
||||
|
||||
-- MS(升温动量)
|
||||
('MS', 'lookback_days', 60.000000, '服务行为回溯窗口(天)', DATE '2026-01-01'),
|
||||
('MS', 'session_merge_hours', 4.000000, '会话合并阈值(小时)', DATE '2026-01-01'),
|
||||
('MS', 'incentive_weight', 1.500000, '激励课权重', DATE '2026-01-01'),
|
||||
('MS', 'halflife_short', 7.000000, '短期半衰期(天)', DATE '2026-01-01'),
|
||||
('MS', 'halflife_long', 30.000000, '长期半衰期(天)', DATE '2026-01-01'),
|
||||
('MS', 'eps', 0.000001, '数值稳定项', DATE '2026-01-01'),
|
||||
('MS', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-01-01'),
|
||||
('MS', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-01-01'),
|
||||
('MS', 'compression_mode', 1.000000, '压缩模式:0=none,1=log1p,2=asinh', DATE '2026-01-01'),
|
||||
('MS', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-01-01'),
|
||||
('MS', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-01-01'),
|
||||
|
||||
-- ML(付费关联)
|
||||
('ML', 'lookback_days', 60.000000, '充值行为回溯窗口(天)', DATE '2026-01-01'),
|
||||
('ML', 'amount_base', 500.000000, '金额压缩基准', DATE '2026-01-01'),
|
||||
('ML', 'halflife_recharge', 21.000000, '充值半衰期(天)', DATE '2026-01-01'),
|
||||
('ML', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-01-01'),
|
||||
('ML', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-01-01'),
|
||||
('ML', 'compression_mode', 1.000000, '压缩模式:0=none,1=log1p,2=asinh', DATE '2026-01-01'),
|
||||
('ML', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-01-01'),
|
||||
('ML', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-01-01')
|
||||
ON CONFLICT (index_type, param_name, effective_from) DO UPDATE SET
|
||||
param_value = EXCLUDED.param_value,
|
||||
description = EXCLUDED.description,
|
||||
updated_at = NOW();
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- SPI(消费力指数)参数
|
||||
-- 生效时间:北京时间 2026-02-23
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO dws.cfg_index_parameters
|
||||
(index_type, param_name, param_value, description, effective_from)
|
||||
VALUES
|
||||
-- 窗口参数
|
||||
('SPI', 'spend_window_short_days', 30.000000, '短期消费窗口(天)', DATE '2026-02-23'),
|
||||
('SPI', 'spend_window_long_days', 90.000000, '长期消费窗口(天)', DATE '2026-02-23'),
|
||||
('SPI', 'ewma_alpha_daily_spend', 0.300000, '日消费 EWMA 平滑系数', DATE '2026-02-23'),
|
||||
-- 金额压缩基数(基于典型台球门店消费水平的初始默认值)
|
||||
('SPI', 'amount_base_spend_30', 500.000000, '30天消费额压缩基数', DATE '2026-02-23'),
|
||||
('SPI', 'amount_base_spend_90', 1500.000000, '90天消费额压缩基数', DATE '2026-02-23'),
|
||||
('SPI', 'amount_base_ticket_90', 200.000000, '90天客单价压缩基数', DATE '2026-02-23'),
|
||||
('SPI', 'amount_base_recharge_90', 1000.000000, '90天充值额压缩基数', DATE '2026-02-23'),
|
||||
('SPI', 'amount_base_speed_abs', 100.000000, '绝对速度压缩基数', DATE '2026-02-23'),
|
||||
('SPI', 'amount_base_ewma_90', 50.000000, '日消费EWMA压缩基数', DATE '2026-02-23'),
|
||||
-- Level 子分权重
|
||||
('SPI', 'w_level_spend_30', 0.300000, 'Level子分:30天消费权重', DATE '2026-02-23'),
|
||||
('SPI', 'w_level_spend_90', 0.350000, 'Level子分:90天消费权重', DATE '2026-02-23'),
|
||||
('SPI', 'w_level_ticket_90', 0.200000, 'Level子分:90天客单权重', DATE '2026-02-23'),
|
||||
('SPI', 'w_level_recharge_90', 0.150000, 'Level子分:90天充值权重', DATE '2026-02-23'),
|
||||
-- Speed 子分权重
|
||||
('SPI', 'w_speed_abs', 0.500000, 'Speed子分:绝对速度权重', DATE '2026-02-23'),
|
||||
('SPI', 'w_speed_rel', 0.300000, 'Speed子分:相对速度权重', DATE '2026-02-23'),
|
||||
('SPI', 'w_speed_ewma', 0.200000, 'Speed子分:EWMA速度权重', DATE '2026-02-23'),
|
||||
-- 总分权重
|
||||
('SPI', 'weight_level', 0.600000, 'SPI总分:Level子分权重', DATE '2026-02-23'),
|
||||
('SPI', 'weight_speed', 0.300000, 'SPI总分:Speed子分权重', DATE '2026-02-23'),
|
||||
('SPI', 'weight_stability', 0.100000, 'SPI总分:Stability子分权重', DATE '2026-02-23'),
|
||||
-- 稳定性参数
|
||||
('SPI', 'stability_window_days', 90.000000, '稳定性计算窗口(天)', DATE '2026-02-23'),
|
||||
('SPI', 'use_stability', 1.000000, '是否启用稳定性子分:0=关闭,1=启用', DATE '2026-02-23'),
|
||||
-- 映射与平滑
|
||||
('SPI', 'percentile_lower', 5.000000, '展示分下分位', DATE '2026-02-23'),
|
||||
('SPI', 'percentile_upper', 95.000000, '展示分上分位', DATE '2026-02-23'),
|
||||
('SPI', 'compression_mode', 1.000000, '压缩模式:0=none,1=log1p,2=asinh', DATE '2026-02-23'),
|
||||
('SPI', 'use_smoothing', 1.000000, '是否启用分位平滑', DATE '2026-02-23'),
|
||||
('SPI', 'ewma_alpha', 0.200000, 'EWMA平滑系数', DATE '2026-02-23'),
|
||||
-- 速度计算
|
||||
('SPI', 'speed_epsilon', 0.000001, '速度计算防除零小量', DATE '2026-02-23')
|
||||
ON CONFLICT (index_type, param_name, effective_from) DO UPDATE SET
|
||||
param_value = EXCLUDED.param_value,
|
||||
description = EXCLUDED.description,
|
||||
updated_at = NOW();
|
||||
|
||||
-- =============================================================================
|
||||
-- 验证
|
||||
-- =============================================================================
|
||||
DO $
|
||||
DECLARE
|
||||
rs_count INTEGER;
|
||||
os_count INTEGER;
|
||||
ms_count INTEGER;
|
||||
ml_count INTEGER;
|
||||
nci_count INTEGER;
|
||||
wbi_count INTEGER;
|
||||
spi_count INTEGER;
|
||||
BEGIN
|
||||
SELECT COUNT(*) INTO rs_count
|
||||
FROM dws.cfg_index_parameters
|
||||
WHERE index_type = 'RS';
|
||||
|
||||
SELECT COUNT(*) INTO os_count
|
||||
FROM dws.cfg_index_parameters
|
||||
WHERE index_type = 'OS';
|
||||
|
||||
SELECT COUNT(*) INTO ms_count
|
||||
FROM dws.cfg_index_parameters
|
||||
WHERE index_type = 'MS';
|
||||
|
||||
SELECT COUNT(*) INTO ml_count
|
||||
FROM dws.cfg_index_parameters
|
||||
WHERE index_type = 'ML';
|
||||
|
||||
SELECT COUNT(*) INTO nci_count
|
||||
FROM dws.cfg_index_parameters
|
||||
WHERE index_type = 'NCI';
|
||||
|
||||
SELECT COUNT(*) INTO wbi_count
|
||||
FROM dws.cfg_index_parameters
|
||||
WHERE index_type = 'WBI';
|
||||
|
||||
SELECT COUNT(*) INTO spi_count
|
||||
FROM dws.cfg_index_parameters
|
||||
WHERE index_type = 'SPI';
|
||||
|
||||
RAISE NOTICE 'RS 参数数量: %', rs_count;
|
||||
RAISE NOTICE 'OS 参数数量: %', os_count;
|
||||
RAISE NOTICE 'MS 参数数量: %', ms_count;
|
||||
RAISE NOTICE 'ML 参数数量: %', ml_count;
|
||||
RAISE NOTICE '新客转化参数数量: %', nci_count;
|
||||
RAISE NOTICE '唤回指数参数数量: %', wbi_count;
|
||||
RAISE NOTICE 'SPI 消费力指数参数数量: %', spi_count;
|
||||
END $;
|
||||
|
||||
SELECT
|
||||
index_type,
|
||||
param_name,
|
||||
param_value,
|
||||
description,
|
||||
effective_from
|
||||
FROM dws.cfg_index_parameters
|
||||
ORDER BY index_type, param_name, effective_from;
|
||||
@@ -1,6 +1,6 @@
|
||||
-- =============================================================================
|
||||
-- etl_feiqiu / meta(ETL 调度元数据)
|
||||
-- 生成日期:2026-03-15
|
||||
-- 生成日期:2026-04-05
|
||||
-- 来源:测试库(通过脚本自动导出)
|
||||
-- =============================================================================
|
||||
|
||||
@@ -75,105 +75,3 @@ ALTER TABLE meta.etl_run ADD CONSTRAINT etl_run_pkey PRIMARY KEY (run_id);
|
||||
ALTER TABLE meta.etl_task ADD CONSTRAINT etl_task_pkey PRIMARY KEY (task_id);
|
||||
ALTER TABLE meta.etl_task ADD CONSTRAINT etl_task_task_code_store_id_key UNIQUE (task_code, store_id);
|
||||
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 种子数据:ODS 任务注册
|
||||
-- =============================================================================
|
||||
|
||||
WITH target_store AS (
|
||||
SELECT 2790685415443269::bigint AS store_id -- TODO: 替换为实际 store_id
|
||||
),
|
||||
task_codes AS (
|
||||
SELECT unnest(ARRAY[
|
||||
'ODS_ASSISTANT_ACCOUNT',
|
||||
'ODS_ASSISTANT_LEDGER',
|
||||
'ODS_SETTLEMENT_RECORDS',
|
||||
'ODS_TABLE_USE',
|
||||
'ODS_PAYMENT',
|
||||
'ODS_REFUND',
|
||||
'ODS_PLATFORM_COUPON',
|
||||
'ODS_MEMBER',
|
||||
'ODS_MEMBER_CARD',
|
||||
'ODS_MEMBER_BALANCE',
|
||||
'ODS_RECHARGE_SETTLE',
|
||||
'ODS_GROUP_PACKAGE',
|
||||
'ODS_GROUP_BUY_REDEMPTION',
|
||||
'ODS_INVENTORY_STOCK',
|
||||
'ODS_INVENTORY_CHANGE',
|
||||
'ODS_TABLES',
|
||||
'ODS_GOODS_CATEGORY',
|
||||
'ODS_STORE_GOODS',
|
||||
'ODS_STORE_GOODS_SALES',
|
||||
'ODS_TABLE_FEE_DISCOUNT',
|
||||
'ODS_TENANT_GOODS'
|
||||
]) AS task_code
|
||||
)
|
||||
INSERT INTO meta.etl_task (task_code, store_id, enabled)
|
||||
SELECT t.task_code, s.store_id, TRUE
|
||||
FROM task_codes t CROSS JOIN target_store s
|
||||
ON CONFLICT (task_code, store_id) DO UPDATE
|
||||
SET enabled = EXCLUDED.enabled;
|
||||
|
||||
-- =============================================================================
|
||||
-- 种子数据:调度任务注册
|
||||
-- =============================================================================
|
||||
|
||||
WITH target_store AS (
|
||||
SELECT 2790685415443269::bigint AS store_id -- TODO: 替换为实际 store_id
|
||||
),
|
||||
task_codes AS (
|
||||
SELECT unnest(ARRAY[
|
||||
'ASSISTANTS',
|
||||
'COUPON_USAGE',
|
||||
'CHECK_CUTOFF',
|
||||
'DWD_LOAD_FROM_ODS',
|
||||
'DWD_QUALITY_CHECK',
|
||||
'INIT_DWD_SCHEMA',
|
||||
'INIT_DWS_SCHEMA',
|
||||
'INIT_ODS_SCHEMA',
|
||||
'INVENTORY_CHANGE',
|
||||
'LEDGER',
|
||||
'MANUAL_INGEST',
|
||||
'MEMBERS',
|
||||
'MEMBERS_DWD',
|
||||
'ODS_JSON_ARCHIVE',
|
||||
'ORDERS',
|
||||
'PACKAGES_DEF',
|
||||
'PAYMENTS',
|
||||
'PAYMENTS_DWD',
|
||||
'PRODUCTS',
|
||||
'REFUNDS',
|
||||
'TABLE_DISCOUNT',
|
||||
'TABLES',
|
||||
'TICKET_DWD',
|
||||
'TOPUPS',
|
||||
'DWS_BUILD_ORDER_SUMMARY',
|
||||
'DWS_ASSISTANT_DAILY',
|
||||
'DWS_ASSISTANT_MONTHLY',
|
||||
'DWS_ASSISTANT_CUSTOMER',
|
||||
'DWS_ASSISTANT_SALARY',
|
||||
'DWS_ASSISTANT_FINANCE',
|
||||
'DWS_MEMBER_CONSUMPTION',
|
||||
'DWS_MEMBER_VISIT',
|
||||
'DWS_FINANCE_DAILY',
|
||||
'DWS_FINANCE_RECHARGE',
|
||||
'DWS_FINANCE_INCOME_STRUCTURE',
|
||||
'DWS_FINANCE_DISCOUNT_DETAIL',
|
||||
'DWS_GOODS_STOCK_DAILY',
|
||||
'DWS_GOODS_STOCK_WEEKLY',
|
||||
'DWS_GOODS_STOCK_MONTHLY',
|
||||
'DWS_WINBACK_INDEX',
|
||||
'DWS_NEWCONV_INDEX',
|
||||
'DWS_RELATION_INDEX',
|
||||
'DWS_ASSISTANT_PROJECT_TAG',
|
||||
'DWS_MEMBER_PROJECT_TAG',
|
||||
'DWS_ML_MANUAL_IMPORT'
|
||||
]) AS task_code
|
||||
)
|
||||
INSERT INTO meta.etl_task (task_code, store_id, enabled)
|
||||
SELECT t.task_code, s.store_id, TRUE
|
||||
FROM task_codes t CROSS JOIN target_store s
|
||||
ON CONFLICT (task_code, store_id) DO UPDATE
|
||||
SET enabled = EXCLUDED.enabled,
|
||||
updated_at = now();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- =============================================================================
|
||||
-- etl_feiqiu / ods(原始数据层)
|
||||
-- 生成日期:2026-03-15
|
||||
-- 生成日期:2026-04-05
|
||||
-- 来源:测试库(通过脚本自动导出)
|
||||
-- =============================================================================
|
||||
|
||||
@@ -148,7 +148,9 @@ CREATE TABLE ods.assistant_service_records (
|
||||
content_hash text NOT NULL,
|
||||
source_file text,
|
||||
source_endpoint text,
|
||||
fetched_at timestamp with time zone DEFAULT now()
|
||||
fetched_at timestamp with time zone DEFAULT now(),
|
||||
deduct_leave_seconds integer DEFAULT 0,
|
||||
order_from integer
|
||||
);
|
||||
|
||||
CREATE TABLE ods.goods_stock_movements (
|
||||
@@ -198,7 +200,8 @@ CREATE TABLE ods.goods_stock_summary (
|
||||
source_endpoint text,
|
||||
fetched_at timestamp with time zone DEFAULT now(),
|
||||
payload jsonb NOT NULL,
|
||||
siteid bigint
|
||||
siteid bigint,
|
||||
createtime timestamp without time zone
|
||||
);
|
||||
|
||||
CREATE TABLE ods.group_buy_package_details (
|
||||
@@ -394,7 +397,11 @@ CREATE TABLE ods.member_profiles (
|
||||
source_endpoint text,
|
||||
fetched_at timestamp with time zone DEFAULT now(),
|
||||
payload jsonb NOT NULL,
|
||||
birthday date
|
||||
birthday date,
|
||||
other_pay_money_sum numeric(18,2),
|
||||
last_consume_time timestamp without time zone,
|
||||
non_consume_day_num integer,
|
||||
first_consumption integer
|
||||
);
|
||||
|
||||
CREATE TABLE ods.member_stored_value_cards (
|
||||
@@ -719,7 +726,8 @@ CREATE TABLE ods.settlement_records (
|
||||
source_file text,
|
||||
source_endpoint text,
|
||||
fetched_at timestamp with time zone DEFAULT now(),
|
||||
payload jsonb NOT NULL
|
||||
payload jsonb NOT NULL,
|
||||
orderfrom integer
|
||||
);
|
||||
|
||||
CREATE TABLE ods.site_tables_master (
|
||||
@@ -939,7 +947,10 @@ CREATE TABLE ods.store_goods_sales_records (
|
||||
content_hash text NOT NULL,
|
||||
source_file text,
|
||||
source_endpoint text,
|
||||
fetched_at timestamp with time zone DEFAULT now()
|
||||
fetched_at timestamp with time zone DEFAULT now(),
|
||||
activity_amount numeric(18,2) DEFAULT 0,
|
||||
activity_id bigint DEFAULT 0,
|
||||
order_from integer
|
||||
);
|
||||
|
||||
CREATE TABLE ods.table_fee_discount_records (
|
||||
@@ -1025,7 +1036,8 @@ CREATE TABLE ods.table_fee_transactions (
|
||||
content_hash text NOT NULL,
|
||||
source_file text,
|
||||
source_endpoint text,
|
||||
fetched_at timestamp with time zone DEFAULT now()
|
||||
fetched_at timestamp with time zone DEFAULT now(),
|
||||
order_from integer
|
||||
);
|
||||
|
||||
CREATE TABLE ods.tenant_goods_master (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- =============================================================================
|
||||
-- FDW 跨库映射(在 zqyy_app 中执行)
|
||||
-- 生成日期:2026-03-15
|
||||
-- 生成日期:2026-04-05
|
||||
-- 来源:db/fdw/setup_fdw.sql
|
||||
-- =============================================================================
|
||||
|
||||
|
||||
86
docs/database/ddl/fdw_reverse.sql
Normal file
86
docs/database/ddl/fdw_reverse.sql
Normal file
@@ -0,0 +1,86 @@
|
||||
-- =============================================================================
|
||||
-- FDW 反向映射配置(生产环境)— 在 etl_feiqiu 数据库中执行
|
||||
-- 用途:通过 postgres_fdw 将 zqyy_app.member_retention_clue 只读映射到 etl_feiqiu,
|
||||
-- 使 ETL DWS 任务无需直接连接业务库即可读取维客线索数据。
|
||||
-- 方向:etl_feiqiu → zqyy_app(与 setup_fdw.sql 的 zqyy_app → etl_feiqiu 方向相反)
|
||||
-- 前提:zqyy_app 数据库已部署 member_retention_clue 表
|
||||
-- 测试环境版本:setup_fdw_reverse_test.sql(指向 test_zqyy_app)
|
||||
-- CHANGE 2026-02-26 | member_birthday_manual → member_retention_clue(维客线索重构)
|
||||
-- =============================================================================
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 1. 安装 postgres_fdw 扩展(如已安装则跳过)
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE EXTENSION IF NOT EXISTS postgres_fdw;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 2. 创建外部服务器(指向 zqyy_app 业务库)
|
||||
-- 部署时按实际环境替换 host / port
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE SERVER IF NOT EXISTS zqyy_app_server
|
||||
FOREIGN DATA WRAPPER postgres_fdw
|
||||
OPTIONS (host 'localhost', dbname 'zqyy_app', port '5432');
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 3. 创建用户映射(只读角色)
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE USER MAPPING IF NOT EXISTS FOR etl_user
|
||||
SERVER zqyy_app_server
|
||||
OPTIONS (user 'app_reader', password '***');
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 4. 创建目标 schema(存放来自业务库的外部表)
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE SCHEMA IF NOT EXISTS fdw_app;
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 5. 创建外部表:member_retention_clue
|
||||
-- 映射 zqyy_app.public.member_retention_clue,ETL 侧只读
|
||||
-- -----------------------------------------------------------------------------
|
||||
CREATE FOREIGN TABLE IF NOT EXISTS fdw_app.member_retention_clue (
|
||||
id BIGINT,
|
||||
member_id BIGINT,
|
||||
category VARCHAR(20),
|
||||
summary VARCHAR(200),
|
||||
detail TEXT,
|
||||
recorded_by_assistant_id BIGINT,
|
||||
recorded_by_name VARCHAR(50),
|
||||
recorded_at TIMESTAMPTZ,
|
||||
site_id BIGINT
|
||||
) SERVER zqyy_app_server
|
||||
OPTIONS (schema_name 'public', table_name 'member_retention_clue');
|
||||
|
||||
-- -----------------------------------------------------------------------------
|
||||
-- 6. 授权:允许 etl_user 访问 fdw_app schema 及其外部表
|
||||
-- -----------------------------------------------------------------------------
|
||||
GRANT USAGE ON SCHEMA fdw_app TO etl_user;
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA fdw_app TO etl_user;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA fdw_app GRANT SELECT ON TABLES TO etl_user;
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 回滚脚本(按逆序执行)
|
||||
-- =============================================================================
|
||||
-- ALTER DEFAULT PRIVILEGES IN SCHEMA fdw_app REVOKE SELECT ON TABLES FROM etl_user;
|
||||
-- REVOKE SELECT ON ALL TABLES IN SCHEMA fdw_app FROM etl_user;
|
||||
-- REVOKE USAGE ON SCHEMA fdw_app FROM etl_user;
|
||||
-- DROP FOREIGN TABLE IF EXISTS fdw_app.member_retention_clue;
|
||||
-- DROP SCHEMA IF EXISTS fdw_app CASCADE;
|
||||
-- DROP USER MAPPING IF EXISTS FOR etl_user SERVER zqyy_app_server;
|
||||
-- DROP SERVER IF EXISTS zqyy_app_server CASCADE;
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 验证 SQL
|
||||
-- =============================================================================
|
||||
-- 1. 确认外部服务器存在
|
||||
-- SELECT srvname, srvoptions FROM pg_foreign_server
|
||||
-- WHERE srvname = 'zqyy_app_server';
|
||||
|
||||
-- 2. 确认外部表列结构完整(9 列)
|
||||
-- SELECT column_name, data_type FROM information_schema.columns
|
||||
-- WHERE table_schema = 'fdw_app' AND table_name = 'member_retention_clue'
|
||||
-- ORDER BY ordinal_position;
|
||||
|
||||
-- 3. 确认外部表可读取
|
||||
-- SELECT COUNT(*) FROM fdw_app.member_retention_clue;
|
||||
@@ -1,6 +1,6 @@
|
||||
-- =============================================================================
|
||||
-- zqyy_app / auth(用户认证与权限)
|
||||
-- 生成日期:2026-03-15
|
||||
-- 生成日期:2026-04-05
|
||||
-- 来源:测试库(通过脚本自动导出)
|
||||
-- =============================================================================
|
||||
|
||||
@@ -10,12 +10,22 @@ CREATE SCHEMA IF NOT EXISTS auth;
|
||||
CREATE SEQUENCE IF NOT EXISTS auth.permissions_id_seq AS integer;
|
||||
CREATE SEQUENCE IF NOT EXISTS auth.roles_id_seq AS integer;
|
||||
CREATE SEQUENCE IF NOT EXISTS auth.site_code_mapping_id_seq AS integer;
|
||||
CREATE SEQUENCE IF NOT EXISTS auth.tenant_admins_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS auth.user_applications_id_seq AS integer;
|
||||
CREATE SEQUENCE IF NOT EXISTS auth.user_assistant_binding_id_seq AS integer;
|
||||
CREATE SEQUENCE IF NOT EXISTS auth.user_site_roles_id_seq AS integer;
|
||||
CREATE SEQUENCE IF NOT EXISTS auth.users_id_seq AS integer;
|
||||
|
||||
-- 表
|
||||
CREATE TABLE auth._archived_site_code_mapping (
|
||||
id integer DEFAULT nextval('auth.site_code_mapping_id_seq'::regclass) NOT NULL,
|
||||
site_code character varying(10) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
site_name character varying(200),
|
||||
tenant_id bigint,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE auth.permissions (
|
||||
id integer DEFAULT nextval('auth.permissions_id_seq'::regclass) NOT NULL,
|
||||
code character varying(100) NOT NULL,
|
||||
@@ -37,13 +47,19 @@ CREATE TABLE auth.roles (
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE auth.site_code_mapping (
|
||||
id integer DEFAULT nextval('auth.site_code_mapping_id_seq'::regclass) NOT NULL,
|
||||
site_code character varying(10) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
site_name character varying(200),
|
||||
tenant_id bigint,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
CREATE TABLE auth.tenant_admins (
|
||||
id bigint DEFAULT nextval('auth.tenant_admins_id_seq'::regclass) NOT NULL,
|
||||
username character varying(50) NOT NULL,
|
||||
password_hash character varying(255) NOT NULL,
|
||||
display_name character varying(100),
|
||||
tenant_id bigint NOT NULL,
|
||||
managed_site_ids _int8 NOT NULL,
|
||||
is_active boolean DEFAULT true,
|
||||
created_by bigint,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
last_login_at timestamp with time zone,
|
||||
deleted_at timestamp with time zone,
|
||||
admin_type character varying(20) DEFAULT 'tenant_admin'::character varying NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE auth.user_applications (
|
||||
@@ -68,7 +84,9 @@ CREATE TABLE auth.user_assistant_binding (
|
||||
assistant_id bigint,
|
||||
staff_id bigint,
|
||||
binding_type character varying(20) NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
is_removed boolean DEFAULT false NOT NULL,
|
||||
removed_at timestamp with time zone
|
||||
);
|
||||
|
||||
CREATE TABLE auth.user_site_roles (
|
||||
@@ -76,7 +94,9 @@ CREATE TABLE auth.user_site_roles (
|
||||
user_id integer NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
role_id integer NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
is_removed boolean DEFAULT false NOT NULL,
|
||||
removed_at timestamp with time zone
|
||||
);
|
||||
|
||||
CREATE TABLE auth.users (
|
||||
@@ -88,10 +108,17 @@ CREATE TABLE auth.users (
|
||||
phone character varying(20),
|
||||
status character varying(20) DEFAULT 'new'::character varying NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
rejection_count integer DEFAULT 0 NOT NULL,
|
||||
avatar_url character varying(500)
|
||||
);
|
||||
|
||||
-- 约束(主键 / 唯一 / 外键)
|
||||
ALTER TABLE auth._archived_site_code_mapping ADD CONSTRAINT site_code_mapping_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE auth._archived_site_code_mapping ADD CONSTRAINT site_code_mapping_site_code_key UNIQUE (site_code);
|
||||
ALTER TABLE auth._archived_site_code_mapping ADD CONSTRAINT site_code_mapping_site_id_key UNIQUE (site_id);
|
||||
ALTER TABLE auth._archived_site_code_mapping ADD CONSTRAINT uq_site_code_mapping_site_code UNIQUE (site_code);
|
||||
ALTER TABLE auth._archived_site_code_mapping ADD CONSTRAINT uq_site_code_mapping_site_id UNIQUE (site_id);
|
||||
ALTER TABLE auth.permissions ADD CONSTRAINT permissions_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE auth.permissions ADD CONSTRAINT permissions_code_key UNIQUE (code);
|
||||
ALTER TABLE auth.permissions ADD CONSTRAINT uq_permissions_code UNIQUE (code);
|
||||
@@ -103,11 +130,8 @@ ALTER TABLE auth.role_permissions ADD CONSTRAINT role_permissions_pkey PRIMARY K
|
||||
ALTER TABLE auth.roles ADD CONSTRAINT roles_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE auth.roles ADD CONSTRAINT roles_code_key UNIQUE (code);
|
||||
ALTER TABLE auth.roles ADD CONSTRAINT uq_roles_code UNIQUE (code);
|
||||
ALTER TABLE auth.site_code_mapping ADD CONSTRAINT site_code_mapping_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE auth.site_code_mapping ADD CONSTRAINT site_code_mapping_site_code_key UNIQUE (site_code);
|
||||
ALTER TABLE auth.site_code_mapping ADD CONSTRAINT site_code_mapping_site_id_key UNIQUE (site_id);
|
||||
ALTER TABLE auth.site_code_mapping ADD CONSTRAINT uq_site_code_mapping_site_code UNIQUE (site_code);
|
||||
ALTER TABLE auth.site_code_mapping ADD CONSTRAINT uq_site_code_mapping_site_id UNIQUE (site_id);
|
||||
ALTER TABLE auth.tenant_admins ADD CONSTRAINT tenant_admins_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE auth.tenant_admins ADD CONSTRAINT tenant_admins_username_key UNIQUE (username);
|
||||
ALTER TABLE auth.user_applications ADD CONSTRAINT fk_user_applications_user_id FOREIGN KEY (user_id) REFERENCES auth.users(id) ON DELETE CASCADE;
|
||||
ALTER TABLE auth.user_applications ADD CONSTRAINT user_applications_user_id_fkey FOREIGN KEY (user_id) REFERENCES auth.users(id) ON DELETE CASCADE;
|
||||
ALTER TABLE auth.user_applications ADD CONSTRAINT user_applications_pkey PRIMARY KEY (id);
|
||||
@@ -126,60 +150,14 @@ ALTER TABLE auth.users ADD CONSTRAINT uq_users_wx_openid UNIQUE (wx_openid);
|
||||
ALTER TABLE auth.users ADD CONSTRAINT users_wx_openid_key UNIQUE (wx_openid);
|
||||
|
||||
-- 索引
|
||||
CREATE INDEX ix_site_code_mapping_site_code ON auth.site_code_mapping USING btree (site_code);
|
||||
CREATE INDEX ix_site_code_mapping_site_code ON auth._archived_site_code_mapping USING btree (site_code);
|
||||
CREATE INDEX idx_tenant_admin_tenant ON auth.tenant_admins USING btree (tenant_id);
|
||||
CREATE INDEX idx_tenant_admins_active_not_deleted ON auth.tenant_admins USING btree (is_active) WHERE (deleted_at IS NULL);
|
||||
CREATE INDEX ix_user_applications_status ON auth.user_applications USING btree (status);
|
||||
CREATE INDEX ix_user_applications_user_id ON auth.user_applications USING btree (user_id);
|
||||
CREATE INDEX idx_user_assistant_binding_active ON auth.user_assistant_binding USING btree (user_id, site_id) WHERE (is_removed = false);
|
||||
CREATE INDEX idx_user_site_roles_active ON auth.user_site_roles USING btree (user_id, site_id) WHERE (is_removed = false);
|
||||
CREATE INDEX ix_user_site_roles_user_site ON auth.user_site_roles USING btree (user_id, site_id);
|
||||
CREATE INDEX ix_users_status ON auth.users USING btree (status);
|
||||
CREATE INDEX ix_users_wx_openid ON auth.users USING btree (wx_openid);
|
||||
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 种子数据:权限列表(5 条)
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO auth.permissions (code, name, description) VALUES
|
||||
('view_tasks', '查看任务', '允许查看任务列表和任务详情'),
|
||||
('view_board', '查看看板', '允许查看数据看板概览'),
|
||||
('view_board_finance', '查看财务看板', '允许查看财务相关的数据看板'),
|
||||
('view_board_customer', '查看客户看板', '允许查看客户相关的数据看板'),
|
||||
('view_board_coach', '查看助教看板', '允许查看助教相关的数据看板')
|
||||
ON CONFLICT (code) DO NOTHING;
|
||||
|
||||
-- =============================================================================
|
||||
-- 种子数据:默认角色(4 条)
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO auth.roles (code, name, description) VALUES
|
||||
('coach', '助教', '球房助教,可查看任务和助教看板'),
|
||||
('staff', '员工', '球房员工,可查看任务和数据看板'),
|
||||
('site_admin', '店铺管理员', '单店管理员,可查看所有看板'),
|
||||
('tenant_admin', '租户管理员', '租户级管理员,拥有全部权限')
|
||||
ON CONFLICT (code) DO NOTHING;
|
||||
|
||||
-- =============================================================================
|
||||
-- 种子数据:角色-权限映射(14 条)
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO auth.role_permissions (role_id, permission_id)
|
||||
SELECT r.id, p.id
|
||||
FROM auth.roles r
|
||||
CROSS JOIN auth.permissions p
|
||||
WHERE (r.code, p.code) IN (
|
||||
('coach', 'view_tasks'),
|
||||
('coach', 'view_board_coach'),
|
||||
('staff', 'view_tasks'),
|
||||
('staff', 'view_board'),
|
||||
('site_admin', 'view_tasks'),
|
||||
('site_admin', 'view_board'),
|
||||
('site_admin', 'view_board_finance'),
|
||||
('site_admin', 'view_board_customer'),
|
||||
('site_admin', 'view_board_coach'),
|
||||
('tenant_admin', 'view_tasks'),
|
||||
('tenant_admin', 'view_board'),
|
||||
('tenant_admin', 'view_board_finance'),
|
||||
('tenant_admin', 'view_board_customer'),
|
||||
('tenant_admin', 'view_board_coach')
|
||||
)
|
||||
ON CONFLICT (role_id, permission_id) DO NOTHING;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- =============================================================================
|
||||
-- zqyy_app / biz(核心业务表(任务/备注/触发器))
|
||||
-- 生成日期:2026-03-20
|
||||
-- 生成日期:2026-04-05
|
||||
-- 来源:测试库(通过脚本自动导出)
|
||||
-- =============================================================================
|
||||
|
||||
@@ -10,9 +10,23 @@ CREATE SCHEMA IF NOT EXISTS biz;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.ai_cache_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.ai_conversations_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.ai_messages_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.ai_run_logs_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.ai_trigger_jobs_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.cfg_task_generator_params_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.coach_task_history_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.coach_task_transfer_log_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.coach_tasks_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.connectors_id_seq AS integer;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.dws_assistant_task_monthly_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.excel_upload_log_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.notes_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.salary_adjustments_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.site_code_history_id_seq AS integer;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.sites_id_seq AS integer;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.stg_finance_expense_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.stg_platform_income_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.stg_recharge_commission_id_seq AS bigint;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.tenants_id_seq AS integer;
|
||||
CREATE SEQUENCE IF NOT EXISTS biz.trigger_jobs_id_seq AS integer;
|
||||
|
||||
-- 表
|
||||
@@ -25,7 +39,8 @@ CREATE TABLE biz.ai_cache (
|
||||
score integer,
|
||||
triggered_by character varying(100),
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
expires_at timestamp with time zone
|
||||
expires_at timestamp with time zone,
|
||||
status character varying(20) DEFAULT 'valid'::character varying
|
||||
);
|
||||
|
||||
CREATE TABLE biz.ai_conversations (
|
||||
@@ -36,12 +51,13 @@ CREATE TABLE biz.ai_conversations (
|
||||
site_id bigint NOT NULL,
|
||||
source_page character varying(100),
|
||||
source_context jsonb,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
context_type character varying(20),
|
||||
context_id character varying(50),
|
||||
title character varying(200),
|
||||
last_message text,
|
||||
last_message_at timestamp with time zone,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
session_id character varying(100)
|
||||
);
|
||||
|
||||
CREATE TABLE biz.ai_messages (
|
||||
@@ -50,10 +66,54 @@ CREATE TABLE biz.ai_messages (
|
||||
role character varying(10) NOT NULL,
|
||||
content text NOT NULL,
|
||||
tokens_used integer,
|
||||
reference_card jsonb,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
reference_card jsonb
|
||||
);
|
||||
|
||||
CREATE TABLE biz.ai_run_logs (
|
||||
id bigint DEFAULT nextval('biz.ai_run_logs_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
app_type character varying(30) NOT NULL,
|
||||
trigger_type character varying(20) NOT NULL,
|
||||
member_id bigint,
|
||||
request_prompt text,
|
||||
response_text text,
|
||||
tokens_used integer DEFAULT 0,
|
||||
latency_ms integer,
|
||||
status character varying(20) DEFAULT 'pending'::character varying NOT NULL,
|
||||
error_message text,
|
||||
session_id character varying(100),
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
finished_at timestamp with time zone,
|
||||
alert_status character varying(20) DEFAULT NULL::character varying
|
||||
);
|
||||
|
||||
CREATE TABLE biz.ai_trigger_jobs (
|
||||
id bigint DEFAULT nextval('biz.ai_trigger_jobs_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
event_type character varying(30) NOT NULL,
|
||||
connector_type character varying(30) DEFAULT 'feiqiu'::character varying,
|
||||
member_id bigint,
|
||||
payload jsonb,
|
||||
status character varying(20) DEFAULT 'pending'::character varying NOT NULL,
|
||||
is_forced boolean DEFAULT false,
|
||||
app_chain character varying(100),
|
||||
started_at timestamp with time zone,
|
||||
finished_at timestamp with time zone,
|
||||
error_message text,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE biz.cfg_task_generator_params (
|
||||
id bigint DEFAULT nextval('biz.cfg_task_generator_params_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint,
|
||||
param_key character varying(64) NOT NULL,
|
||||
param_value numeric NOT NULL,
|
||||
description text,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_by bigint
|
||||
);
|
||||
|
||||
CREATE TABLE biz.coach_task_history (
|
||||
id bigint DEFAULT nextval('biz.coach_task_history_id_seq'::regclass) NOT NULL,
|
||||
task_id bigint NOT NULL,
|
||||
@@ -66,6 +126,20 @@ CREATE TABLE biz.coach_task_history (
|
||||
created_at timestamp with time zone DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE biz.coach_task_transfer_log (
|
||||
id bigint DEFAULT nextval('biz.coach_task_transfer_log_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
member_id bigint NOT NULL,
|
||||
from_assistant_id bigint NOT NULL,
|
||||
to_assistant_id bigint NOT NULL,
|
||||
from_task_id bigint NOT NULL,
|
||||
to_task_id bigint,
|
||||
transfer_reason text,
|
||||
guard_checks jsonb,
|
||||
transfer_score numeric,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE biz.coach_tasks (
|
||||
id bigint DEFAULT nextval('biz.coach_tasks_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
@@ -81,7 +155,50 @@ CREATE TABLE biz.coach_tasks (
|
||||
completed_task_type character varying(50),
|
||||
parent_task_id bigint,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now()
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
transfer_count integer DEFAULT 0 NOT NULL,
|
||||
transferred_from bigint,
|
||||
transferred_at timestamp with time zone
|
||||
);
|
||||
|
||||
CREATE TABLE biz.connectors (
|
||||
id integer DEFAULT nextval('biz.connectors_id_seq'::regclass) NOT NULL,
|
||||
connector_key character varying(50) NOT NULL,
|
||||
display_name character varying(100) NOT NULL,
|
||||
is_active boolean DEFAULT true NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE biz.dws_assistant_task_monthly (
|
||||
id bigint DEFAULT nextval('biz.dws_assistant_task_monthly_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
assistant_id bigint NOT NULL,
|
||||
stat_month date NOT NULL,
|
||||
recall_created integer DEFAULT 0 NOT NULL,
|
||||
follow_up_created integer DEFAULT 0 NOT NULL,
|
||||
relationship_created integer DEFAULT 0 NOT NULL,
|
||||
total_created integer DEFAULT 0 NOT NULL,
|
||||
recall_completed integer DEFAULT 0 NOT NULL,
|
||||
follow_up_completed integer DEFAULT 0 NOT NULL,
|
||||
total_completed integer DEFAULT 0 NOT NULL,
|
||||
abandoned_count integer DEFAULT 0 NOT NULL,
|
||||
transferred_count integer DEFAULT 0 NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE biz.excel_upload_log (
|
||||
id bigint DEFAULT nextval('biz.excel_upload_log_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
upload_type character varying(30) NOT NULL,
|
||||
file_name character varying(255) NOT NULL,
|
||||
uploaded_by bigint NOT NULL,
|
||||
row_count integer DEFAULT 0,
|
||||
conflict_count integer DEFAULT 0,
|
||||
resolved_count integer DEFAULT 0,
|
||||
status character varying(20) NOT NULL,
|
||||
error_detail jsonb,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
confirmed_at timestamp with time zone
|
||||
);
|
||||
|
||||
CREATE TABLE biz.notes (
|
||||
@@ -102,6 +219,89 @@ CREATE TABLE biz.notes (
|
||||
score smallint
|
||||
);
|
||||
|
||||
CREATE TABLE biz.salary_adjustments (
|
||||
id bigint DEFAULT nextval('biz.salary_adjustments_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
assistant_id bigint,
|
||||
assistant_name character varying(100) NOT NULL,
|
||||
assistant_number character varying(50) NOT NULL,
|
||||
salary_month character varying(7) NOT NULL,
|
||||
adjustment_type character varying(20) NOT NULL,
|
||||
amount numeric(12,2) NOT NULL,
|
||||
reason character varying(200) NOT NULL,
|
||||
upload_batch_id bigint,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
created_by bigint
|
||||
);
|
||||
|
||||
CREATE TABLE biz.site_code_history (
|
||||
id integer DEFAULT nextval('biz.site_code_history_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
site_code character varying(6) NOT NULL,
|
||||
is_current boolean DEFAULT false NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
retired_at timestamp with time zone
|
||||
);
|
||||
|
||||
CREATE TABLE biz.sites (
|
||||
id integer DEFAULT nextval('biz.sites_id_seq'::regclass) NOT NULL,
|
||||
tenant_id integer NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
site_name character varying(200),
|
||||
site_code character varying(6),
|
||||
site_label character varying(50),
|
||||
is_active boolean DEFAULT true NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE biz.stg_finance_expense (
|
||||
id bigint DEFAULT nextval('biz.stg_finance_expense_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
expense_month character varying(7) NOT NULL,
|
||||
category character varying(50) NOT NULL,
|
||||
amount numeric(12,2) NOT NULL,
|
||||
remark text,
|
||||
upload_batch_id bigint,
|
||||
synced_at timestamp with time zone,
|
||||
created_at timestamp with time zone DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE biz.stg_platform_income (
|
||||
id bigint DEFAULT nextval('biz.stg_platform_income_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
income_month character varying(7) NOT NULL,
|
||||
platform_name character varying(100) NOT NULL,
|
||||
amount numeric(12,2) NOT NULL,
|
||||
remark text,
|
||||
upload_batch_id bigint,
|
||||
synced_at timestamp with time zone,
|
||||
created_at timestamp with time zone DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE biz.stg_recharge_commission (
|
||||
id bigint DEFAULT nextval('biz.stg_recharge_commission_id_seq'::regclass) NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
recharge_date date NOT NULL,
|
||||
member_name character varying(100) NOT NULL,
|
||||
recharge_amount numeric(12,2) NOT NULL,
|
||||
assigned_assistant character varying(100) NOT NULL,
|
||||
reward_amount numeric(12,2) NOT NULL,
|
||||
upload_batch_id bigint,
|
||||
synced_at timestamp with time zone,
|
||||
created_at timestamp with time zone DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE biz.tenants (
|
||||
id integer DEFAULT nextval('biz.tenants_id_seq'::regclass) NOT NULL,
|
||||
connector_id integer NOT NULL,
|
||||
tenant_id bigint NOT NULL,
|
||||
tenant_name character varying(200),
|
||||
is_active boolean DEFAULT true NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
updated_at timestamp with time zone DEFAULT now() NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE biz.trigger_jobs (
|
||||
id integer DEFAULT nextval('biz.trigger_jobs_id_seq'::regclass) NOT NULL,
|
||||
job_type character varying(100) NOT NULL,
|
||||
@@ -111,7 +311,10 @@ CREATE TABLE biz.trigger_jobs (
|
||||
last_run_at timestamp with time zone,
|
||||
next_run_at timestamp with time zone,
|
||||
status character varying(20) DEFAULT 'enabled'::character varying NOT NULL,
|
||||
created_at timestamp with time zone DEFAULT now()
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
last_error text,
|
||||
description text,
|
||||
last_stats jsonb
|
||||
);
|
||||
|
||||
-- 约束(主键 / 唯一 / 外键)
|
||||
@@ -119,12 +322,42 @@ ALTER TABLE biz.ai_cache ADD CONSTRAINT ai_cache_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.ai_conversations ADD CONSTRAINT ai_conversations_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.ai_messages ADD CONSTRAINT ai_messages_conversation_id_fkey FOREIGN KEY (conversation_id) REFERENCES biz.ai_conversations(id) ON DELETE CASCADE;
|
||||
ALTER TABLE biz.ai_messages ADD CONSTRAINT ai_messages_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.ai_run_logs ADD CONSTRAINT ai_run_logs_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.ai_trigger_jobs ADD CONSTRAINT ai_trigger_jobs_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.cfg_task_generator_params ADD CONSTRAINT cfg_task_generator_params_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.cfg_task_generator_params ADD CONSTRAINT cfg_task_generator_params_site_id_param_key_key UNIQUE (site_id, param_key);
|
||||
ALTER TABLE biz.coach_task_history ADD CONSTRAINT coach_task_history_task_id_fkey FOREIGN KEY (task_id) REFERENCES biz.coach_tasks(id);
|
||||
ALTER TABLE biz.coach_task_history ADD CONSTRAINT coach_task_history_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.coach_task_transfer_log ADD CONSTRAINT coach_task_transfer_log_from_task_id_fkey FOREIGN KEY (from_task_id) REFERENCES biz.coach_tasks(id);
|
||||
ALTER TABLE biz.coach_task_transfer_log ADD CONSTRAINT coach_task_transfer_log_to_task_id_fkey FOREIGN KEY (to_task_id) REFERENCES biz.coach_tasks(id);
|
||||
ALTER TABLE biz.coach_task_transfer_log ADD CONSTRAINT coach_task_transfer_log_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.coach_tasks ADD CONSTRAINT coach_tasks_parent_task_id_fkey FOREIGN KEY (parent_task_id) REFERENCES biz.coach_tasks(id);
|
||||
ALTER TABLE biz.coach_tasks ADD CONSTRAINT fk_coach_tasks_transferred_from FOREIGN KEY (transferred_from) REFERENCES biz.coach_tasks(id);
|
||||
ALTER TABLE biz.coach_tasks ADD CONSTRAINT coach_tasks_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.connectors ADD CONSTRAINT connectors_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.connectors ADD CONSTRAINT connectors_connector_key_key UNIQUE (connector_key);
|
||||
ALTER TABLE biz.dws_assistant_task_monthly ADD CONSTRAINT dws_assistant_task_monthly_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.dws_assistant_task_monthly ADD CONSTRAINT dws_assistant_task_monthly_site_id_assistant_id_stat_month_key UNIQUE (site_id, assistant_id, stat_month);
|
||||
ALTER TABLE biz.excel_upload_log ADD CONSTRAINT excel_upload_log_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.notes ADD CONSTRAINT notes_task_id_fkey FOREIGN KEY (task_id) REFERENCES biz.coach_tasks(id);
|
||||
ALTER TABLE biz.notes ADD CONSTRAINT notes_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.salary_adjustments ADD CONSTRAINT salary_adjustments_upload_batch_id_fkey FOREIGN KEY (upload_batch_id) REFERENCES biz.excel_upload_log(id);
|
||||
ALTER TABLE biz.salary_adjustments ADD CONSTRAINT salary_adjustments_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.site_code_history ADD CONSTRAINT site_code_history_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.site_code_history ADD CONSTRAINT site_code_history_site_code_key UNIQUE (site_code);
|
||||
ALTER TABLE biz.sites ADD CONSTRAINT sites_tenant_id_fkey FOREIGN KEY (tenant_id) REFERENCES biz.tenants(id);
|
||||
ALTER TABLE biz.sites ADD CONSTRAINT sites_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.sites ADD CONSTRAINT sites_site_code_key UNIQUE (site_code);
|
||||
ALTER TABLE biz.sites ADD CONSTRAINT sites_site_id_key UNIQUE (site_id);
|
||||
ALTER TABLE biz.stg_finance_expense ADD CONSTRAINT stg_finance_expense_upload_batch_id_fkey FOREIGN KEY (upload_batch_id) REFERENCES biz.excel_upload_log(id);
|
||||
ALTER TABLE biz.stg_finance_expense ADD CONSTRAINT stg_finance_expense_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.stg_platform_income ADD CONSTRAINT stg_platform_income_upload_batch_id_fkey FOREIGN KEY (upload_batch_id) REFERENCES biz.excel_upload_log(id);
|
||||
ALTER TABLE biz.stg_platform_income ADD CONSTRAINT stg_platform_income_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.stg_recharge_commission ADD CONSTRAINT stg_recharge_commission_upload_batch_id_fkey FOREIGN KEY (upload_batch_id) REFERENCES biz.excel_upload_log(id);
|
||||
ALTER TABLE biz.stg_recharge_commission ADD CONSTRAINT stg_recharge_commission_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.tenants ADD CONSTRAINT tenants_connector_id_fkey FOREIGN KEY (connector_id) REFERENCES biz.connectors(id);
|
||||
ALTER TABLE biz.tenants ADD CONSTRAINT tenants_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.tenants ADD CONSTRAINT tenants_connector_id_tenant_id_key UNIQUE (connector_id, tenant_id);
|
||||
ALTER TABLE biz.trigger_jobs ADD CONSTRAINT trigger_jobs_pkey PRIMARY KEY (id);
|
||||
ALTER TABLE biz.trigger_jobs ADD CONSTRAINT trigger_jobs_job_name_key UNIQUE (job_name);
|
||||
|
||||
@@ -132,32 +365,26 @@ ALTER TABLE biz.trigger_jobs ADD CONSTRAINT trigger_jobs_job_name_key UNIQUE (jo
|
||||
CREATE INDEX idx_ai_cache_cleanup ON biz.ai_cache USING btree (cache_type, site_id, target_id, created_at);
|
||||
CREATE INDEX idx_ai_cache_lookup ON biz.ai_cache USING btree (cache_type, site_id, target_id, created_at DESC);
|
||||
CREATE INDEX idx_ai_conv_app_site ON biz.ai_conversations USING btree (app_id, site_id, created_at DESC);
|
||||
CREATE INDEX idx_ai_conv_user_site ON biz.ai_conversations USING btree (user_id, site_id, created_at DESC);
|
||||
CREATE INDEX idx_ai_conv_context ON biz.ai_conversations USING btree (user_id, site_id, context_type, context_id, last_message_at DESC NULLS LAST) WHERE (context_type IS NOT NULL);
|
||||
CREATE INDEX idx_ai_conv_last_msg ON biz.ai_conversations USING btree (user_id, site_id, last_message_at DESC NULLS LAST);
|
||||
CREATE INDEX idx_ai_conv_user_site ON biz.ai_conversations USING btree (user_id, site_id, created_at DESC);
|
||||
CREATE INDEX idx_ai_msg_conv ON biz.ai_messages USING btree (conversation_id, created_at);
|
||||
CREATE INDEX idx_ai_run_logs_alert ON biz.ai_run_logs USING btree (alert_status, created_at DESC) WHERE ((status)::text = ANY ((ARRAY['failed'::character varying, 'timeout'::character varying, 'circuit_open'::character varying])::text[]));
|
||||
CREATE INDEX idx_ai_run_logs_created ON biz.ai_run_logs USING btree (created_at);
|
||||
CREATE INDEX idx_ai_run_logs_created_brin ON biz.ai_run_logs USING brin (created_at) WITH (pages_per_range='32');
|
||||
CREATE INDEX idx_ai_run_logs_site_app ON biz.ai_run_logs USING btree (site_id, app_type);
|
||||
CREATE INDEX idx_ai_run_logs_status ON biz.ai_run_logs USING btree (status);
|
||||
CREATE INDEX idx_ai_trigger_jobs_dedup ON biz.ai_trigger_jobs USING btree (event_type, member_id, site_id, created_at) WHERE ((status)::text <> 'skipped_duplicate'::text);
|
||||
CREATE INDEX idx_ai_trigger_jobs_site ON biz.ai_trigger_jobs USING btree (site_id, event_type);
|
||||
CREATE INDEX idx_ai_trigger_jobs_status ON biz.ai_trigger_jobs USING btree (status);
|
||||
CREATE INDEX idx_transfer_log_member ON biz.coach_task_transfer_log USING btree (member_id, created_at DESC);
|
||||
CREATE INDEX idx_transfer_log_site_created ON biz.coach_task_transfer_log USING btree (site_id, created_at DESC);
|
||||
CREATE INDEX idx_coach_tasks_assistant_status ON biz.coach_tasks USING btree (site_id, assistant_id, status);
|
||||
CREATE UNIQUE INDEX idx_coach_tasks_site_assistant_member_type ON biz.coach_tasks USING btree (site_id, assistant_id, member_id, task_type) WHERE ((status)::text = 'active'::text);
|
||||
CREATE INDEX idx_task_monthly_assistant ON biz.dws_assistant_task_monthly USING btree (assistant_id, stat_month DESC);
|
||||
CREATE INDEX idx_task_monthly_site_month ON biz.dws_assistant_task_monthly USING btree (site_id, stat_month DESC);
|
||||
CREATE INDEX idx_excel_log_site ON biz.excel_upload_log USING btree (site_id, created_at DESC);
|
||||
CREATE INDEX idx_notes_target ON biz.notes USING btree (site_id, target_type, target_id);
|
||||
CREATE INDEX idx_salary_adj_assistant_month ON biz.salary_adjustments USING btree (assistant_id, salary_month);
|
||||
CREATE INDEX idx_salary_adj_site_month ON biz.salary_adjustments USING btree (site_id, salary_month);
|
||||
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 种子数据:触发器配置(4 条)
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO biz.trigger_jobs (job_type, job_name, trigger_condition, trigger_config, next_run_at)
|
||||
VALUES
|
||||
('task_generator', 'task_generator', 'cron',
|
||||
'{"cron_expression": "0 7 * * *"}',
|
||||
(CURRENT_DATE + 1) + INTERVAL '7 hours'),
|
||||
('task_expiry_check', 'task_expiry_check', 'interval',
|
||||
'{"interval_seconds": 3600}',
|
||||
NOW() + INTERVAL '1 hour'),
|
||||
('recall_completion_check', 'recall_completion_check', 'event',
|
||||
'{"event_name": "etl_data_updated"}',
|
||||
NULL),
|
||||
('note_reclassify_backfill', 'note_reclassify_backfill', 'event',
|
||||
'{"event_name": "recall_completed"}',
|
||||
NULL)
|
||||
ON CONFLICT (job_name) DO NOTHING;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- =============================================================================
|
||||
-- zqyy_app / public(小程序业务表)
|
||||
-- 生成日期:2026-03-15
|
||||
-- 生成日期:2026-04-05
|
||||
-- 来源:测试库(通过脚本自动导出)
|
||||
-- =============================================================================
|
||||
|
||||
@@ -24,7 +24,8 @@ CREATE TABLE public.admin_users (
|
||||
site_id bigint NOT NULL,
|
||||
is_active boolean DEFAULT true,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now()
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
roles _text DEFAULT '{site_admin}'::text[] NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE public.approvals (
|
||||
@@ -47,7 +48,8 @@ CREATE TABLE public.member_retention_clue (
|
||||
recorded_by_name character varying(50),
|
||||
recorded_at timestamp with time zone DEFAULT now() NOT NULL,
|
||||
site_id bigint NOT NULL,
|
||||
source character varying(20) DEFAULT 'manual'::character varying NOT NULL
|
||||
source character varying(20) DEFAULT 'manual'::character varying NOT NULL,
|
||||
is_hidden boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE public.permissions (
|
||||
@@ -83,7 +85,11 @@ CREATE TABLE public.scheduled_tasks (
|
||||
run_count integer DEFAULT 0,
|
||||
last_status character varying(20),
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
updated_at timestamp with time zone DEFAULT now()
|
||||
updated_at timestamp with time zone DEFAULT now(),
|
||||
min_run_interval_value integer DEFAULT 0 NOT NULL,
|
||||
min_run_interval_unit character varying(20) DEFAULT 'minutes'::character varying NOT NULL,
|
||||
last_success_at timestamp with time zone,
|
||||
min_run_intervals jsonb DEFAULT '{}'::jsonb NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE public.task_execution_log (
|
||||
@@ -101,7 +107,8 @@ CREATE TABLE public.task_execution_log (
|
||||
error_log text,
|
||||
summary jsonb,
|
||||
created_at timestamp with time zone DEFAULT now(),
|
||||
schedule_id uuid
|
||||
schedule_id uuid,
|
||||
config jsonb
|
||||
);
|
||||
|
||||
CREATE TABLE public.task_queue (
|
||||
@@ -198,20 +205,3 @@ CREATE INDEX idx_user_roles_site_id ON public.user_roles USING btree (site_id);
|
||||
CREATE INDEX idx_users_mobile ON public.users USING btree (mobile);
|
||||
CREATE INDEX idx_users_site_id ON public.users USING btree (site_id);
|
||||
|
||||
|
||||
|
||||
-- =============================================================================
|
||||
-- 种子数据:Web 管理后台默认管理员账号
|
||||
-- 默认密码:admin123(bcrypt hash,cost=12)
|
||||
-- 生产环境部署后务必立即修改密码
|
||||
-- =============================================================================
|
||||
|
||||
INSERT INTO admin_users (username, password_hash, display_name, site_id, is_active)
|
||||
VALUES (
|
||||
'admin',
|
||||
'$2b$12$2MTWlJKL0HTgHIkv5Rmpie2pQ9PkeJu0iciLbzPEpPcA94ZakIQzq',
|
||||
'默认管理员',
|
||||
1,
|
||||
TRUE
|
||||
)
|
||||
ON CONFLICT (username) DO NOTHING;
|
||||
|
||||
Reference in New Issue
Block a user