mall数据库文件

This commit is contained in:
comlibmb
2026-01-30 16:17:13 +08:00
parent cfec4a16c0
commit 8f181b2b6a
42 changed files with 12758 additions and 2 deletions

View File

@@ -0,0 +1,342 @@
-- ============================================
-- DATA_DETAIL_RPCS.sql
-- 数据分析详情页专用 RPC 定义
-- ============================================
-- 目标:
-- 1) 为 `pages/mall/analytics/data-detail.uvue` 提供统一的数据服务
-- 2) 仅复用现有 analytics_* 表与业务表,不新增物理表
-- 3) 权限完全依赖各表自身的 RLS 策略,本文件只负责函数与 GRANT
--
-- 依赖前置脚本:
-- - 01_create_tables.sql
-- - ../../user/test/USER_AUTH_SCHEMA.sql
-- - ../../user/test/USER_AUTH_TRIGGER.sql
-- - ANALYTICS_DB_SCHEMA.sql
--
-- 使用说明:
-- - 前端通过 supabase-js / UTS 调用 `rpc()` 访问本文件中的函数
-- - 所有函数仅对 `authenticated` 角色开放执行权限
-- ============================================
-- --------------------------------------------
-- 1. 报表基础信息(用于初始化筛选器)
-- --------------------------------------------
-- 根据报表 ID 返回基础配置,包含标题、类型、时间范围等
CREATE OR REPLACE FUNCTION public.rpc_data_detail_report_info(
p_report_id uuid
)
RETURNS TABLE (
id uuid,
title text,
type text,
period text,
date_start date,
date_end date,
status text,
merchant_id uuid
)
LANGUAGE sql
AS $$
SELECT
r.id,
r.title,
r.type,
r.period,
r.date_start,
r.date_end,
r.status,
r.merchant_id
FROM public.analytics_reports r
WHERE r.id = p_report_id
$$;
REVOKE ALL ON FUNCTION public.rpc_data_detail_report_info(uuid) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_data_detail_report_info(uuid) TO authenticated;
-- --------------------------------------------
-- 2. 报表明细行(表格数据)
-- --------------------------------------------
-- 说明:
-- - 以 analytics_report_rows 作为数据源
-- - 可按日期 / GMV / 订单数 / 用户数排序
-- - 维度信息通过 extra(JSONB) 透出,前端可自由解析
CREATE OR REPLACE FUNCTION public.rpc_data_detail_rows(
p_report_id uuid,
p_sort_by text DEFAULT 'row_date', -- row_date | gmv | orders | users
p_sort_dir text DEFAULT 'asc', -- asc | desc
p_limit integer DEFAULT 200,
p_offset integer DEFAULT 0
)
RETURNS TABLE (
row_date date,
gmv numeric,
orders integer,
users integer,
conversion numeric,
avg_order_amount numeric,
extra jsonb
)
LANGUAGE plpgsql
AS $$
BEGIN
-- 统一的 LIMIT / OFFSET 处理
IF lower(p_sort_by) = 'gmv' THEN
IF lower(p_sort_dir) = 'desc' THEN
RETURN QUERY
SELECT
r.row_date,
r.gmv,
r.orders,
r.users,
r.conversion,
r.avg_order_amount,
r.extra
FROM public.analytics_report_rows r
WHERE r.report_id = p_report_id
ORDER BY r.gmv DESC, r.row_date DESC
LIMIT GREATEST(p_limit, 0)
OFFSET GREATEST(p_offset, 0);
ELSE
RETURN QUERY
SELECT
r.row_date,
r.gmv,
r.orders,
r.users,
r.conversion,
r.avg_order_amount,
r.extra
FROM public.analytics_report_rows r
WHERE r.report_id = p_report_id
ORDER BY r.gmv ASC, r.row_date ASC
LIMIT GREATEST(p_limit, 0)
OFFSET GREATEST(p_offset, 0);
END IF;
ELSIF lower(p_sort_by) = 'orders' THEN
IF lower(p_sort_dir) = 'desc' THEN
RETURN QUERY
SELECT
r.row_date,
r.gmv,
r.orders,
r.users,
r.conversion,
r.avg_order_amount,
r.extra
FROM public.analytics_report_rows r
WHERE r.report_id = p_report_id
ORDER BY r.orders DESC, r.row_date DESC
LIMIT GREATEST(p_limit, 0)
OFFSET GREATEST(p_offset, 0);
ELSE
RETURN QUERY
SELECT
r.row_date,
r.gmv,
r.orders,
r.users,
r.conversion,
r.avg_order_amount,
r.extra
FROM public.analytics_report_rows r
WHERE r.report_id = p_report_id
ORDER BY r.orders ASC, r.row_date ASC
LIMIT GREATEST(p_limit, 0)
OFFSET GREATEST(p_offset, 0);
END IF;
ELSIF lower(p_sort_by) = 'users' THEN
IF lower(p_sort_dir) = 'desc' THEN
RETURN QUERY
SELECT
r.row_date,
r.gmv,
r.orders,
r.users,
r.conversion,
r.avg_order_amount,
r.extra
FROM public.analytics_report_rows r
WHERE r.report_id = p_report_id
ORDER BY r.users DESC, r.row_date DESC
LIMIT GREATEST(p_limit, 0)
OFFSET GREATEST(p_offset, 0);
ELSE
RETURN QUERY
SELECT
r.row_date,
r.gmv,
r.orders,
r.users,
r.conversion,
r.avg_order_amount,
r.extra
FROM public.analytics_report_rows r
WHERE r.report_id = p_report_id
ORDER BY r.users ASC, r.row_date ASC
LIMIT GREATEST(p_limit, 0)
OFFSET GREATEST(p_offset, 0);
END IF;
ELSE
-- 默认按日期排序
IF lower(p_sort_dir) = 'desc' THEN
RETURN QUERY
SELECT
r.row_date,
r.gmv,
r.orders,
r.users,
r.conversion,
r.avg_order_amount,
r.extra
FROM public.analytics_report_rows r
WHERE r.report_id = p_report_id
ORDER BY r.row_date DESC
LIMIT GREATEST(p_limit, 0)
OFFSET GREATEST(p_offset, 0);
ELSE
RETURN QUERY
SELECT
r.row_date,
r.gmv,
r.orders,
r.users,
r.conversion,
r.avg_order_amount,
r.extra
FROM public.analytics_report_rows r
WHERE r.report_id = p_report_id
ORDER BY r.row_date ASC
LIMIT GREATEST(p_limit, 0)
OFFSET GREATEST(p_offset, 0);
END IF;
END IF;
END;
$$;
REVOKE ALL ON FUNCTION public.rpc_data_detail_rows(uuid,text,text,integer,integer) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_data_detail_rows(uuid,text,text,integer,integer) TO authenticated;
-- --------------------------------------------
-- 3. 钻取指标列表KPI / 汇总卡片)
-- --------------------------------------------
-- 说明:
-- - 直接从 analytics_report_metrics 读取
-- - 前端可根据 format 字段决定展示方式(数字 / 金额 / 百分比)
CREATE OR REPLACE FUNCTION public.rpc_data_detail_drill_items(
p_report_id uuid
)
RETURNS TABLE (
metric_key text,
metric_label text,
metric_value_num numeric,
metric_value_text text,
format text,
change_pct numeric,
icon text,
color text
)
LANGUAGE sql
AS $$
SELECT
m.metric_key,
m.metric_label,
m.metric_value_num,
m.metric_value_text,
m.format,
m.change_pct,
m.icon,
m.color
FROM public.analytics_report_metrics m
WHERE m.report_id = p_report_id
ORDER BY m.metric_key
$$;
REVOKE ALL ON FUNCTION public.rpc_data_detail_drill_items(uuid) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_data_detail_drill_items(uuid) TO authenticated;
-- --------------------------------------------
-- 4. GMV 对比数据(当前周期 vs 对比周期)
-- --------------------------------------------
-- 说明:
-- - 当前周期 = analytics_reports.period / date_start/date_end 所定义的范围
-- - 对比周期 = 与当前周期长度相同的上一段时间
-- - 聚合来源orders
CREATE OR REPLACE FUNCTION public.rpc_data_detail_compare_gmv(
p_report_id uuid
)
RETURNS TABLE (
day date,
gmv_current numeric,
gmv_previous numeric
)
LANGUAGE plpgsql
AS $$
DECLARE
v_date_start date;
v_date_end date;
v_period_len integer;
BEGIN
SELECT
COALESCE(r.date_start, (now() - INTERVAL '7 days')::date),
COALESCE(r.date_end, now()::date)
INTO v_date_start, v_date_end
FROM public.analytics_reports r
WHERE r.id = p_report_id;
IF v_date_start IS NULL OR v_date_end IS NULL THEN
RETURN;
END IF;
v_period_len := (v_date_end - v_date_start) + 1;
RETURN QUERY
WITH cur AS (
SELECT
o.created_at::date AS day,
SUM(o.total_amount) AS gmv
FROM public.orders o
WHERE o.created_at::date BETWEEN v_date_start AND v_date_end
AND o.status = 2
GROUP BY o.created_at::date
),
prev_range AS (
SELECT
(v_date_start - v_period_len) AS start_date,
(v_date_start - 1) AS end_date
),
prev AS (
SELECT
o.created_at::date AS day,
SUM(o.total_amount) AS gmv
FROM public.orders o, prev_range pr
WHERE o.created_at::date BETWEEN pr.start_date AND pr.end_date
AND o.status = 2
GROUP BY o.created_at::date
),
series AS (
SELECT generate_series(v_date_start, v_date_end, INTERVAL '1 day')::date AS day
)
SELECT
s.day,
COALESCE(c.gmv, 0) AS gmv_current,
COALESCE(p.gmv, 0) AS gmv_previous
FROM series s
LEFT JOIN cur c ON c.day = s.day
LEFT JOIN prev p ON p.day = (s.day - v_period_len);
END;
$$;
REVOKE ALL ON FUNCTION public.rpc_data_detail_compare_gmv(uuid) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_data_detail_compare_gmv(uuid) TO authenticated;
-- ============================================
-- 文件结束
-- ============================================