Files
akmon/doc_mall/database/quick_role_migration.sql
2026-01-20 08:04:15 +08:00

250 lines
7.6 KiB
PL/PgSQL
Raw Permalink 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.
-- ====================================================================
-- 角色字段统一说明
-- ====================================================================
-- 注意:角色信息统一存储在 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 字段';
*/