-- ============================================= -- 优惠券分析测试数据 Seed(至少 20 条样本) -- 说明: -- - 依赖表:coupon_templates, user_coupons, coupon_usage_logs, users, merchants, orders -- - 用于驱动 /pages/mall/analytics/coupon-analysis.uvue 页面联调 -- - 设计目标: -- - 8 种券类型覆盖(满减/折扣/免运费/新人/会员/品类/商家/限时) -- - 6 种发放渠道覆盖(manual/auto/campaign/invite/cs/points) -- - 最近 30 天有发放 + 使用 + 未使用 + 即将到期券 -- - 可重复执行:通过 WHERE NOT EXISTS / 固定模板名称 避免重复插入 -- ============================================= -- 1) 准备一个测试商家(如不存在则创建) INSERT INTO public.merchants (id, shop_name, created_at) SELECT '30000000-0000-0000-0000-000000000001'::uuid, '优惠券测试商家', now() - interval '60 days' WHERE NOT EXISTS ( SELECT 1 FROM public.merchants WHERE id = '30000000-0000-0000-0000-000000000001' ); -- 2) 准备 3 个测试用户(如不存在则创建) INSERT INTO public.users (id, phone, email, nickname, created_at) VALUES ('40000000-0000-0000-0000-000000000001'::uuid, '13900001001', 'coupon_user1@test.com', '券用户1', now() - interval '30 days'), ('40000000-0000-0000-0000-000000000002'::uuid, '13900001002', 'coupon_user2@test.com', '券用户2', now() - interval '20 days'), ('40000000-0000-0000-0000-000000000003'::uuid, '13900001003', 'coupon_user3@test.com', '券用户3', now() - interval '10 days') ON CONFLICT (id) DO NOTHING; -- 3) 插入 8 个优惠券模板(覆盖 mall.md 的 8 种类型) INSERT INTO public.coupon_templates ( id, name, description, coupon_type, discount_type, discount_value, min_order_amount, max_discount_amount, total_quantity, per_user_limit, usage_limit, merchant_id, start_time, end_time, status, created_at ) VALUES ('50000000-0000-0000-0000-000000000001'::uuid, '满100减20', '满100减20元', 1, 1, 20.00, 100.00, NULL, 1000, 3, 1, '30000000-0000-0000-0000-000000000001', now() - interval '30 days', now() + interval '30 days', 1, now() - interval '30 days'), ('50000000-0000-0000-0000-000000000002'::uuid, '9折优惠券', '全场9折', 2, 2, 9.00, 0.00, 50.00, 1000, 3, 1, '30000000-0000-0000-0000-000000000001', now() - interval '30 days', now() + interval '30 days', 1, now() - interval '30 days'), ('50000000-0000-0000-0000-000000000003'::uuid, '免运费券', '免配送费', 3, 3, 0.00, 0.00, 10.00, 1000, 5, 1, '30000000-0000-0000-0000-000000000001', now() - interval '30 days', now() + interval '30 days', 1, now() - interval '30 days'), ('50000000-0000-0000-0000-000000000004'::uuid, '新人专享满50减25', '新用户首单优惠', 4, 1, 25.00, 50.00, NULL, 500, 1, 1, '30000000-0000-0000-0000-000000000001', now() - interval '15 days', now() + interval '45 days', 1, now() - interval '15 days'), ('50000000-0000-0000-0000-000000000005'::uuid, '会员折扣券', '会员专享8.5折', 5, 2, 8.50, 0.00, 80.00, 500, 5, 1, '30000000-0000-0000-0000-000000000001', now() - interval '20 days', now() + interval '40 days', 1, now() - interval '20 days'), ('50000000-0000-0000-0000-000000000006'::uuid, '生鲜品类券', '生鲜类满60减15', 6, 1, 15.00, 60.00, NULL, 500, 3, 1, '30000000-0000-0000-0000-000000000001', now() - interval '25 days', now() + interval '35 days', 1, now() - interval '25 days'), ('50000000-0000-0000-0000-000000000007'::uuid, '商家专属券', '指定商家满80减30', 7, 1, 30.00, 80.00, NULL, 300, 3, 1, '30000000-0000-0000-0000-000000000001', now() - interval '10 days', now() + interval '50 days', 1, now() - interval '10 days'), ('50000000-0000-0000-0000-000000000008'::uuid, '限时秒杀券', '限时满40减10', 8, 1, 10.00, 40.00, NULL, 300, 2, 1, '30000000-0000-0000-0000-000000000001', now() - interval '5 days', now() + interval '10 days', 1, now() - interval '5 days') ON CONFLICT (id) DO NOTHING; -- 4) 生成用户优惠券 + 使用数据 DO $$ DECLARE v_users uuid[] := ARRAY[ '40000000-0000-0000-0000-000000000001'::uuid, '40000000-0000-0000-0000-000000000002'::uuid, '40000000-0000-0000-0000-000000000003'::uuid ]; v_templates uuid[] := ARRAY[ '50000000-0000-0000-0000-000000000001'::uuid, '50000000-0000-0000-0000-000000000002'::uuid, '50000000-0000-0000-0000-000000000003'::uuid, '50000000-0000-0000-0000-000000000004'::uuid, '50000000-0000-0000-0000-000000000005'::uuid, '50000000-0000-0000-0000-000000000006'::uuid, '50000000-0000-0000-0000-000000000007'::uuid, '50000000-0000-0000-0000-000000000008'::uuid ]; v_channels text[] := ARRAY['manual','auto','campaign','invite','cs','points']; i int; j int; v_uc_id uuid; v_user uuid; v_tpl uuid; v_channel text; v_received_at timestamptz; v_expire_at timestamptz; v_order_id uuid; v_order_amount numeric; v_discount_amount numeric; v_used_at timestamptz; BEGIN -- 为最近 30 天生成多条券(部分使用,部分未使用,部分即将到期) FOR i IN 0..29 LOOP -- 当天发放 2~4 条券 FOR j IN 1..(2 + (i % 3)) LOOP v_user := v_users[1 + (i + j) % array_length(v_users, 1)]; v_tpl := v_templates[1 + (i + j) % array_length(v_templates, 1)]; v_channel := v_channels[1 + (i + j) % array_length(v_channels, 1)]; v_received_at := (now() - (i || ' days')::interval); v_expire_at := v_received_at + interval '20 days'; -- 通过 coupon_code 幂等插入,并返回最终 id(避免 ON CONFLICT DO NOTHING 导致 v_uc_id 无对应记录) INSERT INTO public.user_coupons ( id, user_id, template_id, coupon_code, status, received_at, expire_at, obtain_channel, merchant_id ) VALUES ( gen_random_uuid(), v_user, v_tpl, 'TESTCOUPON-' || i || '-' || j, 1, -- 初始未使用 v_received_at, v_expire_at, v_channel, '30000000-0000-0000-0000-000000000001'::uuid ) ON CONFLICT (coupon_code) DO UPDATE SET user_id = EXCLUDED.user_id, template_id = EXCLUDED.template_id, received_at = EXCLUDED.received_at, expire_at = EXCLUDED.expire_at, obtain_channel= EXCLUDED.obtain_channel, merchant_id = EXCLUDED.merchant_id RETURNING id INTO v_uc_id; -- 约一半的券会在 0~10 天内被使用,生成对应订单和使用记录 IF (i + j) % 2 = 0 THEN v_order_id := gen_random_uuid(); v_order_amount := 50 + (10 * ((i + j) % 5)); -- 50~90 的订单金额 v_discount_amount := CASE WHEN (i + j) % 4 = 0 THEN 10 WHEN (i + j) % 4 = 1 THEN 15 WHEN (i + j) % 4 = 2 THEN 20 ELSE 5 END; v_used_at := v_received_at + ( (1 + (i % 5)) || ' days')::interval; -- 插入订单 INSERT INTO public.orders ( id, user_id, merchant_id, total_amount, status, created_at, updated_at ) VALUES ( v_order_id, v_user, '30000000-0000-0000-0000-000000000001'::uuid, v_order_amount, 2, -- 已完成 v_used_at, v_used_at ) ON CONFLICT (id) DO NOTHING; -- 更新 user_coupons 为已使用(确认对应记录存在) UPDATE public.user_coupons SET status = 2, used_at = v_used_at, order_id = v_order_id WHERE id = v_uc_id; -- 插入使用流水(仅当对应 user_coupon 存在时生效) INSERT INTO public.coupon_usage_logs ( id, user_coupon_id, order_id, discount_amount, used_at, user_id, template_id, merchant_id, order_amount, created_at ) VALUES ( gen_random_uuid(), v_uc_id, v_order_id, v_discount_amount, v_used_at, v_user, v_tpl, '30000000-0000-0000-0000-000000000001'::uuid, v_order_amount, v_used_at ); END IF; END LOOP; END LOOP; END; $$; -- 完成 SELECT 'coupon test data seed completed!' AS message;