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