-- ==================================================================== -- 角色字段统一说明 -- ==================================================================== -- 注意:角色信息统一存储在 ak_users.role 字段中 -- ml_user_profiles 表不再包含 role 字段,避免数据重复 -- 本脚本主要用于清理可能存在的重复字段和更新相关函数 -- ==================================================================== \echo '检查角色字段统一状态...' BEGIN; -- ==================================================================== -- 1. 安全检查 -- ==================================================================== -- 检查表是否存在 DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'ml_user_profiles') THEN RAISE EXCEPTION '表 ml_user_profiles 不存在,请先运行完整数据库创建脚本'; END IF; END $$; -- 检查是否已经有 role 字段 DO $$ BEGIN IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'ml_user_profiles' AND column_name = 'role') THEN RAISE NOTICE '检测到 role 字段已存在,跳过字段创建'; ELSE RAISE NOTICE '开始添加 role 字段'; -- 添加 role 字段 ALTER TABLE public.ml_user_profiles ADD COLUMN role TEXT DEFAULT 'customer'; END IF; END $$; -- ==================================================================== -- 2. 数据迁移 -- ==================================================================== -- 迁移现有 user_type 数据到 role 字段 UPDATE public.ml_user_profiles SET role = CASE WHEN user_type = 1 THEN 'customer' -- 消费者 WHEN user_type = 2 THEN 'merchant' -- 商家 WHEN user_type = 3 THEN 'delivery' -- 配送员 WHEN user_type = 4 THEN 'service' -- 客服 WHEN user_type = 5 THEN 'admin' -- 管理员 ELSE 'customer' END WHERE role = 'customer' OR role IS NULL; -- 设置非空约束 ALTER TABLE public.ml_user_profiles ALTER COLUMN role SET NOT NULL; -- ==================================================================== -- 3. 约束和索引更新 -- ==================================================================== -- 添加新的约束 DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM information_schema.check_constraints WHERE constraint_name = 'chk_ml_user_role') THEN ALTER TABLE public.ml_user_profiles ADD CONSTRAINT chk_ml_user_role CHECK (role IN ('customer', 'merchant', 'delivery', 'service', 'admin')); RAISE NOTICE '已添加 role 字段约束'; END IF; END $$; -- 创建新索引 DROP INDEX IF EXISTS idx_ml_user_profiles_role; CREATE INDEX idx_ml_user_profiles_role ON public.ml_user_profiles(role); -- ==================================================================== -- 4. 同步 ak_users 表的 role 字段 -- ==================================================================== -- 同步 ak_users.role 字段 UPDATE public.ak_users SET role = p.role, updated_at = CURRENT_TIMESTAMP FROM public.ml_user_profiles p WHERE ak_users.id = p.user_id AND (ak_users.role != p.role OR ak_users.role IS NULL); -- ==================================================================== -- 5. 更新函数和视图 -- ==================================================================== -- 更新商家验证函数 CREATE OR REPLACE FUNCTION public.is_verified_merchant(user_uuid UUID) RETURNS BOOLEAN LANGUAGE plpgsql SECURITY DEFINER AS $$ DECLARE result BOOLEAN := FALSE; BEGIN SELECT (role = 'merchant' AND verification_status = 1) INTO result FROM public.ml_user_profiles WHERE user_id = user_uuid; RETURN COALESCE(result, FALSE); END; $$; -- 更新用户信息视图 CREATE OR REPLACE VIEW public.ml_users_view AS SELECT u.id, u.email, u.username, u.phone, u.avatar_url, u.status as user_status, u.gender, u.birthday, u.bio, u.created_at as user_created_at, u.updated_at as user_updated_at, p.role, p.status, p.real_name, p.credit_score, p.verification_status, p.created_at as profile_created_at, p.updated_at as profile_updated_at, CASE WHEN p.role = 'customer' THEN '消费者' WHEN p.role = 'merchant' THEN '商家' WHEN p.role = 'delivery' THEN '配送员' WHEN p.role = 'service' THEN '客服' WHEN p.role = 'admin' THEN '管理员' ELSE '未知' END as role_name FROM public.ak_users u LEFT JOIN public.ml_user_profiles p ON u.id = p.user_id; -- ==================================================================== -- 6. 更新字段注释 -- ==================================================================== COMMENT ON COLUMN public.ml_user_profiles.role IS '用户角色:customer消费者, merchant商家, delivery配送员, service客服, admin管理员'; -- ==================================================================== -- 7. 验证迁移结果 -- ==================================================================== DO $$ DECLARE total_users INTEGER; migrated_users INTEGER; role_stats RECORD; BEGIN -- 统计总用户数 SELECT COUNT(*) INTO total_users FROM public.ml_user_profiles; -- 统计已迁移用户数 SELECT COUNT(*) INTO migrated_users FROM public.ml_user_profiles WHERE role IN ('customer', 'merchant', 'delivery', 'service', 'admin'); RAISE NOTICE '迁移完成:总用户 %, 已迁移 %', total_users, migrated_users; -- 显示角色分布 RAISE NOTICE '角色分布统计:'; FOR role_stats IN SELECT role, COUNT(*) as count FROM public.ml_user_profiles GROUP BY role ORDER BY count DESC LOOP RAISE NOTICE ' %: % 用户', role_stats.role, role_stats.count; END LOOP; END $$; COMMIT; \echo '角色字段迁移完成!' -- ==================================================================== -- 8. 可选:清理旧字段(请谨慎执行) -- ==================================================================== /* -- 警告:以下操作将永久删除 user_type 字段,请确保迁移成功后再执行 BEGIN; -- 删除旧约束 ALTER TABLE public.ml_user_profiles DROP CONSTRAINT IF EXISTS chk_ml_user_type; -- 删除旧索引 DROP INDEX IF EXISTS idx_ml_user_profiles_type; -- 删除旧字段 ALTER TABLE public.ml_user_profiles DROP COLUMN IF EXISTS user_type; COMMIT; \echo '旧 user_type 字段清理完成'; */ -- ==================================================================== -- 9. 回滚脚本(如需回滚,请执行以下命令) -- ==================================================================== /* -- 回滚到 user_type 字段(仅在必要时执行) BEGIN; -- 重新添加 user_type 字段 ALTER TABLE public.ml_user_profiles ADD COLUMN user_type INTEGER DEFAULT 1; -- 从 role 字段恢复数据 UPDATE public.ml_user_profiles SET user_type = CASE WHEN role = 'customer' THEN 1 WHEN role = 'merchant' THEN 2 WHEN role = 'delivery' THEN 3 WHEN role = 'service' THEN 4 WHEN role = 'admin' THEN 5 ELSE 1 END; -- 设置非空约束 ALTER TABLE public.ml_user_profiles ALTER COLUMN user_type SET NOT NULL; -- 重新添加约束 ALTER TABLE public.ml_user_profiles ADD CONSTRAINT chk_ml_user_type CHECK (user_type IN (1,2,3,4,5)); -- 重新创建索引 CREATE INDEX idx_ml_user_profiles_type ON public.ml_user_profiles(user_type); -- 删除 role 字段 ALTER TABLE public.ml_user_profiles DROP CONSTRAINT IF EXISTS chk_ml_user_role; ALTER TABLE public.ml_user_profiles DROP COLUMN IF EXISTS role; COMMIT; \echo '已回滚到 user_type 字段'; */