diff --git a/.kiro/specs/admin-system/design.md b/.kiro/specs/admin-system/design.md index bcf69164..4362e7e7 100644 --- a/.kiro/specs/admin-system/design.md +++ b/.kiro/specs/admin-system/design.md @@ -2,7 +2,9 @@ ## Overview -HoneyBox.Admin 是一个独立可复用的后台管理模块,采用 ASP.NET Core 8.0 后端 + Vue3 + Element Plus 前端架构。后端提供 RESTful API,前端打包后部署到 wwwroot 目录实现一体化部署。 +HoneyBox.Admin 是一个独立可复用的后台管理模块,采用 ASP.NET Core 10.0 后端(.NET 10 + ASP.NET Core + Entity Framework Core 8 (SQL Server) + Autofac + JWT Bearer + Serilog + Mapster + Scalar (OpenAPI) + StackExchange.Redis + Newtonsoft.Json ) + Vue3 + Element Plus + TypeScript 前端架构。后端提供 RESTful API,前端打包后部署到 wwwroot 目录实现一体化部署。 + +**Design Decision**: 前端使用 TypeScript 以提供更好的类型安全和开发体验,符合 Requirements 9.1 的要求。 ## Architecture @@ -16,6 +18,7 @@ HoneyBox.Admin 是一个独立可复用的后台管理模块,采用 ASP.NET Co │ ├── index.html │ ├── AuthController.cs │ │ ├── assets/ │ ├── MenuController.cs │ │ └── (Vue3 打包文件) │ ├── RoleController.cs │ +│ │ ├── DepartmentController.cs │ │ │ ├── AdminUserController.cs │ │ │ └── OperationLogController.cs │ ├─────────────────────────────────────────────────────────────────┤ @@ -23,7 +26,8 @@ HoneyBox.Admin 是一个独立可复用的后台管理模块,采用 ASP.NET Co │ ├── AuthService.cs │ ├── AdminUser.cs │ │ ├── MenuService.cs │ ├── Role.cs │ │ ├── RoleService.cs │ ├── Menu.cs │ -│ ├── AdminUserService.cs │ ├── Permission.cs │ +│ ├── AdminUserService.cs │ ├── Department.cs │ +│ ├── DepartmentService.cs │ ├── Permission.cs │ │ ├── PermissionService.cs │ └── OperationLog.cs │ │ └── OperationLogService.cs │ │ ├─────────────────────────────────────────────────────────────────┤ @@ -146,11 +150,44 @@ public class AdminUserController : ControllerBase // PUT /api/admin/users/{id} - 更新管理员 // DELETE /api/admin/users/{id} - 删除管理员 // PUT /api/admin/users/{id}/roles - 分配角色 + // PUT /api/admin/users/{id}/menus - 分配用户专属菜单 + // PUT /api/admin/users/{id}/department - 分配部门 // PUT /api/admin/users/{id}/status - 启用/禁用 // PUT /api/admin/users/{id}/reset-password - 重置密码 } ``` +#### DepartmentController + +```csharp +[ApiController] +[Route("api/admin/departments")] +[AdminAuth] +public class DepartmentController : ControllerBase +{ + // GET /api/admin/departments - 获取部门树 + // GET /api/admin/departments/{id} - 获取部门详情 + // POST /api/admin/departments - 创建部门 + // PUT /api/admin/departments/{id} - 更新部门 + // DELETE /api/admin/departments/{id} - 删除部门 + // PUT /api/admin/departments/{id}/menus - 分配部门菜单 + // GET /api/admin/departments/{id}/users - 获取部门下用户 +} +``` + +#### OperationLogController + +```csharp +[ApiController] +[Route("api/admin/logs")] +[AdminAuth] +public class OperationLogController : ControllerBase +{ + // GET /api/admin/logs - 获取操作日志列表(分页、筛选) + // GET /api/admin/logs/{id} - 获取日志详情 +} +``` + ### 2. Service Interfaces ```csharp @@ -170,6 +207,7 @@ public interface IMenuService Task UpdateAsync(long id, UpdateMenuRequest request); Task DeleteAsync(long id); Task> GetUserMenusAsync(long adminUserId); + // 用户菜单 = 部门菜单 ∪ 角色菜单 ∪ 用户专属菜单 } public interface IRoleService @@ -191,18 +229,65 @@ public interface IAdminUserService Task UpdateAsync(long id, UpdateAdminUserRequest request); Task DeleteAsync(long id); Task AssignRolesAsync(long userId, List roleIds); + Task AssignMenusAsync(long userId, List menuIds); + Task AssignDepartmentAsync(long userId, long? departmentId); Task SetStatusAsync(long userId, bool enabled); Task ResetPasswordAsync(long userId, string newPassword); } +public interface IDepartmentService +{ + Task> GetDepartmentTreeAsync(); + Task GetByIdAsync(long id); + Task CreateAsync(CreateDepartmentRequest request); + Task UpdateAsync(long id, UpdateDepartmentRequest request); + Task DeleteAsync(long id); + Task AssignMenusAsync(long departmentId, List menuIds); + Task> GetDepartmentUsersAsync(long departmentId); +} + public interface IPermissionService { Task> GetUserPermissionsAsync(long adminUserId); Task HasPermissionAsync(long adminUserId, string permissionCode); void InvalidateCache(long adminUserId); } + +public interface IOperationLogService +{ + Task LogAsync(OperationLogRequest request); + Task> GetListAsync(OperationLogQueryRequest request); + Task GetByIdAsync(long id); +} ``` +### 3. DataSeeder + +```csharp +public interface IDataSeeder +{ + Task SeedAsync(); +} + +public class DataSeeder : IDataSeeder +{ + // 初始化超级管理员账号 (admin/admin123) + // 初始化超级管理员角色 (super_admin) + // 初始化系统菜单 (系统管理、菜单管理、角色管理、管理员管理、操作日志) + // 初始化系统权限 (所有 API 权限) + + public async Task SeedAsync() + { + await SeedPermissionsAsync(); + await SeedRolesAsync(); + await SeedMenusAsync(); + await SeedAdminUserAsync(); + } +} +``` + +**Design Decision**: DataSeeder 在应用启动时检查是否需要初始化数据,仅在数据库为空时执行种子数据插入,避免重复初始化。 + ## Data Models @@ -219,6 +304,7 @@ public class AdminUser public string? Avatar { get; set; } public string? Email { get; set; } public string? Phone { get; set; } + public long? DepartmentId { get; set; } public byte Status { get; set; } = 1; // 0禁用 1启用 public DateTime? LastLoginTime { get; set; } public string? LastLoginIp { get; set; } @@ -229,7 +315,26 @@ public class AdminUser public long? CreatedBy { get; set; } public string? Remark { get; set; } + public Department? Department { get; set; } public ICollection AdminUserRoles { get; set; } + public ICollection AdminUserMenus { get; set; } +} + +// 部门(支持无限嵌套) +public class Department +{ + public long Id { get; set; } + public long ParentId { get; set; } = 0; + public string Name { get; set; } + public string? Code { get; set; } + public string? Description { get; set; } + public int SortOrder { get; set; } = 0; + public byte Status { get; set; } = 1; + public DateTime CreatedAt { get; set; } + public DateTime? UpdatedAt { get; set; } + + public ICollection AdminUsers { get; set; } + public ICollection DepartmentMenus { get; set; } } // 角色 @@ -330,6 +435,26 @@ public class RolePermission public Role Role { get; set; } public Permission Permission { get; set; } } + +// 部门-菜单关联 +public class DepartmentMenu +{ + public long Id { get; set; } + public long DepartmentId { get; set; } + public long MenuId { get; set; } + public Department Department { get; set; } + public Menu Menu { get; set; } +} + +// 用户-菜单关联(用户专属菜单) +public class AdminUserMenu +{ + public long Id { get; set; } + public long AdminUserId { get; set; } + public long MenuId { get; set; } + public AdminUser AdminUser { get; set; } + public Menu Menu { get; set; } +} ``` @@ -397,12 +522,112 @@ public class MenuTreeDto public int SortOrder { get; set; } public List Children { get; set; } } + +// 操作日志 +public class OperationLogDto +{ + public long Id { get; set; } + public long? AdminUserId { get; set; } + public string? Username { get; set; } + public string? Module { get; set; } + public string? Action { get; set; } + public string? Method { get; set; } + public string? Url { get; set; } + public string? Ip { get; set; } + public byte Status { get; set; } + public int Duration { get; set; } + public DateTime CreatedAt { get; set; } +} + +public class OperationLogQueryRequest +{ + public int Page { get; set; } = 1; + public int PageSize { get; set; } = 20; + public long? AdminUserId { get; set; } + public string? Module { get; set; } + public string? Action { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } +} + +public class OperationLogRequest +{ + public long? AdminUserId { get; set; } + public string? Username { get; set; } + public string? Module { get; set; } + public string? Action { get; set; } + public string? Method { get; set; } + public string? Url { get; set; } + public string? Ip { get; set; } + public string? RequestData { get; set; } + public string? ResponseData { get; set; } + public byte Status { get; set; } + public string? ErrorMsg { get; set; } + public int Duration { get; set; } +} + +// 部门树 +public class DepartmentTreeDto +{ + public long Id { get; set; } + public long ParentId { get; set; } + public string Name { get; set; } + public string? Code { get; set; } + public int SortOrder { get; set; } + public byte Status { get; set; } + public int UserCount { get; set; } + public List Children { get; set; } +} + +public class DepartmentDto +{ + public long Id { get; set; } + public long ParentId { get; set; } + public string Name { get; set; } + public string? Code { get; set; } + public string? Description { get; set; } + public int SortOrder { get; set; } + public byte Status { get; set; } + public List MenuIds { get; set; } +} + +public class CreateDepartmentRequest +{ + public long ParentId { get; set; } = 0; + public string Name { get; set; } + public string? Code { get; set; } + public string? Description { get; set; } + public int SortOrder { get; set; } = 0; +} + +public class UpdateDepartmentRequest +{ + public long ParentId { get; set; } + public string Name { get; set; } + public string? Code { get; set; } + public string? Description { get; set; } + public int SortOrder { get; set; } + public byte Status { get; set; } +} ``` ## Database Schema 数据库表结构参见迁移计划文档 `docs/后台管理系统迁移计划.md` 第三节。 +### 连接配置 + +```json +{ + "ConnectionStrings": { + "DefaultConnection": "Server=192.168.195.15;uid=sa;pwd=Dbt@com@123;Database=honey_box_admin;MultipleActiveResultSets=true;pooling=true;min pool size=5;max pool size=32767;connect timeout=20;Encrypt=True;TrustServerCertificate=True;", + "Redis": "192.168.195.15:6379,abortConnect=false,connectTimeout=5000" + } +} +``` + +**MCP 工具**: 使用 `admin-sqlserver` MCP 插件可以直接查询数据库,用于反向生成实体或验证表结构。 + ### AdminDbContext 配置 ```csharp @@ -411,10 +636,13 @@ public class AdminDbContext : DbContext public DbSet AdminUsers { get; set; } public DbSet Roles { get; set; } public DbSet Menus { get; set; } + public DbSet Departments { get; set; } public DbSet Permissions { get; set; } public DbSet AdminUserRoles { get; set; } + public DbSet AdminUserMenus { get; set; } public DbSet RoleMenus { get; set; } public DbSet RolePermissions { get; set; } + public DbSet DepartmentMenus { get; set; } public DbSet OperationLogs { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) @@ -429,15 +657,24 @@ public class AdminDbContext : DbContext modelBuilder.Entity() .HasIndex(e => e.Code).IsUnique(); + modelBuilder.Entity() + .HasIndex(e => e.Code).IsUnique(); + // 配置关联表复合唯一索引 modelBuilder.Entity() .HasIndex(e => new { e.AdminUserId, e.RoleId }).IsUnique(); + modelBuilder.Entity() + .HasIndex(e => new { e.AdminUserId, e.MenuId }).IsUnique(); + modelBuilder.Entity() .HasIndex(e => new { e.RoleId, e.MenuId }).IsUnique(); modelBuilder.Entity() .HasIndex(e => new { e.RoleId, e.PermissionId }).IsUnique(); + + modelBuilder.Entity() + .HasIndex(e => new { e.DepartmentId, e.MenuId }).IsUnique(); } } ``` @@ -456,6 +693,7 @@ admin-web/ │ │ ├── auth.ts │ │ ├── menu.ts │ │ ├── role.ts +│ │ ├── department.ts │ │ └── user.ts │ ├── assets/ # 静态资源 │ │ └── styles/ @@ -485,6 +723,7 @@ admin-web/ │ │ └── system/ # 系统管理 │ │ ├── menu/ # 菜单管理 │ │ ├── role/ # 角色管理 +│ │ ├── department/ # 部门管理 │ │ └── user/ # 管理员管理 │ ├── directives/ # 自定义指令 │ │ └── permission.ts # v-permission @@ -581,43 +820,91 @@ export const permission: Directive = { **Validates: Requirements 3.3** -### Property 4: Valid JWT tokens authenticate successfully +### Property 4: Account lockout after failed attempts + +*For any* admin user, after 5 consecutive failed login attempts, the account SHALL be locked for 30 minutes and subsequent login attempts SHALL be rejected until the lockout period expires. + +**Validates: Requirements 3.4** + +### Property 5: Valid JWT tokens authenticate successfully *For any* valid, non-expired JWT token issued by the system, requests with this token SHALL be authenticated successfully. **Validates: Requirements 3.6** -### Property 5: Invalid JWT tokens return 401 +### Property 6: Invalid JWT tokens return 401 *For any* invalid, expired, or malformed JWT token, requests SHALL return 401 Unauthorized. **Validates: Requirements 3.7** -### Property 6: Menu tree structure integrity +### Property 7: Menu tree structure integrity *For any* set of menus with parent-child relationships, the GetMenuTree operation SHALL return a valid tree where each menu appears exactly once and children are nested under their parent. **Validates: Requirements 4.1** -### Property 7: Menu with children cannot be deleted +### Property 8: Menu with children cannot be deleted *For any* menu that has child menus (other menus with parent_id pointing to it), deletion SHALL fail with an error. **Validates: Requirements 4.4** -### Property 8: User menus are role-restricted +### Property 9: User menus are multi-source merged -*For any* admin user, the menus returned by GetUserMenus SHALL be a subset of the menus assigned to the user's roles. +*For any* admin user, the menus returned by GetUserMenus SHALL be the union of: department menus, role menus, and user-specific menus. -**Validates: Requirements 4.7** +**Validates: Requirements 4.7, 11.2, 11.3** -### Property 9: Permission enforcement +### Property 10: Department tree structure integrity + +*For any* set of departments with parent-child relationships, the GetDepartmentTree operation SHALL return a valid tree where each department appears exactly once and children are nested under their parent. + +**Validates: Requirements 10.2** + +### Property 11: Department with children cannot be deleted + +*For any* department that has child departments (other departments with parent_id pointing to it), deletion SHALL fail with an error. + +**Validates: Requirements 10.5** + +### Property 12: Department with users cannot be deleted + +*For any* department that has users assigned to it, deletion SHALL fail with an error. + +**Validates: Requirements 10.6** + +### Property 13: Department cannot be its own ancestor + +*For any* department update operation, setting parent_id to itself or any of its descendants SHALL fail with an error. + +**Validates: Requirements 10.4** + +### Property 14: System role protection + +*For any* role with is_system = true, deletion SHALL fail with an error. + +**Validates: Requirements 5.4** + +### Property 15: Last super admin protection + +*For any* deletion attempt on the last admin user with super admin role, the deletion SHALL fail with an error. + +**Validates: Requirements 6.4** + +### Property 16: Permission enforcement *For any* API endpoint with a permission attribute, if the requesting user lacks that permission, the request SHALL return 403 Forbidden. **Validates: Requirements 7.1, 7.2** -### Property 10: Operation logging completeness +### Property 17: Permission cache invalidation + +*For any* admin user whose roles, department, or direct menus are changed, the permission cache SHALL be invalidated and subsequent permission checks SHALL reflect the new assignments. + +**Validates: Requirements 7.5, 11.5** + +### Property 18: Operation logging completeness *For any* create, update, or delete operation performed by an admin user, an operation log entry SHALL be created with the admin user id, action, and timestamp. @@ -659,6 +946,10 @@ public static class AdminErrorCodes public const int MenuHasChildren = 40204; public const int CannotDeleteSystemRole = 40205; public const int CannotDeleteLastSuperAdmin = 40206; + public const int DepartmentHasChildren = 40207; + public const int DepartmentHasUsers = 40208; + public const int DepartmentCircularReference = 40209; + public const int DuplicateDepartmentCode = 40210; // Server public const int InternalError = 50001; diff --git a/.kiro/specs/admin-system/requirements.md b/.kiro/specs/admin-system/requirements.md index b7c702c4..89cb2279 100644 --- a/.kiro/specs/admin-system/requirements.md +++ b/.kiro/specs/admin-system/requirements.md @@ -6,8 +6,9 @@ HoneyBox 后台管理系统基础框架,提供完整的 RBAC 权限管理功 ## Glossary -- **Admin_System**: 后台管理系统,包含认证、菜单、角色、权限等核心功能 +- **Admin_System**: 后台管理系统,包含认证、菜单、角色、权限、部门等核心功能 - **Admin_User**: 后台管理员,拥有登录后台的权限 +- **Department**: 部门,支持无限层级嵌套的组织架构单元 - **Role**: 角色,权限的集合,可分配给管理员 - **Menu**: 菜单,前端路由和导航项,支持树形结构 - **Permission**: 权限,API 级别的访问控制标识 @@ -35,13 +36,14 @@ HoneyBox 后台管理系统基础框架,提供完整的 RBAC 权限管理功 #### Acceptance Criteria -1. THE Admin_System SHALL create AdminUser entity with username, password_hash, real_name, avatar, status, last_login_time fields +1. THE Admin_System SHALL create AdminUser entity with username, password_hash, real_name, avatar, status, last_login_time, department_id fields 2. THE Admin_System SHALL create Role entity with name, code, description, sort_order, status, is_system fields 3. THE Admin_System SHALL create Menu entity with parent_id, name, path, component, icon, menu_type, permission, sort_order, status fields 4. THE Admin_System SHALL create Permission entity with name, code, module, description fields -5. THE Admin_System SHALL create AdminUserRole, RoleMenu, RolePermission junction entities for many-to-many relationships -6. THE Admin_System SHALL create OperationLog entity for audit logging -7. THE Admin_System SHALL create AdminDbContext with all entity configurations +5. THE Admin_System SHALL create AdminUserRole, RoleMenu, RolePermission, DepartmentMenu, AdminUserMenu junction entities for many-to-many relationships +6. THE Admin_System SHALL create Department entity with parent_id, name, code, sort_order, status fields +7. THE Admin_System SHALL create OperationLog entity for audit logging +8. THE Admin_System SHALL create AdminDbContext with all entity configurations ### Requirement 3: 管理员认证 @@ -70,7 +72,7 @@ HoneyBox 后台管理系统基础框架,提供完整的 RBAC 权限管理功 4. WHEN deleting a menu with children, THE Menu_Service SHALL prevent deletion and return an error 5. WHEN deleting a menu without children, THE Menu_Service SHALL remove the menu record 6. THE Menu_Service SHALL support three menu types: directory, menu, and button -7. WHEN requesting user menus, THE Menu_Service SHALL return only menus assigned to user's roles +7. WHEN requesting user menus, THE Menu_Service SHALL return menus merged from user's department, roles, and direct assignments ### Requirement 5: 角色管理 @@ -140,7 +142,34 @@ HoneyBox 后台管理系统基础框架,提供完整的 RBAC 权限管理功 7. THE Frontend SHALL implement permission directive v-permission for button-level control 8. WHEN built, THE Frontend SHALL output to HoneyBox.Admin/wwwroot folder -### Requirement 10: 数据初始化 +### Requirement 10: 部门管理 + +**User Story:** As an admin user, I want to manage departments with hierarchical structure, so that I can organize users and assign permissions at department level. + +#### Acceptance Criteria + +1. THE Admin_System SHALL create Department entity with parent_id supporting unlimited nesting levels +2. WHEN requesting department list, THE Department_Service SHALL return departments as a tree structure +3. WHEN creating a department, THE Department_Service SHALL validate required fields and parent existence +4. WHEN updating a department, THE Department_Service SHALL prevent setting parent to itself or its descendants +5. WHEN deleting a department with children, THE Department_Service SHALL prevent deletion and return an error +6. WHEN deleting a department with users, THE Department_Service SHALL prevent deletion and return an error +7. WHEN assigning menus to a department, THE Department_Service SHALL update the department-menu associations +8. THE Admin_System SHALL support assigning users to departments + +### Requirement 11: 用户菜单多维度配置 + +**User Story:** As an admin user, I want to configure user menus from multiple sources (department, role, direct assignment), so that I can have flexible permission control. + +#### Acceptance Criteria + +1. THE Admin_System SHALL support assigning menus directly to individual users +2. WHEN requesting user menus, THE Menu_Service SHALL merge menus from three sources: department menus, role menus, and user-specific menus +3. THE final user menu SHALL be the union of department menus, role menus, and user-specific menus +4. WHEN a user belongs to multiple departments, THE Menu_Service SHALL merge menus from all departments +5. WHEN user's department/role/direct menus change, THE Permission_Service SHALL invalidate the menu cache + +### Requirement 12: 数据初始化 **User Story:** As a developer, I want to initialize default data, so that the system is ready to use after deployment. @@ -150,3 +179,4 @@ HoneyBox 后台管理系统基础框架,提供完整的 RBAC 权限管理功 2. THE Admin_System SHALL create default super admin role with all permissions 3. THE Admin_System SHALL create default system menus for admin management 4. THE Admin_System SHALL create default permissions for all admin APIs +5. THE Admin_System SHALL create default root department diff --git a/.kiro/specs/admin-system/tasks.md b/.kiro/specs/admin-system/tasks.md index 3d7abf83..5a8291db 100644 --- a/.kiro/specs/admin-system/tasks.md +++ b/.kiro/specs/admin-system/tasks.md @@ -15,18 +15,18 @@ - [ ] 2. 实现数据库实体和 DbContext - [ ] 2.1 创建 Entity 类 - - 创建 AdminUser, Role, Menu, Permission 实体 - - 创建 AdminUserRole, RoleMenu, RolePermission 关联实体 + - 创建 AdminUser, Role, Menu, Permission, Department 实体 + - 创建 AdminUserRole, RoleMenu, RolePermission, DepartmentMenu, AdminUserMenu 关联实体 - 创建 OperationLog 实体 - - _Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6_ + - _Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7_ - [ ] 2.2 创建 AdminDbContext - 配置 DbSet 属性 - 配置实体关系和索引 - - _Requirements: 2.7_ + - _Requirements: 2.8_ - [ ] 2.3 执行数据库迁移 - 创建数据库表 - 验证表结构 - - _Requirements: 2.1-2.7_ + - _Requirements: 2.1-2.8_ - [ ] 3. 实现认证服务 - [ ] 3.1 创建 DTO 模型 @@ -48,7 +48,6 @@ - 处理无效/过期 Token - _Requirements: 3.6, 3.7_ - - [ ] 4. 实现菜单管理 - [ ] 4.1 创建菜单相关 DTO - 创建 MenuDto, MenuTreeDto, CreateMenuRequest, UpdateMenuRequest @@ -56,8 +55,8 @@ - [ ] 4.2 实现 IMenuService 和 MenuService - 实现 GetMenuTreeAsync (构建树形结构) - 实现 CRUD 方法 - - 实现 GetUserMenusAsync (基于角色过滤) - - _Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 4.7_ + - 实现 GetUserMenusAsync (合并部门菜单、角色菜单、用户专属菜单) + - _Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 4.7, 11.2, 11.3_ - [ ] 4.3 创建 MenuController - 实现所有菜单管理 API - _Requirements: 4.1-4.7_ @@ -82,131 +81,150 @@ - [ ] 6.2 实现 IAdminUserService 和 AdminUserService - 实现分页查询 - 实现 CRUD 方法 - - 实现角色分配、状态切换、密码重置 - - _Requirements: 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7_ + - 实现角色分配、部门分配、用户专属菜单分配、状态切换、密码重置 + - _Requirements: 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7, 10.8, 11.1_ - [ ] 6.3 创建 AdminUserController - 实现所有管理员管理 API - - _Requirements: 6.1-6.7_ + - 包含分配部门、分配用户专属菜单接口 + - _Requirements: 6.1-6.7, 10.8, 11.1_ -- [ ] 7. 实现权限控制 - - [ ] 7.1 实现 IPermissionService 和 PermissionService +- [ ] 7. 实现部门管理 + - [ ] 7.1 创建部门相关 DTO + - 创建 DepartmentDto, DepartmentTreeDto, CreateDepartmentRequest, UpdateDepartmentRequest + - _Requirements: 10.1, 10.2_ + - [ ] 7.2 实现 IDepartmentService 和 DepartmentService + - 实现 GetDepartmentTreeAsync (构建树形结构,支持无限嵌套) + - 实现 CRUD 方法 + - 实现部门菜单分配 + - 实现循环引用检测 (防止部门设为自己的子部门) + - _Requirements: 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7_ + - [ ] 7.3 创建 DepartmentController + - 实现所有部门管理 API + - _Requirements: 10.1-10.8_ + +- [ ] 8. 实现权限控制 + - [ ] 8.1 实现 IPermissionService 和 PermissionService - 实现 GetUserPermissionsAsync - 实现 HasPermissionAsync - - 实现权限缓存和失效 - - _Requirements: 7.1, 7.4, 7.5_ - - [ ] 7.2 创建 PermissionFilter + - 实现权限缓存和失效 (角色、部门、用户菜单变更时失效) + - _Requirements: 7.1, 7.4, 7.5, 11.5_ + - [ ] 8.2 创建 PermissionFilter - 实现 AdminPermissionAttribute - 实现权限验证逻辑 - _Requirements: 7.1, 7.2, 7.3_ - - [ ] 7.3 创建 PermissionController + - [ ] 8.3 创建 PermissionController - 实现权限列表查询 API - _Requirements: 7.1_ - -- [ ] 8. 实现操作日志 - - [ ] 8.1 实现 IOperationLogService 和 OperationLogService +- [ ] 9. 实现操作日志 + - [ ] 9.1 实现 IOperationLogService 和 OperationLogService - 实现日志记录方法 - 实现分页查询 - _Requirements: 8.1, 8.2, 8.3, 8.4_ - - [ ] 8.2 创建 OperationLogFilter + - [ ] 9.2 创建 OperationLogFilter - 自动记录 API 操作日志 - _Requirements: 8.1, 8.2_ - - [ ] 8.3 创建 OperationLogController + - [ ] 9.3 创建 OperationLogController - 实现日志查询 API - _Requirements: 8.3, 8.4_ -- [ ] 9. 配置服务注册和静态文件 - - [ ] 9.1 创建 ServiceCollectionExtensions +- [ ] 10. 配置服务注册和静态文件 + - [ ] 10.1 创建 ServiceCollectionExtensions - 实现 AddHoneyBoxAdmin() 扩展方法 - 注册所有服务和 DbContext - _Requirements: 1.5_ - - [ ] 9.2 配置 Program.cs + - [ ] 10.2 配置 Program.cs - 配置静态文件服务 - 配置 SPA Fallback 路由 - 配置 JWT 认证 - _Requirements: 1.3, 1.4_ -- [ ] 10. 数据初始化 - - [ ] 10.1 创建 DataSeeder +- [ ] 11. 数据初始化 + - [ ] 11.1 创建 DataSeeder - 初始化超级管理员账号 (admin/admin123) - 初始化超级管理员角色 - 初始化系统菜单 - 初始化系统权限 - - _Requirements: 10.1, 10.2, 10.3, 10.4_ + - 初始化根部门 + - _Requirements: 12.1, 12.2, 12.3, 12.4, 12.5_ -- [ ] 11. Checkpoint - 后端 API 完成 +- [ ] 12. Checkpoint - 后端 API 完成 - 确保所有 API 可正常调用 - 确保认证和权限控制正常工作 - 使用 Postman 或 .http 文件测试 -- [ ] 12. 创建 Vue3 前端项目 - - [ ] 12.1 初始化项目 +- [ ] 13. 创建 Vue3 前端项目 + - [ ] 13.1 初始化项目 - 使用 Vite 创建 Vue3 + TypeScript 项目 - 安装 Element Plus, Pinia, Vue Router, Axios - 配置 vite.config.ts 输出到 wwwroot - _Requirements: 9.1, 9.2, 9.3, 9.4, 9.8_ - - [ ] 12.2 创建基础结构 + - [ ] 13.2 创建基础结构 - 创建目录结构 (api, store, router, views, layout, utils) - 配置 Axios 请求封装 - 配置 Token 管理 - _Requirements: 9.1, 9.2, 9.3_ - -- [ ] 13. 实现前端登录功能 - - [ ] 13.1 创建登录页面 +- [ ] 14. 实现前端登录功能 + - [ ] 14.1 创建登录页面 - 实现登录表单 (用户名、密码) - 实现表单验证 - 调用登录 API - _Requirements: 9.5_ - - [ ] 13.2 实现用户状态管理 + - [ ] 14.2 实现用户状态管理 - 创建 user store (Pinia) - 存储 token 和用户信息 - _Requirements: 9.3_ -- [ ] 14. 实现前端布局和路由 - - [ ] 14.1 创建主布局 +- [ ] 15. 实现前端布局和路由 + - [ ] 15.1 创建主布局 - 实现侧边栏菜单组件 - 实现顶部栏组件 - 实现主内容区域 - _Requirements: 9.6_ - - [ ] 14.2 实现动态路由 + - [ ] 15.2 实现动态路由 - 创建 permission store - 根据用户菜单生成动态路由 - 实现路由守卫 - _Requirements: 9.4_ - - [ ] 14.3 实现权限指令 + - [ ] 15.3 实现权限指令 - 创建 v-permission 指令 - 实现按钮级别权限控制 - _Requirements: 9.7_ -- [ ] 15. 实现前端系统管理页面 - - [ ] 15.1 实现菜单管理页面 +- [ ] 16. 实现前端系统管理页面 + - [ ] 16.1 实现菜单管理页面 - 菜单树形表格 - 新增/编辑/删除菜单 - _Requirements: 4.1-4.7_ - - [ ] 15.2 实现角色管理页面 + - [ ] 16.2 实现角色管理页面 - 角色列表表格 - 新增/编辑/删除角色 - 分配菜单/权限 - _Requirements: 5.1-5.7_ - - [ ] 15.3 实现管理员管理页面 + - [ ] 16.3 实现部门管理页面 + - 部门树形表格 + - 新增/编辑/删除部门 + - 分配部门菜单 + - _Requirements: 10.1-10.8_ + - [ ] 16.4 实现管理员管理页面 - 管理员列表表格 - 新增/编辑/删除管理员 - - 分配角色、启用/禁用 - - _Requirements: 6.1-6.7_ + - 分配角色、分配部门、分配用户专属菜单、启用/禁用 + - _Requirements: 6.1-6.7, 10.8, 11.1_ -- [ ] 16. 实现首页仪表盘 +- [ ] 17. 实现首页仪表盘 - 创建 Dashboard 页面 - 显示基本统计信息 - _Requirements: 9.6_ -- [ ] 17. 前端打包和部署配置 +- [ ] 18. 前端打包和部署配置 - 配置生产环境构建 - 输出到 HoneyBox.Admin/wwwroot - 验证一体化部署 - _Requirements: 9.8_ -- [ ] 18. Final Checkpoint - 系统完成 +- [ ] 19. Final Checkpoint - 系统完成 - 确保前后端联调正常 - 确保所有功能可用 - 确保权限控制正常 @@ -217,3 +235,4 @@ - Checkpoint 任务用于阶段性验证 - 前端打包后部署到 wwwroot,实现一体化部署 - 默认管理员账号: admin / admin123 +- 用户菜单 = 部门菜单 ∪ 角色菜单 ∪ 用户专属菜单