feat(rbac): 添加 RBAC 角色管理 API 代理和模拟数据
添加角色基于访问控制(RBAC)相关接口: 1. API 代理路由 - api.v3.rbac.roles._index.tsx: 角色列表和创建 - api.v3.rbac.roles.$roleId.tsx: 角色详情、更新和删除 - api.v3.rbac.roles.$roleId.users.tsx: 角色用户关联管理 - api.v3.rbac.users.$userId.roles.tsx: 用户角色列表 - api.v3.rbac.users.$userId.roles.$roleId.tsx: 用户角色分配 2. 模拟数据服务 - rbac-mock-data.server.ts: 提供模拟角色和用户角色数据 - 支持 CRUD 操作 - 包含预置的系统管理员、开发者等角色 接口功能: - ✅ 获取角色列表(支持分页和搜索) - ✅ 获取角色详情 - ✅ 创建、更新、删除角色 - ✅ 获取角色的用户列表 - ✅ 为用户分配/移除角色 注:当前使用模拟数据,待后端接口完善后切换到真实 API 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* RBAC API 代理 - 获取角色列表
|
||||
* GET /api/v3/rbac/roles
|
||||
*/
|
||||
|
||||
import { json, type LoaderFunctionArgs } from "@remix-run/node";
|
||||
import { mockRoles, mockUserRoles, addRole } from "~/services/rbac-mock-data.server";
|
||||
|
||||
// GET - 获取角色列表
|
||||
export async function loader({ request }: LoaderFunctionArgs) {
|
||||
console.log('📡 [API Route] GET /api/v3/rbac/roles 被调用');
|
||||
|
||||
// 解析查询参数
|
||||
const url = new URL(request.url);
|
||||
const page = parseInt(url.searchParams.get('page') || '1');
|
||||
const pageSize = parseInt(url.searchParams.get('page_size') || '20');
|
||||
const roleKey = url.searchParams.get('role_key');
|
||||
const roleName = url.searchParams.get('role_name');
|
||||
|
||||
console.log('📋 [API Route] 查询参数:', { page, pageSize, roleKey, roleName });
|
||||
|
||||
// 过滤数据
|
||||
let filteredRoles = [...mockRoles];
|
||||
|
||||
if (roleKey) {
|
||||
filteredRoles = filteredRoles.filter(r => r.role_key.includes(roleKey));
|
||||
}
|
||||
|
||||
if (roleName) {
|
||||
filteredRoles = filteredRoles.filter(r => r.role_name.includes(roleName));
|
||||
}
|
||||
|
||||
// 添加用户数统计
|
||||
const rolesWithCount = filteredRoles.map(role => ({
|
||||
...role,
|
||||
user_count: mockUserRoles.filter(ur => ur.role_id === role.id).length,
|
||||
permission_count: 0 // 暂时写死
|
||||
}));
|
||||
|
||||
// 分页
|
||||
const total = rolesWithCount.length;
|
||||
const start = (page - 1) * pageSize;
|
||||
const end = start + pageSize;
|
||||
const items = rolesWithCount.slice(start, end);
|
||||
|
||||
// 返回标准格式
|
||||
const response = {
|
||||
code: 200,
|
||||
message: 'success',
|
||||
data: {
|
||||
total,
|
||||
page,
|
||||
page_size: pageSize,
|
||||
items
|
||||
}
|
||||
};
|
||||
|
||||
console.log('✅ [API Route] 返回数据:', { total, itemsCount: items.length });
|
||||
|
||||
return json(response, {
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// POST - 创建角色
|
||||
export async function action({ request }: LoaderFunctionArgs) {
|
||||
const method = request.method;
|
||||
|
||||
if (method === 'POST') {
|
||||
console.log('📡 [API Route] POST /api/v3/rbac/roles 被调用');
|
||||
|
||||
const body = await request.json();
|
||||
console.log('📋 [API Route] 请求体:', body);
|
||||
|
||||
// 使用共享Mock数据
|
||||
const newRole = addRole({
|
||||
role_key: body.role_key,
|
||||
role_name: body.role_name,
|
||||
description: body.description || '',
|
||||
data_scope: body.data_scope || 'SELF',
|
||||
priority: body.priority || 10,
|
||||
is_system: false
|
||||
});
|
||||
|
||||
console.log('✅ [API Route] 角色创建成功:', newRole);
|
||||
|
||||
return json({
|
||||
code: 200,
|
||||
message: '角色创建成功',
|
||||
data: newRole
|
||||
});
|
||||
}
|
||||
|
||||
return json({ code: 405, message: 'Method Not Allowed' }, { status: 405 });
|
||||
}
|
||||
Reference in New Issue
Block a user