Files
medical-mall/pages/mall/analytics/test/01_create_coupon_tables.sql
2026-01-30 16:17:13 +08:00

224 lines
8.4 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =============================================
-- 优惠券业务基础表(最小集,用于优惠券效果分析)
-- 说明:
-- - 基于项目规格文档 pages/mall/mall.md 第4节“优惠券系统”抽象而来。
-- - 仅创建 Analytics 所需的最小字段集合,兼容后续完整业务表替换。
-- - 可安全重复执行IF NOT EXISTS + 列存在性检查)。
-- - 依赖merchants、orders 表已存在(由 01_create_tables.sql 提供)。
-- =============================================
-- 1) 优惠券模板表coupon_templates
CREATE TABLE IF NOT EXISTS public.coupon_templates (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
name text NOT NULL,
description text,
coupon_type integer NOT NULL, -- 1..8:满减/折扣/免运费/新人/会员/品类/商家/限时(见 mall.md
discount_type integer NOT NULL, -- 满减 / 折扣 / 免运费 等类型枚举
discount_value numeric(10,2) NOT NULL, -- 金额或折扣值
min_order_amount numeric(10,2) DEFAULT 0,
max_discount_amount numeric(10,2),
total_quantity integer,
per_user_limit integer DEFAULT 1,
usage_limit integer DEFAULT 1,
merchant_id uuid,
category_ids jsonb,
product_ids jsonb,
user_type_limit integer,
start_time timestamptz NOT NULL,
end_time timestamptz NOT NULL,
status integer DEFAULT 1,
created_at timestamptz DEFAULT now()
);
DO $$
BEGIN
-- 若缺少 merchant_id 外键且 merchants 表存在,则补充外键
IF EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_schema = 'public' AND table_name = 'merchants'
) THEN
IF NOT EXISTS (
SELECT 1
FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE n.nspname = 'public'
AND t.relname = 'coupon_templates'
AND c.conname = 'coupon_templates_merchant_id_fkey'
) THEN
ALTER TABLE public.coupon_templates
ADD CONSTRAINT coupon_templates_merchant_id_fkey
FOREIGN KEY (merchant_id) REFERENCES public.merchants(id) ON DELETE SET NULL;
END IF;
END IF;
END;
$$;
COMMENT ON TABLE public.coupon_templates IS '优惠券模板表(业务权威表,来自 mall.md';
COMMENT ON COLUMN public.coupon_templates.coupon_type IS '券类型1..8(满减/折扣/免运费/新人/会员/品类/商家/限时)';
-- 2) 用户优惠券表user_coupons
CREATE TABLE IF NOT EXISTS public.user_coupons (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_id uuid,
template_id uuid REFERENCES public.coupon_templates(id) ON DELETE CASCADE,
coupon_code varchar(50) UNIQUE NOT NULL,
status integer DEFAULT 1, -- 1 未使用2 已使用3 已过期 等(与 mall.md 对齐)
used_at timestamptz,
order_id uuid,
received_at timestamptz DEFAULT now(),
expire_at timestamptz NOT NULL
);
DO $$
BEGIN
-- 若 users 表存在则补 user_id 外键(保证幂等)
IF EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_schema = 'public' AND table_name = 'users'
) THEN
IF NOT EXISTS (
SELECT 1
FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE n.nspname = 'public'
AND t.relname = 'user_coupons'
AND c.conname = 'user_coupons_user_id_fkey'
) THEN
ALTER TABLE public.user_coupons
ADD CONSTRAINT user_coupons_user_id_fkey
FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
END IF;
END IF;
-- 若 orders 表存在则补 order_id 外键
IF EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_schema = 'public' AND table_name = 'orders'
) THEN
IF NOT EXISTS (
SELECT 1
FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE n.nspname = 'public'
AND t.relname = 'user_coupons'
AND c.conname = 'user_coupons_order_id_fkey'
) THEN
ALTER TABLE public.user_coupons
ADD CONSTRAINT user_coupons_order_id_fkey
FOREIGN KEY (order_id) REFERENCES public.orders(id) ON DELETE SET NULL;
END IF;
END IF;
-- 分析增强字段:发放渠道 obtain_channel
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'user_coupons' AND column_name = 'obtain_channel'
) THEN
ALTER TABLE public.user_coupons ADD COLUMN obtain_channel text;
END IF;
-- 分析增强字段:冗余 merchant_id便于按商家过滤
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'user_coupons' AND column_name = 'merchant_id'
) THEN
ALTER TABLE public.user_coupons ADD COLUMN merchant_id uuid;
END IF;
END;
$$;
COMMENT ON TABLE public.user_coupons IS '用户优惠券表(领取/使用/到期信息)';
COMMENT ON COLUMN public.user_coupons.obtain_channel IS '发放渠道manual/auto/campaign/invite/cs/points 等';
-- 3) 优惠券使用记录表coupon_usage_logs
CREATE TABLE IF NOT EXISTS public.coupon_usage_logs (
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
user_coupon_id uuid REFERENCES public.user_coupons(id) ON DELETE CASCADE,
order_id uuid NOT NULL,
discount_amount numeric(10,2) NOT NULL,
used_at timestamptz DEFAULT now()
);
DO $$
BEGIN
-- 若 orders 表存在则补 order_id 外键
IF EXISTS (
SELECT 1 FROM information_schema.tables
WHERE table_schema = 'public' AND table_name = 'orders'
) THEN
IF NOT EXISTS (
SELECT 1
FROM pg_constraint c
JOIN pg_class t ON t.oid = c.conrelid
JOIN pg_namespace n ON n.oid = t.relnamespace
WHERE n.nspname = 'public'
AND t.relname = 'coupon_usage_logs'
AND c.conname = 'coupon_usage_logs_order_id_fkey'
) THEN
ALTER TABLE public.coupon_usage_logs
ADD CONSTRAINT coupon_usage_logs_order_id_fkey
FOREIGN KEY (order_id) REFERENCES public.orders(id) ON DELETE CASCADE;
END IF;
END IF;
-- 分析增强字段:冗余 user_id / template_id / merchant_id / order_amount / created_at
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'coupon_usage_logs' AND column_name = 'user_id'
) THEN
ALTER TABLE public.coupon_usage_logs ADD COLUMN user_id uuid;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'coupon_usage_logs' AND column_name = 'template_id'
) THEN
ALTER TABLE public.coupon_usage_logs ADD COLUMN template_id uuid;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'coupon_usage_logs' AND column_name = 'merchant_id'
) THEN
ALTER TABLE public.coupon_usage_logs ADD COLUMN merchant_id uuid;
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'coupon_usage_logs' AND column_name = 'order_amount'
) THEN
ALTER TABLE public.coupon_usage_logs ADD COLUMN order_amount numeric(10,2);
END IF;
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'coupon_usage_logs' AND column_name = 'created_at'
) THEN
ALTER TABLE public.coupon_usage_logs ADD COLUMN created_at timestamptz DEFAULT now();
END IF;
END;
$$;
COMMENT ON TABLE public.coupon_usage_logs IS '优惠券使用记录表(单次核销流水,用于 GMV / ROI 分析)';
-- 4) 索引(幂等)
CREATE INDEX IF NOT EXISTS idx_coupon_templates_merchant_id ON public.coupon_templates(merchant_id);
CREATE INDEX IF NOT EXISTS idx_user_coupons_user_id ON public.user_coupons(user_id);
CREATE INDEX IF NOT EXISTS idx_user_coupons_template_id ON public.user_coupons(template_id);
CREATE INDEX IF NOT EXISTS idx_user_coupons_status ON public.user_coupons(status);
CREATE INDEX IF NOT EXISTS idx_user_coupons_received_at ON public.user_coupons(received_at);
CREATE INDEX IF NOT EXISTS idx_user_coupons_expire_at ON public.user_coupons(expire_at);
CREATE INDEX IF NOT EXISTS idx_coupon_usage_logs_order_id ON public.coupon_usage_logs(order_id);
CREATE INDEX IF NOT EXISTS idx_coupon_usage_logs_used_at ON public.coupon_usage_logs(used_at);
-- 完成
SELECT 'coupon tables ensured' AS message;