admin模块接入数据库
This commit is contained in:
133
docs/sql/30_rpc/distribution/rpc_admin_get_promoter_list_v1.sql
Normal file
133
docs/sql/30_rpc/distribution/rpc_admin_get_promoter_list_v1.sql
Normal file
@@ -0,0 +1,133 @@
|
||||
-- RPC: rpc_admin_get_promoter_list
|
||||
-- 管理端推广员列表聚合统计
|
||||
-- 口径:集合=B(上级+下级都算)=> 关系表中出现过的 uid/inviter_uid 都算推广员候选
|
||||
-- 统计:
|
||||
-- - 推广用户数量:以该用户作为 inviter_uid 的下级人数
|
||||
-- - 推广订单数量/金额:其下级用户在 ml_orders 中已完成(order_status=4)的订单数与 paid_amount 汇总
|
||||
-- - 佣金:从 ak_commission_logs 聚合
|
||||
|
||||
CREATE OR REPLACE FUNCTION public.rpc_admin_get_promoter_list(
|
||||
p_search text DEFAULT NULL,
|
||||
p_page integer DEFAULT 1,
|
||||
p_page_size integer DEFAULT 20,
|
||||
p_start_time timestamptz DEFAULT NULL,
|
||||
p_end_time timestamptz DEFAULT NULL
|
||||
)
|
||||
RETURNS TABLE (
|
||||
id uuid,
|
||||
nickname text,
|
||||
name text,
|
||||
phone text,
|
||||
avatar_url text,
|
||||
level text,
|
||||
"userCount" bigint,
|
||||
"orderCount" bigint,
|
||||
"orderAmount" numeric,
|
||||
"commissionTotal" numeric,
|
||||
"withdrawnAmount" numeric,
|
||||
"withdrawCount" bigint,
|
||||
"unwithdrawnAmount" numeric
|
||||
)
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
SET search_path = public
|
||||
AS $$
|
||||
DECLARE
|
||||
v_page integer := GREATEST(1, COALESCE(p_page, 1));
|
||||
v_page_size integer := LEAST(200, GREATEST(1, COALESCE(p_page_size, 20)));
|
||||
v_offset integer := (v_page - 1) * v_page_size;
|
||||
BEGIN
|
||||
-- 仅管理员可调用
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM public.ak_users u
|
||||
WHERE u.id = auth.uid() AND u.role = 'admin'
|
||||
) THEN
|
||||
RAISE EXCEPTION 'permission denied';
|
||||
END IF;
|
||||
|
||||
RETURN QUERY
|
||||
WITH promoters AS (
|
||||
SELECT DISTINCT x.uid
|
||||
FROM (
|
||||
SELECT r.uid FROM public.ak_promoter_relations r
|
||||
UNION
|
||||
SELECT r.inviter_uid FROM public.ak_promoter_relations r
|
||||
) x
|
||||
),
|
||||
base AS (
|
||||
SELECT
|
||||
u.id,
|
||||
u.username AS nickname,
|
||||
u.real_name AS name,
|
||||
u.phone,
|
||||
u.avatar_url,
|
||||
u.role AS level
|
||||
FROM promoters p
|
||||
JOIN public.ak_users u ON u.id = p.uid
|
||||
WHERE (
|
||||
p_search IS NULL OR p_search = ''
|
||||
OR u.username ILIKE ('%' || p_search || '%')
|
||||
OR COALESCE(u.real_name, '') ILIKE ('%' || p_search || '%')
|
||||
OR COALESCE(u.phone, '') ILIKE ('%' || p_search || '%')
|
||||
OR u.id::text ILIKE ('%' || p_search || '%')
|
||||
)
|
||||
),
|
||||
downline AS (
|
||||
SELECT inviter_uid, uid
|
||||
FROM public.ak_promoter_relations
|
||||
),
|
||||
user_stats AS (
|
||||
SELECT
|
||||
d.inviter_uid AS id,
|
||||
COUNT(*)::bigint AS "userCount"
|
||||
FROM downline d
|
||||
GROUP BY d.inviter_uid
|
||||
),
|
||||
order_stats AS (
|
||||
SELECT
|
||||
d.inviter_uid AS id,
|
||||
COUNT(o.id)::bigint AS "orderCount",
|
||||
COALESCE(SUM(o.paid_amount), 0)::numeric AS "orderAmount"
|
||||
FROM downline d
|
||||
JOIN public.ml_orders o ON o.user_id = d.uid
|
||||
WHERE o.order_status = 4
|
||||
AND (p_start_time IS NULL OR o.completed_at >= p_start_time)
|
||||
AND (p_end_time IS NULL OR o.completed_at <= p_end_time)
|
||||
GROUP BY d.inviter_uid
|
||||
),
|
||||
commission_stats AS (
|
||||
SELECT
|
||||
c.uid AS id,
|
||||
COALESCE(SUM(c.amount), 0)::numeric AS "commissionTotal",
|
||||
COALESCE(SUM(CASE WHEN c.status = 'withdrawn' THEN c.amount ELSE 0 END), 0)::numeric AS "withdrawnAmount",
|
||||
0::bigint AS "withdrawCount",
|
||||
COALESCE(SUM(CASE WHEN c.status IN ('frozen','available') THEN c.amount ELSE 0 END), 0)::numeric AS "unwithdrawnAmount"
|
||||
FROM public.ak_commission_logs c
|
||||
GROUP BY c.uid
|
||||
)
|
||||
SELECT
|
||||
b.id,
|
||||
b.nickname,
|
||||
b.name,
|
||||
b.phone,
|
||||
b.avatar_url,
|
||||
b.level,
|
||||
COALESCE(us."userCount", 0) AS "userCount",
|
||||
COALESCE(os."orderCount", 0) AS "orderCount",
|
||||
COALESCE(os."orderAmount", 0) AS "orderAmount",
|
||||
COALESCE(cs."commissionTotal", 0) AS "commissionTotal",
|
||||
COALESCE(cs."withdrawnAmount", 0) AS "withdrawnAmount",
|
||||
COALESCE(cs."withdrawCount", 0) AS "withdrawCount",
|
||||
COALESCE(cs."unwithdrawnAmount", 0) AS "unwithdrawnAmount"
|
||||
FROM base b
|
||||
LEFT JOIN user_stats us ON us.id = b.id
|
||||
LEFT JOIN order_stats os ON os.id = b.id
|
||||
LEFT JOIN commission_stats cs ON cs.id = b.id
|
||||
ORDER BY b.id
|
||||
LIMIT v_page_size OFFSET v_offset;
|
||||
END;
|
||||
$$;
|
||||
|
||||
-- 授权:仅允许 authenticated 调用,函数内部再做 admin 校验
|
||||
REVOKE ALL ON FUNCTION public.rpc_admin_get_promoter_list(text, integer, integer, timestamptz, timestamptz) FROM PUBLIC;
|
||||
GRANT EXECUTE ON FUNCTION public.rpc_admin_get_promoter_list(text, integer, integer, timestamptz, timestamptz) TO authenticated;
|
||||
Reference in New Issue
Block a user