diff --git a/app/routes/api.v3.rbac.roles.$roleId.tsx b/app/routes/api.v3.rbac.roles.$roleId.tsx deleted file mode 100644 index 81fcf22..0000000 --- a/app/routes/api.v3.rbac.roles.$roleId.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/** - * RBAC API 代理 - 单个角色操作 - * GET /api/v3/rbac/roles/:roleId - 获取角色详情 - * PUT /api/v3/rbac/roles/:roleId - 更新角色 - * DELETE /api/v3/rbac/roles/:roleId - 删除角色 - */ - -import { json, type LoaderFunctionArgs } from "@remix-run/node"; -import { mockRoles, updateRole as updateMockRole, deleteRole as deleteMockRole } from "~/services/rbac-mock-data.server"; - -// GET - 获取角色详情 -export async function loader({ params }: LoaderFunctionArgs) { - const roleId = parseInt(params.roleId || '0'); - console.log('📡 [API Route] GET /api/v3/rbac/roles/' + roleId); - - const role = mockRoles.find(r => r.id === roleId); - - if (!role) { - return json({ - detail: '角色不存在' - }, { status: 404 }); - } - - return json({ - code: 200, - message: 'success', - data: role - }); -} - -// PUT/DELETE -export async function action({ request, params }: LoaderFunctionArgs) { - const roleId = parseInt(params.roleId || '0'); - const method = request.method; - - console.log('📡 [API Route]', method, '/api/v3/rbac/roles/' + roleId); - - const role = mockRoles.find(r => r.id === roleId); - - if (!role) { - return json({ - detail: '角色不存在' - }, { status: 404 }); - } - - if (method === 'PUT') { - // 更新角色 - const body = await request.json(); - console.log('📋 [API Route] 更新数据:', body); - - // 系统角色保护 - if (role.is_system && body.role_key) { - return json({ - detail: '系统角色的role_key不可修改' - }, { status: 400 }); - } - - // 使用共享Mock数据更新 - updateMockRole(roleId, body); - - return json({ - code: 200, - message: '角色更新成功', - data: role - }); - } - - if (method === 'DELETE') { - // 删除角色 - if (role.is_system) { - return json({ - detail: '系统角色不能删除' - }, { status: 400 }); - } - - // 使用共享Mock数据删除 - deleteMockRole(roleId); - - return json({ - code: 200, - message: '角色删除成功' - }); - } - - return json({ code: 405, message: 'Method Not Allowed' }, { status: 405 }); -} diff --git a/app/routes/api.v3.rbac.roles.$roleId.users.tsx b/app/routes/api.v3.rbac.roles.$roleId.users.tsx deleted file mode 100644 index 0d36e3f..0000000 --- a/app/routes/api.v3.rbac.roles.$roleId.users.tsx +++ /dev/null @@ -1,65 +0,0 @@ -/** - * 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 - } - }); -} diff --git a/app/routes/api.v3.rbac.roles._index.tsx b/app/routes/api.v3.rbac.roles._index.tsx deleted file mode 100644 index 4d6a81c..0000000 --- a/app/routes/api.v3.rbac.roles._index.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/** - * 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 }); -} diff --git a/app/routes/api.v3.rbac.users.$userId.roles.$roleId.tsx b/app/routes/api.v3.rbac.users.$userId.roles.$roleId.tsx deleted file mode 100644 index a760797..0000000 --- a/app/routes/api.v3.rbac.users.$userId.roles.$roleId.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/** - * RBAC API 代理 - 移除用户角色 - * DELETE /api/v3/rbac/users/:userId/roles/:roleId - */ - -import { json, type LoaderFunctionArgs } from "@remix-run/node"; -import { removeUserRole } from "~/services/rbac-mock-data.server"; - -// DELETE - 移除用户角色 -export async function action({ params }: LoaderFunctionArgs) { - const userId = parseInt(params.userId || '0'); - const roleId = parseInt(params.roleId || '0'); - - console.log('📡 [API Route] DELETE /api/v3/rbac/users/' + userId + '/roles/' + roleId); - - // 使用共享Mock数据移除角色 - const success = removeUserRole(userId, roleId); - - if (success) { - - return json({ - code: 200, - message: '用户角色移除成功' - }); - } - - return json({ - detail: '用户角色关联不存在' - }, { status: 404 }); -} diff --git a/app/routes/api.v3.rbac.users.$userId.roles.tsx b/app/routes/api.v3.rbac.users.$userId.roles.tsx deleted file mode 100644 index 729faf7..0000000 --- a/app/routes/api.v3.rbac.users.$userId.roles.tsx +++ /dev/null @@ -1,38 +0,0 @@ -/** - * RBAC API 代理 - 用户角色管理 - * POST /api/v3/rbac/users/:userId/roles - 为用户分配角色 - */ - -import { json, type LoaderFunctionArgs } from "@remix-run/node"; -import { assignUserRole } from "~/services/rbac-mock-data.server"; - -// POST - 为用户分配角色 -export async function action({ request, params }: LoaderFunctionArgs) { - const userId = parseInt(params.userId || '0'); - const method = request.method; - - console.log('📡 [API Route]', method, '/api/v3/rbac/users/' + userId + '/roles'); - - if (method === 'POST') { - const body = await request.json(); - const roleIds = body.role_ids || []; - - console.log('📋 [API Route] 分配角色:', { userId, roleIds }); - - // 使用共享Mock数据分配角色 - roleIds.forEach((roleId: number) => { - assignUserRole(userId, roleId); - }); - - return json({ - code: 200, - message: '角色分配成功', - data: { - user_id: userId, - roles: roleIds.map((id: number) => ({ role_id: id })) - } - }); - } - - return json({ code: 405, message: 'Method Not Allowed' }, { status: 405 }); -} diff --git a/app/services/rbac-mock-data.server.ts b/app/services/rbac-mock-data.server.ts deleted file mode 100644 index 93f4b66..0000000 --- a/app/services/rbac-mock-data.server.ts +++ /dev/null @@ -1,226 +0,0 @@ -/** - * RBAC Mock数据 - 共享存储 - * 所有Remix API路由共享这个数据源 - */ - -// ==================== 角色数据(与数据库实际数据一致)==================== - -export const mockRoles = [ - { - id: 1, - role_key: 'admin', - role_name: '市级管理员', - description: '负责本地区的所有业务管理,不包括系统设置和角色权限管理', - data_scope: 'DEPT', - is_system: false, - priority: 0, - created_at: '2025-07-18T10:35:39+08:00', - updated_at: '2025-07-18T10:35:39+08:00' - }, - { - id: 2, - role_key: 'common', - role_name: '普通员工', - description: '仅能操作自己的数据', - data_scope: 'SELF', - is_system: false, - priority: 0, - created_at: '2025-07-18T10:35:39+08:00', - updated_at: '2025-07-18T10:35:39+08:00' - }, - { - id: 52, - role_key: 'provincial_admin', - role_name: '省级管理员', - description: '拥有全部权限,可以管理所有地区的评查点规则、提示词、动态按钮、评查组', - data_scope: 'ALL', - is_system: true, - priority: 1, - created_at: '2025-11-19T17:25:45+08:00', - updated_at: '2025-11-19T17:25:45+08:00' - } -]; - -// ==================== 用户数据 ==================== - -export const mockUsers = [ - { - id: 1, - user_id: 1, - username: 'admin', - nick_name: '系统管理员', - phone_number: '13800138000', - email: 'admin@example.com', - ou_name: '广东省烟草专卖局', - area: '广东省', - status: 1, - is_leader: true - }, - { - id: 2, - user_id: 2, - username: 'zhangsan', - nick_name: '张三', - phone_number: '13800138001', - email: 'zhangsan@example.com', - ou_name: '梅州市烟草专卖局', - area: '梅州', - status: 1, - is_leader: true - }, - { - id: 3, - user_id: 3, - username: 'lisi', - nick_name: '李四', - phone_number: '13800138002', - email: 'lisi@example.com', - ou_name: '云浮市烟草专卖局', - area: '云浮', - status: 1, - is_leader: false - }, - { - id: 4, - user_id: 4, - username: 'wangwu', - nick_name: '王五', - phone_number: '13800138003', - email: 'wangwu@example.com', - ou_name: '揭阳市烟草专卖局', - area: '揭阳', - status: 1, - is_leader: false - }, - { - id: 5, - user_id: 5, - username: 'zhaoliu', - nick_name: '赵六', - phone_number: '13800138004', - email: 'zhaoliu@example.com', - ou_name: '潮州市烟草专卖局', - area: '潮州', - status: 1, - is_leader: false - }, - { - id: 6, - user_id: 6, - username: 'sunqi', - nick_name: '孙七', - phone_number: '13800138005', - email: 'sunqi@example.com', - ou_name: '汕头市烟草专卖局', - area: '汕头', - status: 1, - is_leader: true - } -]; - -// ==================== 用户-角色关联数据 ==================== - -export const mockUserRoles: Array<{ user_id: number; role_id: number; assigned_at: string }> = [ - { user_id: 1, role_id: 52, assigned_at: '2025-01-20T10:00:00' }, // admin - provincial_admin (id=52) - { user_id: 2, role_id: 1, assigned_at: '2025-01-21T10:00:00' }, // zhangsan - 市级管理员 (id=1) - { user_id: 3, role_id: 1, assigned_at: '2025-01-21T11:00:00' }, // lisi - 市级管理员 (id=1) - { user_id: 4, role_id: 2, assigned_at: '2025-01-21T12:00:00' }, // wangwu - 普通员工 (id=2) -]; - -// ==================== 辅助函数 ==================== - -/** - * 获取角色的用户列表 - */ -export function getRoleUsers(roleId: number) { - const userIds = mockUserRoles - .filter(ur => ur.role_id === roleId) - .map(ur => ur.user_id); - - return mockUsers.filter(u => userIds.includes(u.id || u.user_id)); -} - -/** - * 为用户分配角色 - */ -export function assignUserRole(userId: number, roleId: number) { - // 检查是否已存在 - const exists = mockUserRoles.some( - ur => ur.user_id === userId && ur.role_id === roleId - ); - - if (!exists) { - mockUserRoles.push({ - user_id: userId, - role_id: roleId, - assigned_at: new Date().toISOString() - }); - console.log('✅ [Mock Data] 用户角色分配成功:', { userId, roleId }); - console.log('📊 [Mock Data] 当前用户-角色关联:', mockUserRoles); - } else { - console.log('⚠️ [Mock Data] 用户角色关联已存在:', { userId, roleId }); - } -} - -/** - * 移除用户角色 - */ -export function removeUserRole(userId: number, roleId: number) { - const index = mockUserRoles.findIndex( - ur => ur.user_id === userId && ur.role_id === roleId - ); - - if (index > -1) { - mockUserRoles.splice(index, 1); - console.log('✅ [Mock Data] 用户角色移除成功:', { userId, roleId }); - console.log('📊 [Mock Data] 当前用户-角色关联:', mockUserRoles); - return true; - } - - console.log('⚠️ [Mock Data] 用户角色关联不存在:', { userId, roleId }); - return false; -} - -/** - * 添加新角色 - */ -export function addRole(roleData: any) { - const newRole = { - id: Math.max(...mockRoles.map(r => r.id), 0) + 1, - ...roleData, - created_at: new Date().toISOString(), - updated_at: new Date().toISOString() - }; - - mockRoles.push(newRole); - console.log('✅ [Mock Data] 角色创建成功:', newRole); - return newRole; -} - -/** - * 更新角色 - */ -export function updateRole(roleId: number, updates: any) { - const role = mockRoles.find(r => r.id === roleId); - if (role) { - Object.assign(role, updates, { - updated_at: new Date().toISOString() - }); - console.log('✅ [Mock Data] 角色更新成功:', role); - return role; - } - return null; -} - -/** - * 删除角色 - */ -export function deleteRole(roleId: number) { - const index = mockRoles.findIndex(r => r.id === roleId); - if (index > -1) { - const deleted = mockRoles.splice(index, 1)[0]; - console.log('✅ [Mock Data] 角色删除成功:', deleted); - return true; - } - return false; -}