Files
medical-mall/sql/seed_medical_homepage_data.sql

576 lines
40 KiB
PL/PgSQL
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.
-- 医疗项目首页种子数据
-- 目标:补齐首页分类栏 + 首页商品流所需的基础数据
-- 适用public.ml_categories / public.ml_brands / public.ml_products / public.ml_shops / public.ak_users
-- 说明:
-- 1. 首页分类栏读取 ml_categories
-- 2. 首页商品流主要读取 ml_products_detail_view底层为 ml_products 联表)
-- 3. 本脚本可重复执行,使用固定 UUID + ON CONFLICT 保持幂等
-- 4. 服务首页当前仍是本地 mock本脚本只覆盖“商城首页”数据
BEGIN;
DO $$
DECLARE
v_has_role BOOLEAN := FALSE;
v_has_email BOOLEAN := FALSE;
v_has_username BOOLEAN := FALSE;
v_has_phone BOOLEAN := FALSE;
v_has_avatar_url BOOLEAN := FALSE;
v_has_status BOOLEAN := FALSE;
v_has_registration_source BOOLEAN := FALSE;
v_has_nickname BOOLEAN := FALSE;
v_has_real_name BOOLEAN := FALSE;
v_has_created_at BOOLEAN := FALSE;
v_has_updated_at BOOLEAN := FALSE;
v_cols TEXT;
v_vals TEXT;
v_index INTEGER;
v_merchant_ids UUID[] := ARRAY[
'5f0e7c4d-7c8a-4f6f-9a16-100000000001'::uuid,
'5f0e7c4d-7c8a-4f6f-9a16-100000000002'::uuid,
'5f0e7c4d-7c8a-4f6f-9a16-100000000003'::uuid,
'5f0e7c4d-7c8a-4f6f-9a16-100000000004'::uuid,
'5f0e7c4d-7c8a-4f6f-9a16-100000000005'::uuid,
'5f0e7c4d-7c8a-4f6f-9a16-100000000006'::uuid
];
v_usernames TEXT[] := ARRAY['医疗首页商家01', '医疗首页商家02', '医疗首页商家03', '医疗首页商家04', '医疗首页商家05', '医疗首页商家06'];
v_nicknames TEXT[] := ARRAY['康养精选商家', '慢病管理商家', '营养保健商家', '康复护理商家', '本草调理商家', '银龄照护商家'];
v_real_names TEXT[] := ARRAY['康养医疗馆', '慢病健康馆', '营养优选馆', '康复护理馆', '本草调理馆', '银龄照护馆'];
v_emails TEXT[] := ARRAY['seed.medical.home01@local.test', 'seed.medical.home02@local.test', 'seed.medical.home03@local.test', 'seed.medical.home04@local.test', 'seed.medical.home05@local.test', 'seed.medical.home06@local.test'];
v_phones TEXT[] := ARRAY['13900000001', '13900000002', '13900000003', '13900000004', '13900000005', '13900000006'];
BEGIN
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'role'
) INTO v_has_role;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'email'
) INTO v_has_email;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'username'
) INTO v_has_username;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'phone'
) INTO v_has_phone;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'avatar_url'
) INTO v_has_avatar_url;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'status'
) INTO v_has_status;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'registration_source'
) INTO v_has_registration_source;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'nickname'
) INTO v_has_nickname;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'real_name'
) INTO v_has_real_name;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'created_at'
) INTO v_has_created_at;
SELECT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'ak_users' AND column_name = 'updated_at'
) INTO v_has_updated_at;
FOR v_index IN 1..array_length(v_merchant_ids, 1) LOOP
v_cols := 'id';
v_vals := quote_literal(v_merchant_ids[v_index]::text) || '::uuid';
IF v_has_email THEN
v_cols := v_cols || ', email';
v_vals := v_vals || ', ' || quote_literal(v_emails[v_index]);
END IF;
IF v_has_username THEN
v_cols := v_cols || ', username';
v_vals := v_vals || ', ' || quote_literal(v_usernames[v_index]);
END IF;
IF v_has_nickname THEN
v_cols := v_cols || ', nickname';
v_vals := v_vals || ', ' || quote_literal(v_nicknames[v_index]);
END IF;
IF v_has_real_name THEN
v_cols := v_cols || ', real_name';
v_vals := v_vals || ', ' || quote_literal(v_real_names[v_index]);
END IF;
IF v_has_role THEN
v_cols := v_cols || ', role';
v_vals := v_vals || ', ''merchant''';
END IF;
IF v_has_phone THEN
v_cols := v_cols || ', phone';
v_vals := v_vals || ', ' || quote_literal(v_phones[v_index]);
END IF;
IF v_has_avatar_url THEN
v_cols := v_cols || ', avatar_url';
v_vals := v_vals || ', ' || quote_literal('https://picsum.photos/seed/medical-merchant-avatar-' || v_index::text || '/240/240');
END IF;
IF v_has_status THEN
v_cols := v_cols || ', status';
v_vals := v_vals || ', ''active''';
END IF;
IF v_has_registration_source THEN
v_cols := v_cols || ', registration_source';
v_vals := v_vals || ', ''seed''';
END IF;
IF v_has_created_at THEN
v_cols := v_cols || ', created_at';
v_vals := v_vals || ', NOW()';
END IF;
IF v_has_updated_at THEN
v_cols := v_cols || ', updated_at';
v_vals := v_vals || ', NOW()';
END IF;
EXECUTE 'INSERT INTO public.ak_users (' || v_cols || ') VALUES (' || v_vals || ') ON CONFLICT (id) DO NOTHING';
END LOOP;
END $$;
INSERT INTO public.ml_shops (
merchant_id,
shop_name,
shop_logo,
description,
contact_name,
contact_phone,
status,
product_count,
rating_avg,
rating_count,
created_at,
updated_at
)
VALUES
('5f0e7c4d-7c8a-4f6f-9a16-100000000001', '康养医疗精选馆', 'https://picsum.photos/seed/medical-shop-logo-01/320/320', '主打家庭常备药与家用监测器械。', '康养精选商家', '13900000001', 1, 10, 4.8, 268, NOW(), NOW()),
('5f0e7c4d-7c8a-4f6f-9a16-100000000002', '安心慢病管理馆', 'https://picsum.photos/seed/medical-shop-logo-02/320/320', '覆盖慢病监测、呼吸护理与居家健康管理。', '慢病管理商家', '13900000002', 1, 10, 4.7, 196, NOW(), NOW()),
('5f0e7c4d-7c8a-4f6f-9a16-100000000003', '益寿营养保健馆', 'https://picsum.photos/seed/medical-shop-logo-03/320/320', '面向骨骼营养、免疫支持与恢复期补充。', '营养保健商家', '13900000003', 1, 10, 4.8, 212, NOW(), NOW()),
('5f0e7c4d-7c8a-4f6f-9a16-100000000004', '术后康复护理馆', 'https://picsum.photos/seed/medical-shop-logo-04/320/320', '提供术后恢复、伤口护理和家庭康复用品。', '康复护理商家', '13900000004', 1, 10, 4.9, 184, NOW(), NOW()),
('5f0e7c4d-7c8a-4f6f-9a16-100000000005', '本草理疗调养馆', 'https://picsum.photos/seed/medical-shop-logo-05/320/320', '主打艾灸理疗、草本贴敷和中式调理商品。', '本草调理商家', '13900000005', 1, 10, 4.7, 173, NOW(), NOW()),
('5f0e7c4d-7c8a-4f6f-9a16-100000000006', '银龄居家照护馆', 'https://picsum.photos/seed/medical-shop-logo-06/320/320', '覆盖长者行动辅助和居家安全防护商品。', '银龄照护商家', '13900000006', 1, 10, 4.8, 205, NOW(), NOW())
ON CONFLICT (merchant_id) DO UPDATE SET
shop_name = EXCLUDED.shop_name,
shop_logo = EXCLUDED.shop_logo,
description = EXCLUDED.description,
contact_name = EXCLUDED.contact_name,
contact_phone = EXCLUDED.contact_phone,
status = EXCLUDED.status,
product_count = EXCLUDED.product_count,
rating_avg = EXCLUDED.rating_avg,
rating_count = EXCLUDED.rating_count,
updated_at = NOW();
INSERT INTO public.ml_brands (id, name, logo_url, description, website, is_active, created_at, updated_at)
VALUES
('6f0e7c4d-7c8a-4f6f-9a16-200000000001', '康宁健康', 'https://picsum.photos/seed/brand-kangning/240/240', '家庭医疗器械与健康监测品牌', 'https://example.com/brands/kangning', TRUE, NOW(), NOW()),
('6f0e7c4d-7c8a-4f6f-9a16-200000000002', '益寿本草', 'https://picsum.photos/seed/brand-yishou/240/240', '中医调理与养护品牌', 'https://example.com/brands/yishou', TRUE, NOW(), NOW()),
('6f0e7c4d-7c8a-4f6f-9a16-200000000003', '安护优选', 'https://picsum.photos/seed/brand-anhu/240/240', '康复护理与长者照护品牌', 'https://example.com/brands/anhu', TRUE, NOW(), NOW()),
('6f0e7c4d-7c8a-4f6f-9a16-200000000004', '呼吸康泰', 'https://picsum.photos/seed/brand-huxi/240/240', '呼吸护理与慢病监测设备品牌', 'https://example.com/brands/huxi', TRUE, NOW(), NOW()),
('6f0e7c4d-7c8a-4f6f-9a16-200000000005', '乐龄守护', 'https://picsum.photos/seed/brand-laoling/240/240', '银龄照护与辅助出行品牌', 'https://example.com/brands/laoling', TRUE, NOW(), NOW()),
('6f0e7c4d-7c8a-4f6f-9a16-200000000006', '家庭医伴', 'https://picsum.photos/seed/brand-yiban/240/240', '家庭常备药与日用健康用品品牌', 'https://example.com/brands/yiban', TRUE, NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
logo_url = EXCLUDED.logo_url,
description = EXCLUDED.description,
website = EXCLUDED.website,
is_active = EXCLUDED.is_active,
updated_at = NOW();
INSERT INTO public.ml_categories (
id, parent_id, name, slug, description, icon_url, banner_url, sort_order, level, path, is_active, seo_title, seo_description, created_at, updated_at
)
VALUES
('7f0e7c4d-7c8a-4f6f-9a16-300000000001', NULL, '常用药品', 'medical-common-medicine', '面向家庭常备、感冒发热、肠胃不适等常见场景的药品分类', 'https://picsum.photos/seed/cat-common-med/200/200', 'https://picsum.photos/seed/cat-common-med-banner/1200/400', 10, 1, ARRAY['常用药品'], TRUE, '常用药品分类', '家庭常备药、感冒发热、肠胃常用药', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000002', NULL, '医疗器械', 'medical-devices', '覆盖血压计、血糖仪、雾化器等家庭监测设备', 'https://picsum.photos/seed/cat-devices/200/200', 'https://picsum.photos/seed/cat-devices-banner/1200/400', 20, 1, ARRAY['医疗器械'], TRUE, '医疗器械分类', '血压计、血糖仪、雾化器等家庭器械', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000003', NULL, '营养保健', 'nutrition-care', '适合免疫增强、骨关节与长者营养补充的保健类商品', 'https://picsum.photos/seed/cat-nutrition/200/200', 'https://picsum.photos/seed/cat-nutrition-banner/1200/400', 30, 1, ARRAY['营养保健'], TRUE, '营养保健分类', '蛋白粉、钙片、维生素等营养保健品', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000004', NULL, '康复护理', 'rehab-care', '适合术后恢复、慢病管理和家庭护理的康复用品', 'https://picsum.photos/seed/cat-rehab/200/200', 'https://picsum.photos/seed/cat-rehab-banner/1200/400', 40, 1, ARRAY['康复护理'], TRUE, '康复护理分类', '术后恢复、压疮护理、日常护理用品', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000005', NULL, '中医调理', 'tcm-care', '包含理疗贴、艾灸养护和中式调理产品', 'https://picsum.photos/seed/cat-tcm/200/200', 'https://picsum.photos/seed/cat-tcm-banner/1200/400', 50, 1, ARRAY['中医调理'], TRUE, '中医调理分类', '艾灸、穴位贴、草本调理产品', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000006', NULL, '老年照护', 'elder-care', '适合长者居家照护、安全防护和辅助生活的商品', 'https://picsum.photos/seed/cat-elder/200/200', 'https://picsum.photos/seed/cat-elder-banner/1200/400', 60, 1, ARRAY['老年照护'], TRUE, '老年照护分类', '轮椅、助行器、防跌用品等长者照护商品', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000101', '7f0e7c4d-7c8a-4f6f-9a16-300000000001', '感冒发热', 'cold-fever', '退热、止痛、感冒常备药', 'https://picsum.photos/seed/sub-cold-fever/200/200', NULL, 11, 2, ARRAY['常用药品','感冒发热'], TRUE, '感冒发热用药', '适用于家庭常备的感冒发热场景', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000102', '7f0e7c4d-7c8a-4f6f-9a16-300000000001', '肠胃调理', 'digestive-care', '适合肠胃不适和日常调理', 'https://picsum.photos/seed/sub-digestive/200/200', NULL, 12, 2, ARRAY['常用药品','肠胃调理'], TRUE, '肠胃调理用药', '肠胃调理及胃肠不适场景用药', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000201', '7f0e7c4d-7c8a-4f6f-9a16-300000000002', '血压监测', 'blood-pressure-monitoring', '家庭血压监测设备', 'https://picsum.photos/seed/sub-bp/200/200', NULL, 21, 2, ARRAY['医疗器械','血压监测'], TRUE, '血压监测设备', '适用于家庭与长者的血压监测设备', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000202', '7f0e7c4d-7c8a-4f6f-9a16-300000000002', '呼吸理疗', 'respiratory-care', '雾化与呼吸辅助设备', 'https://picsum.photos/seed/sub-respiratory/200/200', NULL, 22, 2, ARRAY['医疗器械','呼吸理疗'], TRUE, '呼吸理疗设备', '雾化器、制氧及呼吸辅助商品', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000301', '7f0e7c4d-7c8a-4f6f-9a16-300000000003', '骨骼营养', 'bone-nutrition', '钙、维生素 D 等骨骼关节营养商品', 'https://picsum.photos/seed/sub-bone/200/200', NULL, 31, 2, ARRAY['营养保健','骨骼营养'], TRUE, '骨骼营养补充', '适合中老年与骨骼健康场景', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000302', '7f0e7c4d-7c8a-4f6f-9a16-300000000003', '免疫支持', 'immune-support', '蛋白、维生素与免疫支持产品', 'https://picsum.photos/seed/sub-immune/200/200', NULL, 32, 2, ARRAY['营养保健','免疫支持'], TRUE, '免疫支持营养', '适合日常营养补充与免疫支持', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000401', '7f0e7c4d-7c8a-4f6f-9a16-300000000004', '术后恢复', 'post-surgery-recovery', '适用于术后恢复阶段的护理产品', 'https://picsum.photos/seed/sub-postop/200/200', NULL, 41, 2, ARRAY['康复护理','术后恢复'], TRUE, '术后恢复护理', '术后康复、恢复期护理场景', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000402', '7f0e7c4d-7c8a-4f6f-9a16-300000000004', '伤口护理', 'wound-care', '敷料、护理包和伤口辅助用品', 'https://picsum.photos/seed/sub-wound/200/200', NULL, 42, 2, ARRAY['康复护理','伤口护理'], TRUE, '伤口护理用品', '家庭和术后伤口护理场景用品', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000501', '7f0e7c4d-7c8a-4f6f-9a16-300000000005', '艾灸理疗', 'moxa-therapy', '艾灸盒、艾条和温灸护理商品', 'https://picsum.photos/seed/sub-moxa/200/200', NULL, 51, 2, ARRAY['中医调理','艾灸理疗'], TRUE, '艾灸理疗用品', '家庭艾灸、温灸理疗商品', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000502', '7f0e7c4d-7c8a-4f6f-9a16-300000000005', '草本贴敷', 'herbal-patch', '草本热敷、穴位贴与理疗贴', 'https://picsum.photos/seed/sub-herbal-patch/200/200', NULL, 52, 2, ARRAY['中医调理','草本贴敷'], TRUE, '草本贴敷用品', '肩颈腰腿舒缓与理疗贴类商品', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000601', '7f0e7c4d-7c8a-4f6f-9a16-300000000006', '行动辅助', 'mobility-aid', '轮椅、助行器和起身辅助用品', 'https://picsum.photos/seed/sub-mobility/200/200', NULL, 61, 2, ARRAY['老年照护','行动辅助'], TRUE, '行动辅助用品', '长者安全出行与行动辅助商品', NOW(), NOW()),
('7f0e7c4d-7c8a-4f6f-9a16-300000000602', '7f0e7c4d-7c8a-4f6f-9a16-300000000006', '居家防护', 'home-safety', '防滑、防跌和床旁安全辅助用品', 'https://picsum.photos/seed/sub-home-safety/200/200', NULL, 62, 2, ARRAY['老年照护','居家防护'], TRUE, '居家防护用品', '适合长者家庭安全防护场景', NOW(), NOW())
ON CONFLICT (id) DO UPDATE SET
parent_id = EXCLUDED.parent_id,
name = EXCLUDED.name,
slug = EXCLUDED.slug,
description = EXCLUDED.description,
icon_url = EXCLUDED.icon_url,
banner_url = EXCLUDED.banner_url,
sort_order = EXCLUDED.sort_order,
level = EXCLUDED.level,
path = EXCLUDED.path,
is_active = EXCLUDED.is_active,
seo_title = EXCLUDED.seo_title,
seo_description = EXCLUDED.seo_description,
updated_at = NOW();
WITH seed_templates AS (
SELECT *
FROM (
VALUES
(1, '5f0e7c4d-7c8a-4f6f-9a16-100000000001'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000006'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000101'::uuid, '家庭退热护理贴', '家庭常备退热护理,适合儿童与成人', '常用药品', 29.90, 4.50, 0.12, ARRAY['退热护理','家庭常备','首页推荐']::text[], '8片/盒', '直接贴敷于额头或太阳穴附近', '皮肤破损处慎用', '24个月', '阴凉干燥处保存', '粤械注准20261', '夜间应急降温与陪护', '儿童发热、成人低烧与家庭药箱场景', '家庭药箱、值班陪护、夜间临时应对', '贴敷型物理护理,不占用口服用药节奏'),
(2, '5f0e7c4d-7c8a-4f6f-9a16-100000000001'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000006'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000102'::uuid, '草本暖胃调理贴', '腹部热敷舒缓,适合肠胃日常调理', '常用药品', 42.00, 5.00, 0.10, ARRAY['肠胃调理','草本贴敷','居家护理']::text[], '6贴/盒', '贴于腹部不适区域每次4至6小时', '避免高温环境使用', '24个月', '阴凉处保存', '粤械注准20262', '餐后腹部热敷与换季调理', '久坐人群、饮食不规律人群与女性日常护理', '办公室抽屉、宿舍常备、出差随身护理', '贴敷型胃腹护理,更适合连续日常使用'),
(3, '5f0e7c4d-7c8a-4f6f-9a16-100000000002'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000001'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000201'::uuid, '智能血压监测仪', '语音播报与大屏显示,适合居家监测', '医疗器械', 199.00, 18.00, 0.85, ARRAY['血压监测','家用器械','老人适用']::text[], '1台/盒', '绑好袖带后按开始键测量', '测量前请静坐5分钟', '长期', '干燥处保存', '粤械注准20263', '居家晨晚双时段血压记录', '长者家庭、慢病管理用户与社区随访场景', '卧室床头、客厅药柜、社区义诊随身箱', '适合作为家庭监测主设备,强调读数稳定和易读性'),
(4, '5f0e7c4d-7c8a-4f6f-9a16-100000000002'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000004'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000202'::uuid, '静音雾化护理机', '家庭呼吸理疗,适合儿童与长者', '医疗器械', 239.00, 22.00, 1.20, ARRAY['呼吸护理','静音雾化','家庭理疗']::text[], '1台/盒', '加注溶液后按说明启动', '使用后及时清洁雾化杯', '长期', '干燥处保存', '粤械注准20264', '换季敏感期与夜间呼吸护理', '儿童鼻咽不适、长者呼吸护理与家庭理疗用户', '床旁护理区、儿童房、家庭护理角', '雾化颗粒更细,适合家庭安静环境连续使用'),
(5, '5f0e7c4d-7c8a-4f6f-9a16-100000000003'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000002'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000301'::uuid, '高钙维D营养片', '骨骼营养补充,适合中老年日常使用', '营养保健', 79.00, 7.00, 0.28, ARRAY['骨骼营养','维D补充','长者营养']::text[], '60片/瓶', '每日1至2片咀嚼后吞服', '勿超过推荐量服用', '24个月', '阴凉干燥处保存', '食健备G20265', '骨骼基础营养与长期补给', '中老年、久坐办公族与骨密度关注人群', '早餐后补充、家庭常备营养角、长周期回购', '更适合做月度补给型商品,强调长期规律使用'),
(6, '5f0e7c4d-7c8a-4f6f-9a16-100000000003'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000006'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000302'::uuid, '乳清蛋白营养粉', '恢复期与长者补充营养更省心', '营养保健', 168.00, 15.00, 0.90, ARRAY['免疫支持','高蛋白','恢复期']::text[], '900g/罐', '温水冲调每次20至30g', '开封后尽快食用', '18个月', '密封避光保存', '食健备G20266', '术后恢复与日常增补蛋白', '恢复期、体质偏弱、食量不足与长者营养支持人群', '早餐代餐、术后陪护、营养加餐和睡前补给', '更适合搭配恢复期护理场景,强调蛋白摄入效率'),
(7, '5f0e7c4d-7c8a-4f6f-9a16-100000000004'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000003'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000401'::uuid, '术后支撑恢复带', '弹性支撑设计,辅助日常活动恢复', '康复护理', 128.00, 12.00, 0.42, ARRAY['术后恢复','支撑护具','康复护理']::text[], '1件/盒', '按说明固定于腰腹或术后恢复部位', '过紧佩戴会影响舒适度', '长期', '干燥通风处保存', '粤械注准20267', '术后起身支撑与短程活动辅助', '腹部术后、产后恢复与腰腹支撑需求人群', '住院陪护包、居家恢复期、复查往返途中', '更适合作为恢复阶段核心护理单品,强调支撑稳定'),
(8, '5f0e7c4d-7c8a-4f6f-9a16-100000000004'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000003'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000402'::uuid, '无菌伤口护理包', '含敷料与清洁耗材,家庭护理更方便', '康复护理', 58.00, 6.00, 0.22, ARRAY['伤口护理','无菌敷料','家庭护理']::text[], '1包/套', '按说明进行伤口清洁与覆盖', '严重伤口请及时就医', '24个月', '阴凉干燥处保存', '粤械注准20268', '换药清洁与创面日常防护', '轻度创面护理、术后换药与家庭备用耗材需求人群', '居家药箱、门诊复诊、旅行应急护理包', '耗材组合更完整,适合作为高频消耗型护理商品'),
(9, '5f0e7c4d-7c8a-4f6f-9a16-100000000005'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000002'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000501'::uuid, '家用艾灸温灸盒', '居家温灸理疗,适合肩颈腰腿舒缓', '中医调理', 88.00, 8.00, 0.35, ARRAY['艾灸理疗','居家调理','肩颈舒缓']::text[], '1套/盒', '放入艾柱后按说明固定使用', '避免直接接触烫伤', '长期', '干燥处保存', '粤械注准20269', '肩颈腰腿温灸放松与日常养护', '久坐办公族、居家理疗人群与中式养护偏好用户', '晚间放松、周末理疗、家庭保健角', '理疗氛围感更强,适合作为中式调养类主推单品'),
(10, '5f0e7c4d-7c8a-4f6f-9a16-100000000005'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000002'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000502'::uuid, '肩颈草本热敷贴', '办公居家适用,帮助肩颈腰背舒缓', '中医调理', 49.90, 5.50, 0.16, ARRAY['草本贴敷','肩颈护理','居家理疗']::text[], '10贴/盒', '直接贴于肩颈腰背部位', '睡眠时不建议长时间贴敷', '24个月', '密封避光保存', '粤械注准20270', '久坐肩颈热敷与午后舒缓', '办公久坐、伏案学习与轻度劳损舒缓人群', '办公桌抽屉、车载收纳、差旅随行护理包', '贴敷便捷,适合作为通勤和办公场景高频复购商品'),
(11, '5f0e7c4d-7c8a-4f6f-9a16-100000000006'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000005'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000601'::uuid, '折叠助行辅助器', '轻便稳固,适合长者居家外出', '老年照护', 268.00, 16.00, 2.80, ARRAY['行动辅助','长者照护','安全出行']::text[], '1台/件', '展开后调节合适高度使用', '地面湿滑时请减速慢行', '长期', '干燥环境保存', '粤械注准20271', '长者短距离行走与外出辅助', '腿脚无力长者、术后康复期与家庭陪护人群', '客厅日常使用、社区散步、医院复诊外出', '更适合作为银龄照护大件主推,强调折叠与稳固兼顾'),
(12, '5f0e7c4d-7c8a-4f6f-9a16-100000000006'::uuid, '6f0e7c4d-7c8a-4f6f-9a16-200000000005'::uuid, '7f0e7c4d-7c8a-4f6f-9a16-300000000602'::uuid, '浴室防滑扶手套装', '长者洗浴与走道区域安全防护', '老年照护', 139.00, 11.00, 1.15, ARRAY['居家防护','防跌安全','长者必备']::text[], '2件/套', '安装于浴室或走道墙面', '安装前确认墙面承重', '长期', '常温保存', '粤械注准20272', '洗浴区起身借力与走道安全防护', '居家长者、术后行动不稳人群与家庭照护用户', '卫生间、卧室过道、床边起身点位', '更适合作为居家改造类商品,强调安装场景和防跌价值')
) AS t(template_index, merchant_id, brand_id, category_id, product_prefix, subtitle_base, scene_name, base_price, price_step, base_weight, tags, specification, usage, precautions, expiry_date, storage_conditions, approval_prefix, care_focus, audience_focus, usage_scene, merch_focus)
),
image_map AS (
SELECT *
FROM (
VALUES
(1, 'https://upload.wikimedia.org/wikipedia/commons/2/20/Applying_transdermal_patch.jpg'),
(2, 'https://images.unsplash.com/photo-1773747608435-0fa80d11a32f?q=80&w=627&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'),
(3, 'https://images.unsplash.com/photo-1631815584191-0ed1723f0ead?q=80&w=678&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'),
(4, 'https://images.unsplash.com/photo-1645273474824-1facac10c30c?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'),
(5, 'https://images.unsplash.com/photo-1729700985369-c04bb4557431?q=80&w=687&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'),
(6, 'https://images.unsplash.com/photo-1704650311190-7eeb9c4f6e11?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'),
(7, 'https://images.unsplash.com/photo-1768839725129-98df1d51e4b7?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'),
(8, 'https://images.unsplash.com/photo-1765996796562-ce301df337a0?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'),
(9, 'https://upload.wikimedia.org/wikipedia/commons/f/f2/Ibuki_moxa_set.jpg'),
(10, 'https://upload.wikimedia.org/wikipedia/commons/1/18/Kinesio_taping_on_neck.jpg'),
(11, 'https://upload.wikimedia.org/wikipedia/commons/3/3a/Medical_Walker.JPG'),
(12, 'https://images.unsplash.com/photo-1656646523834-dd1cc57d33c9?q=80&w=1170&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D')
) AS t(template_index, image_url)
),
seed_products AS (
SELECT
('8f0e7c4d-7c8a-4f6f-9a16-' || LPAD((((template_index - 1) * 5) + seq)::text, 12, '0'))::uuid AS id,
merchant_id,
category_id,
brand_id,
format('MEDHOME-20260520-%s', LPAD((((template_index - 1) * 5) + seq)::text, 3, '0')) AS product_code,
product_prefix || CASE seq
WHEN 1 THEN ' 标准款'
WHEN 2 THEN ' 家庭常备装'
WHEN 3 THEN ' 舒适加强款'
WHEN 4 THEN ' 便携随行装'
ELSE ' 臻选礼盒装'
END AS name,
subtitle_base || CASE seq
WHEN 1 THEN ',适合作为日常基础护理选择'
WHEN 2 THEN ',更适合居家储备与多人使用'
WHEN 3 THEN ',覆盖更集中的护理与调理需求'
WHEN 4 THEN ',适合通勤、陪护或外出携带'
ELSE ',兼顾体验感与送礼陈列场景'
END AS subtitle,
scene_name || CASE seq
WHEN 1 THEN '场景常规推荐款,适合门店首页稳定陈列与日常转化。'
WHEN 2 THEN '场景家庭囤货款,强调使用周期更长、备货更省心。'
WHEN 3 THEN '场景强化护理款,适合症状较集中或恢复阶段的重点选择。'
WHEN 4 THEN '场景轻便出行款,方便通勤、探视、陪护和短期外带。'
ELSE '场景升级体验款,适合首页活动位、礼赠位或高客单展示。'
END || ' 核心关注:' || care_focus || '。适用人群:' || audience_focus || '' AS description,
image_map.image_url AS main_image_url,
jsonb_build_array(image_map.image_url) AS image_urls,
'[]'::jsonb AS video_urls,
ROUND((base_price + (
CASE seq
WHEN 1 THEN 0
WHEN 2 THEN price_step * 2.2
WHEN 3 THEN price_step * 4.8
WHEN 4 THEN price_step * 1.1
ELSE price_step * 7.4
END
))::numeric, 2)::numeric(10,2) AS base_price,
ROUND((base_price + (
CASE seq
WHEN 1 THEN price_step * 2.8
WHEN 2 THEN price_step * 5.2
WHEN 3 THEN price_step * 8.0
WHEN 4 THEN price_step * 3.9
ELSE price_step * 11.4
END
))::numeric, 2)::numeric(10,2) AS market_price,
ROUND((base_price + (
CASE seq
WHEN 1 THEN 0
WHEN 2 THEN price_step * 2.2
WHEN 3 THEN price_step * 4.8
WHEN 4 THEN price_step * 1.1
ELSE price_step * 7.4
END
)) * 0.58, 2)::numeric(10,2) AS cost_price,
CASE seq
WHEN 1 THEN 160 + (template_index * 18)
WHEN 2 THEN 240 + (template_index * 24)
WHEN 3 THEN 130 + (template_index * 16)
WHEN 4 THEN 210 + (template_index * 20)
ELSE 96 + (template_index * 12)
END AS total_stock,
CASE seq
WHEN 1 THEN 148 + (template_index * 16)
WHEN 2 THEN 222 + (template_index * 20)
WHEN 3 THEN 118 + (template_index * 14)
WHEN 4 THEN 192 + (template_index * 18)
ELSE 84 + (template_index * 10)
END AS available_stock,
1 AS min_order_qty,
CASE seq
WHEN 1 THEN 3
WHEN 2 THEN 6
WHEN 3 THEN 2
WHEN 4 THEN 2
ELSE 1
END AS max_order_qty,
(base_weight + (
CASE seq
WHEN 1 THEN 0.00
WHEN 2 THEN 0.18
WHEN 3 THEN 0.32
WHEN 4 THEN -0.05
ELSE 0.46
END
))::numeric(10,2) AS weight,
jsonb_build_object(
'length', 16 + template_index + CASE seq WHEN 2 THEN 4 WHEN 3 THEN 2 WHEN 4 THEN -1 ELSE 5 END,
'width', 10 + CASE seq WHEN 2 THEN 3 WHEN 3 THEN 2 WHEN 4 THEN 0 ELSE 4 END,
'height', 4 + CASE seq WHEN 2 THEN 2 WHEN 3 THEN 1 WHEN 4 THEN 0 ELSE 3 END + (template_index / 3)
) AS dimensions,
1 AS status,
CASE WHEN seq IN (1, 2) THEN TRUE ELSE FALSE END AS is_featured,
CASE WHEN seq IN (2, 4, 5) THEN TRUE ELSE FALSE END AS is_new,
CASE WHEN seq IN (1, 3) THEN TRUE ELSE FALSE END AS is_hot,
1200 + (template_index * 280) + (seq * 160) AS view_count,
260 + (template_index * 80) + (seq * 45) AS sale_count,
48 + (template_index * 18) + (seq * 9) AS favorite_count,
LEAST(4.9, 4.5 + (template_index * 0.02) + (seq * 0.05))::numeric(3,1) AS rating_avg,
60 + (template_index * 14) + (seq * 8) AS rating_count,
tags || ARRAY[
CASE seq
WHEN 1 THEN '标准护理'
WHEN 2 THEN '家庭常备'
WHEN 3 THEN '加强调理'
WHEN 4 THEN '便携随行'
ELSE '臻选礼盒'
END,
CASE
WHEN scene_name = '常用药品' THEN '家庭药箱'
WHEN scene_name = '医疗器械' THEN '居家监测'
WHEN scene_name = '营养保健' THEN '营养补给'
WHEN scene_name = '康复护理' THEN '恢复护理'
WHEN scene_name = '中医调理' THEN '理疗养护'
ELSE '银龄照护'
END,
'医疗首页'
] AS full_tags,
jsonb_build_object(
'specification', specification || CASE seq
WHEN 1 THEN ',标准单元配置,适合首次购买与基础日常使用'
WHEN 2 THEN ',家庭周期装,单次备货覆盖时间更长'
WHEN 3 THEN ',加强护理配置,核心用量或强度做了上调'
WHEN 4 THEN ',便携小规格配置,适合外出或复诊随身携带'
ELSE ',礼盒陈列配置,更适合作为高客单或送礼选择'
END,
'usage', usage || CASE seq
WHEN 1 THEN ',适合日常基础使用频率。'
WHEN 2 THEN ',建议放置于家庭常用药箱、护理柜或床旁储物区。'
WHEN 3 THEN ',适合恢复期、症状较集中阶段或连续护理周期使用。'
WHEN 4 THEN ',适合外出、复诊、短期陪护或车载随手包场景携带。'
ELSE ',适合首页活动展示、礼赠组合或高意向用户选购。'
END,
'side_effects', CASE seq
WHEN 3 THEN '个别人群可能出现短时不适,建议先小量体验'
WHEN 5 THEN '首次使用建议阅读说明或咨询专业人员'
ELSE '一般耐受良好'
END,
'precautions', precautions || CASE seq
WHEN 2 THEN ',启封后建议尽快按周期用完。'
WHEN 4 THEN ',随身携带时注意防潮防压。'
WHEN 5 THEN ',升级配置请结合实际需求选择。'
ELSE ''
END,
'expiry_date', expiry_date,
'storage_conditions', storage_conditions,
'approval_number', approval_prefix || LPAD((((template_index - 1) * 5) + seq)::text, 4, '0'),
'target_population', CASE seq
WHEN 1 THEN audience_focus || ',偏基础护理与首次购买'
WHEN 2 THEN audience_focus || ',偏家庭常备与多人共享'
WHEN 3 THEN audience_focus || ',偏重点护理与连续使用'
WHEN 4 THEN audience_focus || ',偏短期外带与移动场景'
ELSE audience_focus || ',偏礼赠、升级体验与高意向消费'
END,
'selling_points', jsonb_build_array(
CASE seq
WHEN 1 THEN '入门门槛低,适合首页常规爆款位与首次下单'
WHEN 2 THEN '容量与周期更长,适合家庭储备和周期补货'
WHEN 3 THEN '重点场景更聚焦,适合恢复期或强化护理转化'
WHEN 4 THEN '规格更轻便,适合外带、复诊包和临时使用'
ELSE '陈列感更强,适合活动位、礼赠位与高客单展示'
END,
'支持医疗首页分类流与推荐流展示',
scene_name || '场景匹配度高',
merch_focus,
CASE seq
WHEN 1 THEN '价格带适合作为基础转化款'
WHEN 2 THEN '价格带适合作为家庭囤货款'
WHEN 3 THEN '价格带适合作为强化护理款'
WHEN 4 THEN '价格带适合作为便携补充款'
ELSE '价格带适合作为高价值展示款'
END
),
'price_band', CASE seq
WHEN 1 THEN '基础入门'
WHEN 2 THEN '家庭常备'
WHEN 3 THEN '加强护理'
WHEN 4 THEN '便携补充'
ELSE '礼盒升级'
END,
'stock_strategy', CASE seq
WHEN 1 THEN '稳定补货'
WHEN 2 THEN '高库存常备'
WHEN 3 THEN '中库存重点护理'
WHEN 4 THEN '中高库存便携周转'
ELSE '低库存陈列展示'
END,
'care_focus', care_focus,
'usage_scene', usage_scene,
'merch_focus', merch_focus
) AS attributes,
LOWER(REPLACE(product_prefix, ' ', '-')) AS slug_base
FROM seed_templates
INNER JOIN image_map ON image_map.template_index = seed_templates.template_index
CROSS JOIN generate_series(1, 5) AS seq
)
INSERT INTO public.ml_products (
id, merchant_id, category_id, brand_id, product_code, name, subtitle, description,
main_image_url, image_urls, video_urls,
base_price, market_price, cost_price,
total_stock, available_stock, min_order_qty, max_order_qty,
weight, dimensions,
status, is_featured, is_new, is_hot,
view_count, sale_count, favorite_count, rating_avg, rating_count,
seo_title, seo_description, seo_keywords, slug, tags, attributes,
created_at, updated_at, published_at
)
SELECT
id,
merchant_id,
category_id,
brand_id,
product_code,
name,
subtitle,
description,
main_image_url,
image_urls,
video_urls,
base_price,
market_price,
cost_price,
total_stock,
available_stock,
min_order_qty,
max_order_qty,
weight,
dimensions,
status,
is_featured,
is_new,
is_hot,
view_count,
sale_count,
favorite_count,
rating_avg,
rating_count,
name AS seo_title,
description AS seo_description,
full_tags,
slug_base || '-' || RIGHT(product_code, 3),
full_tags,
attributes,
NOW(),
NOW(),
NOW()
FROM seed_products
ON CONFLICT (id) DO UPDATE SET
merchant_id = EXCLUDED.merchant_id,
category_id = EXCLUDED.category_id,
brand_id = EXCLUDED.brand_id,
product_code = EXCLUDED.product_code,
name = EXCLUDED.name,
subtitle = EXCLUDED.subtitle,
description = EXCLUDED.description,
main_image_url = EXCLUDED.main_image_url,
image_urls = EXCLUDED.image_urls,
video_urls = EXCLUDED.video_urls,
base_price = EXCLUDED.base_price,
market_price = EXCLUDED.market_price,
cost_price = EXCLUDED.cost_price,
total_stock = EXCLUDED.total_stock,
available_stock = EXCLUDED.available_stock,
min_order_qty = EXCLUDED.min_order_qty,
max_order_qty = EXCLUDED.max_order_qty,
weight = EXCLUDED.weight,
dimensions = EXCLUDED.dimensions,
status = EXCLUDED.status,
is_featured = EXCLUDED.is_featured,
is_new = EXCLUDED.is_new,
is_hot = EXCLUDED.is_hot,
view_count = EXCLUDED.view_count,
sale_count = EXCLUDED.sale_count,
favorite_count = EXCLUDED.favorite_count,
rating_avg = EXCLUDED.rating_avg,
rating_count = EXCLUDED.rating_count,
seo_title = EXCLUDED.seo_title,
seo_description = EXCLUDED.seo_description,
seo_keywords = EXCLUDED.seo_keywords,
slug = EXCLUDED.slug,
tags = EXCLUDED.tags,
attributes = EXCLUDED.attributes,
updated_at = NOW(),
published_at = EXCLUDED.published_at;
COMMIT;
-- 执行完成后可运行以下校验语句:
-- SELECT id, name, level, parent_id FROM public.ml_categories WHERE slug LIKE 'medical-%' OR slug IN ('cold-fever','digestive-care','blood-pressure-monitoring','respiratory-care','bone-nutrition','immune-support','post-surgery-recovery','wound-care','moxa-therapy','herbal-patch','mobility-aid','home-safety') ORDER BY sort_order;
-- SELECT product_code, name, base_price, sale_count, is_featured, is_new, is_hot FROM public.ml_products WHERE product_code LIKE 'MEDHOME-%' ORDER BY product_code;
-- SELECT category_name, brand_name, shop_name, merchant_name, name FROM public.ml_products_detail_view WHERE product_code LIKE 'MEDHOME-%' ORDER BY product_code;