f938ca6c00
添加角色基于访问控制(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>
66 lines
1.8 KiB
TypeScript
66 lines
1.8 KiB
TypeScript
/**
|
|
* RBAC API 代理 - 角色用户管理
|
|
* GET /api/v3/rbac/roles/:roleId/users - 获取角色的用户列表
|
|
*/
|
|
|
|
import { json, type LoaderFunctionArgs } from "@remix-run/node";
|
|
import { mockUsers, mockUserRoles, getRoleUsers } from "~/services/rbac-mock-data.server";
|
|
|
|
// GET - 获取角色的用户列表
|
|
export async function loader({ params, request }: LoaderFunctionArgs) {
|
|
const roleId = parseInt(params.roleId || '0');
|
|
console.log('📡 [API Route] GET /api/v3/rbac/roles/' + roleId + '/users');
|
|
|
|
// 解析查询参数
|
|
const url = new URL(request.url);
|
|
const page = parseInt(url.searchParams.get('page') || '1');
|
|
const pageSize = parseInt(url.searchParams.get('page_size') || '20');
|
|
const area = url.searchParams.get('area');
|
|
const username = url.searchParams.get('username');
|
|
|
|
// 使用共享Mock数据获取角色用户
|
|
let users = getRoleUsers(roleId);
|
|
|
|
// 过滤
|
|
if (area) {
|
|
users = users.filter(u => u.area.includes(area));
|
|
}
|
|
|
|
if (username) {
|
|
users = users.filter(u =>
|
|
u.username.includes(username) || u.nick_name.includes(username)
|
|
);
|
|
}
|
|
|
|
// 添加assigned_at时间戳
|
|
const usersWithTime = users.map(user => {
|
|
const userRole = mockUserRoles.find(
|
|
ur => ur.user_id === (user.user_id || user.id) && ur.role_id === roleId
|
|
);
|
|
return {
|
|
...user,
|
|
user_id: user.user_id || user.id,
|
|
assigned_at: userRole?.assigned_at || new Date().toISOString()
|
|
};
|
|
});
|
|
|
|
// 分页
|
|
const total = usersWithTime.length;
|
|
const start = (page - 1) * pageSize;
|
|
const end = start + pageSize;
|
|
const items = usersWithTime.slice(start, end);
|
|
|
|
console.log('✅ [API Route] 返回用户数据:', { roleId, total, itemsCount: items.length });
|
|
|
|
return json({
|
|
code: 200,
|
|
message: 'success',
|
|
data: {
|
|
total,
|
|
page,
|
|
page_size: pageSize,
|
|
items
|
|
}
|
|
});
|
|
}
|