diff --git a/.kiro/settings/mcp.json b/.kiro/settings/mcp.json index b6cc8864..67647a3c 100644 --- a/.kiro/settings/mcp.json +++ b/.kiro/settings/mcp.json @@ -36,6 +36,18 @@ "MSSQL_DATABASE": "honey_box" }, "autoApprove": ["execute_sql"] + }, + "admin-sqlserver": { + "command": "node", + "args": ["server/scripts/mssql-mcp-server/index.js"], + "env": { + "MSSQL_SERVER": "192.168.195.15", + "MSSQL_PORT": "1433", + "MSSQL_USER": "sa", + "MSSQL_PASSWORD": "Dbt@com@123", + "MSSQL_DATABASE": "honey_box_admin" + }, + "autoApprove": ["execute_sql"] } } } \ No newline at end of file diff --git a/.kiro/specs/admin-system/design.md b/.kiro/specs/admin-system/design.md new file mode 100644 index 00000000..bcf69164 --- /dev/null +++ b/.kiro/specs/admin-system/design.md @@ -0,0 +1,696 @@ +# Design Document + +## Overview + +HoneyBox.Admin 是一个独立可复用的后台管理模块,采用 ASP.NET Core 8.0 后端 + Vue3 + Element Plus 前端架构。后端提供 RESTful API,前端打包后部署到 wwwroot 目录实现一体化部署。 + +## Architecture + +### 整体架构 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ HoneyBox.Admin 项目 │ +├─────────────────────────────────────────────────────────────────┤ +│ wwwroot/ │ Controllers/ │ +│ ├── index.html │ ├── AuthController.cs │ +│ ├── assets/ │ ├── MenuController.cs │ +│ └── (Vue3 打包文件) │ ├── RoleController.cs │ +│ │ ├── AdminUserController.cs │ +│ │ └── OperationLogController.cs │ +├─────────────────────────────────────────────────────────────────┤ +│ Services/ │ Entities/ │ +│ ├── AuthService.cs │ ├── AdminUser.cs │ +│ ├── MenuService.cs │ ├── Role.cs │ +│ ├── RoleService.cs │ ├── Menu.cs │ +│ ├── AdminUserService.cs │ ├── Permission.cs │ +│ ├── PermissionService.cs │ └── OperationLog.cs │ +│ └── OperationLogService.cs │ │ +├─────────────────────────────────────────────────────────────────┤ +│ Data/ │ Models/ │ +│ └── AdminDbContext.cs │ ├── Auth/ (LoginRequest, etc) │ +│ │ ├── Menu/ (MenuDto, etc) │ +│ │ └── Common/ (ApiResponse, etc) │ +├─────────────────────────────────────────────────────────────────┤ +│ Filters/ │ Extensions/ │ +│ ├── AdminAuthFilter.cs │ └── ServiceCollectionExt.cs │ +│ └── PermissionFilter.cs │ │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ + ┌───────────────────────────────┐ + │ honey_box_admin │ + │ (SQL Server 数据库) │ + └───────────────────────────────┘ +``` + +### 请求处理流程 + +``` +HTTP Request + │ + ▼ +┌─────────────┐ +│ 静态文件? │──Yes──▶ wwwroot/index.html (Vue3 SPA) +└─────────────┘ + │ No + ▼ +┌─────────────┐ +│ /api/*? │──No───▶ SPA Fallback (index.html) +└─────────────┘ + │ Yes + ▼ +┌─────────────┐ +│ AdminAuth │──Fail──▶ 401 Unauthorized +│ Filter │ +└─────────────┘ + │ Pass + ▼ +┌─────────────┐ +│ Permission │──Fail──▶ 403 Forbidden +│ Filter │ +└─────────────┘ + │ Pass + ▼ +┌─────────────┐ +│ Controller │ +│ Action │ +└─────────────┘ +``` + + +## Components and Interfaces + +### 1. Controllers + +#### AuthController + +```csharp +[ApiController] +[Route("api/admin/auth")] +public class AuthController : ControllerBase +{ + // POST /api/admin/auth/login - 管理员登录 + // POST /api/admin/auth/logout - 退出登录 + // GET /api/admin/auth/info - 获取当前用户信息 + // PUT /api/admin/auth/password - 修改密码 +} +``` + +#### MenuController + +```csharp +[ApiController] +[Route("api/admin/menus")] +[AdminAuth] +public class MenuController : ControllerBase +{ + // GET /api/admin/menus - 获取菜单树 + // GET /api/admin/menus/{id} - 获取菜单详情 + // POST /api/admin/menus - 创建菜单 + // PUT /api/admin/menus/{id} - 更新菜单 + // DELETE /api/admin/menus/{id} - 删除菜单 + // GET /api/admin/menus/user - 获取当前用户菜单 +} +``` + +#### RoleController + +```csharp +[ApiController] +[Route("api/admin/roles")] +[AdminAuth] +public class RoleController : ControllerBase +{ + // GET /api/admin/roles - 获取角色列表 + // GET /api/admin/roles/{id} - 获取角色详情 + // POST /api/admin/roles - 创建角色 + // PUT /api/admin/roles/{id} - 更新角色 + // DELETE /api/admin/roles/{id} - 删除角色 + // PUT /api/admin/roles/{id}/menus - 分配菜单 + // PUT /api/admin/roles/{id}/permissions - 分配权限 +} +``` + +#### AdminUserController + +```csharp +[ApiController] +[Route("api/admin/users")] +[AdminAuth] +public class AdminUserController : ControllerBase +{ + // GET /api/admin/users - 获取管理员列表 + // GET /api/admin/users/{id} - 获取管理员详情 + // POST /api/admin/users - 创建管理员 + // PUT /api/admin/users/{id} - 更新管理员 + // DELETE /api/admin/users/{id} - 删除管理员 + // PUT /api/admin/users/{id}/roles - 分配角色 + // PUT /api/admin/users/{id}/status - 启用/禁用 + // PUT /api/admin/users/{id}/reset-password - 重置密码 +} +``` + +### 2. Service Interfaces + +```csharp +public interface IAuthService +{ + Task LoginAsync(LoginRequest request, string ipAddress); + Task LogoutAsync(long adminUserId); + Task GetCurrentUserInfoAsync(long adminUserId); + Task ChangePasswordAsync(long adminUserId, ChangePasswordRequest request); +} + +public interface IMenuService +{ + Task> GetMenuTreeAsync(); + Task GetByIdAsync(long id); + Task CreateAsync(CreateMenuRequest request); + Task UpdateAsync(long id, UpdateMenuRequest request); + Task DeleteAsync(long id); + Task> GetUserMenusAsync(long adminUserId); +} + +public interface IRoleService +{ + Task> GetListAsync(RoleQueryRequest request); + Task GetByIdAsync(long id); + Task CreateAsync(CreateRoleRequest request); + Task UpdateAsync(long id, UpdateRoleRequest request); + Task DeleteAsync(long id); + Task AssignMenusAsync(long roleId, List menuIds); + Task AssignPermissionsAsync(long roleId, List permissionIds); +} + +public interface IAdminUserService +{ + Task> GetListAsync(AdminUserQueryRequest request); + Task GetByIdAsync(long id); + Task CreateAsync(CreateAdminUserRequest request); + Task UpdateAsync(long id, UpdateAdminUserRequest request); + Task DeleteAsync(long id); + Task AssignRolesAsync(long userId, List roleIds); + Task SetStatusAsync(long userId, bool enabled); + Task ResetPasswordAsync(long userId, string newPassword); +} + +public interface IPermissionService +{ + Task> GetUserPermissionsAsync(long adminUserId); + Task HasPermissionAsync(long adminUserId, string permissionCode); + void InvalidateCache(long adminUserId); +} +``` + + +## Data Models + +### Entity Classes + +```csharp +// 管理员 +public class AdminUser +{ + public long Id { get; set; } + public string Username { get; set; } + public string PasswordHash { get; set; } + public string? RealName { get; set; } + public string? Avatar { get; set; } + public string? Email { get; set; } + public string? Phone { get; set; } + public byte Status { get; set; } = 1; // 0禁用 1启用 + public DateTime? LastLoginTime { get; set; } + public string? LastLoginIp { get; set; } + public int LoginFailCount { get; set; } = 0; + public DateTime? LockoutEnd { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime? UpdatedAt { get; set; } + public long? CreatedBy { get; set; } + public string? Remark { get; set; } + + public ICollection AdminUserRoles { get; set; } +} + +// 角色 +public class Role +{ + public long Id { get; set; } + 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 bool IsSystem { get; set; } = false; + public DateTime CreatedAt { get; set; } + public DateTime? UpdatedAt { get; set; } + + public ICollection AdminUserRoles { get; set; } + public ICollection RoleMenus { get; set; } + public ICollection RolePermissions { get; set; } +} + +// 菜单 +public class Menu +{ + public long Id { get; set; } + public long ParentId { get; set; } = 0; + public string Name { get; set; } + public string? Path { get; set; } + public string? Component { get; set; } + public string? Icon { get; set; } + public byte MenuType { get; set; } = 1; // 1目录 2菜单 3按钮 + public string? Permission { get; set; } + public int SortOrder { get; set; } = 0; + public byte Status { get; set; } = 1; // 0隐藏 1显示 + public bool IsExternal { get; set; } = false; + public bool IsCache { get; set; } = true; + public DateTime CreatedAt { get; set; } + public DateTime? UpdatedAt { get; set; } + + public ICollection RoleMenus { get; set; } +} + +// 权限 +public class Permission +{ + public long Id { get; set; } + public string Name { get; set; } + public string Code { get; set; } + public string? Module { get; set; } + public string? Description { get; set; } + public DateTime CreatedAt { get; set; } + + public ICollection RolePermissions { get; set; } +} + +// 操作日志 +public class OperationLog +{ + 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 string? RequestData { get; set; } + public string? ResponseData { get; set; } + public byte Status { get; set; } // 0失败 1成功 + public string? ErrorMsg { get; set; } + public int Duration { get; set; } + public DateTime CreatedAt { get; set; } +} + +// 关联表 +public class AdminUserRole +{ + public long Id { get; set; } + public long AdminUserId { get; set; } + public long RoleId { get; set; } + public AdminUser AdminUser { get; set; } + public Role Role { get; set; } +} + +public class RoleMenu +{ + public long Id { get; set; } + public long RoleId { get; set; } + public long MenuId { get; set; } + public Role Role { get; set; } + public Menu Menu { get; set; } +} + +public class RolePermission +{ + public long Id { get; set; } + public long RoleId { get; set; } + public long PermissionId { get; set; } + public Role Role { get; set; } + public Permission Permission { get; set; } +} +``` + + +### DTO Models + +```csharp +// 通用响应 +public class ApiResponse +{ + public int Code { get; set; } + public string Message { get; set; } + public T? Data { get; set; } + + public static ApiResponse Success(T data, string message = "success") + => new() { Code = 0, Message = message, Data = data }; + + public static ApiResponse Error(int code, string message) + => new() { Code = code, Message = message }; +} + +// 分页结果 +public class PagedResult +{ + public List List { get; set; } + public int Total { get; set; } + public int Page { get; set; } + public int PageSize { get; set; } +} + +// 登录请求/响应 +public class LoginRequest +{ + public string Username { get; set; } + public string Password { get; set; } +} + +public class LoginResponse +{ + public string Token { get; set; } + public long ExpiresIn { get; set; } + public AdminUserInfo UserInfo { get; set; } +} + +public class AdminUserInfo +{ + public long Id { get; set; } + public string Username { get; set; } + public string? RealName { get; set; } + public string? Avatar { get; set; } + public List Roles { get; set; } + public List Permissions { get; set; } +} + +// 菜单树 +public class MenuTreeDto +{ + public long Id { get; set; } + public long ParentId { get; set; } + public string Name { get; set; } + public string? Path { get; set; } + public string? Component { get; set; } + public string? Icon { get; set; } + public byte MenuType { get; set; } + public string? Permission { get; set; } + public int SortOrder { get; set; } + public List Children { get; set; } +} +``` + +## Database Schema + +数据库表结构参见迁移计划文档 `docs/后台管理系统迁移计划.md` 第三节。 + +### AdminDbContext 配置 + +```csharp +public class AdminDbContext : DbContext +{ + public DbSet AdminUsers { get; set; } + public DbSet Roles { get; set; } + public DbSet Menus { get; set; } + public DbSet Permissions { get; set; } + public DbSet AdminUserRoles { get; set; } + public DbSet RoleMenus { get; set; } + public DbSet RolePermissions { get; set; } + public DbSet OperationLogs { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + // 配置唯一索引 + modelBuilder.Entity() + .HasIndex(e => e.Username).IsUnique(); + + 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.RoleId, e.MenuId }).IsUnique(); + + modelBuilder.Entity() + .HasIndex(e => new { e.RoleId, e.PermissionId }).IsUnique(); + } +} +``` + + +## Vue3 Frontend Structure + +### 项目结构 + +``` +admin-web/ +├── public/ +│ └── favicon.ico +├── src/ +│ ├── api/ # API 接口 +│ │ ├── auth.ts +│ │ ├── menu.ts +│ │ ├── role.ts +│ │ └── user.ts +│ ├── assets/ # 静态资源 +│ │ └── styles/ +│ ├── components/ # 公共组件 +│ │ └── SvgIcon/ +│ ├── layout/ # 布局组件 +│ │ ├── index.vue # 主布局 +│ │ ├── Sidebar/ # 侧边栏 +│ │ ├── Header/ # 顶部栏 +│ │ └── TagsView/ # 标签页 +│ ├── router/ # 路由 +│ │ ├── index.ts +│ │ └── routes.ts +│ ├── store/ # Pinia 状态管理 +│ │ ├── modules/ +│ │ │ ├── user.ts # 用户状态 +│ │ │ ├── permission.ts # 权限状态 +│ │ │ └── app.ts # 应用状态 +│ │ └── index.ts +│ ├── utils/ # 工具函数 +│ │ ├── request.ts # Axios 封装 +│ │ ├── auth.ts # Token 管理 +│ │ └── permission.ts # 权限工具 +│ ├── views/ # 页面组件 +│ │ ├── login/ # 登录页 +│ │ ├── dashboard/ # 首页 +│ │ └── system/ # 系统管理 +│ │ ├── menu/ # 菜单管理 +│ │ ├── role/ # 角色管理 +│ │ └── user/ # 管理员管理 +│ ├── directives/ # 自定义指令 +│ │ └── permission.ts # v-permission +│ ├── App.vue +│ └── main.ts +├── index.html +├── package.json +├── tsconfig.json +└── vite.config.ts +``` + +### 动态路由生成 + +```typescript +// router/index.ts +import { createRouter, createWebHistory } from 'vue-router' +import { usePermissionStore } from '@/store/modules/permission' + +const router = createRouter({ + history: createWebHistory(), + routes: [ + { path: '/login', component: () => import('@/views/login/index.vue') }, + { path: '/', redirect: '/dashboard' } + ] +}) + +router.beforeEach(async (to, from, next) => { + const token = getToken() + if (token) { + if (to.path === '/login') { + next('/') + } else { + const permissionStore = usePermissionStore() + if (!permissionStore.routes.length) { + // 获取用户菜单并生成动态路由 + await permissionStore.generateRoutes() + next({ ...to, replace: true }) + } else { + next() + } + } + } else { + if (to.path === '/login') { + next() + } else { + next('/login') + } + } +}) +``` + +### 权限指令 + +```typescript +// directives/permission.ts +import type { Directive } from 'vue' +import { useUserStore } from '@/store/modules/user' + +export const permission: Directive = { + mounted(el, binding) { + const { value } = binding + const userStore = useUserStore() + const permissions = userStore.permissions + + if (value && !permissions.includes(value)) { + el.parentNode?.removeChild(el) + } + } +} + +// 使用: 新增 +``` + + +## Correctness Properties + +*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.* + +### Property 1: Valid credentials return JWT token + +*For any* admin user with valid credentials (correct username and password, enabled status, not locked), calling the login API SHALL return a valid JWT token and user info. + +**Validates: Requirements 3.1** + +### Property 2: Invalid credentials are rejected + +*For any* login attempt with invalid credentials (wrong username or wrong password), the Auth_Service SHALL return an authentication error and not issue a token. + +**Validates: Requirements 3.2** + +### Property 3: Disabled accounts cannot login + +*For any* admin user with disabled status (status = 0), login attempts SHALL be rejected regardless of correct password. + +**Validates: Requirements 3.3** + +### Property 4: 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 + +*For any* invalid, expired, or malformed JWT token, requests SHALL return 401 Unauthorized. + +**Validates: Requirements 3.7** + +### Property 6: 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 + +*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 + +*For any* admin user, the menus returned by GetUserMenus SHALL be a subset of the menus assigned to the user's roles. + +**Validates: Requirements 4.7** + +### Property 9: 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 + +*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. + +**Validates: Requirements 8.1, 8.2** + + +## Error Handling + +### Error Code Specification + +| Code Range | Category | Description | +|------------|----------|-------------| +| 0 | Success | 操作成功 | +| 40001-40099 | Authentication | 认证相关错误 | +| 40101-40199 | Authorization | 权限相关错误 | +| 40201-40299 | Validation | 参数验证错误 | +| 50001-50099 | Server | 服务器内部错误 | + +### Specific Error Codes + +```csharp +public static class AdminErrorCodes +{ + // Authentication + public const int InvalidCredentials = 40001; + public const int AccountDisabled = 40002; + public const int AccountLocked = 40003; + public const int TokenExpired = 40004; + public const int TokenInvalid = 40005; + + // Authorization + public const int PermissionDenied = 40101; + public const int RoleNotFound = 40102; + + // Validation + public const int InvalidParameter = 40201; + public const int DuplicateUsername = 40202; + public const int DuplicateRoleCode = 40203; + public const int MenuHasChildren = 40204; + public const int CannotDeleteSystemRole = 40205; + public const int CannotDeleteLastSuperAdmin = 40206; + + // Server + public const int InternalError = 50001; + public const int DatabaseError = 50002; +} +``` + +## Testing Strategy + +### Unit Tests + +- Service 层单元测试,使用 Mock 数据库 +- 测试各 Service 的核心业务逻辑 +- 测试边界条件和异常情况 + +### Integration Tests + +- API 集成测试,使用内存数据库 +- 测试完整的请求-响应流程 +- 测试认证和权限过滤器 + +### Property-Based Tests + +使用 FsCheck 或类似库进行属性测试: +- 测试 JWT Token 的生成和验证 +- 测试菜单树结构的正确性 +- 测试权限检查的一致性 + +### Test Configuration + +```csharp +// 使用 xUnit + Moq + FluentAssertions +// 每个属性测试至少运行 100 次迭代 +// 测试标签格式: Feature: admin-system, Property N: {property_text} +``` diff --git a/.kiro/specs/admin-system/requirements.md b/.kiro/specs/admin-system/requirements.md new file mode 100644 index 00000000..b7c702c4 --- /dev/null +++ b/.kiro/specs/admin-system/requirements.md @@ -0,0 +1,152 @@ +# Requirements Document + +## Introduction + +HoneyBox 后台管理系统基础框架,提供完整的 RBAC 权限管理功能。采用 ASP.NET Core 后端 + Vue3 + Element Plus 前端的架构,前端打包后部署到后端 wwwroot 目录,实现一体化部署。 + +## Glossary + +- **Admin_System**: 后台管理系统,包含认证、菜单、角色、权限等核心功能 +- **Admin_User**: 后台管理员,拥有登录后台的权限 +- **Role**: 角色,权限的集合,可分配给管理员 +- **Menu**: 菜单,前端路由和导航项,支持树形结构 +- **Permission**: 权限,API 级别的访问控制标识 +- **JWT_Token**: JSON Web Token,用于身份认证 +- **RBAC**: Role-Based Access Control,基于角色的访问控制 + +## Requirements + +### Requirement 1: 项目结构搭建 + +**User Story:** As a developer, I want to create the HoneyBox.Admin project structure, so that I can have an independent and reusable admin module. + +#### Acceptance Criteria + +1. THE Admin_System SHALL create a new ASP.NET Core project named HoneyBox.Admin +2. THE Admin_System SHALL contain Entities, Services, Models, Data, Controllers folders +3. THE Admin_System SHALL configure static file serving from wwwroot folder +4. THE Admin_System SHALL support SPA fallback routing for Vue3 frontend +5. THE Admin_System SHALL register all services via extension method AddHoneyBoxAdmin() + + +### Requirement 2: 数据库实体设计 + +**User Story:** As a developer, I want to define database entities for admin management, so that I can persist admin users, roles, menus and permissions. + +#### Acceptance Criteria + +1. THE Admin_System SHALL create AdminUser entity with username, password_hash, real_name, avatar, status, last_login_time 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 + +### Requirement 3: 管理员认证 + +**User Story:** As an admin user, I want to login with username and password, so that I can access the admin system securely. + +#### Acceptance Criteria + +1. WHEN an admin user submits valid credentials, THE Auth_Service SHALL return a JWT token and user info +2. WHEN an admin user submits invalid credentials, THE Auth_Service SHALL return an authentication error +3. WHEN an admin user's account is disabled, THE Auth_Service SHALL reject the login attempt +4. WHEN login fails 5 times consecutively, THE Auth_Service SHALL lock the account for 30 minutes +5. THE Auth_Service SHALL record login time and IP address on successful login +6. WHEN a valid JWT token is provided, THE Admin_System SHALL authenticate the request +7. WHEN an invalid or expired JWT token is provided, THE Admin_System SHALL return 401 Unauthorized + + +### Requirement 4: 菜单管理 + +**User Story:** As an admin user, I want to manage system menus, so that I can configure the navigation structure. + +#### Acceptance Criteria + +1. WHEN requesting menu list, THE Menu_Service SHALL return menus as a tree structure +2. WHEN creating a menu, THE Menu_Service SHALL validate required fields and save to database +3. WHEN updating a menu, THE Menu_Service SHALL update the existing record +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 + +### Requirement 5: 角色管理 + +**User Story:** As an admin user, I want to manage roles, so that I can group permissions and assign them to users. + +#### Acceptance Criteria + +1. WHEN requesting role list, THE Role_Service SHALL return paginated role data +2. WHEN creating a role, THE Role_Service SHALL validate unique code and save to database +3. WHEN updating a role, THE Role_Service SHALL update the existing record +4. WHEN deleting a system role, THE Role_Service SHALL prevent deletion and return an error +5. WHEN deleting a non-system role, THE Role_Service SHALL remove the role and its associations +6. WHEN assigning menus to a role, THE Role_Service SHALL update the role-menu associations +7. WHEN assigning permissions to a role, THE Role_Service SHALL update the role-permission associations + + +### Requirement 6: 管理员管理 + +**User Story:** As an admin user, I want to manage admin accounts, so that I can control who has access to the system. + +#### Acceptance Criteria + +1. WHEN requesting admin user list, THE AdminUser_Service SHALL return paginated user data with role info +2. WHEN creating an admin user, THE AdminUser_Service SHALL validate unique username and hash the password +3. WHEN updating an admin user, THE AdminUser_Service SHALL update the existing record +4. WHEN deleting the last super admin, THE AdminUser_Service SHALL prevent deletion +5. WHEN assigning roles to an admin user, THE AdminUser_Service SHALL update the user-role associations +6. WHEN enabling/disabling an admin user, THE AdminUser_Service SHALL update the status field +7. WHEN resetting password, THE AdminUser_Service SHALL generate a new hashed password + +### Requirement 7: 权限控制 + +**User Story:** As a system, I want to enforce permission checks on API endpoints, so that unauthorized access is prevented. + +#### Acceptance Criteria + +1. WHEN an API endpoint has permission attribute, THE Permission_Filter SHALL verify user has the required permission +2. WHEN user lacks required permission, THE Permission_Filter SHALL return 403 Forbidden +3. WHEN user has required permission, THE Permission_Filter SHALL allow the request to proceed +4. THE Permission_Service SHALL cache user permissions for performance +5. WHEN user roles change, THE Permission_Service SHALL invalidate the permission cache + + +### Requirement 8: 操作日志 + +**User Story:** As an admin user, I want to view operation logs, so that I can audit system activities. + +#### Acceptance Criteria + +1. WHEN an admin performs a create/update/delete operation, THE Log_Service SHALL record the operation details +2. THE Operation_Log SHALL include admin_user_id, username, module, action, method, url, ip, request_data, response_status, duration +3. WHEN requesting operation logs, THE Log_Service SHALL return paginated log data with filters +4. THE Log_Service SHALL support filtering by admin user, module, action, and date range + +### Requirement 9: Vue3 前端框架 + +**User Story:** As a developer, I want to create a Vue3 + Element Plus frontend, so that admins can interact with the system through a modern UI. + +#### Acceptance Criteria + +1. THE Frontend SHALL use Vue3 with Composition API and TypeScript +2. THE Frontend SHALL use Element Plus as the UI component library +3. THE Frontend SHALL use Pinia for state management +4. THE Frontend SHALL use Vue Router with dynamic route generation based on user menus +5. THE Frontend SHALL implement login page with form validation +6. THE Frontend SHALL implement layout with sidebar menu, header, and main content area +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: 数据初始化 + +**User Story:** As a developer, I want to initialize default data, so that the system is ready to use after deployment. + +#### Acceptance Criteria + +1. THE Admin_System SHALL create default super admin account (admin/admin123) on first run +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 diff --git a/.kiro/specs/admin-system/tasks.md b/.kiro/specs/admin-system/tasks.md new file mode 100644 index 00000000..3d7abf83 --- /dev/null +++ b/.kiro/specs/admin-system/tasks.md @@ -0,0 +1,219 @@ +# Implementation Plan: Admin System + +## Overview + +实现 HoneyBox.Admin 后台管理系统,包括后端 API 和 Vue3 前端。采用分阶段实现:先搭建后端框架和核心功能,再实现前端界面。 + +## Tasks + +- [ ] 1. 创建 HoneyBox.Admin 项目结构 + - 创建 ASP.NET Core Web API 项目 + - 配置项目文件夹结构 (Controllers, Services, Entities, Models, Data, Filters, Extensions) + - 添加必要的 NuGet 包引用 + - 配置 appsettings.json 数据库连接 + - _Requirements: 1.1, 1.2_ + +- [ ] 2. 实现数据库实体和 DbContext + - [ ] 2.1 创建 Entity 类 + - 创建 AdminUser, Role, Menu, Permission 实体 + - 创建 AdminUserRole, RoleMenu, RolePermission 关联实体 + - 创建 OperationLog 实体 + - _Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6_ + - [ ] 2.2 创建 AdminDbContext + - 配置 DbSet 属性 + - 配置实体关系和索引 + - _Requirements: 2.7_ + - [ ] 2.3 执行数据库迁移 + - 创建数据库表 + - 验证表结构 + - _Requirements: 2.1-2.7_ + +- [ ] 3. 实现认证服务 + - [ ] 3.1 创建 DTO 模型 + - 创建 LoginRequest, LoginResponse, AdminUserInfo + - 创建 ApiResponse 通用响应模型 + - _Requirements: 3.1_ + - [ ] 3.2 实现 IAuthService 和 AuthService + - 实现 LoginAsync 方法 (验证凭据、生成 JWT) + - 实现登录失败计数和账户锁定逻辑 + - 实现 GetCurrentUserInfoAsync 方法 + - _Requirements: 3.1, 3.2, 3.3, 3.4, 3.5_ + - [ ] 3.3 创建 AuthController + - 实现 POST /api/admin/auth/login + - 实现 GET /api/admin/auth/info + - 实现 PUT /api/admin/auth/password + - _Requirements: 3.1, 3.6_ + - [ ] 3.4 创建 AdminAuthFilter + - 实现 JWT Token 验证 + - 处理无效/过期 Token + - _Requirements: 3.6, 3.7_ + + +- [ ] 4. 实现菜单管理 + - [ ] 4.1 创建菜单相关 DTO + - 创建 MenuDto, MenuTreeDto, CreateMenuRequest, UpdateMenuRequest + - _Requirements: 4.1_ + - [ ] 4.2 实现 IMenuService 和 MenuService + - 实现 GetMenuTreeAsync (构建树形结构) + - 实现 CRUD 方法 + - 实现 GetUserMenusAsync (基于角色过滤) + - _Requirements: 4.1, 4.2, 4.3, 4.4, 4.5, 4.7_ + - [ ] 4.3 创建 MenuController + - 实现所有菜单管理 API + - _Requirements: 4.1-4.7_ + +- [ ] 5. 实现角色管理 + - [ ] 5.1 创建角色相关 DTO + - 创建 RoleDto, CreateRoleRequest, UpdateRoleRequest, RoleQueryRequest + - _Requirements: 5.1_ + - [ ] 5.2 实现 IRoleService 和 RoleService + - 实现分页查询 + - 实现 CRUD 方法 + - 实现菜单/权限分配 + - _Requirements: 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7_ + - [ ] 5.3 创建 RoleController + - 实现所有角色管理 API + - _Requirements: 5.1-5.7_ + +- [ ] 6. 实现管理员管理 + - [ ] 6.1 创建管理员相关 DTO + - 创建 AdminUserDto, CreateAdminUserRequest, UpdateAdminUserRequest + - _Requirements: 6.1_ + - [ ] 6.2 实现 IAdminUserService 和 AdminUserService + - 实现分页查询 + - 实现 CRUD 方法 + - 实现角色分配、状态切换、密码重置 + - _Requirements: 6.1, 6.2, 6.3, 6.4, 6.5, 6.6, 6.7_ + - [ ] 6.3 创建 AdminUserController + - 实现所有管理员管理 API + - _Requirements: 6.1-6.7_ + +- [ ] 7. 实现权限控制 + - [ ] 7.1 实现 IPermissionService 和 PermissionService + - 实现 GetUserPermissionsAsync + - 实现 HasPermissionAsync + - 实现权限缓存和失效 + - _Requirements: 7.1, 7.4, 7.5_ + - [ ] 7.2 创建 PermissionFilter + - 实现 AdminPermissionAttribute + - 实现权限验证逻辑 + - _Requirements: 7.1, 7.2, 7.3_ + - [ ] 7.3 创建 PermissionController + - 实现权限列表查询 API + - _Requirements: 7.1_ + + +- [ ] 8. 实现操作日志 + - [ ] 8.1 实现 IOperationLogService 和 OperationLogService + - 实现日志记录方法 + - 实现分页查询 + - _Requirements: 8.1, 8.2, 8.3, 8.4_ + - [ ] 8.2 创建 OperationLogFilter + - 自动记录 API 操作日志 + - _Requirements: 8.1, 8.2_ + - [ ] 8.3 创建 OperationLogController + - 实现日志查询 API + - _Requirements: 8.3, 8.4_ + +- [ ] 9. 配置服务注册和静态文件 + - [ ] 9.1 创建 ServiceCollectionExtensions + - 实现 AddHoneyBoxAdmin() 扩展方法 + - 注册所有服务和 DbContext + - _Requirements: 1.5_ + - [ ] 9.2 配置 Program.cs + - 配置静态文件服务 + - 配置 SPA Fallback 路由 + - 配置 JWT 认证 + - _Requirements: 1.3, 1.4_ + +- [ ] 10. 数据初始化 + - [ ] 10.1 创建 DataSeeder + - 初始化超级管理员账号 (admin/admin123) + - 初始化超级管理员角色 + - 初始化系统菜单 + - 初始化系统权限 + - _Requirements: 10.1, 10.2, 10.3, 10.4_ + +- [ ] 11. Checkpoint - 后端 API 完成 + - 确保所有 API 可正常调用 + - 确保认证和权限控制正常工作 + - 使用 Postman 或 .http 文件测试 + +- [ ] 12. 创建 Vue3 前端项目 + - [ ] 12.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 创建基础结构 + - 创建目录结构 (api, store, router, views, layout, utils) + - 配置 Axios 请求封装 + - 配置 Token 管理 + - _Requirements: 9.1, 9.2, 9.3_ + + +- [ ] 13. 实现前端登录功能 + - [ ] 13.1 创建登录页面 + - 实现登录表单 (用户名、密码) + - 实现表单验证 + - 调用登录 API + - _Requirements: 9.5_ + - [ ] 13.2 实现用户状态管理 + - 创建 user store (Pinia) + - 存储 token 和用户信息 + - _Requirements: 9.3_ + +- [ ] 14. 实现前端布局和路由 + - [ ] 14.1 创建主布局 + - 实现侧边栏菜单组件 + - 实现顶部栏组件 + - 实现主内容区域 + - _Requirements: 9.6_ + - [ ] 14.2 实现动态路由 + - 创建 permission store + - 根据用户菜单生成动态路由 + - 实现路由守卫 + - _Requirements: 9.4_ + - [ ] 14.3 实现权限指令 + - 创建 v-permission 指令 + - 实现按钮级别权限控制 + - _Requirements: 9.7_ + +- [ ] 15. 实现前端系统管理页面 + - [ ] 15.1 实现菜单管理页面 + - 菜单树形表格 + - 新增/编辑/删除菜单 + - _Requirements: 4.1-4.7_ + - [ ] 15.2 实现角色管理页面 + - 角色列表表格 + - 新增/编辑/删除角色 + - 分配菜单/权限 + - _Requirements: 5.1-5.7_ + - [ ] 15.3 实现管理员管理页面 + - 管理员列表表格 + - 新增/编辑/删除管理员 + - 分配角色、启用/禁用 + - _Requirements: 6.1-6.7_ + +- [ ] 16. 实现首页仪表盘 + - 创建 Dashboard 页面 + - 显示基本统计信息 + - _Requirements: 9.6_ + +- [ ] 17. 前端打包和部署配置 + - 配置生产环境构建 + - 输出到 HoneyBox.Admin/wwwroot + - 验证一体化部署 + - _Requirements: 9.8_ + +- [ ] 18. Final Checkpoint - 系统完成 + - 确保前后端联调正常 + - 确保所有功能可用 + - 确保权限控制正常 + +## Notes + +- 任务按顺序执行,后端优先于前端 +- Checkpoint 任务用于阶段性验证 +- 前端打包后部署到 wwwroot,实现一体化部署 +- 默认管理员账号: admin / admin123 diff --git a/docs/后台管理系统迁移计划.md b/docs/后台管理系统迁移计划.md new file mode 100644 index 00000000..d595acff --- /dev/null +++ b/docs/后台管理系统迁移计划.md @@ -0,0 +1,594 @@ +# HoneyBox 后台管理系统迁移计划 + +## 一、迁移概述 + +### 1.1 迁移目标 + +将 PHP (ThinkPHP 6.0) 后台管理系统迁移至 ASP.NET Core,采用前后端分离架构,实现现代化的后台管理系统。 + +### 1.2 迁移策略 + +- **基础先行**:先搭建权限管理框架(登录、菜单、角色、权限),再逐步迁移业务模块 +- **后端分离**:新建独立类库 `HoneyBox.Admin` 处理后台 API +- **数据库分离**:独立的后台管理数据库 `honey_box_admin`,与业务库解耦 +- **渐进式迁移**:按模块逐个迁移,降低风险 + +--- + +## 二、架构设计 + +### 2.1 整体架构 + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ 前端应用层 │ +│ ┌─────────────────────────────┐ ┌─────────────────────────────────────┐ │ +│ │ UniApp (小程序/H5/APP) │ │ Vue3 + Element Plus (后台管理) │ │ +│ │ 用户端前端 │ │ 管理端前端 │ │ +│ └─────────────────────────────┘ └─────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────────────────┘ + │ │ + ▼ ▼ +┌───────────────────────────────┐ ┌─────────────────────────────────────────┐ +│ HoneyBox.Api │ │ HoneyBox.Admin │ +│ (用户端 API) │ │ (后台管理 - 独立可复用项目) │ +│ ┌─────────────────────────┐ │ │ ┌─────────────────────────────────┐ │ +│ │ /api/* (用户端接口) │ │ │ │ Controllers/ (后台管理 API) │ │ +│ └─────────────────────────┘ │ │ │ Services/ (业务逻辑层) │ │ +│ │ │ │ │ Entities/ (数据实体) │ │ +│ ▼ │ │ │ Models/ (DTO/ViewModel) │ │ +│ ┌─────────────────────────┐ │ │ │ Data/ (DbContext) │ │ +│ │ HoneyBox.Core │ │ │ └─────────────────────────────────┘ │ +│ │ (用户端业务逻辑) │ │ │ │ │ +│ └─────────────────────────┘ │ │ │ (可选引用) │ +│ │ │ │ ▼ │ +│ ▼ │ │ ┌─────────────────────────────────┐ │ +│ ┌─────────────────────────┐ │ │ │ HoneyBox.Core (业务数据查询) │ │ +│ │ HoneyBox.Model │ │ │ │ HoneyBox.Model (业务实体) │ │ +│ │ (业务数据模型) │ │ │ └─────────────────────────────────┘ │ +│ └─────────────────────────┘ │ └─────────────────────────────────────────┘ +│ │ │ │ +│ ▼ │ ▼ +│ ┌─────────────────────────┐ │ ┌─────────────────────────────────────────┐ +│ │ honey_box │ │ │ honey_box_admin │ +│ │ (业务数据库) │ │ │ (后台管理数据库) │ +│ └─────────────────────────┘ │ └─────────────────────────────────────────┘ +└───────────────────────────────┘ +``` + +### 2.2 HoneyBox.Admin 设计理念 + +`HoneyBox.Admin` 是一个**独立可复用的后台管理模块**,具有以下特点: + +1. **自包含** - 内部包含 Entities、Services、DbContext,不依赖外部 Model 层 +2. **可移植** - 可以轻松复制到其他项目中使用 +3. **松耦合** - 通过可选引用 `HoneyBox.Core/Model` 来访问业务数据 +4. **独立数据库** - 使用独立的 `honey_box_admin` 数据库 + +### 2.3 项目结构 + +``` +HoneyBox.sln +├── src/ +│ ├── HoneyBox.Api/ # 用户端 API (现有) +│ │ ├── Controllers/ # 用户端控制器 +│ │ └── Filters/ +│ │ +│ ├── HoneyBox.Admin/ # 后台管理 (新增 - 独立可复用项目) +│ │ ├── Controllers/ # 后台管理 API 控制器 +│ │ │ ├── AuthController.cs # 登录认证 +│ │ │ ├── MenuController.cs # 菜单管理 +│ │ │ ├── RoleController.cs # 角色管理 +│ │ │ ├── AdminUserController.cs # 管理员管理 +│ │ │ ├── PermissionController.cs # 权限管理 +│ │ │ └── Business/ # 业务模块控制器 (迁移后) +│ │ │ ├── UserController.cs # 用户管理 +│ │ │ ├── GoodsController.cs # 商品管理 +│ │ │ ├── OrderController.cs # 订单管理 +│ │ │ └── ... +│ │ │ +│ │ ├── Services/ # 业务服务层 +│ │ │ ├── Interfaces/ # 接口定义 +│ │ │ │ ├── IAuthService.cs +│ │ │ │ ├── IMenuService.cs +│ │ │ │ ├── IRoleService.cs +│ │ │ │ └── ... +│ │ │ ├── AuthService.cs # 认证服务 +│ │ │ ├── MenuService.cs # 菜单服务 +│ │ │ ├── RoleService.cs # 角色服务 +│ │ │ ├── PermissionService.cs # 权限服务 +│ │ │ └── AdminUserService.cs # 管理员服务 +│ │ │ +│ │ ├── Entities/ # 数据实体 (后台管理专用) +│ │ │ ├── AdminUser.cs # 管理员 +│ │ │ ├── Role.cs # 角色 +│ │ │ ├── Menu.cs # 菜单 +│ │ │ ├── Permission.cs # 权限 +│ │ │ ├── AdminUserRole.cs # 管理员-角色关联 +│ │ │ ├── RoleMenu.cs # 角色-菜单关联 +│ │ │ ├── RolePermission.cs # 角色-权限关联 +│ │ │ └── OperationLog.cs # 操作日志 +│ │ │ +│ │ ├── Models/ # DTO / ViewModel +│ │ │ ├── Auth/ # 认证相关 +│ │ │ │ ├── LoginRequest.cs +│ │ │ │ ├── LoginResponse.cs +│ │ │ │ └── AdminUserInfo.cs +│ │ │ ├── Menu/ # 菜单相关 +│ │ │ ├── Role/ # 角色相关 +│ │ │ └── Common/ # 通用模型 +│ │ │ ├── PagedRequest.cs +│ │ │ └── ApiResponse.cs +│ │ │ +│ │ ├── Data/ # 数据访问层 +│ │ │ └── AdminDbContext.cs # 后台管理数据库上下文 +│ │ │ +│ │ ├── Filters/ # 过滤器 +│ │ │ ├── AdminAuthFilter.cs # 后台认证过滤器 +│ │ │ └── PermissionFilter.cs # 权限验证过滤器 +│ │ │ +│ │ ├── Extensions/ # 扩展方法 +│ │ │ └── ServiceCollectionExtensions.cs # DI 注册扩展 +│ │ │ +│ │ └── HoneyBox.Admin.csproj +│ │ +│ ├── HoneyBox.Core/ # 用户端业务层 (现有) +│ ├── HoneyBox.Model/ # 用户端数据层 (现有) +│ └── HoneyBox.Infrastructure/ # 基础设施层 (现有) +│ +└── tests/ + └── HoneyBox.Admin.Tests/ # 后台管理测试 (新增) +``` + +### 2.4 项目依赖关系 + +``` +HoneyBox.Admin (独立可复用) + │ + ├── 自包含: Entities, Services, Models, DbContext + │ + └── 可选引用 (访问业务数据时): + ├── HoneyBox.Core (业务逻辑复用) + └── HoneyBox.Model (业务实体查询) +``` + +**复用到其他项目时:** +- 只需复制 `HoneyBox.Admin` 项目 +- 修改 `AdminDbContext` 连接字符串 +- 移除对 `HoneyBox.Core/Model` 的引用(如果不需要) +- 即可获得完整的后台管理功能 + +--- + +## 三、数据库设计 + +### 3.1 数据库分离策略 + +| 数据库 | 用途 | 说明 | +|--------|------|------| +| `honey_box` | 业务数据库 | 用户、商品、订单等业务数据 | +| `honey_box_admin` | 后台管理数据库 | 管理员、角色、菜单、权限、日志 | + +### 3.2 后台管理数据库表设计 + +#### 3.2.1 管理员表 (admin_users) + +```sql +CREATE TABLE admin_users ( + id BIGINT PRIMARY KEY IDENTITY(1,1), + username NVARCHAR(50) NOT NULL UNIQUE, -- 用户名 + password_hash NVARCHAR(256) NOT NULL, -- 密码哈希 + real_name NVARCHAR(50), -- 真实姓名 + avatar NVARCHAR(500), -- 头像 + email NVARCHAR(100), -- 邮箱 + phone NVARCHAR(20), -- 手机号 + status TINYINT DEFAULT 1, -- 状态: 0禁用 1启用 + last_login_time DATETIME2, -- 最后登录时间 + last_login_ip NVARCHAR(50), -- 最后登录IP + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2, + created_by BIGINT, -- 创建人 + remark NVARCHAR(500) -- 备注 +); +``` + +#### 3.2.2 角色表 (roles) + +```sql +CREATE TABLE roles ( + id BIGINT PRIMARY KEY IDENTITY(1,1), + name NVARCHAR(50) NOT NULL UNIQUE, -- 角色名称 + code NVARCHAR(50) NOT NULL UNIQUE, -- 角色编码 + description NVARCHAR(200), -- 描述 + sort_order INT DEFAULT 0, -- 排序 + status TINYINT DEFAULT 1, -- 状态: 0禁用 1启用 + is_system BIT DEFAULT 0, -- 是否系统角色(不可删除) + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 +); +``` + +#### 3.2.3 菜单表 (menus) + +```sql +CREATE TABLE menus ( + id BIGINT PRIMARY KEY IDENTITY(1,1), + parent_id BIGINT DEFAULT 0, -- 父级ID + name NVARCHAR(50) NOT NULL, -- 菜单名称 + path NVARCHAR(200), -- 路由路径 + component NVARCHAR(200), -- 组件路径 + icon NVARCHAR(100), -- 图标 + menu_type TINYINT DEFAULT 1, -- 类型: 1目录 2菜单 3按钮 + permission NVARCHAR(100), -- 权限标识 + sort_order INT DEFAULT 0, -- 排序 + status TINYINT DEFAULT 1, -- 状态: 0隐藏 1显示 + is_external BIT DEFAULT 0, -- 是否外链 + is_cache BIT DEFAULT 1, -- 是否缓存 + created_at DATETIME2 DEFAULT GETDATE(), + updated_at DATETIME2 +); +``` + +#### 3.2.4 权限表 (permissions) + +```sql +CREATE TABLE permissions ( + id BIGINT PRIMARY KEY IDENTITY(1,1), + name NVARCHAR(50) NOT NULL, -- 权限名称 + code NVARCHAR(100) NOT NULL UNIQUE, -- 权限编码 (如: user:list, user:add) + module NVARCHAR(50), -- 所属模块 + description NVARCHAR(200), -- 描述 + created_at DATETIME2 DEFAULT GETDATE() +); +``` + +#### 3.2.5 关联表 + +```sql +-- 管理员-角色关联 +CREATE TABLE admin_user_roles ( + id BIGINT PRIMARY KEY IDENTITY(1,1), + admin_user_id BIGINT NOT NULL, + role_id BIGINT NOT NULL, + UNIQUE(admin_user_id, role_id) +); + +-- 角色-菜单关联 +CREATE TABLE role_menus ( + id BIGINT PRIMARY KEY IDENTITY(1,1), + role_id BIGINT NOT NULL, + menu_id BIGINT NOT NULL, + UNIQUE(role_id, menu_id) +); + +-- 角色-权限关联 +CREATE TABLE role_permissions ( + id BIGINT PRIMARY KEY IDENTITY(1,1), + role_id BIGINT NOT NULL, + permission_id BIGINT NOT NULL, + UNIQUE(role_id, permission_id) +); +``` + +#### 3.2.6 操作日志表 (operation_logs) + +```sql +CREATE TABLE operation_logs ( + id BIGINT PRIMARY KEY IDENTITY(1,1), + admin_user_id BIGINT, -- 操作人ID + username NVARCHAR(50), -- 操作人用户名 + module NVARCHAR(50), -- 操作模块 + action NVARCHAR(50), -- 操作类型 + method NVARCHAR(10), -- 请求方法 + url NVARCHAR(500), -- 请求URL + ip NVARCHAR(50), -- IP地址 + request_data NVARCHAR(MAX), -- 请求参数 + response_data NVARCHAR(MAX), -- 响应数据 + status TINYINT, -- 状态: 0失败 1成功 + error_msg NVARCHAR(1000), -- 错误信息 + duration INT, -- 耗时(ms) + created_at DATETIME2 DEFAULT GETDATE() +); +``` + +--- + +## 四、迁移阶段规划 + +### 阶段一:基础框架搭建 (预计 1-2 周) + +#### 4.1.1 目标 +- 创建后台管理相关项目 +- 搭建数据库和基础表 +- 实现登录认证 + +#### 4.1.2 任务清单 + +| 序号 | 任务 | 说明 | 优先级 | +|------|------|------|--------| +| 1 | 创建 `HoneyBox.Admin` 项目 | 独立可复用的后台管理项目 | P0 | +| 2 | 创建 Entities 实体类 | AdminUser, Role, Menu, Permission 等 | P0 | +| 3 | 创建 AdminDbContext | 后台管理数据库上下文 | P0 | +| 4 | 创建 `honey_box_admin` 数据库 | 执行建表脚本 | P0 | +| 5 | 实现管理员登录 API | JWT 认证 | P0 | +| 6 | 实现后台权限过滤器 | 基于角色/权限的访问控制 | P0 | +| 7 | 创建 DI 扩展方法 | `AddHoneyBoxAdmin()` 便于复用 | P0 | +| 8 | 初始化超级管理员账号 | 默认 admin/admin123 | P0 | + +### 阶段二:权限管理模块 (预计 1-2 周) + +#### 4.2.1 目标 +- 实现完整的 RBAC 权限管理 +- 菜单、角色、权限的增删改查 + +#### 4.2.2 任务清单 + +| 序号 | 任务 | 说明 | 优先级 | +|------|------|------|--------| +| 1 | 菜单管理 CRUD | 树形结构菜单 | P0 | +| 2 | 角色管理 CRUD | 角色分配菜单/权限 | P0 | +| 3 | 管理员管理 CRUD | 管理员分配角色 | P0 | +| 4 | 权限管理 | 权限列表、分配 | P1 | +| 5 | 操作日志 | 记录管理员操作 | P1 | +| 6 | 登录日志 | 记录登录历史 | P2 | + +### 阶段三:业务模块迁移 (预计 4-6 周) + +按优先级逐步迁移 PHP 后台的业务模块: + +| 优先级 | 模块 | PHP 控制器 | 说明 | +|--------|------|-----------|------| +| P0 | 首页仪表盘 | Index | 数据统计概览 | +| P0 | 用户管理 | User | 用户列表、封禁、资金变动 | +| P0 | 商品管理 | Goods, GoodsType | 盒子管理、奖品配置 | +| P0 | 订单管理 | Order | 订单列表、发货、退款 | +| P1 | 财务管理 | Finance, Withdraw | 资金流水、提现审核 | +| P1 | 抽奖配置 | Draw, Cardextractor | 抽奖活动配置 | +| P1 | 系统配置 | Config | 支付、上传等配置 | +| P2 | 营销管理 | Coupon, Reward, Rank | 优惠券、奖励、排行榜 | +| P2 | 内容管理 | Advert, Danye, News | 广告、单页、公告 | +| P2 | 统计报表 | Statistics | 数据分析报表 | + +--- + +## 五、技术选型 + +### 5.1 后端技术栈 + +| 技术 | 版本 | 用途 | +|------|------|------| +| ASP.NET Core | 8.0 | Web API 框架 | +| Entity Framework Core | 8.0 | ORM | +| SQL Server | 2019+ | 数据库 | +| JWT | - | 身份认证 | +| Serilog | - | 日志 | +| Mapster | 7.4 | 对象映射 | +| Redis | - | 缓存、Token 存储 | + +### 5.2 前端技术栈 (建议) + +| 技术 | 版本 | 用途 | +|------|------|------| +| Vue.js | 3.x | 前端框架 | +| Element Plus | 2.x | UI 组件库 | +| Vite | 5.x | 构建工具 | +| Pinia | 2.x | 状态管理 | +| Vue Router | 4.x | 路由 | +| Axios | 1.x | HTTP 请求 | +| ECharts | 5.x | 图表 | + +--- + +## 六、API 设计规范 + +### 6.1 URL 规范 + +``` +后台管理 API 统一前缀: /api/admin + +认证相关: +POST /api/admin/auth/login # 登录 +POST /api/admin/auth/logout # 登出 +GET /api/admin/auth/info # 获取当前用户信息 +POST /api/admin/auth/refresh # 刷新 Token + +菜单管理: +GET /api/admin/menus # 菜单列表(树形) +GET /api/admin/menus/{id} # 菜单详情 +POST /api/admin/menus # 新增菜单 +PUT /api/admin/menus/{id} # 编辑菜单 +DELETE /api/admin/menus/{id} # 删除菜单 + +角色管理: +GET /api/admin/roles # 角色列表 +GET /api/admin/roles/{id} # 角色详情 +POST /api/admin/roles # 新增角色 +PUT /api/admin/roles/{id} # 编辑角色 +DELETE /api/admin/roles/{id} # 删除角色 +PUT /api/admin/roles/{id}/menus # 分配菜单 +PUT /api/admin/roles/{id}/permissions # 分配权限 + +管理员管理: +GET /api/admin/users # 管理员列表 +GET /api/admin/users/{id} # 管理员详情 +POST /api/admin/users # 新增管理员 +PUT /api/admin/users/{id} # 编辑管理员 +DELETE /api/admin/users/{id} # 删除管理员 +PUT /api/admin/users/{id}/roles # 分配角色 +PUT /api/admin/users/{id}/status # 启用/禁用 +PUT /api/admin/users/{id}/password # 重置密码 +``` + +### 6.2 响应格式 + +```json +// 成功响应 +{ + "code": 0, + "message": "success", + "data": { ... } +} + +// 分页响应 +{ + "code": 0, + "message": "success", + "data": { + "list": [...], + "total": 100, + "page": 1, + "pageSize": 20 + } +} + +// 错误响应 +{ + "code": 40001, + "message": "用户名或密码错误", + "data": null +} +``` + +### 6.3 错误码规范 + +| 错误码范围 | 说明 | +|-----------|------| +| 0 | 成功 | +| 40001-40099 | 认证相关错误 | +| 40101-40199 | 权限相关错误 | +| 40201-40299 | 参数验证错误 | +| 50001-50099 | 服务器内部错误 | + +--- + +## 七、安全设计 + +### 7.1 认证机制 + +- 使用 JWT Token 进行身份认证 +- Token 有效期 24 小时,支持刷新 +- 登录失败次数限制(5次锁定30分钟) +- 支持多设备登录/单设备登录配置 + +### 7.2 权限控制 + +- 基于 RBAC 模型 +- 接口级别权限控制(通过 `[AdminPermission("user:list")]` 特性) +- 菜单级别权限控制(前端动态路由) +- 按钮级别权限控制(前端指令 `v-permission`) + +### 7.3 安全措施 + +- 密码使用 BCrypt 加密存储 +- 敏感操作记录操作日志 +- 支持 IP 白名单 +- 防止 SQL 注入(EF Core 参数化查询) +- 防止 XSS 攻击(输入过滤) + +--- + +## 八、HoneyBox.Admin 与业务系统的关系 + +### 8.1 数据库关系 + +``` +honey_box (业务库) honey_box_admin (后台管理库) +┌─────────────────┐ ┌─────────────────┐ +│ users │◄───────────│ admin_users │ (通过 user_id 关联查询) +│ goods │ │ roles │ +│ orders │ │ menus │ +│ order_list │ │ permissions │ +│ ... │ │ operation_logs │ +└─────────────────┘ └─────────────────┘ +``` + +### 8.2 代码引用关系 + +```csharp +// HoneyBox.Admin.csproj + + + net8.0 + + + + + + + + + + + + + + + + +``` + +### 8.3 复用到其他项目 + +当需要将 `HoneyBox.Admin` 复用到其他项目时: + +1. **复制项目** - 将 `HoneyBox.Admin` 文件夹复制到新项目 +2. **修改命名空间** - 可选,根据新项目命名规范调整 +3. **配置数据库** - 修改 `appsettings.json` 中的连接字符串 +4. **移除业务引用** - 删除对 `HoneyBox.Core/Model` 的引用 +5. **注册服务** - 在新项目的 `Program.cs` 中调用扩展方法 + +```csharp +// 新项目中使用 +builder.Services.AddHoneyBoxAdmin(options => +{ + options.ConnectionString = "your-connection-string"; + options.JwtSecret = "your-jwt-secret"; +}); +``` + +--- + +## 九、前端管理系统 (后续规划) + +### 9.1 推荐方案 + +使用 Vue3 + Element Plus 构建现代化管理后台,可选择: + +1. **从零搭建** - 完全自定义,灵活度高 +2. **使用模板** - 如 vue-element-admin、vue-vben-admin + +### 9.2 目录结构 (建议) + +``` +admin-web/ +├── src/ +│ ├── api/ # API 接口 +│ ├── assets/ # 静态资源 +│ ├── components/ # 公共组件 +│ ├── layout/ # 布局组件 +│ ├── router/ # 路由配置 +│ ├── store/ # 状态管理 +│ ├── utils/ # 工具函数 +│ └── views/ # 页面组件 +│ ├── login/ # 登录页 +│ ├── dashboard/ # 首页仪表盘 +│ ├── system/ # 系统管理 +│ │ ├── menu/ # 菜单管理 +│ │ ├── role/ # 角色管理 +│ │ └── user/ # 管理员管理 +│ └── business/ # 业务模块 +├── package.json +└── vite.config.js +``` + +--- + +## 十、下一步行动 + +1. **确认本文档** - 确认架构设计和迁移策略 +2. **创建项目结构** - 新建 `HoneyBox.Admin` 和 `HoneyBox.Admin.Model` 项目 +3. **创建数据库** - 执行建表脚本创建 `honey_box_admin` 数据库 +4. **实现登录认证** - 完成管理员登录 API +5. **实现权限框架** - 完成菜单、角色、权限管理 + +确认后我可以开始创建项目和代码。