sql数据流,amdin业务逻辑接入

This commit is contained in:
comlibmb
2026-02-15 16:37:37 +08:00
parent ec636dc703
commit e648ff0c22
43 changed files with 5412 additions and 1024 deletions

View File

@@ -0,0 +1,41 @@
-- =====================================================================================
-- Schema: 分销代理商管理表
-- 位置docs/sql/10_schema/distribution/ak_distribution_agents_v1.sql
-- 说明:管理事业部旗下的代理商,按商家隔离。
-- =====================================================================================
CREATE TABLE IF NOT EXISTS public.ak_distribution_agents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
division_id UUID NOT NULL REFERENCES public.ak_distribution_divisions(id) ON DELETE CASCADE,
uid UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
name TEXT NOT NULL, -- 代理商名称(或备注名)
status BOOLEAN DEFAULT true, -- 状态: true开启, false关闭
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
-- 约束:一个用户在一个商家下只能成为一个代理商
UNIQUE(merchant_id, uid)
);
-- 启用 RLS
ALTER TABLE public.ak_distribution_agents ENABLE ROW LEVEL SECURITY;
-- 权限策略:商家仅能管理自己的代理商
CREATE POLICY "Merchants manage their own agents"
ON public.ak_distribution_agents FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 允许查看
CREATE POLICY "Authenticated users view active agents"
ON public.ak_distribution_agents FOR SELECT
TO authenticated
USING (status = true);
-- 索引
CREATE INDEX IF NOT EXISTS idx_agents_merchant ON public.ak_distribution_agents(merchant_id);
CREATE INDEX IF NOT EXISTS idx_agents_division ON public.ak_distribution_agents(division_id);

View File

@@ -0,0 +1,45 @@
-- =====================================================================================
-- Schema: 分销事业部申请表
-- 位置docs/sql/10_schema/distribution/ak_distribution_division_applications_v1.sql
-- 说明:记录用户申请加入事业部成为代理商的流水,支持审核流转,按商家隔离。
-- =====================================================================================
CREATE TABLE IF NOT EXISTS public.ak_distribution_division_applications (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
uid UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
division_id UUID NOT NULL REFERENCES public.ak_distribution_divisions(id) ON DELETE CASCADE,
name TEXT NOT NULL, -- 申请人填写的代理商名称
phone TEXT NOT NULL, -- 申请人联系电话
images JSONB DEFAULT '[]'::jsonb, -- 申请附件图片 (数组)
status INTEGER DEFAULT 1, -- 状态: 1待审核, 2已同意, 3已拒绝
admin_remark TEXT, -- 审核备注
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 启用 RLS
ALTER TABLE public.ak_distribution_division_applications ENABLE ROW LEVEL SECURITY;
-- 权限策略
CREATE POLICY "Merchants manage their own applications"
ON public.ak_distribution_division_applications FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 允许用户提交和查看自己的申请
CREATE POLICY "Users handle own applications"
ON public.ak_distribution_division_applications FOR ALL
TO authenticated
USING (uid = auth.uid())
WITH CHECK (uid = auth.uid());
-- 索引
CREATE INDEX IF NOT EXISTS idx_div_app_merchant ON public.ak_distribution_division_applications(merchant_id);
CREATE INDEX IF NOT EXISTS idx_div_app_uid ON public.ak_distribution_division_applications(uid);
CREATE INDEX IF NOT EXISTS idx_div_app_status ON public.ak_distribution_division_applications(status);

View File

@@ -0,0 +1,46 @@
-- =====================================================================================
-- Schema: 分销事业部管理表
-- 位置docs/sql/10_schema/distribution/ak_distribution_divisions_v1.sql
-- 说明:管理分销体系中的事业部,支持独立分销比例、邀请码及有效期,按商家隔离。
-- =====================================================================================
CREATE TABLE IF NOT EXISTS public.ak_distribution_divisions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
uid UUID NOT NULL REFERENCES public.ak_users(id), -- 事业部负责人UID
name TEXT NOT NULL, -- 事业部名称
invite_code TEXT UNIQUE NOT NULL, -- 事业部专属邀请码
ratio DECIMAL(5,2) DEFAULT 0, -- 事业部额外分销比例 (%)
agent_count INTEGER DEFAULT 0, -- 下属代理商数量 (由程序或触发器维护)
end_time TIMESTAMPTZ, -- 协议截止时间
status BOOLEAN DEFAULT true, -- 状态: true开启, false关闭
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
-- 约束:一个用户在一个商家下只能负责一个事业部
UNIQUE(merchant_id, uid)
);
-- 启用 RLS
ALTER TABLE public.ak_distribution_divisions ENABLE ROW LEVEL SECURITY;
-- 权限策略
CREATE POLICY "Merchants manage their own divisions"
ON public.ak_distribution_divisions FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 允许查看
CREATE POLICY "Authenticated users view active divisions"
ON public.ak_distribution_divisions FOR SELECT
TO authenticated
USING (status = true);
-- 索引
CREATE INDEX IF NOT EXISTS idx_divisions_merchant ON public.ak_distribution_divisions(merchant_id);
CREATE INDEX IF NOT EXISTS idx_divisions_uid ON public.ak_distribution_divisions(uid);

View File

@@ -0,0 +1,77 @@
-- =====================================================================================
-- Schema: 秒杀与拼团活动表
-- 位置docs/sql/10_schema/marketing/ak_advanced_marketing_v1.sql
-- 说明:管理秒杀活动与拼团活动,按商家隔离。
-- =====================================================================================
-- 1. 秒杀活动表
CREATE TABLE IF NOT EXISTS public.ak_seckill_activities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
title TEXT NOT NULL, -- 活动标题
single_limit INTEGER DEFAULT 1, -- 单次限购
total_limit INTEGER DEFAULT 10, -- 总购买数量限制
product_count INTEGER DEFAULT 0, -- 包含商品数量
time_range TEXT NOT NULL, -- 活动时段 (如 "06:00-24:00")
start_date TIMESTAMPTZ NOT NULL, -- 开始日期
end_date TIMESTAMPTZ NOT NULL, -- 结束日期
status BOOLEAN DEFAULT true, -- 状态: true开启, false关闭
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 2. 拼团活动表 (开团记录)
CREATE TABLE IF NOT EXISTS public.ak_combination_activities (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
uid UUID NOT NULL REFERENCES public.ak_users(id), -- 开团团长
product_id UUID NOT NULL REFERENCES public.ml_products(id), -- 拼团商品
people INTEGER DEFAULT 2, -- 几人团
count_people INTEGER DEFAULT 1, -- 当前几人参加
start_time TIMESTAMPTZ DEFAULT now(), -- 开团时间
stop_time TIMESTAMPTZ NOT NULL, -- 结束时间
status TEXT NOT NULL DEFAULT 'ongoing', -- ongoing进行中, pending未完成, ended已成功
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
CONSTRAINT chk_comb_status CHECK (status IN ('ongoing', 'pending', 'ended'))
);
-- 3. 启用 RLS
ALTER TABLE public.ak_seckill_activities ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.ak_combination_activities ENABLE ROW LEVEL SECURITY;
-- 4. 创建权限策略 (按 merchant_id 隔离)
-- 秒杀策略
CREATE POLICY "Merchants can manage their own seckill activities"
ON public.ak_seckill_activities FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 拼团策略
CREATE POLICY "Merchants can manage their own combination activities"
ON public.ak_combination_activities FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 允许所有认证用户查看(用于移动端展示)
CREATE POLICY "Anyone can view active marketing activities"
ON public.ak_seckill_activities FOR SELECT
TO authenticated
USING (status = true);
CREATE POLICY "Anyone can view ongoing combinations"
ON public.ak_combination_activities FOR SELECT
TO authenticated
USING (true);

View File

@@ -0,0 +1,78 @@
-- =====================================================================================
-- Schema: 砍价与团购活动表
-- 位置docs/sql/10_schema/marketing/ak_bargain_groupbuy_v1.sql
-- 说明:管理砍价与团购活动,按商家隔离。
-- =====================================================================================
-- 1. 砍价活动表
CREATE TABLE IF NOT EXISTS public.ak_marketing_bargains (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
product_id UUID NOT NULL REFERENCES public.ml_products(id) ON DELETE CASCADE,
title TEXT NOT NULL, -- 活动标题
min_price DECIMAL(12,2) NOT NULL DEFAULT 0, -- 砍价最低价
stock INTEGER DEFAULT 0, -- 活动库存
start_time TIMESTAMPTZ NOT NULL, -- 开始时间
stop_time TIMESTAMPTZ NOT NULL, -- 结束时间
status BOOLEAN DEFAULT true, -- 状态: true开启, false关闭
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 2. 团购活动表
CREATE TABLE IF NOT EXISTS public.ak_marketing_groupbuys (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
product_id UUID NOT NULL REFERENCES public.ml_products(id) ON DELETE CASCADE,
title TEXT NOT NULL, -- 活动标题
price DECIMAL(12,2) NOT NULL DEFAULT 0, -- 团购价格
people INTEGER DEFAULT 2, -- 成团人数要求
stock INTEGER DEFAULT 0, -- 活动库存
start_time TIMESTAMPTZ NOT NULL, -- 开始时间
stop_time TIMESTAMPTZ NOT NULL, -- 结束时间
status BOOLEAN DEFAULT true, -- 状态: true开启, false关闭
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 3. 启用 RLS
ALTER TABLE public.ak_marketing_bargains ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.ak_marketing_groupbuys ENABLE ROW LEVEL SECURITY;
-- 4. 创建权限策略 (按 merchant_id 隔离)
-- 砍价策略
CREATE POLICY "Merchants can manage their own bargains"
ON public.ak_marketing_bargains FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 团购策略
CREATE POLICY "Merchants can manage their own groupbuys"
ON public.ak_marketing_groupbuys FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 允许所有认证用户查看(用于移动端展示)
CREATE POLICY "Anyone can view active marketing activities"
ON public.ak_marketing_bargains FOR SELECT
TO authenticated
USING (status = true);
CREATE POLICY "Anyone can view active groupbuys"
ON public.ak_marketing_groupbuys FOR SELECT
TO authenticated
USING (status = true);
-- 5. 索引
CREATE INDEX IF NOT EXISTS idx_bargains_merchant ON public.ak_marketing_bargains(merchant_id);
CREATE INDEX IF NOT EXISTS idx_groupbuys_merchant ON public.ak_marketing_groupbuys(merchant_id);

View File

@@ -0,0 +1,41 @@
-- =====================================================================================
-- Schema: 直播商品管理表
-- 位置docs/sql/10_schema/marketing/ak_live_products_v1.sql
-- 说明:管理直播活动关联的商品,支持直播价设置与审核状态,按商家隔离。
-- =====================================================================================
CREATE TABLE IF NOT EXISTS public.ak_marketing_live_products (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
product_id UUID NOT NULL REFERENCES public.ml_products(id) ON DELETE CASCADE,
live_price DECIMAL(12,2) NOT NULL DEFAULT 0, -- 直播专属价
stock INTEGER DEFAULT 0, -- 直播可用库存
audit_status INTEGER DEFAULT 1, -- 审核状态: 1待审核, 2审核通过, 3审核驳回
is_show BOOLEAN DEFAULT true, -- 是否在直播间显示
sort_order INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 启用 RLS
ALTER TABLE public.ak_marketing_live_products ENABLE ROW LEVEL SECURITY;
-- 权限策略:商家仅能管理自己的直播商品
CREATE POLICY "Merchants can manage their own live products"
ON public.ak_marketing_live_products FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 允许查看审核通过的商品
CREATE POLICY "Anyone can view approved live products"
ON public.ak_marketing_live_products FOR SELECT
TO authenticated
USING (audit_status = 2 AND is_show = true);
-- 索引
CREATE INDEX IF NOT EXISTS idx_live_products_merchant ON public.ak_marketing_live_products(merchant_id);
CREATE INDEX IF NOT EXISTS idx_live_products_product ON public.ak_marketing_live_products(product_id);

View File

@@ -0,0 +1,93 @@
-- =====================================================================================
-- Schema: 抽奖与直播管理表
-- 位置docs/sql/10_schema/marketing/ak_lottery_live_v1.sql
-- 说明:管理抽奖活动、奖品、主播及直播间,按商家隔离。
-- =====================================================================================
-- 1. 抽奖活动表
CREATE TABLE IF NOT EXISTS public.ak_marketing_lotteries (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
name TEXT NOT NULL, -- 活动名称
type INTEGER DEFAULT 1, -- 活动类型: 1积分抽奖, 2订单评价, 3订单支付
start_time TIMESTAMPTZ NOT NULL, -- 开始时间
end_time TIMESTAMPTZ NOT NULL, -- 结束时间
is_open BOOLEAN DEFAULT true, -- 是否开启
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 2. 抽奖奖品表
CREATE TABLE IF NOT EXISTS public.ak_marketing_lottery_prizes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
lottery_id UUID NOT NULL REFERENCES public.ak_marketing_lotteries(id) ON DELETE CASCADE,
name TEXT NOT NULL, -- 奖品名称
prize_type TEXT NOT NULL, -- 奖品类型: points, balance, coupon, physical
amount DECIMAL(12,2) DEFAULT 0, -- 奖励面值/数量
stock INTEGER DEFAULT 0, -- 奖品库存
probability DECIMAL(5,2) DEFAULT 0, -- 中奖概率 (0-100)
sort_order INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT now()
);
-- 3. 直播主播表
CREATE TABLE IF NOT EXISTS public.ak_marketing_live_anchors (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
nickname TEXT NOT NULL, -- 主播昵称
wechat TEXT, -- 微信号
phone TEXT, -- 联系电话
avatar_url TEXT, -- 头像
status BOOLEAN DEFAULT true, -- 状态
created_at TIMESTAMPTZ DEFAULT now()
);
-- 4. 直播间管理表
CREATE TABLE IF NOT EXISTS public.ak_marketing_live_rooms (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
anchor_id UUID REFERENCES public.ak_marketing_live_anchors(id) ON DELETE SET NULL,
name TEXT NOT NULL, -- 直播间名称
background_url TEXT, -- 背景图
share_img_url TEXT, -- 分享图
start_time TIMESTAMPTZ NOT NULL, -- 开始时间
end_time TIMESTAMPTZ NOT NULL, -- 计划结束时间
sort INTEGER DEFAULT 0, -- 排序
type TEXT DEFAULT 'phone', -- 类型: phone手机直播等
like_enabled BOOLEAN DEFAULT true, -- 开启点赞
sale_enabled BOOLEAN DEFAULT true, -- 开启卖货
comment_enabled BOOLEAN DEFAULT true, -- 开启评论
is_show BOOLEAN DEFAULT true, -- 是否显示
live_status INTEGER DEFAULT 1, -- 1未开始, 2直播中, 3暂停, 4已结束
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 5. 启用 RLS
ALTER TABLE public.ak_marketing_lotteries ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.ak_marketing_lottery_prizes ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.ak_marketing_live_anchors ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.ak_marketing_live_rooms ENABLE ROW LEVEL SECURITY;
-- 6. 创建权限策略 (按 merchant_id 隔离)
CREATE POLICY "Merchants manage their own lotteries" ON public.ak_marketing_lotteries FOR ALL TO authenticated USING (merchant_id = auth.uid()) WITH CHECK (merchant_id = auth.uid());
CREATE POLICY "Merchants manage their own anchors" ON public.ak_marketing_live_anchors FOR ALL TO authenticated USING (merchant_id = auth.uid()) WITH CHECK (merchant_id = auth.uid());
CREATE POLICY "Merchants manage their own rooms" ON public.ak_marketing_live_rooms FOR ALL TO authenticated USING (merchant_id = auth.uid()) WITH CHECK (merchant_id = auth.uid());
-- 允许查看
CREATE POLICY "Users can view lotteries" ON public.ak_marketing_lotteries FOR SELECT TO authenticated USING (is_open = true);
CREATE POLICY "Users can view active rooms" ON public.ak_marketing_live_rooms FOR SELECT TO authenticated USING (is_show = true);

View File

@@ -0,0 +1,39 @@
-- =====================================================================================
-- Schema: 打卡/签到增强配置表
-- 位置docs/sql/10_schema/marketing/ak_marketing_checkin_configs_v1.sql
-- 说明:管理打卡开关、模式、提醒及基础奖励(积分/经验),按商家隔离。
-- =====================================================================================
CREATE TABLE IF NOT EXISTS public.ak_marketing_checkin_configs (
id TEXT PRIMARY KEY DEFAULT 'checkin_config',
merchant_id UUID NOT NULL UNIQUE REFERENCES public.ak_users(id) ON DELETE CASCADE,
is_open BOOLEAN DEFAULT true, -- 签到开关
mode TEXT DEFAULT 'none', -- 签到模式: none(无限制), week(周循环), month(月循环)
notice_enabled BOOLEAN DEFAULT false, -- 签到提醒开关
integral_reward INTEGER DEFAULT 10, -- 每日签到赠送积分
exp_reward INTEGER DEFAULT 1, -- 每日签到赠送经验
updated_at TIMESTAMPTZ DEFAULT now(),
updated_by UUID REFERENCES auth.users(id)
);
-- 启用 RLS
ALTER TABLE public.ak_marketing_checkin_configs ENABLE ROW LEVEL SECURITY;
-- 权限策略:商家仅能管理自己的打卡配置
CREATE POLICY "Merchants manage their own checkin configs"
ON public.ak_marketing_checkin_configs FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 允许所有认证用户查看(用于前台展示)
CREATE POLICY "Anyone can view checkin config"
ON public.ak_marketing_checkin_configs FOR SELECT
TO authenticated
USING (true);
-- 插入初始化数据(为每个管理员/商家初始化一条)
-- 实际应在商家创建时触发,此处先预留

View File

@@ -0,0 +1,35 @@
-- =====================================================================================
-- Schema: 新人礼配置表
-- 位置docs/sql/10_schema/marketing/ak_marketing_newcomer_config_v1.sql
-- 说明:管理新用户注册后的奖励(余额、积分、优惠券),按商家隔离。
-- =====================================================================================
CREATE TABLE IF NOT EXISTS public.ak_marketing_newcomer_config (
id TEXT PRIMARY KEY DEFAULT 'newcomer_config',
merchant_id UUID NOT NULL UNIQUE REFERENCES public.ak_users(id) ON DELETE CASCADE,
balance_reward DECIMAL(12,2) DEFAULT 0.00, -- 赠送余额
integral_reward INTEGER DEFAULT 0, -- 赠送积分
-- 赠送优惠券 (JSONB 格式): [{ "id": "coupon_uuid", "name": "显示名称", "desc": "发放描述" }]
coupons_json JSONB DEFAULT '[]'::jsonb,
updated_at TIMESTAMPTZ DEFAULT now(),
updated_by UUID REFERENCES auth.users(id)
);
-- 启用 RLS
ALTER TABLE public.ak_marketing_newcomer_config ENABLE ROW LEVEL SECURITY;
-- 权限策略:商家仅能管理自己的新人礼配置
CREATE POLICY "Merchants manage their own newcomer configs"
ON public.ak_marketing_newcomer_config FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 允许查看配置(用于移动端展示)
CREATE POLICY "Anyone can view newcomer config"
ON public.ak_marketing_newcomer_config FOR SELECT
TO authenticated
USING (true);

View File

@@ -0,0 +1,36 @@
-- =====================================================================================
-- Schema: 签到记录表
-- 位置docs/sql/10_schema/marketing/ak_marketing_signin_logs_v1.sql
-- 说明:记录用户每日签到的详细流水,按商家隔离。
-- =====================================================================================
CREATE TABLE IF NOT EXISTS public.ak_marketing_signin_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
uid UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
points INTEGER NOT NULL DEFAULT 0, -- 本次签到获得的积分
is_continuous_reward BOOLEAN DEFAULT false, -- 是否包含连续签到额外奖励
created_at TIMESTAMPTZ DEFAULT now()
);
-- 启用 RLS
ALTER TABLE public.ak_marketing_signin_logs ENABLE ROW LEVEL SECURITY;
-- 权限策略:商家仅能管理/查看自己的签到记录
CREATE POLICY "Merchants manage their own signin logs"
ON public.ak_marketing_signin_logs FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 允许用户查看自己的签到记录
CREATE POLICY "Users view own signin logs"
ON public.ak_marketing_signin_logs FOR SELECT
TO authenticated
USING (uid = auth.uid());
-- 索引
CREATE INDEX IF NOT EXISTS idx_signin_logs_merchant ON public.ak_marketing_signin_logs(merchant_id);
CREATE INDEX IF NOT EXISTS idx_signin_logs_uid ON public.ak_marketing_signin_logs(uid, created_at DESC);

View File

@@ -0,0 +1,71 @@
-- =====================================================================================
-- Schema: 付费会员管理相关表
-- 位置docs/sql/10_schema/marketing/ak_member_management_v1.sql
-- 说明:管理会员卡类型、权益内容及基础配置,按商家隔离。
-- =====================================================================================
-- 1. 会员卡类型表
CREATE TABLE IF NOT EXISTS public.ak_marketing_member_types (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
name TEXT NOT NULL, -- 会员名 (如: 月卡, 年卡)
duration_days INTEGER DEFAULT 30, -- 有效期0表示永久
price DECIMAL(12,2) NOT NULL DEFAULT 0, -- 原价
discount_price DECIMAL(12,2) NOT NULL DEFAULT 0, -- 优惠价/实际支付价
is_open BOOLEAN DEFAULT true, -- 是否开启
sort_order INTEGER DEFAULT 0, -- 排序
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 2. 会员权益表
CREATE TABLE IF NOT EXISTS public.ak_marketing_member_rights (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
name TEXT NOT NULL, -- 权益名称
description TEXT, -- 权益简介
icon_url TEXT, -- 权益图标
is_show BOOLEAN DEFAULT true, -- 是否展示
sort_order INTEGER DEFAULT 0, -- 排序
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 3. 会员基础配置表 (每个商家一条记录)
CREATE TABLE IF NOT EXISTS public.ak_marketing_member_config (
id TEXT PRIMARY KEY DEFAULT 'member_config',
merchant_id UUID NOT NULL UNIQUE REFERENCES public.ak_users(id) ON DELETE CASCADE,
is_enabled BOOLEAN DEFAULT true, -- 是否开启付费会员功能
bg_img_url TEXT, -- 会员期内背景图
expire_bg_img_url TEXT, -- 会员到期背景图
rules_description TEXT, -- 会员规则说明文本
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 4. 启用 RLS
ALTER TABLE public.ak_marketing_member_types ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.ak_marketing_member_rights ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.ak_marketing_member_config ENABLE ROW LEVEL SECURITY;
-- 5. 创建权限策略 (按 merchant_id 隔离)
-- 商家管理自己的数据
CREATE POLICY "Merchants manage their own member types" ON public.ak_marketing_member_types FOR ALL TO authenticated USING (merchant_id = auth.uid()) WITH CHECK (merchant_id = auth.uid());
CREATE POLICY "Merchants manage their own member rights" ON public.ak_marketing_member_rights FOR ALL TO authenticated USING (merchant_id = auth.uid()) WITH CHECK (merchant_id = auth.uid());
CREATE POLICY "Merchants manage their own member config" ON public.ak_marketing_member_config FOR ALL TO authenticated USING (merchant_id = auth.uid()) WITH CHECK (merchant_id = auth.uid());
-- 允许所有认证用户查看 (移动端展示)
CREATE POLICY "Users can view active member types" ON public.ak_marketing_member_types FOR SELECT TO authenticated USING (is_open = true);
CREATE POLICY "Users can view active member rights" ON public.ak_marketing_member_rights FOR SELECT TO authenticated USING (is_show = true);
CREATE POLICY "Users can view member config" ON public.ak_marketing_member_config FOR SELECT TO authenticated USING (true);
-- 6. 索引
CREATE INDEX IF NOT EXISTS idx_member_types_merchant ON public.ak_marketing_member_types(merchant_id);
CREATE INDEX IF NOT EXISTS idx_member_rights_merchant ON public.ak_marketing_member_rights(merchant_id);

View File

@@ -0,0 +1,48 @@
-- =====================================================================================
-- Schema: 充值配置与额度模板表
-- 位置docs/sql/10_schema/marketing/ak_recharge_management_v1.sql
-- 说明:管理用户充值开关、最低金额及预设额度,按商家隔离。
-- =====================================================================================
-- 1. 充值基础配置表 (每个商家一条记录)
CREATE TABLE IF NOT EXISTS public.ak_recharge_configs (
id TEXT PRIMARY KEY DEFAULT 'recharge_config',
merchant_id UUID NOT NULL UNIQUE REFERENCES public.ak_users(id) ON DELETE CASCADE,
balance_enabled BOOLEAN DEFAULT true, -- 余额功能是否启用
recharge_notice TEXT, -- 充值注意事项说明
mp_recharge_enabled BOOLEAN DEFAULT false, -- 小程序充值开关
min_recharge_amount DECIMAL(12,2) DEFAULT 0.01, -- 最低充值金额
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 2. 充值额度模板表
CREATE TABLE IF NOT EXISTS public.ak_recharge_quotas (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
price DECIMAL(12,2) NOT NULL DEFAULT 0, -- 售价(实际充值金额)
bonus_price DECIMAL(12,2) NOT NULL DEFAULT 0, -- 赠送金额
is_open BOOLEAN DEFAULT true, -- 是否可用
sort_order INTEGER DEFAULT 0, -- 排序
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 3. 启用 RLS
ALTER TABLE public.ak_recharge_configs ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.ak_recharge_quotas ENABLE ROW LEVEL SECURITY;
-- 4. 创建权限策略 (按 merchant_id 隔离)
CREATE POLICY "Merchants manage their own recharge configs" ON public.ak_recharge_configs FOR ALL TO authenticated USING (merchant_id = auth.uid()) WITH CHECK (merchant_id = auth.uid());
CREATE POLICY "Merchants manage their own recharge quotas" ON public.ak_recharge_quotas FOR ALL TO authenticated USING (merchant_id = auth.uid()) WITH CHECK (merchant_id = auth.uid());
-- 允许所有认证用户查看
CREATE POLICY "Users can view recharge configs" ON public.ak_recharge_configs FOR SELECT TO authenticated USING (true);
CREATE POLICY "Users can view active recharge quotas" ON public.ak_recharge_quotas FOR SELECT TO authenticated USING (is_open = true);
-- 5. 索引
CREATE INDEX IF NOT EXISTS idx_recharge_quotas_merchant ON public.ak_recharge_quotas(merchant_id);

View File

@@ -0,0 +1,42 @@
-- =====================================================================================
-- Schema: 签到规则配置表
-- 位置docs/sql/10_schema/marketing/ak_signin_configs_v1.sql
-- 说明:记录每日签到积分、连续签到奖励及规则说明,按商家隔离。
-- =====================================================================================
CREATE TABLE IF NOT EXISTS public.ak_signin_configs (
id TEXT PRIMARY KEY DEFAULT 'signin_config', -- 每个商家一个配置记录
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
is_enabled BOOLEAN DEFAULT true, -- 签到功能是否启用
daily_points INTEGER DEFAULT 10, -- 每日签到固定奖励积分
-- 连续签到奖励 (JSONB 格式): [{ "day": 3, "points": 20 }, { "day": 7, "points": 50 }]
continuous_rewards JSONB DEFAULT '[]'::jsonb,
rules_description TEXT DEFAULT '1.每日签到可获得积分奖励;\n2.连续签到满足天数可获得额外阶梯奖励;\n3.签到中断将重新从第一天开始计算。',
updated_at TIMESTAMPTZ DEFAULT now(),
updated_by UUID REFERENCES auth.users(id),
-- 约束:同一个商家只有一个签到配置记录
UNIQUE(merchant_id)
);
-- 启用 RLS
ALTER TABLE public.ak_signin_configs ENABLE ROW LEVEL SECURITY;
-- 权限策略:商家仅能管理自己的签到配置
CREATE POLICY "Merchants can manage their own signin configs"
ON public.ak_signin_configs
FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 允许所有认证用户查看配置(用于移动端签到展示)
CREATE POLICY "Authenticated users can view signin configs"
ON public.ak_signin_configs
FOR SELECT
TO authenticated
USING (true);

View File

@@ -0,0 +1,37 @@
-- =====================================================================================
-- Schema: 运费模板表
-- 位置docs/sql/10_schema/product/ak_shipping_templates_v1.sql
-- 说明:管理商家的运费计算规则,按商家隔离。
-- =====================================================================================
CREATE TABLE IF NOT EXISTS public.ak_shipping_templates (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
merchant_id UUID NOT NULL REFERENCES public.ak_users(id) ON DELETE CASCADE,
name TEXT NOT NULL, -- 模板名称
calc_method TEXT DEFAULT 'piece', -- 计费方式: piece(件数), weight(重量), volume(体积)
is_free_shipping BOOLEAN DEFAULT false, -- 是否包邮
sort_order INTEGER DEFAULT 0,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now()
);
-- 启用 RLS
ALTER TABLE public.ak_shipping_templates ENABLE ROW LEVEL SECURITY;
-- 权限策略:商家管理自己的模板
CREATE POLICY "Merchants manage own shipping templates"
ON public.ak_shipping_templates FOR ALL
TO authenticated
USING (merchant_id = auth.uid())
WITH CHECK (merchant_id = auth.uid());
-- 允许查看
CREATE POLICY "Authenticated users view shipping templates"
ON public.ak_shipping_templates FOR SELECT
TO authenticated
USING (true);
-- 索引
CREATE INDEX IF NOT EXISTS idx_shipping_templates_merchant ON public.ak_shipping_templates(merchant_id);

View File

@@ -0,0 +1,39 @@
-- =====================================================================================
-- Schema Update: ml_products 扩展字段 (物流、营销、高级设置)
-- 位置docs/sql/10_schema/product/ml_products_ext_v1.sql
-- 说明:补齐商品编辑页 Step 3-6 所需的持久化字段。
-- =====================================================================================
DO $$
BEGIN
-- 1. 物流设置:关联运费模板
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'ml_products' AND column_name = 'shipping_template_id') THEN
ALTER TABLE public.ml_products ADD COLUMN shipping_template_id UUID REFERENCES public.ak_shipping_templates(id) ON DELETE SET NULL;
COMMENT ON COLUMN public.ml_products.shipping_template_id IS '关联运费模板ID';
END IF;
-- 2. 营销设置:赠送积分
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'ml_products' AND column_name = 'give_integral') THEN
ALTER TABLE public.ml_products ADD COLUMN give_integral INTEGER DEFAULT 0;
COMMENT ON COLUMN public.ml_products.give_integral IS '购买赠送积分';
END IF;
-- 3. 高级设置:警戒库存
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'ml_products' AND column_name = 'stock_warning') THEN
ALTER TABLE public.ml_products ADD COLUMN stock_warning INTEGER DEFAULT 10;
COMMENT ON COLUMN public.ml_products.stock_warning IS '库存报警数值';
END IF;
-- 4. 高级设置:虚拟销量
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'ml_products' AND column_name = 'virtual_sales') THEN
ALTER TABLE public.ml_products ADD COLUMN virtual_sales INTEGER DEFAULT 0;
COMMENT ON COLUMN public.ml_products.virtual_sales IS '虚拟销量(展示用)';
END IF;
-- 5. 高级设置:排序
IF NOT EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'ml_products' AND column_name = 'sort_order') THEN
ALTER TABLE public.ml_products ADD COLUMN sort_order INTEGER DEFAULT 0;
COMMENT ON COLUMN public.ml_products.sort_order IS '商品排序权重';
END IF;
END $$;

View File

@@ -0,0 +1,91 @@
-- RPC: rpc_admin_get_integral_stats
-- 位置docs/sql/30_rpc/marketing/rpc_admin_get_integral_stats_v1.sql
-- 说明:聚合统计积分概况(总额、趋势、分布)
CREATE OR REPLACE FUNCTION public.rpc_admin_get_integral_stats(
p_start_time TIMESTAMP WITH TIME ZONE,
p_end_time TIMESTAMP WITH TIME ZONE
)
RETURNS JSONB
SECURITY DEFINER
SET search_path = public
LANGUAGE plpgsql
AS $$
DECLARE
v_total_stats RECORD;
v_trend_data JSONB;
v_source_dist JSONB;
v_consume_dist JSONB;
BEGIN
-- 1. 权限检查
IF NOT EXISTS (
SELECT 1 FROM public.ak_users
WHERE id = auth.uid() AND role = 'admin'
) THEN
RAISE EXCEPTION 'Permission denied';
END IF;
-- 2. 计算核心指标 (所有时间)
SELECT
COALESCE(SUM(CASE WHEN pm = 1 THEN number ELSE -number END), 0) as current_total,
COALESCE(SUM(CASE WHEN pm = 1 THEN number ELSE 0 END), 0) as cumulative_income,
COALESCE(SUM(CASE WHEN pm = 0 THEN number ELSE 0 END), 0) as cumulative_expend
INTO v_total_stats
FROM public.ml_user_bill
WHERE category = 'integral' AND status = 1;
-- 3. 趋势数据 (按日聚合)
SELECT jsonb_agg(t) INTO v_trend_data
FROM (
SELECT
to_char(date_trunc('day', gs.day), 'MM-DD') AS date_group,
COALESCE((SELECT SUM(number) FROM public.ml_user_bill b
WHERE b.category = 'integral' AND b.pm = 1 AND b.status = 1
AND date_trunc('day', b.created_at) = gs.day), 0) as income,
COALESCE((SELECT SUM(number) FROM public.ml_user_bill b
WHERE b.category = 'integral' AND b.pm = 0 AND b.status = 1
AND date_trunc('day', b.created_at) = gs.day), 0) as expend
FROM generate_series(date_trunc('day', p_start_time), date_trunc('day', p_end_time), '1 day'::interval) gs(day)
ORDER BY gs.day ASC
) t;
-- 4. 来源分布 (按 type 分组)
SELECT jsonb_agg(t) INTO v_source_dist
FROM (
SELECT
type as label,
SUM(number) as value,
ROUND((SUM(number) * 100 / NULLIF(v_total_stats.cumulative_income, 0)), 2) as percent
FROM public.ml_user_bill
WHERE category = 'integral' AND pm = 1 AND status = 1
GROUP BY type
ORDER BY value DESC
) t;
-- 5. 消耗分布 (按 type 分组)
SELECT jsonb_agg(t) INTO v_consume_dist
FROM (
SELECT
type as label,
SUM(number) as value,
ROUND((SUM(number) * 100 / NULLIF(v_total_stats.cumulative_expend, 0)), 2) as percent
FROM public.ml_user_bill
WHERE category = 'integral' AND pm = 0 AND status = 1
GROUP BY type
ORDER BY value DESC
) t;
RETURN jsonb_build_object(
'totals', jsonb_build_object(
'current', v_total_stats.current_total,
'income', v_total_stats.cumulative_income,
'expend', v_total_stats.cumulative_expend
),
'trend', COALESCE(v_trend_data, '[]'::jsonb),
'sources', COALESCE(v_source_dist, '[]'::jsonb),
'consumes', COALESCE(v_consume_dist, '[]'::jsonb)
);
END;
$$;
GRANT EXECUTE ON FUNCTION public.rpc_admin_get_integral_stats(timestamptz, timestamptz) TO authenticated;