Files
medical-mall/pages/mall/analytics/test/ANALYTICS_TEST_SEED.sql
2026-01-30 16:17:13 +08:00

464 lines
14 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- ============================================
-- 数据分析模块测试数据 SeedSupabase/Postgres
-- ============================================
-- 用途:为 `pages/mall/analytics/*` 页面提供可联调的模拟数据
-- 参考:`docs/ANALYTICS_DB_DESIGN.md`
--
-- 执行顺序:
-- 1. 先执行基础业务表的 seedusers/merchants/products/orders等
-- 2. 再执行本文档analytics_* 表 + 基础表补充数据)
--
-- ⚠️ 重要RLS
-- 本脚本会写入已启用 RLS 的表orders/user_sessions/page_views/analytics_*)。
-- 请使用 Supabase Dashboard SQL Editor等价于 postgres/service_role执行
-- 不要用 anon/authenticated 直接执行,否则会被 RLS 策略拦截。
-- ============================================
-- ============================================
-- 1. 基础业务表补充数据(如果还没有)
-- ============================================
-- 1.1 确保有测试用户(分析师)
-- 注意:如果 users 表已通过 02_insert_test_data.sql 插入数据,这里可以跳过或补充
INSERT INTO users (id, phone, email, nickname, last_login_at, created_at)
VALUES
('00000000-0000-0000-0000-000000000001', '13800001001', 'analyst1@test.com', '分析师张三', NOW() - INTERVAL '1 day', NOW() - INTERVAL '30 days'),
('00000000-0000-0000-0000-000000000002', '13800001002', 'analyst2@test.com', '分析师李四', NOW() - INTERVAL '2 days', NOW() - INTERVAL '20 days')
ON CONFLICT (id) DO NOTHING;
-- 1.2 确保有测试商家
-- 注意:如果 merchants 表已通过 02_insert_test_data.sql 插入数据,这里可以跳过或补充
INSERT INTO merchants (id, shop_name, created_at)
VALUES
('10000000-0000-0000-0000-000000000001', '测试商家A', NOW() - INTERVAL '60 days'),
('10000000-0000-0000-0000-000000000002', '测试商家B', NOW() - INTERVAL '50 days')
ON CONFLICT (id) DO NOTHING;
-- 1.3 确保有测试商品
-- 注意:如果 products 表已通过 02_insert_test_data.sql 插入数据,这里可以跳过或补充
INSERT INTO products (id, merchant_id, name, price, sales, status, created_at)
VALUES
('20000000-0000-0000-0000-000000000001', '10000000-0000-0000-0000-000000000001', '测试商品1', 99.00, 50, 1, NOW() - INTERVAL '40 days'),
('20000000-0000-0000-0000-000000000002', '10000000-0000-0000-0000-000000000001', '测试商品2', 199.00, 30, 1, NOW() - INTERVAL '35 days'),
('20000000-0000-0000-0000-000000000003', '10000000-0000-0000-0000-000000000002', '测试商品3', 299.00, 20, 1, NOW() - INTERVAL '30 days')
ON CONFLICT (id) DO NOTHING;
-- 1.4 生成过去30天的测试订单用于首页实时KPI和趋势
DO $$
DECLARE
i INTEGER;
j INTEGER;
order_date DATE;
order_id UUID;
user_id_val UUID := '00000000-0000-0000-0000-000000000001';
merchant_id_val UUID := '10000000-0000-0000-0000-000000000001';
product_id_val UUID := '20000000-0000-0000-0000-000000000001';
BEGIN
FOR i IN 0..29 LOOP
order_date := CURRENT_DATE - (29 - i);
-- 每天生成 5-15 个订单
FOR j IN 1..(5 + (i % 11)) LOOP
order_id := gen_random_uuid();
-- 插入订单状态2=已支付/已完成)
INSERT INTO orders (
id, user_id, merchant_id, status, total_amount, payment_method, created_at
)
VALUES (
order_id,
user_id_val,
merchant_id_val,
2, -- 已支付/已完成
(50 + (j * 10) + (i * 2))::numeric(10,2),
'alipay',
order_date + (random() * INTERVAL '1 day')
)
ON CONFLICT (id) DO NOTHING;
-- 插入订单商品
INSERT INTO order_items (
id, order_id, product_id, quantity, price, total_amount, created_at
)
VALUES (
gen_random_uuid(),
order_id,
product_id_val,
1,
(50 + (j * 10))::numeric(10,2),
(50 + (j * 10))::numeric(10,2),
order_date + (random() * INTERVAL '1 day')
)
ON CONFLICT (id) DO NOTHING;
END LOOP;
END LOOP;
END $$;
-- 1.5 插入 user_sessions在线用户/访问用户统计)
INSERT INTO user_sessions (id, user_id, created_at, last_active_at, is_active)
VALUES
(gen_random_uuid(), '00000000-0000-0000-0000-000000000001', NOW() - INTERVAL '10 minutes', NOW() - INTERVAL '1 minutes', TRUE),
(gen_random_uuid(), '00000000-0000-0000-0000-000000000002', NOW() - INTERVAL '8 minutes', NOW() - INTERVAL '2 minutes', TRUE),
(gen_random_uuid(), '00000000-0000-0000-0000-000000000001', NOW() - INTERVAL '20 minutes', NOW() - INTERVAL '6 minutes', FALSE)
ON CONFLICT DO NOTHING;
-- 1.6 插入 page_views流量来源统计
DO $$
DECLARE
i INTEGER;
v_date DATE;
v_source TEXT;
BEGIN
FOR i IN 0..29 LOOP
v_date := CURRENT_DATE - (29 - i);
v_source := CASE
WHEN (i % 4) = 0 THEN 'direct'
WHEN (i % 4) = 1 THEN 'search'
WHEN (i % 4) = 2 THEN 'social'
ELSE 'ad'
END;
INSERT INTO page_views (id, user_id, path, source, created_at)
VALUES
(gen_random_uuid(), '00000000-0000-0000-0000-000000000001', '/pages/mall/analytics/index', v_source, v_date + (random() * INTERVAL '1 day'))
ON CONFLICT DO NOTHING;
END LOOP;
END $$;
-- ============================================
-- 2. Analytics 表数据
-- ============================================
-- 2.1 分析师偏好设置
INSERT INTO analytics_user_preferences (id, user_id, default_period, timezone, currency, kpi_cards, created_at, updated_at)
VALUES
(
gen_random_uuid(),
'00000000-0000-0000-0000-000000000001',
'7d',
'Asia/Shanghai',
'CNY',
'["gmv", "orders", "users", "conversion"]'::jsonb,
NOW() - INTERVAL '10 days',
NOW()
),
(
gen_random_uuid(),
'00000000-0000-0000-0000-000000000002',
'30d',
'Asia/Shanghai',
'CNY',
'["gmv", "orders"]'::jsonb,
NOW() - INTERVAL '5 days',
NOW()
)
ON CONFLICT (user_id) DO UPDATE SET
default_period = EXCLUDED.default_period,
updated_at = NOW();
-- 2.2 报表定义3个示例报表
INSERT INTO analytics_reports (
id, owner_user_id, merchant_id, title, description, type, period,
date_start, date_end, status, generated_at, created_at, updated_at
)
VALUES
(
'a0000000-0000-0000-0000-000000000001',
'00000000-0000-0000-0000-000000000001',
NULL,
'销售报表 - 近7天',
'展示近7天的销售趋势和核心指标',
'sales',
'7d',
CURRENT_DATE - 7,
CURRENT_DATE,
'ready',
NOW() - INTERVAL '1 hour',
NOW() - INTERVAL '2 days',
NOW() - INTERVAL '1 hour'
),
(
'a0000000-0000-0000-0000-000000000002',
'00000000-0000-0000-0000-000000000001',
NULL,
'用户分析报表 - 近30天',
'用户增长、活跃度、留存率分析',
'users',
'30d',
CURRENT_DATE - 30,
CURRENT_DATE,
'ready',
NOW() - INTERVAL '2 hours',
NOW() - INTERVAL '5 days',
NOW() - INTERVAL '2 hours'
),
(
'a0000000-0000-0000-0000-000000000003',
'00000000-0000-0000-0000-000000000001',
'10000000-0000-0000-0000-000000000001',
'商家销售报表 - 近90天',
'商家A的销售表现分析',
'sales',
'90d',
CURRENT_DATE - 90,
CURRENT_DATE,
'ready',
NOW() - INTERVAL '30 minutes',
NOW() - INTERVAL '10 days',
NOW() - INTERVAL '30 minutes'
)
ON CONFLICT (id) DO NOTHING;
-- 2.3 报表核心指标(为第一个报表生成)
INSERT INTO analytics_report_metrics (
id, report_id, metric_key, metric_label, metric_value_num, metric_value_text,
format, change_pct, icon, color, created_at
)
VALUES
(
gen_random_uuid(),
'a0000000-0000-0000-0000-000000000001',
'gmv',
'GMV',
125680.50,
NULL,
'currency',
15.6,
'money',
'#3b82f6',
NOW()
),
(
gen_random_uuid(),
'a0000000-0000-0000-0000-000000000001',
'orders',
'订单量',
856,
NULL,
'number',
12.3,
'list',
'#10b981',
NOW()
),
(
gen_random_uuid(),
'a0000000-0000-0000-0000-000000000001',
'conversion_rate',
'转化率',
3.45,
NULL,
'percent',
0.8,
'trend',
'#f59e0b',
NOW()
),
(
gen_random_uuid(),
'a0000000-0000-0000-0000-000000000001',
'avg_order_amount',
'客单价',
146.82,
NULL,
'currency',
-2.1,
'wallet',
'#8b5cf6',
NOW()
)
ON CONFLICT DO NOTHING;
-- 2.4 报表明细行趋势数据为第一个报表生成过去7天的数据
DO $$
DECLARE
i INTEGER;
row_date DATE;
report_id_val UUID := 'a0000000-0000-0000-0000-000000000001';
BEGIN
FOR i IN 0..6 LOOP
row_date := CURRENT_DATE - (6 - i);
INSERT INTO analytics_report_rows (
id, report_id, row_date, gmv, orders, users, conversion, avg_order_amount, extra, created_at
)
VALUES (
gen_random_uuid(),
report_id_val,
row_date,
(15000 + (i * 2000) + (random() * 3000))::numeric(10,2),
(100 + (i * 15) + floor(random() * 30))::integer,
(80 + (i * 10) + floor(random() * 20))::integer,
(3.0 + (i * 0.1) + (random() * 0.5))::numeric(5,2),
(140 + (i * 2) + (random() * 20))::numeric(10,2),
'{}'::jsonb,
NOW()
)
ON CONFLICT DO NOTHING;
END LOOP;
END $$;
-- 2.5 数据洞察为第一个报表生成3条洞察
INSERT INTO analytics_insights (
id, report_id, owner_user_id, type, impact, title, content, tags, created_at
)
VALUES
(
gen_random_uuid(),
'a0000000-0000-0000-0000-000000000001',
'00000000-0000-0000-0000-000000000001',
'positive',
'high',
'GMV持续增长',
'近7天GMV较上周期增长15.6%,主要得益于新用户增长和促销活动',
ARRAY['销售', '增长']::text[],
NOW() - INTERVAL '1 hour'
),
(
gen_random_uuid(),
'a0000000-0000-0000-0000-000000000001',
'00000000-0000-0000-0000-000000000001',
'warning',
'medium',
'客单价略有下降',
'客单价较上周期下降2.1%,建议关注高价值商品推广',
ARRAY['客单价', '预警']::text[],
NOW() - INTERVAL '1 hour'
),
(
gen_random_uuid(),
'a0000000-0000-0000-0000-000000000001',
'00000000-0000-0000-0000-000000000001',
'info',
'low',
'转化率稳定',
'转化率保持在3.45%,与行业平均水平相当',
ARRAY['转化率']::text[],
NOW() - INTERVAL '1 hour'
)
ON CONFLICT DO NOTHING;
-- 2.6 报表收藏
INSERT INTO analytics_report_favorites (id, user_id, report_id, created_at)
VALUES
(
gen_random_uuid(),
'00000000-0000-0000-0000-000000000001',
'a0000000-0000-0000-0000-000000000001',
NOW() - INTERVAL '1 day'
),
(
gen_random_uuid(),
'00000000-0000-0000-0000-000000000001',
'a0000000-0000-0000-0000-000000000002',
NOW() - INTERVAL '2 days'
)
ON CONFLICT (user_id, report_id) DO NOTHING;
-- 2.7 导出任务历史
INSERT INTO analytics_export_jobs (
id, user_id, report_id, format, status, file_path, error_message, created_at, finished_at
)
VALUES
(
gen_random_uuid(),
'00000000-0000-0000-0000-000000000001',
'a0000000-0000-0000-0000-000000000001',
'xlsx',
'done',
'exports/report_001.xlsx',
'',
NOW() - INTERVAL '3 days',
NOW() - INTERVAL '3 days' + INTERVAL '5 minutes'
),
(
gen_random_uuid(),
'00000000-0000-0000-0000-000000000001',
'a0000000-0000-0000-0000-000000000002',
'pdf',
'done',
'exports/report_002.pdf',
'',
NOW() - INTERVAL '1 day',
NOW() - INTERVAL '1 day' + INTERVAL '2 minutes'
),
(
gen_random_uuid(),
'00000000-0000-0000-0000-000000000001',
'a0000000-0000-0000-0000-000000000003',
'csv',
'running',
NULL,
'',
NOW() - INTERVAL '10 minutes',
NULL
)
ON CONFLICT DO NOTHING;
-- ============================================
-- 3. 补充报表明细行(为其他报表生成数据)
-- ============================================
-- 为第二个报表用户分析报表生成过去30天的趋势数据
DO $$
DECLARE
i INTEGER;
row_date DATE;
report_id_val UUID := 'a0000000-0000-0000-0000-000000000002';
BEGIN
FOR i IN 0..29 LOOP
row_date := CURRENT_DATE - (29 - i);
INSERT INTO analytics_report_rows (
id, report_id, row_date, gmv, orders, users, conversion, avg_order_amount, extra, created_at
)
VALUES (
gen_random_uuid(),
report_id_val,
row_date,
(18000 + (i * 500) + (random() * 2000))::numeric(10,2),
(120 + (i * 3) + floor(random() * 20))::integer,
(90 + (i * 2) + floor(random() * 15))::integer,
(3.2 + (i * 0.05) + (random() * 0.3))::numeric(5,2),
(150 + (i * 1) + (random() * 30))::numeric(10,2),
'{}'::jsonb,
NOW()
)
ON CONFLICT DO NOTHING;
END LOOP;
END $$;
-- 为第三个报表商家销售报表生成过去90天的趋势数据
DO $$
DECLARE
i INTEGER;
row_date DATE;
report_id_val UUID := 'a0000000-0000-0000-0000-000000000003';
BEGIN
FOR i IN 0..89 LOOP
row_date := CURRENT_DATE - (89 - i);
INSERT INTO analytics_report_rows (
id, report_id, row_date, gmv, orders, users, conversion, avg_order_amount, extra, created_at
)
VALUES (
gen_random_uuid(),
report_id_val,
row_date,
(20000 + (i * 100) + (random() * 3000))::numeric(10,2),
(150 + (i * 1) + floor(random() * 30))::integer,
(100 + (i * 1) + floor(random() * 20))::integer,
(3.5 + (i * 0.01) + (random() * 0.4))::numeric(5,2),
(130 + (i * 0.5) + (random() * 40))::numeric(10,2),
'{}'::jsonb,
NOW()
)
ON CONFLICT DO NOTHING;
END LOOP;
END $$;
-- ============================================
-- 完成
-- ============================================
SELECT 'Analytics test data seed completed!' AS message;