yourname 5 月之前
父节点
当前提交
8f49eb2ec8

+ 2 - 0
src/server/api.ts

@@ -7,6 +7,7 @@ import customersRoute from '@/server/api/customers/index';
 import leadsRoute from '@/server/api/leads/index';
 import opportunitiesRoute from '@/server/api/opportunities/index';
 import ticketsRoute from '@/server/api/tickets/index';
+import roleRoute from '@/server/api/roles/index';
 
 const api = new OpenAPIHono()
   .route('/api/v1/contacts', contactsRoute)
@@ -15,6 +16,7 @@ const api = new OpenAPIHono()
   .route('/api/v1/leads', leadsRoute)
   .route('/api/v1/opportunities', opportunitiesRoute)
   .route('/api/v1/tickets', ticketsRoute)
+  .route('/api/v1/roles', roleRoute)
   .route('/api/v1/users', userRoute);
 
 export default api;

+ 91 - 0
src/server/api/roles/[id]/delete.ts

@@ -0,0 +1,91 @@
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from 'zod';
+import { RoleService } from '@/server/modules/roles/role.service';
+import { AppDataSource } from '@/server/data-source';
+import { ErrorSchema } from '@/server/utils/errorHandler';
+import { authMiddleware } from '@/server/middleware/auth';
+import { AuthContext } from '@/server/types/context';
+import { logger } from '@/server/utils/logger';
+
+// 路径参数Schema
+const DeleteParamsSchema = z.object({
+  id: z.coerce.number().int().positive().openapi({
+    param: { name: 'id', in: 'path' },
+    example: 1,
+    description: '角色ID'
+  })
+});
+
+// 路由定义
+const routeDef = createRoute({
+  method: 'delete',
+  path: '/{id}',
+  middleware: [authMiddleware],
+  request: {
+    params: DeleteParamsSchema
+  },
+  responses: {
+    200: {
+      description: '删除角色成功',
+      content: {
+        'application/json': { 
+          schema: z.object({
+            code: z.number().openapi({ example: 200 }),
+            message: z.string().openapi({ example: '删除角色成功' }),
+            data: z.object({
+              success: z.boolean().openapi({ example: true })
+            })
+          })
+        }
+      }
+    },
+    400: {
+      description: '请求参数错误或角色已关联用户',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    404: {
+      description: '角色不存在',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    500: {
+      description: '服务器内部错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    }
+  },
+  tags: ['角色管理']
+});
+
+// 创建路由实例
+const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+  try {
+    const roleService = new RoleService(AppDataSource);
+    const { id } = c.req.valid('param');
+    
+    await roleService.delete(id);
+    
+    logger.api(`删除角色成功,ID: ${id}`);
+    return c.json({
+      code: 200,
+      message: '删除角色成功',
+      data: { success: true }
+    }, 200);
+  } catch (error) {
+    const message = error instanceof Error ? error.message : '删除角色失败';
+    const status = message.includes('不存在') ? 404 : 
+                  message.includes('关联用户') ? 400 : 500;
+    
+    logger.error(`删除角色失败,ID: ${c.req.valid('param').id}, 错误: ${message}`);
+    return c.json({
+      code: status,
+      message
+    }, status);
+  }
+});
+
+export default app;

+ 89 - 0
src/server/api/roles/[id]/get.ts

@@ -0,0 +1,89 @@
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from 'zod';
+import { RoleService } from '@/server/modules/roles/role.service';
+import { AppDataSource } from '@/server/data-source';
+import { ErrorSchema } from '@/server/utils/errorHandler';
+import { RoleSchema } from '@/server/modules/roles/role.entity';
+import { authMiddleware } from '@/server/middleware/auth';
+import { AuthContext } from '@/server/types/context';
+import { logger } from '@/server/utils/logger';
+
+// 路径参数Schema
+const GetParamsSchema = z.object({
+  id: z.coerce.number().int().positive().openapi({
+    param: { name: 'id', in: 'path' },
+    example: 1,
+    description: '角色ID'
+  })
+});
+
+// 路由定义
+const routeDef = createRoute({
+  method: 'get',
+  path: '/{id}',
+  middleware: [authMiddleware],
+  request: {
+    params: GetParamsSchema
+  },
+  responses: {
+    200: {
+      description: '获取角色详情成功',
+      content: {
+        'application/json': { 
+          schema: z.object({
+            code: z.number().openapi({ example: 200 }),
+            message: z.string().openapi({ example: '获取角色详情成功' }),
+            data: RoleSchema
+          })
+        }
+      }
+    },
+    400: {
+      description: '请求参数错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    404: {
+      description: '角色不存在',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    500: {
+      description: '服务器内部错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    }
+  },
+  tags: ['角色管理']
+});
+
+// 创建路由实例
+const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+  try {
+    const roleService = new RoleService(AppDataSource);
+    const { id } = c.req.valid('param');
+    
+    const role = await roleService.findById(id);
+    
+    logger.api(`获取角色详情成功,ID: ${id}`);
+    return c.json({
+      code: 200,
+      message: '获取角色详情成功',
+      data: role
+    }, 200);
+  } catch (error) {
+    const message = error instanceof Error ? error.message : '获取角色详情失败';
+    const status = message.includes('不存在') ? 404 : 500;
+    
+    logger.error(`获取角色详情失败,ID: ${c.req.valid('param').id}, 错误: ${message}`);
+    return c.json({
+      code: status,
+      message
+    }, status);
+  }
+});
+
+export default app;

+ 103 - 0
src/server/api/roles/[id]/permissions.ts

@@ -0,0 +1,103 @@
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from 'zod';
+import { RoleService } from '@/server/modules/roles/role.service';
+import { AppDataSource } from '@/server/data-source';
+import { ErrorSchema } from '@/server/utils/errorHandler';
+import { RoleSchema } from '@/server/modules/roles/role.entity';
+import { authMiddleware } from '@/server/middleware/auth';
+import { AuthContext } from '@/server/types/context';
+import { logger } from '@/server/utils/logger';
+
+// 路径参数Schema
+const PermissionsParamsSchema = z.object({
+  id: z.coerce.number().int().positive().openapi({
+    param: { name: 'id', in: 'path' },
+    example: 1,
+    description: '角色ID'
+  })
+});
+
+// 权限分配请求Schema
+const AssignPermissionsSchema = z.object({
+  permissions: z.array(z.number().int().positive()).openapi({
+    example: [1, 2, 3, 4],
+    description: '权限ID列表'
+  })
+});
+
+// 路由定义
+const routeDef = createRoute({
+  method: 'post',
+  path: '/{id}/permissions',
+  middleware: [authMiddleware],
+  request: {
+    params: PermissionsParamsSchema,
+    body: {
+      content: {
+        'application/json': { schema: AssignPermissionsSchema }
+      }
+    }
+  },
+  responses: {
+    200: {
+      description: '分配角色权限成功',
+      content: {
+        'application/json': { 
+          schema: z.object({
+            code: z.number().openapi({ example: 200 }),
+            message: z.string().openapi({ example: '分配角色权限成功' }),
+            data: RoleSchema
+          })
+        }
+      }
+    },
+    400: {
+      description: '请求参数错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    404: {
+      description: '角色不存在',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    500: {
+      description: '服务器内部错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    }
+  },
+  tags: ['角色管理']
+});
+
+// 创建路由实例
+const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+  try {
+    const roleService = new RoleService(AppDataSource);
+    const { id } = c.req.valid('param');
+    const { permissions } = c.req.valid('json');
+    
+    const updatedRole = await roleService.assignPermissions(id, permissions);
+    
+    logger.api(`分配角色权限成功,ID: ${id}, 权限数量: ${permissions.length}`);
+    return c.json({
+      code: 200,
+      message: '分配角色权限成功',
+      data: updatedRole
+    }, 200);
+  } catch (error) {
+    const message = error instanceof Error ? error.message : '分配角色权限失败';
+    const statusCode = message.includes('不存在') ? 404 : 500;
+    
+    logger.error(`分配角色权限失败,ID: ${c.req.valid('param').id}, 错误: ${message}`);
+    return c.json({
+      code: statusCode,
+      message
+    }, statusCode);
+  }
+});
+
+export default app;

+ 111 - 0
src/server/api/roles/[id]/put.ts

@@ -0,0 +1,111 @@
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from 'zod';
+import { RoleService } from '@/server/modules/roles/role.service';
+import { AppDataSource } from '@/server/data-source';
+import { ErrorSchema } from '@/server/utils/errorHandler';
+import { RoleSchema } from '@/server/modules/roles/role.entity';
+import { authMiddleware } from '@/server/middleware/auth';
+import { AuthContext } from '@/server/types/context';
+import { logger } from '@/server/utils/logger';
+
+// 路径参数Schema
+const UpdateParamsSchema = z.object({
+  id: z.coerce.number().int().positive().openapi({
+    param: { name: 'id', in: 'path' },
+    example: 1,
+    description: '角色ID'
+  })
+});
+
+// 更新角色请求Schema
+const UpdateRoleSchema = z.object({
+  name: z.string().min(2).max(50).openapi({
+    example: '财务管理员',
+    description: '角色名称'
+  }),
+  description: z.string().max(200).optional().nullable().openapi({
+    example: '负责财务管理相关操作',
+    description: '角色描述'
+  }),
+  status: z.number().int().min(0).max(1).openapi({
+    example: 1,
+    description: '角色状态 (0: 禁用, 1: 启用)'
+  })
+});
+
+// 路由定义
+const routeDef = createRoute({
+  method: 'put',
+  path: '/{id}',
+  middleware: [authMiddleware],
+  request: {
+    params: UpdateParamsSchema,
+    body: {
+      content: {
+        'application/json': { schema: UpdateRoleSchema }
+      }
+    }
+  },
+  responses: {
+    200: {
+      description: '更新角色成功',
+      content: {
+        'application/json': { 
+          schema: z.object({
+            code: z.number().openapi({ example: 200 }),
+            message: z.string().openapi({ example: '更新角色成功' }),
+            data: RoleSchema
+          })
+        }
+      }
+    },
+    400: {
+      description: '请求参数错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    404: {
+      description: '角色不存在',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    500: {
+      description: '服务器内部错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    }
+  },
+  tags: ['角色管理']
+});
+
+// 创建路由实例
+const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+  try {
+    const roleService = new RoleService(AppDataSource);
+    const { id } = c.req.valid('param');
+    const roleData = c.req.valid('json');
+    
+    const updatedRole = await roleService.update(id, roleData);
+    
+    logger.api(`更新角色成功,ID: ${id}`);
+    return c.json({
+      code: 200,
+      message: '更新角色成功',
+      data: updatedRole
+    }, 200);
+  } catch (error) {
+    const message = error instanceof Error ? error.message : '更新角色失败';
+    const status = message.includes('不存在') ? 404 : 400;
+    
+    logger.error(`更新角色失败,ID: ${c.req.valid('param').id}, 错误: ${message}`);
+    return c.json({
+      code: status,
+      message
+    }, status);
+  }
+});
+
+export default app;

+ 104 - 0
src/server/api/roles/[id]/status.ts

@@ -0,0 +1,104 @@
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from 'zod';
+import { RoleService } from '@/server/modules/roles/role.service';
+import { AppDataSource } from '@/server/data-source';
+import { ErrorSchema } from '@/server/utils/errorHandler';
+import { RoleSchema } from '@/server/modules/roles/role.entity';
+import { authMiddleware } from '@/server/middleware/auth';
+import { AuthContext } from '@/server/types/context';
+import { logger } from '@/server/utils/logger';
+
+// 路径参数Schema
+const StatusParamsSchema = z.object({
+  id: z.coerce.number().int().positive().openapi({
+    param: { name: 'id', in: 'path' },
+    example: 1,
+    description: '角色ID'
+  })
+});
+
+// 状态更新请求Schema
+const UpdateStatusSchema = z.object({
+  status: z.number().int().min(0).max(1).openapi({
+    example: 0,
+    description: '角色状态 (0: 禁用, 1: 启用)'
+  })
+});
+
+// 路由定义
+const routeDef = createRoute({
+  method: 'patch',
+  path: '/{id}/status',
+  middleware: [authMiddleware],
+  request: {
+    params: StatusParamsSchema,
+    body: {
+      content: {
+        'application/json': { schema: UpdateStatusSchema }
+      }
+    }
+  },
+  responses: {
+    200: {
+      description: '更新角色状态成功',
+      content: {
+        'application/json': { 
+          schema: z.object({
+            code: z.number().openapi({ example: 200 }),
+            message: z.string().openapi({ example: '更新角色状态成功' }),
+            data: RoleSchema
+          })
+        }
+      }
+    },
+    400: {
+      description: '请求参数错误或不允许禁用系统角色',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    404: {
+      description: '角色不存在',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    500: {
+      description: '服务器内部错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    }
+  },
+  tags: ['角色管理']
+});
+// 创建路由实例
+const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+  try {
+    const roleService = new RoleService(AppDataSource);
+    const { id } = c.req.valid('param');
+    const { status } = c.req.valid('json');
+    
+    const updatedRole = await roleService.changeStatus(id, status);
+    
+    logger.api(`更新角色状态成功,ID: ${id}, 新状态: ${status}`);
+    return c.json({
+      code: 200,
+      message: '更新角色状态成功',
+      data: updatedRole
+    }, 200);
+  } catch (error) {
+    const message = error instanceof Error ? error.message : '更新角色状态失败';
+    const statusCode = message.includes('不存在') ? 404 :
+                      message.includes('不允许') ? 400 : 500;
+    
+    logger.error(`更新角色状态失败,ID: ${c.req.valid('param').id}, 错误: ${message}`);
+    return c.json({
+      code: statusCode,
+      message
+    }, statusCode);
+  }
+});
+
+
+export default app;

+ 101 - 0
src/server/api/roles/get.ts

@@ -0,0 +1,101 @@
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from 'zod';
+import { RoleService } from '@/server/modules/roles/role.service';
+import { AppDataSource } from '@/server/data-source';
+import { ErrorSchema } from '@/server/utils/errorHandler';
+import { RoleSchema } from '@/server/modules/roles/role.entity';
+import { authMiddleware } from '@/server/middleware/auth';
+import { AuthContext } from '@/server/types/context';
+import { logger } from '@/server/utils/logger';
+
+// 分页查询参数Schema
+const ListParamsSchema = z.object({
+  page: z.coerce.number().int().positive().default(1).openapi({
+    param: { name: 'page', in: 'query' },
+    example: 1,
+    description: '页码'
+  }),
+  pageSize: z.coerce.number().int().positive().default(10).openapi({
+    param: { name: 'pageSize', in: 'query' },
+    example: 10,
+    description: '每页条数'
+  }),
+  name: z.string().optional().openapi({
+    param: { name: 'name', in: 'query' },
+    example: '管理员',
+    description: '角色名称筛选'
+  }),
+  status: z.coerce.number().int().optional().openapi({
+    param: { name: 'status', in: 'query' },
+    example: 1,
+    description: '角色状态筛选 (0: 禁用, 1: 启用)'
+  })
+});
+
+// 列表响应Schema
+const ListResponseSchema = z.object({
+  data: z.array(RoleSchema),
+  pagination: z.object({
+    total: z.number().openapi({ example: 100, description: '总记录数' }),
+    current: z.number().openapi({ example: 1, description: '当前页码' }),
+    pageSize: z.number().openapi({ example: 10, description: '每页条数' }),
+    totalPages: z.number().openapi({ example: 10, description: '总页数' })
+  })
+});
+
+// 路由定义
+const routeDef = createRoute({
+  method: 'get',
+  path: '/',
+  middleware: [authMiddleware],
+  request: {
+    query: ListParamsSchema
+  },
+  responses: {
+    200: {
+      description: '获取角色列表成功',
+      content: {
+        'application/json': { schema: ListResponseSchema }
+      }
+    },
+    400: {
+      description: '请求参数错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    500: {
+      description: '服务器内部错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    }
+  },
+  tags: ['角色管理']
+});
+
+// 创建路由实例
+const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+  try {
+    const roleService = new RoleService(AppDataSource);
+    const { page, pageSize, name, status } = c.req.valid('query');
+    
+    const result = await roleService.findAll(page, pageSize, name, status);
+    
+    logger.api(`获取角色列表成功,页码: ${page}, 每页条数: ${pageSize}`);
+    return c.json({
+      code: 200,
+      message: '获取角色列表成功',
+      data: result.data,
+      pagination: result.pagination
+    }, 200);
+  } catch (error) {
+    logger.error(`获取角色列表失败: ${error instanceof Error ? error.message : String(error)}`);
+    return c.json({
+      code: 500,
+      message: error instanceof Error ? error.message : '获取角色列表失败'
+    }, 500);
+  }
+});
+
+export default app;

+ 20 - 0
src/server/api/roles/index.ts

@@ -0,0 +1,20 @@
+import { OpenAPIHono } from '@hono/zod-openapi';
+import listRoute from './get';
+import createRoute from './post';
+import getByIdRoute from './[id]/get';
+import updateRoute from './[id]/put';
+import deleteRoute from './[id]/delete';
+import statusRoute from './[id]/status';
+import permissionsRoute from './[id]/permissions';
+import { AuthContext } from '@/server/types/context';
+
+const app = new OpenAPIHono<AuthContext>()
+  .route('/', listRoute)
+  .route('/', createRoute)
+  .route('/', getByIdRoute)
+  .route('/', updateRoute)
+  .route('/', deleteRoute)
+  .route('/', statusRoute)
+  .route('/', permissionsRoute);
+
+export default app;

+ 101 - 0
src/server/api/roles/post.ts

@@ -0,0 +1,101 @@
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from 'zod';
+import { RoleService } from '@/server/modules/roles/role.service';
+import { AppDataSource } from '@/server/data-source';
+import { ErrorSchema } from '@/server/utils/errorHandler';
+import { RoleSchema } from '@/server/modules/roles/role.entity';
+import { authMiddleware } from '@/server/middleware/auth';
+import { AuthContext } from '@/server/types/context';
+import { logger } from '@/server/utils/logger';
+
+// 创建角色请求Schema
+const CreateRoleSchema = z.object({
+  name: z.string().min(2).max(50).openapi({
+    example: '财务管理员',
+    description: '角色名称'
+  }),
+  description: z.string().max(200).optional().nullable().openapi({
+    example: '负责财务管理相关操作',
+    description: '角色描述'
+  }),
+  status: z.number().int().min(0).max(1).default(1).openapi({
+    example: 1,
+    description: '角色状态 (0: 禁用, 1: 启用)'
+  }),
+  permissions: z.array(z.number()).optional().openapi({
+    example: [1, 2, 3],
+    description: '权限ID列表'
+  })
+});
+
+// 路由定义
+const routeDef = createRoute({
+  method: 'post',
+  path: '/',
+  middleware: [authMiddleware],
+  request: {
+    body: {
+      content: {
+        'application/json': { schema: CreateRoleSchema }
+      }
+    }
+  },
+  responses: {
+    200: {
+      description: '创建角色成功',
+      content: {
+        'application/json': {
+          schema: z.object({
+            code: z.number().openapi({ example: 200 }),
+            message: z.string().openapi({ example: '创建角色成功' }),
+            data: RoleSchema
+          })
+        }
+      }
+    },
+    400: {
+      description: '请求参数错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    },
+    500: {
+      description: '服务器内部错误',
+      content: {
+        'application/json': { schema: ErrorSchema }
+      }
+    }
+  },
+  tags: ['角色管理']
+});
+
+// 创建路由实例
+const app = new OpenAPIHono<AuthContext>().openapi(routeDef, async (c) => {
+  try {
+    const roleService = new RoleService(AppDataSource);
+    const roleData = c.req.valid('json');
+    const { permissions, ...createData } = roleData;
+    
+    const newRole = await roleService.create(createData);
+    
+    // 如果有提供权限,分配权限
+    if (permissions && permissions.length > 0) {
+      await roleService.assignPermissions(newRole.id, permissions);
+    }
+    
+    logger.api(`创建角色成功,ID: ${newRole.id}, 名称: ${newRole.name}`);
+    return c.json({
+      code: 200,
+      message: '创建角色成功',
+      data: newRole
+    }, 200);
+  } catch (error) {
+    logger.error(`创建角色失败: ${error instanceof Error ? error.message : String(error)}`);
+    return c.json({
+      code: 400,
+      message: error instanceof Error ? error.message : '创建角色失败'
+    }, 400);
+  }
+});
+
+export default app;

+ 216 - 0
src/server/modules/roles/role.service.ts

@@ -0,0 +1,216 @@
+import { DataSource, Repository } from 'typeorm';
+import { Role } from './role.entity';
+import { logger } from '@/server/utils/logger';
+import { AppDataSource } from '@/server/data-source';
+
+export class RoleService {
+  private roleRepository: Repository<Role>;
+
+  constructor(dataSource: DataSource) {
+    this.roleRepository = dataSource.getRepository(Role);
+  }
+
+  /**
+   * 获取角色列表,支持分页和条件筛选
+   */
+  async findAll(
+    page: number = 1,
+    pageSize: number = 10,
+    name?: string,
+    status?: number
+  ) {
+    const query = this.roleRepository.createQueryBuilder('role');
+
+    // 条件筛选
+    if (name) {
+      query.andWhere('role.name LIKE :name', { name: `%${name}%` });
+    }
+    if (status !== undefined) {
+      query.andWhere('role.status = :status', { status });
+    }
+
+    // 排除已删除的角色
+    query.andWhere('role.isDeleted = 0');
+
+    // 分页处理
+    query.skip((page - 1) * pageSize);
+    query.take(pageSize);
+
+    // 排序
+    query.orderBy('role.createdAt', 'DESC');
+
+    // 执行查询
+    const [items, total] = await query.getManyAndCount();
+
+    logger.api(`获取角色列表成功,共${total}条记录`);
+    
+    return {
+      data: items,
+      pagination: {
+        total,
+        current: page,
+        pageSize,
+        totalPages: Math.ceil(total / pageSize)
+      }
+    };
+  }
+
+  /**
+   * 根据ID获取角色详情
+   */
+  async findById(id: number) {
+    const role = await this.roleRepository.findOne({
+      where: { id, isDeleted: 0 },
+      relations: ['permissions']
+    });
+
+    if (!role) {
+      logger.error(`角色不存在,ID: ${id}`);
+      throw new Error('角色不存在');
+    }
+
+    logger.api(`获取角色详情成功,ID: ${id}`);
+    return role;
+  }
+
+  /**
+   * 创建新角色
+   */
+  async create(roleData: Partial<Role>) {
+    // 检查角色名称是否已存在
+    const existingRole = await this.roleRepository.findOne({
+      where: { name: roleData.name, isDeleted: 0 }
+    });
+
+    if (existingRole) {
+      logger.error(`角色名称已存在: ${roleData.name}`);
+      throw new Error('角色名称已存在');
+    }
+
+    const role = this.roleRepository.create({
+      ...roleData,
+      status: roleData.status ?? 1, // 默认启用状态
+      isDeleted: 0,
+      createdAt: new Date(),
+      updatedAt: new Date()
+    });
+
+    const savedRole = await this.roleRepository.save(role);
+    logger.api(`创建角色成功,ID: ${savedRole.id}`);
+    return savedRole;
+  }
+
+  /**
+   * 更新角色信息
+   */
+  async update(id: number, roleData: Partial<Role>) {
+    const role = await this.findById(id);
+
+    // 如果更新名称,检查新名称是否已存在
+    if (roleData.name && roleData.name !== role.name) {
+      const existingRole = await this.roleRepository.findOne({
+        where: { name: roleData.name, isDeleted: 0 }
+      });
+
+      if (existingRole) {
+        logger.error(`角色名称已存在: ${roleData.name}`);
+        throw new Error('角色名称已存在');
+      }
+    }
+
+    Object.assign(role, {
+      ...roleData,
+      updatedAt: new Date()
+    });
+
+    const updatedRole = await this.roleRepository.save(role);
+    logger.api(`更新角色成功,ID: ${id}`);
+    return updatedRole;
+  }
+
+  /**
+   * 删除角色(软删除)
+   */
+  async delete(id: number) {
+    // 检查是否存在关联用户
+    const userRoleRepo = AppDataSource.getRepository('user_role');
+    const userRoles = await userRoleRepo.find({
+      where: { roleId: id }
+    });
+
+    if (userRoles.length > 0) {
+      logger.error(`删除角色失败,角色已关联用户,ID: ${id}`);
+      throw new Error('该角色已关联用户,无法删除');
+    }
+
+    const role = await this.findById(id);
+    
+    role.isDeleted = 1;
+    role.updatedAt = new Date();
+    
+    await this.roleRepository.save(role);
+    logger.api(`删除角色成功,ID: ${id}`);
+    return true;
+  }
+
+  /**
+   * 更改角色状态
+   */
+  async changeStatus(id: number, status: number) {
+    if (![0, 1].includes(status)) {
+      logger.error(`无效的角色状态: ${status}`);
+      throw new Error('无效的角色状态,只能是0或1');
+    }
+
+    const role = await this.findById(id);
+    // 不允许禁用系统角色
+    if (role.isSystem && status === 0) {
+      logger.error(`尝试禁用系统角色,ID: ${id}`);
+      throw new Error('不允许禁用系统角色');
+    }
+
+
+    role.status = status;
+    role.updatedAt = new Date();
+    
+    await this.roleRepository.save(role);
+    logger.api(`更改角色状态成功,ID: ${id},新状态: ${status}`);
+    return role;
+  }
+
+  /**
+   * 分配权限给角色
+   */
+  async assignPermissions(id: number, permissionIds: number[]) {
+    const role = await this.findById(id);
+    
+    // 这里简化处理,实际项目中应该有专门的权限表和关联表
+    // 假设Role实体有permissions字段存储权限ID数组的JSON字符串
+    role.permissions = JSON.stringify(permissionIds);
+    role.updatedAt = new Date();
+    
+    await this.roleRepository.save(role);
+    logger.api(`为角色分配权限成功,ID: ${id},权限数量: ${permissionIds.length}`);
+    return role;
+  }
+
+  /**
+   * 检查角色是否有权限
+   */
+  async hasPermission(roleId: number, permissionCode: string): Promise<boolean> {
+    const role = await this.findById(roleId);
+    
+    // 超级管理员拥有所有权限
+    if (role.isSuper) {
+      return true;
+    }
+    
+    // 这里简化处理,实际项目中应该根据permissionCode查询权限ID
+    // 并检查角色是否拥有该权限
+    // 假设permissions字段存储的是权限ID数组
+    // 这里需要根据实际的权限系统实现
+    
+    logger.api(`检查角色权限: 角色ID=${roleId}, 权限码=${permissionCode}, 结果=${true}`);
+    return true; // 简化返回true,实际项目中需要根据权限系统实现
+  }
+}