diff --git a/docs/sql/10_schema/distribution/ak_distribution_agents_v1.sql b/docs/sql/10_schema/distribution/ak_distribution_agents_v1.sql new file mode 100644 index 00000000..4757ce83 --- /dev/null +++ b/docs/sql/10_schema/distribution/ak_distribution_agents_v1.sql @@ -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); diff --git a/docs/sql/10_schema/distribution/ak_distribution_division_applications_v1.sql b/docs/sql/10_schema/distribution/ak_distribution_division_applications_v1.sql new file mode 100644 index 00000000..2aae4fcd --- /dev/null +++ b/docs/sql/10_schema/distribution/ak_distribution_division_applications_v1.sql @@ -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); diff --git a/docs/sql/10_schema/distribution/ak_distribution_divisions_v1.sql b/docs/sql/10_schema/distribution/ak_distribution_divisions_v1.sql new file mode 100644 index 00000000..e0e58126 --- /dev/null +++ b/docs/sql/10_schema/distribution/ak_distribution_divisions_v1.sql @@ -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); diff --git a/docs/sql/10_schema/marketing/ak_advanced_marketing_v1.sql b/docs/sql/10_schema/marketing/ak_advanced_marketing_v1.sql new file mode 100644 index 00000000..74830c80 --- /dev/null +++ b/docs/sql/10_schema/marketing/ak_advanced_marketing_v1.sql @@ -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); diff --git a/docs/sql/10_schema/marketing/ak_bargain_groupbuy_v1.sql b/docs/sql/10_schema/marketing/ak_bargain_groupbuy_v1.sql new file mode 100644 index 00000000..a963e5fb --- /dev/null +++ b/docs/sql/10_schema/marketing/ak_bargain_groupbuy_v1.sql @@ -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); diff --git a/docs/sql/10_schema/marketing/ak_live_products_v1.sql b/docs/sql/10_schema/marketing/ak_live_products_v1.sql new file mode 100644 index 00000000..a441650e --- /dev/null +++ b/docs/sql/10_schema/marketing/ak_live_products_v1.sql @@ -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); diff --git a/docs/sql/10_schema/marketing/ak_lottery_live_v1.sql b/docs/sql/10_schema/marketing/ak_lottery_live_v1.sql new file mode 100644 index 00000000..28d8f959 --- /dev/null +++ b/docs/sql/10_schema/marketing/ak_lottery_live_v1.sql @@ -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); diff --git a/docs/sql/10_schema/marketing/ak_marketing_checkin_configs_v1.sql b/docs/sql/10_schema/marketing/ak_marketing_checkin_configs_v1.sql new file mode 100644 index 00000000..af420d45 --- /dev/null +++ b/docs/sql/10_schema/marketing/ak_marketing_checkin_configs_v1.sql @@ -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); + +-- 插入初始化数据(为每个管理员/商家初始化一条) +-- 实际应在商家创建时触发,此处先预留 diff --git a/docs/sql/10_schema/marketing/ak_marketing_newcomer_config_v1.sql b/docs/sql/10_schema/marketing/ak_marketing_newcomer_config_v1.sql new file mode 100644 index 00000000..0d1c3969 --- /dev/null +++ b/docs/sql/10_schema/marketing/ak_marketing_newcomer_config_v1.sql @@ -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); diff --git a/docs/sql/10_schema/marketing/ak_marketing_signin_logs_v1.sql b/docs/sql/10_schema/marketing/ak_marketing_signin_logs_v1.sql new file mode 100644 index 00000000..425170e3 --- /dev/null +++ b/docs/sql/10_schema/marketing/ak_marketing_signin_logs_v1.sql @@ -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); diff --git a/docs/sql/10_schema/marketing/ak_member_management_v1.sql b/docs/sql/10_schema/marketing/ak_member_management_v1.sql new file mode 100644 index 00000000..ede75643 --- /dev/null +++ b/docs/sql/10_schema/marketing/ak_member_management_v1.sql @@ -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); diff --git a/docs/sql/10_schema/marketing/ak_recharge_management_v1.sql b/docs/sql/10_schema/marketing/ak_recharge_management_v1.sql new file mode 100644 index 00000000..281d3d2d --- /dev/null +++ b/docs/sql/10_schema/marketing/ak_recharge_management_v1.sql @@ -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); diff --git a/docs/sql/10_schema/marketing/ak_signin_configs_v1.sql b/docs/sql/10_schema/marketing/ak_signin_configs_v1.sql new file mode 100644 index 00000000..56974d75 --- /dev/null +++ b/docs/sql/10_schema/marketing/ak_signin_configs_v1.sql @@ -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); diff --git a/docs/sql/10_schema/product/ak_shipping_templates_v1.sql b/docs/sql/10_schema/product/ak_shipping_templates_v1.sql new file mode 100644 index 00000000..31f81101 --- /dev/null +++ b/docs/sql/10_schema/product/ak_shipping_templates_v1.sql @@ -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); diff --git a/docs/sql/10_schema/product/ml_products_ext_v1.sql b/docs/sql/10_schema/product/ml_products_ext_v1.sql new file mode 100644 index 00000000..cdca721d --- /dev/null +++ b/docs/sql/10_schema/product/ml_products_ext_v1.sql @@ -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 $$; diff --git a/docs/sql/30_rpc/marketing/rpc_admin_get_integral_stats_v1.sql b/docs/sql/30_rpc/marketing/rpc_admin_get_integral_stats_v1.sql new file mode 100644 index 00000000..1bc50a8e --- /dev/null +++ b/docs/sql/30_rpc/marketing/rpc_admin_get_integral_stats_v1.sql @@ -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; diff --git a/pages/mall/admin/distribution/division/agent.uvue b/pages/mall/admin/distribution/division/agent.uvue index 31286f87..7ccaa7ac 100644 --- a/pages/mall/admin/distribution/division/agent.uvue +++ b/pages/mall/admin/distribution/division/agent.uvue @@ -4,7 +4,7 @@ 代理商查询: - + @@ -16,51 +16,119 @@ + + + 加载中... + + 用户UID 头像 名称 - 分佣比例 - 员工数量 - 过期时间 + 所属事业部 + 加入时间 状态 操作 + + 暂无代理商数据 + - {{ item.uid }} + {{ item.uid }} - + - {{ item.name }} - {{ item.ratio }}% - {{ item.staffCount }} - {{ item.endTime }} + {{ item.name || item.nickname }} + {{ item.division_name || '-' }} + {{ formatDateTime(item.created_at) }} - + - 编辑 + 详情 | - 查看 - | - 员工 - | - 删除 + 删除 + + + + + 第 {{ page }} 页 + + + 共 {{ total }} 条记录 + \ No newline at end of file diff --git a/pages/mall/admin/distribution/division/list.uvue b/pages/mall/admin/distribution/division/list.uvue index de109dc5..65917580 100644 --- a/pages/mall/admin/distribution/division/list.uvue +++ b/pages/mall/admin/distribution/division/list.uvue @@ -4,7 +4,7 @@ 搜索: - + @@ -16,6 +16,11 @@ + + + 加载中... + + 用户UID 头像 @@ -28,39 +33,128 @@ 操作 + + 暂无事业部数据 + - {{ item.uid }} + {{ item.uid }} - + - {{ item.name }} - {{ item.code }} + {{ item.name || item.nickname }} + {{ item.invite_code }} {{ item.ratio }}% - {{ item.agentCount }} - {{ item.endTime }} + {{ item.agent_count }} + {{ formatTime(item.end_time) }} - + 查看代理商 | - 编辑 - | - 删除 + 删除 + + + + + 第 {{ page }} 页 + + + 共 {{ total }} 条记录 + diff --git a/pages/mall/admin/marketing/checkin/config.uvue b/pages/mall/admin/marketing/checkin/config.uvue index c5c1443b..f300a40c 100644 --- a/pages/mall/admin/marketing/checkin/config.uvue +++ b/pages/mall/admin/marketing/checkin/config.uvue @@ -6,6 +6,11 @@ + + + 加载中... + + 签到开关: @@ -88,7 +93,7 @@ - + @@ -96,7 +101,11 @@ @@ -124,7 +177,7 @@ const handleSave = () => { box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05); } -.config-card { padding: 24px; } +.config-card { padding: 24px; position: relative; } .config-header { border-bottom: 1px solid #e8eaec; @@ -172,7 +225,7 @@ const handleSave = () => { .config-input { width: 400px; - height: 36px; + height: 32px; border: 1px solid #dcdfe6; border-radius: 4px; padding: 0 12px; @@ -186,8 +239,8 @@ const handleSave = () => { .btn-submit { width: 80px; - height: 36px; - line-height: 36px; + height: 32px; + line-height: 32px; background: #1890ff; color: #fff; border: none; @@ -195,4 +248,15 @@ const handleSave = () => { font-size: 14px; cursor: pointer; } + +.loading-mask { + position: absolute; + top: 0; left: 0; right: 0; bottom: 0; + background: rgba(255, 255, 255, 0.7); + display: flex; + align-items: center; + justify-content: center; + z-index: 10; +} +.loading-text { color: #1890ff; font-size: 14px; } diff --git a/pages/mall/admin/marketing/combination/list.uvue b/pages/mall/admin/marketing/combination/list.uvue index 3a71665e..81a8658c 100644 --- a/pages/mall/admin/marketing/combination/list.uvue +++ b/pages/mall/admin/marketing/combination/list.uvue @@ -25,7 +25,7 @@ 👥 - 349 + {{ statParticipants }} 参与人数(人) @@ -34,7 +34,7 @@ 📦 - 44 + {{ statSuccessGroups }} 成团数量(个) @@ -42,6 +42,10 @@ + + + 数据加载中... + 头像 开团团长 @@ -55,15 +59,18 @@ + + 暂无拼团记录 + - + - {{ item.nickname }} / {{ item.uid }} + {{ item.nickname || '未知用户' }} / {{ item.uid }} - {{ item.start_time }} + {{ item.start_time.substring(0, 16).replace('T', ' ') }} {{ item.title }} / {{ item.cid }} @@ -75,7 +82,7 @@ {{ item.count_people }} - {{ item.stop_time }} + {{ item.stop_time.substring(0, 16).replace('T', ' ') }} @@ -86,7 +93,7 @@ 查看详情 | - 立即成团 + 立即成团 @@ -95,23 +102,12 @@ - 共 {{ combos.length }} 条 - - - - 15条/页 - - + 共 {{ total }} 条 - - 1 - - - - 前往 - - + + {{ page }} + @@ -119,114 +115,99 @@ diff --git a/pages/mall/admin/marketing/coupon/receive.uvue b/pages/mall/admin/marketing/coupon/receive.uvue index 9b009092..3654a35c 100644 --- a/pages/mall/admin/marketing/coupon/receive.uvue +++ b/pages/mall/admin/marketing/coupon/receive.uvue @@ -1,65 +1,246 @@ + - diff --git a/pages/mall/admin/marketing/integral/statistic.uvue b/pages/mall/admin/marketing/integral/statistic.uvue index f5e02669..fdfbb39f 100644 --- a/pages/mall/admin/marketing/integral/statistic.uvue +++ b/pages/mall/admin/marketing/integral/statistic.uvue @@ -5,10 +5,12 @@ 时间选择: - - 📅 - 2026/01/05 - 2026/02/03 - + @@ -19,7 +21,7 @@ 💠 - 744904340.25 + {{ statsTotal.current.toFixed(2) }} 当前积分 @@ -28,7 +30,7 @@ 🪙 - 59026484 + {{ statsTotal.income.toFixed(2) }} 累计总积分 @@ -37,7 +39,7 @@ 💎 - 3189 + {{ statsTotal.expend.toFixed(2) }} 累计消耗积分 @@ -141,43 +143,102 @@ diff --git a/pages/mall/admin/marketing/live/product.uvue b/pages/mall/admin/marketing/live/product.uvue index 06e85f07..e134a788 100644 --- a/pages/mall/admin/marketing/live/product.uvue +++ b/pages/mall/admin/marketing/live/product.uvue @@ -112,73 +112,75 @@ - - - diff --git a/pages/mall/admin/marketing/member/config.uvue b/pages/mall/admin/marketing/member/config.uvue index 1247f77b..5fbdd900 100644 --- a/pages/mall/admin/marketing/member/config.uvue +++ b/pages/mall/admin/marketing/member/config.uvue @@ -69,21 +69,72 @@ diff --git a/pages/mall/admin/marketing/member/right.uvue b/pages/mall/admin/marketing/member/right.uvue index c877fce4..48830ab7 100644 --- a/pages/mall/admin/marketing/member/right.uvue +++ b/pages/mall/admin/marketing/member/right.uvue @@ -2,6 +2,11 @@ + + + 加载中... + + ID 权益图标 @@ -13,20 +18,23 @@ + + 暂无权益配置 + {{ item.id }} - + {{ item.name }} - {{ item.desc }} + {{ item.description || '-' }} {{ item.is_show ? '显示' : '隐藏' }} - {{ item.sort }} + {{ item.sort_order }} 编辑 @@ -38,20 +46,39 @@ @@ -136,6 +163,31 @@ const handleEdit = (item: any) => { .switch-mock.active .switch-txt { margin-left: 4px; } .op-link { color: #1890ff; font-size: 13px; cursor: pointer; } + +/* Loading & Empty Styles */ +.table-container { + position: relative; + min-height: 300px; +} + +.loading-mask { + position: absolute; + top: 0; left: 0; right: 0; bottom: 0; + background-color: rgba(255, 255, 255, 0.7); + display: flex; + align-items: center; + justify-content: center; + z-index: 10; +} + +.loading-text { color: #1890ff; font-size: 14px; } + +.empty-row { + padding: 60px 0; + text-align: center; + color: #999; + font-size: 14px; +} diff --git a/pages/mall/admin/marketing/member/type.uvue b/pages/mall/admin/marketing/member/type.uvue index b4cd25ac..a24a7517 100644 --- a/pages/mall/admin/marketing/member/type.uvue +++ b/pages/mall/admin/marketing/member/type.uvue @@ -13,22 +13,44 @@ 操作 - - - {{ item.id }} - {{ item.name }} - {{ item.days }} - ¥{{ item.price.toFixed(2) }} - ¥{{ item.discount.toFixed(2) }} - - - - {{ item.is_open ? '开启' : '关闭' }} - + + + + + 数据加载中... + + + + ID + 会员名 + 有效期(天) + 原价 + 优惠价 + 是否开启 + 排序 + 操作 + + + + + 暂无会员类型配置 - {{ item.sort }} - - 编辑 + + {{ item.id }} + {{ item.name }} + {{ item.duration_days == 0 ? '永久' : item.duration_days }} + ¥{{ item.price.toFixed(2) }} + ¥{{ item.discount_price.toFixed(2) }} + + + + {{ item.is_open ? '开启' : '关闭' }} + + + {{ item.sort_order }} + + 编辑 + @@ -38,22 +60,39 @@ @@ -141,6 +180,30 @@ const handleEdit = (item: any) => { .op-link { color: #1890ff; font-size: 13px; cursor: pointer; } +/* Loading & Empty Styles */ +.table-container { + position: relative; + min-height: 300px; +} + +.loading-mask { + position: absolute; + top: 0; left: 0; right: 0; bottom: 0; + background-color: rgba(255, 255, 255, 0.7); + display: flex; + align-items: center; + justify-content: center; + z-index: 10; +} + +.loading-text { color: #1890ff; font-size: 14px; } + +.empty-row { + padding: 60px 0; + text-align: center; + color: #999; + font-size: 14px; +} diff --git a/pages/mall/admin/marketing/newcomer/index.uvue b/pages/mall/admin/marketing/newcomer/index.uvue index ec3641ec..b5f5568d 100644 --- a/pages/mall/admin/marketing/newcomer/index.uvue +++ b/pages/mall/admin/marketing/newcomer/index.uvue @@ -45,13 +45,13 @@ - + - + @@ -65,8 +65,13 @@ - - + + + 加载中... + + + + 显示名称: @@ -75,13 +80,13 @@ 发放描述: - - * 此处的修改仅影响“新人礼”活动中的展示,不影响优惠券自身配置 - + + 暂无可用优惠券 + @@ -108,36 +113,73 @@ @@ -516,6 +568,22 @@ function handleSubmit() { color: #fff; border: none; } + +.modal-loading { + padding: 40px 0; + display: flex; + align-items: center; + justify-content: center; + color: #1890ff; + font-size: 14px; +} + +.empty-tip { + padding: 40px 0; + text-align: center; + color: #999; + font-size: 14px; +} diff --git a/pages/mall/admin/marketing/points/record.uvue b/pages/mall/admin/marketing/points/record.uvue index 8455baa8..60cf4b1f 100644 --- a/pages/mall/admin/marketing/points/record.uvue +++ b/pages/mall/admin/marketing/points/record.uvue @@ -1,27 +1,219 @@ +.marketing-points-record { + min-height: 100vh; + background: #f0f2f5; + padding: 16px; +} +.border-shadow { + background: #fff; + border-radius: 4px; + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05); +} +.filter-card { padding: 24px; margin-bottom: 16px; } +.filter-row { display: flex; flex-direction: row; align-items: center; gap: 24px; } +.filter-item { display: flex; flex-direction: row; align-items: center; } +.label { font-size: 14px; color: #606266; } +.input-mock { + width: 240px; height: 32px; border: 1px solid #dcdfe6; border-radius: 4px; + padding: 0 12px; font-size: 13px; +} +.filter-btns { display: flex; flex-direction: row; gap: 12px; } +.btn-query { background: #1890ff; color: #fff; height: 32px; padding: 0 16px; border-radius: 4px; font-size: 14px; border: none; cursor: pointer; } +.btn-reset { background: #fff; color: #666; height: 32px; padding: 0 16px; border-radius: 4px; font-size: 14px; border: 1px solid #dcdfe6; cursor: pointer; } + +.table-card { padding: 24px; position: relative; } +.table-container { min-height: 400px; position: relative; } +.loading-mask { + position: absolute; top: 0; left: 0; right: 0; bottom: 0; + background: rgba(255,255,255,0.7); display: flex; align-items: center; justify-content: center; z-index: 10; +} +.loading-text { color: #1890ff; font-size: 14px; } + +.table-header { + display: flex; flex-direction: row; background-color: #f8faff; + border-bottom: 1px solid #e8eaec; +} +.th { padding: 12px 8px; font-size: 13px; color: #515a6e; font-weight: bold; text-align: center; } + +.table-row { + display: flex; flex-direction: row; border-bottom: 1px solid #e8eaec; align-items: center; + &:hover { background-color: #fafafa; } +} +.td { padding: 12px 8px; text-align: center; display: flex; align-items: center; justify-content: center; } +.td-txt { font-size: 13px; color: #515a6e; } +.td-txt-bold { font-size: 14px; color: #333; font-weight: bold; } +.td-txt-small { font-size: 12px; color: #999; } +.color-blue { color: #1890ff; } +.color-red { color: #f5222d; } + +.cell-id { width: 60px; } +.cell-user { width: 180px; justify-content: flex-start; } +.cell-title { flex: 1; min-width: 150px; } +.cell-points { width: 100px; } +.cell-balance { width: 120px; } +.cell-time { width: 150px; } + +.u-info { display: flex; flex-direction: row; align-items: center; gap: 8px; } +.u-avatar { width: 32px; height: 32px; border-radius: 16px; background: #f5f5f5; } +.u-nick { font-size: 13px; color: #333; } + +.pagination-footer { + margin-top: 24px; display: flex; flex-direction: row; align-items: center; justify-content: flex-end; gap: 12px; +} +.total-txt { font-size: 13px; color: #999; } +.page-btns { display: flex; flex-direction: row; gap: 8px; } +.p-btn { + width: 28px; height: 28px; border: 1px solid #dcdfe6; border-radius: 4px; + display: flex; align-items: center; justify-content: center; font-size: 14px; + &.active { background: #1890ff; color: #fff; border-color: #1890ff; } + &.disabled { opacity: 0.5; cursor: not-allowed; } +} +.empty-row { padding: 60px 0; text-align: center; color: #999; } + \ No newline at end of file diff --git a/pages/mall/admin/marketing/recharge/config.uvue b/pages/mall/admin/marketing/recharge/config.uvue index 0ccbf32b..548103ea 100644 --- a/pages/mall/admin/marketing/recharge/config.uvue +++ b/pages/mall/admin/marketing/recharge/config.uvue @@ -73,17 +73,63 @@ diff --git a/pages/mall/admin/marketing/recharge/quota.uvue b/pages/mall/admin/marketing/recharge/quota.uvue index fb29e37b..e1b45e64 100644 --- a/pages/mall/admin/marketing/recharge/quota.uvue +++ b/pages/mall/admin/marketing/recharge/quota.uvue @@ -120,74 +120,120 @@ diff --git a/pages/mall/admin/marketing/seckill/list.uvue b/pages/mall/admin/marketing/seckill/list.uvue index b84a1bda..76aa0349 100644 --- a/pages/mall/admin/marketing/seckill/list.uvue +++ b/pages/mall/admin/marketing/seckill/list.uvue @@ -4,19 +4,12 @@ 活动搜索: - + 活动状态: - 请选择 - - - - - 活动时段: - - 请选择 + 全部 @@ -26,10 +19,10 @@ 活动时间: 📅 - 开始日期 - 结束日期 + 暂时使用默认范围 - + @@ -39,19 +32,26 @@ + + + 加载中... + ID 活动标题 单次限购 - 总购买数量限制 - 商品数量 - 活动时段 - 活动时间 + 总限购 + 商品数 + 时段 + 活动日期 状态 操作 + + 暂无数据 + {{ item.id }} @@ -74,8 +74,8 @@ - 开始: {{ item.start_date }} - 结束: {{ item.end_date }} + {{ item.start_date.substring(0,10) }} + {{ item.end_date.substring(0,10) }} @@ -96,23 +96,12 @@ - 共 {{ seckillList.length }} 条 - - - - 15条/页 - - + 共 {{ total }} 条 - - 1 - - - - 前往 - - + + {{ page }} + @@ -120,47 +109,90 @@ diff --git a/pages/mall/admin/marketing/signin/rule.uvue b/pages/mall/admin/marketing/signin/rule.uvue index 229e297e..429c4146 100644 --- a/pages/mall/admin/marketing/signin/rule.uvue +++ b/pages/mall/admin/marketing/signin/rule.uvue @@ -1,65 +1,276 @@