feat(admin): complete integration of auth, delivery, and system infrastructure modules

This commit is contained in:
comlibmb
2026-02-18 23:30:39 +08:00
parent 7b27694690
commit 5d00e3d74e
37 changed files with 2830 additions and 1075 deletions

View File

@@ -0,0 +1,33 @@
-- RPC: rpc_admin_delete_permission
-- 管理端删除功能权限/菜单
CREATE OR REPLACE FUNCTION public.rpc_admin_delete_permission(
p_id UUID
)
RETURNS BOOLEAN
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
v_ok BOOLEAN;
BEGIN
-- 1. 权限检查 (仅管理员)
IF NOT EXISTS (
SELECT 1 FROM public.ak_users
WHERE auth_id = auth.uid() AND role = 'admin'
) THEN
RAISE EXCEPTION 'Permission denied';
END IF;
-- 2. 执行级联删除 (外键已配置 ON DELETE CASCADE)
DELETE FROM public.ak_permissions WHERE id = p_id;
GET DIAGNOSTICS v_ok = ROW_COUNT;
RETURN v_ok;
END;
$$;
-- 授权
REVOKE ALL ON FUNCTION public.rpc_admin_delete_permission(UUID) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_admin_delete_permission(UUID) TO authenticated;

View File

@@ -0,0 +1,33 @@
-- RPC: rpc_admin_delete_role
-- 管理端删除角色
CREATE OR REPLACE FUNCTION public.rpc_admin_delete_role(
p_id UUID
)
RETURNS BOOLEAN
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
v_ok BOOLEAN;
BEGIN
-- 1. 权限检查
IF NOT EXISTS (
SELECT 1 FROM public.ak_users
WHERE auth_id = auth.uid() AND role = 'admin'
) THEN
RAISE EXCEPTION 'Permission denied';
END IF;
-- 2. 执行删除
DELETE FROM public.ak_roles WHERE id = p_id;
GET DIAGNOSTICS v_ok = ROW_COUNT;
RETURN v_ok;
END;
$$;
-- 授权
REVOKE ALL ON FUNCTION public.rpc_admin_delete_role(UUID) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_admin_delete_role(UUID) TO authenticated;

View File

@@ -0,0 +1,70 @@
-- RPC: rpc_admin_get_admin_list
-- 管理端获取管理员列表
-- 筛选 ak_users 表中 role 为 'admin' 或 'analytics' 的用户,并关联显示其角色信息
CREATE OR REPLACE FUNCTION public.rpc_admin_get_admin_list(
p_search TEXT DEFAULT NULL,
p_status SMALLINT DEFAULT NULL,
p_page INTEGER DEFAULT 1,
p_page_size INTEGER DEFAULT 20
)
RETURNS JSONB
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
v_offset INTEGER := (p_page - 1) * p_page_size;
v_total BIGINT;
v_items JSONB;
BEGIN
-- 1. 权限检查 (仅管理员)
IF NOT EXISTS (
SELECT 1 FROM public.ak_users
WHERE auth_id = auth.uid() AND role = 'admin'
) THEN
RAISE EXCEPTION 'Permission denied';
END IF;
-- 2. 获取总数
SELECT COUNT(*) INTO v_total
FROM public.ak_users u
WHERE u.role IN ('admin', 'analytics')
AND (p_status IS NULL OR u.is_active = (p_status = 1))
AND (p_search IS NULL OR u.username ILIKE '%' || p_search || '%' OR u.real_name ILIKE '%' || p_search || '%');
-- 3. 获取数据列表 (关联角色)
SELECT jsonb_agg(t) INTO v_items
FROM (
SELECT
u.id,
u.username,
u.real_name,
u.role,
u.is_active,
u.last_login_at,
u.last_login_ip,
(
SELECT jsonb_agg(r.name)
FROM public.ak_admin_roles ar
JOIN public.ak_roles r ON r.id = ar.role_id
WHERE ar.user_id = u.id
) as roles
FROM public.ak_users u
WHERE u.role IN ('admin', 'analytics')
AND (p_status IS NULL OR u.is_active = (p_status = 1))
AND (p_search IS NULL OR u.username ILIKE '%' || p_search || '%' OR u.real_name ILIKE '%' || p_search || '%')
ORDER BY u.created_at DESC
LIMIT p_page_size OFFSET v_offset
) t;
RETURN jsonb_build_object(
'total', v_total,
'items', COALESCE(v_items, '[]'::jsonb)
);
END;
$$;
-- 授权
REVOKE ALL ON FUNCTION public.rpc_admin_get_admin_list(TEXT, SMALLINT, INTEGER, INTEGER) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_admin_get_admin_list(TEXT, SMALLINT, INTEGER, INTEGER) TO authenticated;

View File

@@ -0,0 +1,38 @@
-- RPC: rpc_admin_get_permission_list
-- 管理端获取全量权限/菜单列表 (供前端构建树形结构)
CREATE OR REPLACE FUNCTION public.rpc_admin_get_permission_list()
RETURNS JSONB
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
v_items JSONB;
BEGIN
-- 1. 权限检查
IF NOT EXISTS (
SELECT 1 FROM public.ak_users
WHERE auth_id = auth.uid() AND role = 'admin'
) THEN
RAISE EXCEPTION 'Permission denied';
END IF;
-- 2. 获取全量数据
SELECT jsonb_agg(t) INTO v_items
FROM (
SELECT
id, parent_id, name, code, type,
path, icon, sort_order, is_visible,
created_at, updated_at
FROM public.ak_permissions
ORDER BY sort_order ASC, created_at ASC
) t;
RETURN COALESCE(v_items, '[]'::jsonb);
END;
$$;
-- 授权
REVOKE ALL ON FUNCTION public.rpc_admin_get_permission_list() FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_admin_get_permission_list() TO authenticated;

View File

@@ -0,0 +1,53 @@
-- RPC: rpc_admin_get_role_list
-- 管理端获取角色分页列表
CREATE OR REPLACE FUNCTION public.rpc_admin_get_role_list(
p_search TEXT DEFAULT NULL,
p_page INTEGER DEFAULT 1,
p_page_size INTEGER DEFAULT 20
)
RETURNS JSONB
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
v_offset INTEGER := (p_page - 1) * p_page_size;
v_total BIGINT;
v_items JSONB;
BEGIN
-- 1. 权限检查
IF NOT EXISTS (
SELECT 1 FROM public.ak_users
WHERE auth_id = auth.uid() AND role = 'admin'
) THEN
RAISE EXCEPTION 'Permission denied';
END IF;
-- 2. 获取总数
SELECT COUNT(*) INTO v_total
FROM public.ak_roles
WHERE (p_search IS NULL OR p_search = '' OR name ILIKE '%' || p_search || '%' OR code ILIKE '%' || p_search || '%');
-- 3. 获取明细
SELECT jsonb_agg(t) INTO v_items
FROM (
SELECT
id, name, code, description, is_active,
created_at, updated_at
FROM public.ak_roles
WHERE (p_search IS NULL OR p_search = '' OR name ILIKE '%' || p_search || '%' OR code ILIKE '%' || p_search || '%')
ORDER BY created_at DESC
LIMIT p_page_size OFFSET v_offset
) t;
RETURN jsonb_build_object(
'total', v_total,
'items', COALESCE(v_items, '[]'::jsonb)
);
END;
$$;
-- 授权
REVOKE ALL ON FUNCTION public.rpc_admin_get_role_list(TEXT, INTEGER, INTEGER) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_admin_get_role_list(TEXT, INTEGER, INTEGER) TO authenticated;

View File

@@ -0,0 +1,69 @@
-- RPC: rpc_admin_save_permission
-- 管理端新增或更新功能权限/菜单
CREATE OR REPLACE FUNCTION public.rpc_admin_save_permission(
p_id UUID DEFAULT NULL,
p_parent_id UUID DEFAULT NULL,
p_name TEXT DEFAULT NULL,
p_code TEXT DEFAULT NULL,
p_type TEXT DEFAULT 'menu',
p_path TEXT DEFAULT NULL,
p_icon TEXT DEFAULT NULL,
p_sort_order INTEGER DEFAULT 0,
p_is_visible BOOLEAN DEFAULT TRUE
)
RETURNS UUID
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
v_id UUID;
BEGIN
-- 1. 权限检查
IF NOT EXISTS (
SELECT 1 FROM public.ak_users
WHERE auth_id = auth.uid() AND role = 'admin'
) THEN
RAISE EXCEPTION 'Permission denied';
END IF;
-- 2. 新增
IF p_id IS NULL THEN
IF p_name IS NULL OR p_code IS NULL THEN
RAISE EXCEPTION 'Missing required fields: name or code';
END IF;
INSERT INTO public.ak_permissions (
parent_id, name, code, type, path, icon, sort_order, is_visible
) VALUES (
p_parent_id, p_name, p_code, p_type, p_path, p_icon, p_sort_order, p_is_visible
) RETURNING id INTO v_id;
ELSE
-- 3. 更新
UPDATE public.ak_permissions
SET
parent_id = COALESCE(p_parent_id, parent_id),
name = COALESCE(p_name, name),
code = COALESCE(p_code, code),
type = COALESCE(p_type, type),
path = COALESCE(p_path, path),
icon = COALESCE(p_icon, icon),
sort_order = COALESCE(p_sort_order, sort_order),
is_visible = COALESCE(p_is_visible, is_visible),
updated_at = now()
WHERE id = p_id
RETURNING id INTO v_id;
IF v_id IS NULL THEN
RAISE EXCEPTION 'Permission item not found';
END IF;
END IF;
RETURN v_id;
END;
$$;
-- 授权
REVOKE ALL ON FUNCTION public.rpc_admin_save_permission(UUID, UUID, TEXT, TEXT, TEXT, TEXT, TEXT, INTEGER, BOOLEAN) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_admin_save_permission(UUID, UUID, TEXT, TEXT, TEXT, TEXT, TEXT, INTEGER, BOOLEAN) TO authenticated;

View File

@@ -0,0 +1,61 @@
-- RPC: rpc_admin_save_role
-- 管理端新增或更新角色
CREATE OR REPLACE FUNCTION public.rpc_admin_save_role(
p_id UUID DEFAULT NULL,
p_name TEXT DEFAULT NULL,
p_code TEXT DEFAULT NULL,
p_description TEXT DEFAULT NULL,
p_is_active BOOLEAN DEFAULT TRUE
)
RETURNS UUID
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
v_id UUID;
BEGIN
-- 1. 权限检查
IF NOT EXISTS (
SELECT 1 FROM public.ak_users
WHERE auth_id = auth.uid() AND role = 'admin'
) THEN
RAISE EXCEPTION 'Permission denied';
END IF;
-- 2. 新增
IF p_id IS NULL THEN
IF p_name IS NULL OR p_code IS NULL THEN
RAISE EXCEPTION 'Missing required fields: name or code';
END IF;
INSERT INTO public.ak_roles (
name, code, description, is_active
) VALUES (
p_name, p_code, p_description, p_is_active
) RETURNING id INTO v_id;
ELSE
-- 3. 更新
UPDATE public.ak_roles
SET
name = COALESCE(p_name, name),
code = COALESCE(p_code, code),
description = COALESCE(p_description, description),
is_active = COALESCE(p_is_active, is_active),
updated_at = now()
WHERE id = p_id
RETURNING id INTO v_id;
IF v_id IS NULL THEN
RAISE EXCEPTION 'Role not found';
END IF;
END IF;
RETURN v_id;
END;
$$;
-- 授权
REVOKE ALL ON FUNCTION public.rpc_admin_save_role(UUID, TEXT, TEXT, TEXT, BOOLEAN) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION public.rpc_admin_save_role(UUID, TEXT, TEXT, TEXT, BOOLEAN) TO authenticated;