# Design Document ## Overview 本设计文档描述"内容与辅助"模块从老项目(PHP ThinkPHP + Layui)迁移到新项目(ASP.NET Core + Vue 3 + Element Plus)的技术设计方案。该模块包含三个子模块:单页管理(Danye)、悬浮球配置(FloatBall)、福利屋入口(WelfareHouse)。 ## Architecture ### 系统架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 前端 (Vue 3 + Element Plus) │ ├─────────────────────────────────────────────────────────────────┤ │ views/business/ │ │ ├── danye/ # 单页管理页面 │ │ │ ├── list.vue # 单页列表 │ │ │ └── components/ # 组件 │ │ ├── floatball/ # 悬浮球配置页面 │ │ │ ├── list.vue # 悬浮球列表 │ │ │ └── components/ # 组件 │ │ └── welfarehouse/ # 福利屋入口页面 │ │ ├── list.vue # 福利屋列表 │ │ └── components/ # 组件 │ ├─────────────────────────────────────────────────────────────────┤ │ api/business/ │ │ ├── danye.ts # 单页API │ │ ├── floatball.ts # 悬浮球API │ │ └── welfarehouse.ts # 福利屋API │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 后端 (ASP.NET Core) │ ├─────────────────────────────────────────────────────────────────┤ │ HoneyBox.Admin.Business/ │ │ ├── Controllers/ │ │ │ ├── DanyeController.cs │ │ │ ├── FloatBallController.cs │ │ │ └── WelfareHouseController.cs │ │ ├── Services/ │ │ │ ├── DanyeService.cs │ │ │ ├── FloatBallService.cs │ │ │ └── WelfareHouseService.cs │ │ └── Models/ │ │ ├── Danye/ │ │ ├── FloatBall/ │ │ └── WelfareHouse/ │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 数据库 (SQL Server) │ ├─────────────────────────────────────────────────────────────────┤ │ ├── danye # 单页内容表 (已存在) │ │ ├── float_ball_config # 悬浮球配置表 (已存在) │ │ └── welfare_house # 福利屋配置表 (已存在) │ └─────────────────────────────────────────────────────────────────┘ ``` ### 数据库实体(已存在) #### Danye 实体 ```csharp public class Danye { public int Id { get; set; } public string Title { get; set; } public string Content { get; set; } public int UpdateTime { get; set; } public byte Status { get; set; } public byte IsImageOptimizer { get; set; } } ``` #### FloatBallConfig 实体 ```csharp public class FloatBallConfig { public int Id { get; set; } public byte Status { get; set; } public byte Type { get; set; } // 1展示图片 2跳转页面 public string Image { get; set; } public string LinkUrl { get; set; } public string PositionX { get; set; } public string PositionY { get; set; } public string Width { get; set; } public string Height { get; set; } public byte Effect { get; set; } // 0无 1缩放动画 public string? Title { get; set; } public string? ImageDetails { get; set; } public string? ImageBj { get; set; } public string? ImageDetailsX { get; set; } public string? ImageDetailsY { get; set; } public string? ImageDetailsW { get; set; } public string? ImageDetailsH { get; set; } public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } } ``` #### WelfareHouse 实体 ```csharp public class WelfareHouse { public int Id { get; set; } public string Name { get; set; } public string Image { get; set; } public string Url { get; set; } public int Sort { get; set; } public byte Status { get; set; } public int? CreateTime { get; set; } public int? UpdateTime { get; set; } } ``` ## Components ### 后端组件 #### 1. DanyeController - `GET /api/business/danye` - 获取单页列表 - `GET /api/business/danye/{id}` - 获取单页详情 - `PUT /api/business/danye/{id}` - 更新单页内容 - `PUT /api/business/danye/{id}/image-optimizer` - 切换图片优化状态 #### 2. FloatBallController - `GET /api/business/floatball` - 获取悬浮球列表(分页) - `GET /api/business/floatball/{id}` - 获取悬浮球详情 - `POST /api/business/floatball` - 新增悬浮球 - `PUT /api/business/floatball/{id}` - 更新悬浮球 - `DELETE /api/business/floatball/{id}` - 删除悬浮球 - `PUT /api/business/floatball/{id}/status` - 切换状态 #### 3. WelfareHouseController - `GET /api/business/welfarehouse` - 获取福利屋列表(分页) - `GET /api/business/welfarehouse/{id}` - 获取福利屋详情 - `POST /api/business/welfarehouse` - 新增福利屋入口 - `PUT /api/business/welfarehouse/{id}` - 更新福利屋入口 - `DELETE /api/business/welfarehouse/{id}` - 删除福利屋入口 - `PUT /api/business/welfarehouse/{id}/status` - 切换状态 ### 前端组件 #### 1. 单页管理模块 - `DanyeList.vue` - 单页列表页面 - `DanyeTable.vue` - 单页表格组件 - `DanyeFormDialog.vue` - 单页编辑弹窗(含富文本编辑器) #### 2. 悬浮球配置模块 - `FloatBallList.vue` - 悬浮球列表页面 - `FloatBallTable.vue` - 悬浮球表格组件 - `FloatBallFormDialog.vue` - 悬浮球表单弹窗 #### 3. 福利屋入口模块 - `WelfareHouseList.vue` - 福利屋列表页面 - `WelfareHouseTable.vue` - 福利屋表格组件 - `WelfareHouseFormDialog.vue` - 福利屋表单弹窗 ## Data Models ### 后端 Models #### Danye Models ```csharp // 列表响应 public class DanyeResponse { public int Id { get; set; } public string Title { get; set; } public bool IsImageOptimizer { get; set; } public DateTime UpdateTime { get; set; } } // 详情响应 public class DanyeDetailResponse { public int Id { get; set; } public string Title { get; set; } public string Content { get; set; } public bool IsImageOptimizer { get; set; } } // 更新请求 public class DanyeUpdateRequest { public string? Title { get; set; } public string Content { get; set; } } ``` #### FloatBall Models ```csharp // 列表请求 public class FloatBallListRequest { public int Page { get; set; } = 1; public int PageSize { get; set; } = 10; } // 响应 public class FloatBallResponse { public int Id { get; set; } public string? Title { get; set; } public int Type { get; set; } public string Image { get; set; } public string? ImageBj { get; set; } public string? ImageDetails { get; set; } public string LinkUrl { get; set; } public string PositionX { get; set; } public string PositionY { get; set; } public string Width { get; set; } public string Height { get; set; } public string? ImageDetailsX { get; set; } public string? ImageDetailsY { get; set; } public string? ImageDetailsW { get; set; } public string? ImageDetailsH { get; set; } public int Effect { get; set; } public int Status { get; set; } public DateTime CreatedAt { get; set; } } // 创建/更新请求 public class FloatBallCreateRequest { public string? Title { get; set; } public int Type { get; set; } public string Image { get; set; } public string? ImageBj { get; set; } public string? ImageDetails { get; set; } public string? LinkUrl { get; set; } public string PositionX { get; set; } public string PositionY { get; set; } public string Width { get; set; } public string Height { get; set; } public string? ImageDetailsX { get; set; } public string? ImageDetailsY { get; set; } public string? ImageDetailsW { get; set; } public string? ImageDetailsH { get; set; } public int Effect { get; set; } public int Status { get; set; } = 1; } ``` #### WelfareHouse Models ```csharp // 列表请求 public class WelfareHouseListRequest { public int Page { get; set; } = 1; public int PageSize { get; set; } = 10; } // 响应 public class WelfareHouseResponse { public int Id { get; set; } public string Name { get; set; } public string Image { get; set; } public string Url { get; set; } public int Sort { get; set; } public int Status { get; set; } public DateTime? CreateTime { get; set; } } // 创建/更新请求 public class WelfareHouseCreateRequest { public string Name { get; set; } public string Image { get; set; } public string Url { get; set; } public int Sort { get; set; } public int Status { get; set; } = 1; } ``` ### 前端 TypeScript 接口 ```typescript // Danye interface DanyeResponse { id: number title: string isImageOptimizer: boolean updateTime: string } interface DanyeDetailResponse { id: number title: string content: string isImageOptimizer: boolean } interface DanyeUpdateRequest { title?: string content: string } // FloatBall interface FloatBallListRequest { page: number pageSize: number } interface FloatBallResponse { id: number title?: string type: number image: string imageBj?: string imageDetails?: string linkUrl: string positionX: string positionY: string width: string height: string imageDetailsX?: string imageDetailsY?: string imageDetailsW?: string imageDetailsH?: string effect: number status: number createdAt: string } interface FloatBallCreateRequest { title?: string type: number image: string imageBj?: string imageDetails?: string linkUrl?: string positionX: string positionY: string width: string height: string imageDetailsX?: string imageDetailsY?: string imageDetailsW?: string imageDetailsH?: string effect: number status?: number } // WelfareHouse interface WelfareHouseListRequest { page: number pageSize: number } interface WelfareHouseResponse { id: number name: string image: string url: string sort: number status: number createTime?: string } interface WelfareHouseCreateRequest { name: string image: string url: string sort: number status?: number } ``` ## API Design ### 单页管理 API | 方法 | 路径 | 描述 | 请求体 | 响应 | |------|------|------|--------|------| | GET | /api/business/danye | 获取单页列表 | - | `ApiResponse>` | | GET | /api/business/danye/{id} | 获取单页详情 | - | `ApiResponse` | | PUT | /api/business/danye/{id} | 更新单页内容 | `DanyeUpdateRequest` | `ApiResponse` | | PUT | /api/business/danye/{id}/image-optimizer | 切换图片优化 | `{ isImageOptimizer: bool }` | `ApiResponse` | ### 悬浮球配置 API | 方法 | 路径 | 描述 | 请求体 | 响应 | |------|------|------|--------|------| | GET | /api/business/floatball | 获取悬浮球列表 | Query: page, pageSize | `PagedResponse` | | GET | /api/business/floatball/{id} | 获取悬浮球详情 | - | `ApiResponse` | | POST | /api/business/floatball | 新增悬浮球 | `FloatBallCreateRequest` | `ApiResponse` | | PUT | /api/business/floatball/{id} | 更新悬浮球 | `FloatBallCreateRequest` | `ApiResponse` | | DELETE | /api/business/floatball/{id} | 删除悬浮球 | - | `ApiResponse` | | PUT | /api/business/floatball/{id}/status | 切换状态 | `{ status: int }` | `ApiResponse` | ### 福利屋入口 API | 方法 | 路径 | 描述 | 请求体 | 响应 | |------|------|------|--------|------| | GET | /api/business/welfarehouse | 获取福利屋列表 | Query: page, pageSize | `PagedResponse` | | GET | /api/business/welfarehouse/{id} | 获取福利屋详情 | - | `ApiResponse` | | POST | /api/business/welfarehouse | 新增福利屋入口 | `WelfareHouseCreateRequest` | `ApiResponse` | | PUT | /api/business/welfarehouse/{id} | 更新福利屋入口 | `WelfareHouseCreateRequest` | `ApiResponse` | | DELETE | /api/business/welfarehouse/{id} | 删除福利屋入口 | - | `ApiResponse` | | PUT | /api/business/welfarehouse/{id}/status | 切换状态 | `{ status: int }` | `ApiResponse` | ## UI Design ### 单页管理页面 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 单页管理 │ ├─────────────────────────────────────────────────────────────────┤ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ ID │ 标题 │ 图片优化 │ 更新时间 │ 操作 │ │ │ ├────┼────────────────────────┼─────────┼───────────┼───────┤ │ │ │ 1 │ 关于我们 │ [开关] │ 2026-01-18│ [编辑]│ │ │ │ 2 │ 用户协议 │ [开关] │ 2026-01-18│ [编辑]│ │ │ │ 3 │ 隐私政策 │ [开关] │ 2026-01-18│ [编辑]│ │ │ └─────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` ### 单页编辑弹窗 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 编辑单页 [X] │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 标题: [关于我们________________] (ID 2-20 不可编辑) │ │ │ │ 内容: │ │ ┌─────────────────────────────────────────────────────────────┐│ │ │ [B] [I] [U] [图片] [链接] ... ││ │ ├─────────────────────────────────────────────────────────────┤│ │ │ ││ │ │ 富文本编辑区域 ││ │ │ ││ │ └─────────────────────────────────────────────────────────────┘│ │ │ │ [取消] [保存] │ └─────────────────────────────────────────────────────────────────┘ ``` ### 悬浮球列表页面 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 悬浮球配置 [+ 新增] │ ├─────────────────────────────────────────────────────────────────┤ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ ID │ 标题 │ 图片 │ 背景图 │ 详情图 │ 类型 │ 链接 │ 位置 │ ... │ │ │ ├────┼─────┼─────┼───────┼───────┼─────┼─────┼─────┼─────┤ │ │ │ 1 │ 活动 │ [img]│ [img] │ [img] │ 跳转 │ /act│ 10,20│ ... │ │ │ │ 2 │ 客服 │ [img]│ - │ - │ 展示 │ - │ 10,80│ ... │ │ │ └─────────────────────────────────────────────────────────────┘ │ │ │ │ 共 2 条 < 1 > │ └─────────────────────────────────────────────────────────────────┘ ``` ### 悬浮球表单弹窗 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 新增悬浮球 [X] │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 标题: [____________________] │ │ │ │ 类型: (●) 展示图片 ( ) 跳转页面 │ │ │ │ 悬浮球图片: [上传] [预览] │ │ 背景图片: [上传] [预览] │ │ 详情图片: [上传] [预览] │ │ │ │ 跳转链接: [____________________] (类型为跳转时显示) │ │ │ │ 位置设置: │ │ X: [____] Y: [____] │ │ │ │ 尺寸设置: │ │ 宽: [____] 高: [____] │ │ │ │ 详情图位置: │ │ X: [____] Y: [____] 宽: [____] 高: [____] │ │ │ │ 特效: [无特效 ▼] │ │ 状态: [开关] │ │ │ │ [取消] [保存] │ └─────────────────────────────────────────────────────────────────┘ ``` ### 福利屋入口列表页面 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 福利屋入口 [+ 新增] │ ├─────────────────────────────────────────────────────────────────┤ │ ┌─────────────────────────────────────────────────────────────┐ │ │ │ ID │ 名称 │ 图片 │ 链接 │ 排序 │ 状态 │ 创建时间 │ 操作│ │ ├────┼─────────┼──────┼──────────┼─────┼─────┼─────────┼─────┤ │ │ │ 1 │ 签到有礼 │ [img] │ /sign │ 1 │ [开关]│ 01-18 │ [编辑][删除]│ │ │ 2 │ 新人福利 │ [img] │ /newbie │ 2 │ [开关]│ 01-18 │ [编辑][删除]│ │ └─────────────────────────────────────────────────────────────┘ │ │ │ │ 共 2 条 < 1 > │ └─────────────────────────────────────────────────────────────────┘ ``` ### 福利屋入口表单弹窗 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 新增福利屋入口 [X] │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 名称: [____________________] * │ │ │ │ 图片: [上传] [预览] * │ │ │ │ 跳转链接: [____________________] * │ │ │ │ 排序: [____] * │ │ │ │ 状态: [开关] │ │ │ │ [取消] [保存] │ └─────────────────────────────────────────────────────────────────┘ ``` ## Security Considerations 1. **权限控制**: 所有 API 需要验证管理员登录状态和权限 2. **输入验证**: 后端对所有输入进行验证,防止 XSS 和 SQL 注入 3. **富文本安全**: 富文本内容需要进行 HTML 净化处理 4. **图片上传**: 验证图片类型和大小,防止恶意文件上传 ## Performance Considerations 1. **分页加载**: 悬浮球和福利屋列表使用分页加载 2. **图片懒加载**: 表格中的图片使用懒加载 3. **富文本编辑器**: 按需加载富文本编辑器组件 ## Testing Strategy 1. **单元测试**: 后端 Service 层单元测试 2. **API 测试**: 使用 Swagger 测试 API 接口 3. **前端组件测试**: Vue 组件单元测试 4. **属性测试**: 验证搜索、分页、表单验证等通用属性 ## Dependencies ### 后端依赖 - Entity Framework Core (已有) - Mapster (已有) ### 前端依赖 - Element Plus (已有) - WangEditor 或 TinyMCE (富文本编辑器,需确认项目中使用的编辑器) - Vue Router (已有) ## References - Requirements: `.kiro/specs/content-auxiliary-frontend/requirements.md` - PHP 参考代码: `server/php/app/admin/controller/Danye.php` - PHP 参考代码: `server/php/app/admin/controller/FloatBall.php` - PHP 参考代码: `server/php/app/admin/controller/WelfareHouse.php` - 实体定义: `server/HoneyBox/src/HoneyBox.Model/Entities/Danye.cs` - 实体定义: `server/HoneyBox/src/HoneyBox.Model/Entities/FloatBallConfig.cs` - 实体定义: `server/HoneyBox/src/HoneyBox.Model/Entities/WelfareHouse.cs`