Parcourir la source

✨ feat(crud): 添加基于权限的路由控制功能

- 扩展CrudOptions接口为CrudOptionsWithPermissions,支持权限配置
- 添加permissions配置项,可分别为create/read/update/delete操作指定权限
- 实现buildMiddleware函数,根据权限配置自动添加权限检查中间件
- 为各CRUD路由(列表/创建/获取/更新/删除)添加权限中间件支持
- 权限中间件使用permissionMiddleware和checkPermission实现权限验证
yourname il y a 7 mois
Parent
commit
93aa511bf2
1 fichiers modifiés avec 36 ajouts et 7 suppressions
  1. 36 7
      src/server/utils/generic-crud.routes.ts

+ 36 - 7
src/server/utils/generic-crud.routes.ts

@@ -7,6 +7,23 @@ import { ObjectLiteral } from 'typeorm';
 import { AppDataSource } from '../data-source';
 import { DataPermissionService } from '@/server/modules/permissions/data-permission.service';
 import { DepartmentService } from '@/server/modules/departments/department.service';
+import { checkPermission, permissionMiddleware } from '../middleware/permission.middleware';
+
+// 扩展的权限配置接口
+export interface CrudOptionsWithPermissions<
+  T extends ObjectLiteral,
+  CreateSchema extends z.ZodSchema = z.ZodSchema,
+  UpdateSchema extends z.ZodSchema = z.ZodSchema,
+  GetSchema extends z.ZodSchema = z.ZodSchema,
+  ListSchema extends z.ZodSchema = z.ZodSchema
+> extends CrudOptions<T, CreateSchema, UpdateSchema, GetSchema, ListSchema> {
+  permissions?: {
+    create?: string[];      // CREATE权限
+    read?: string[];        // READ权限
+    update?: string[];      // UPDATE权限
+    delete?: string[];      // DELETE权限
+  };
+}
 
 export function createCrudRoutes<
   T extends ObjectLiteral,
@@ -14,8 +31,8 @@ export function createCrudRoutes<
   UpdateSchema extends z.ZodSchema = z.ZodSchema,
   GetSchema extends z.ZodSchema = z.ZodSchema,
   ListSchema extends z.ZodSchema = z.ZodSchema
->(options: CrudOptions<T, CreateSchema, UpdateSchema, GetSchema, ListSchema>) {
-  const { entity, createSchema, updateSchema, getSchema, listSchema, searchFields, relations, middleware = [], userTracking, dataPermission } = options;
+>(options: CrudOptionsWithPermissions<T, CreateSchema, UpdateSchema, GetSchema, ListSchema>) {
+  const { entity, createSchema, updateSchema, getSchema, listSchema, searchFields, relations, middleware = [], userTracking, dataPermission, permissions } = options;
   
   // 创建部门服务和数据权限服务
   const departmentService = new DepartmentService(AppDataSource);
@@ -35,11 +52,23 @@ export function createCrudRoutes<
   // 创建路由实例
   const app = new OpenAPIHono<AuthContext>();
   
+  // 构建权限中间件
+  const buildMiddleware = (baseMiddleware: any[], permissionType?: string[]) => {
+    const result = [...baseMiddleware];
+    
+    // 添加权限检查中间件(如果有配置)
+    if (permissionType && permissionType.length > 0) {
+      result.push(permissionMiddleware(checkPermission(permissionType)));
+    }
+    
+    return result;
+  };
+  
   // 分页查询路由
   const listRoute = createRoute({
     method: 'get',
     path: '/',
-    middleware,
+    middleware: buildMiddleware(middleware, permissions?.read),
     request: {
       query: z.object({
         page: z.coerce.number().int().positive().default(1).openapi({
@@ -100,7 +129,7 @@ export function createCrudRoutes<
   const createRouteDef = createRoute({
     method: 'post',
     path: '/',
-    middleware,
+    middleware: buildMiddleware(middleware, permissions?.create),
     request: {
       body: {
         content: {
@@ -128,7 +157,7 @@ export function createCrudRoutes<
   const getRouteDef = createRoute({
     method: 'get',
     path: '/{id}',
-    middleware,
+    middleware: buildMiddleware(middleware, permissions?.read),
     request: {
       params: z.object({
         id: z.coerce.number().openapi({
@@ -162,7 +191,7 @@ export function createCrudRoutes<
   const updateRouteDef = createRoute({
     method: 'put',
     path: '/{id}',
-    middleware,
+    middleware: buildMiddleware(middleware, permissions?.update),
     request: {
       params: z.object({
         id: z.coerce.number().openapi({
@@ -201,7 +230,7 @@ export function createCrudRoutes<
   const deleteRouteDef = createRoute({
     method: 'delete',
     path: '/{id}',
-    middleware,
+    middleware: buildMiddleware(middleware, permissions?.delete),
     request: {
       params: z.object({
         id: z.coerce.number().openapi({