224 lines
8.4 KiB
SQL
224 lines
8.4 KiB
SQL
-- =============================================
|
||
-- 优惠券业务基础表(最小集,用于优惠券效果分析)
|
||
-- 说明:
|
||
-- - 基于项目规格文档 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;
|
||
|