# Design Document ## Overview 本设计文档描述后台管理系统 9 个未修复 BUG 的技术修复方案。BUG 分布在统计报表、商品管理、营销活动和内容管理四个模块,主要涉及后端接口修复和少量前端调整。 ## Architecture ### 受影响模块架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 前端 (Vue 3 + Element Plus) │ ├─────────────────────────────────────────────────────────────────┤ │ views/business/ │ │ ├── statistics/ # 统计报表 (cs100_2, cs100_3) │ │ ├── goods/ # 商品管理 (cs100_4, cs100_5, cs100_6) │ │ ├── marketing/ # 营销活动 (cs100_11, cs100_13, cs100_14) │ │ └── danye/ # 内容管理 (cs100_15) │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ 后端 (ASP.NET Core) │ ├─────────────────────────────────────────────────────────────────┤ │ HoneyBox.Admin.Business/ │ │ ├── Controllers/ │ │ │ ├── StatisticsController.cs # 统计报表接口 │ │ │ ├── GoodsController.cs # 商品管理接口 │ │ │ ├── MarketingController.cs # 营销活动接口 │ │ │ └── DanyeController.cs # 单页管理接口 │ │ └── Services/ │ │ ├── StatisticsService.cs │ │ ├── GoodsService.cs │ │ ├── MarketingService.cs │ │ └── DanyeService.cs │ └─────────────────────────────────────────────────────────────────┘ ``` ## Bug Analysis & Solutions ### 1. 统计报表模块 (cs100_2, cs100_3) #### 问题分析 - 用户盈亏统计和用户邀请统计按用户ID搜索时返回"请求失败" - 可能原因: 1. 用户ID参数类型不匹配(前端传string,后端期望int) 2. 查询条件构建错误 3. 空值处理异常 #### 修复方案 ```csharp // StatisticsService.cs public async Task> GetUserProfitStatsAsync( UserProfitStatsRequest request) { var query = _dbContext.UserProfitStats.AsQueryable(); // 修复:正确处理用户ID搜索 if (!string.IsNullOrEmpty(request.UserId)) { if (int.TryParse(request.UserId, out var userId)) { query = query.Where(x => x.UserId == userId); } } // ... 分页逻辑 } ``` ### 2. 商品管理模块 - 盒子类型搜索 (cs100_4) #### 问题分析 - 盒子类型为"全部"时搜索无结果 - 可能原因: 1. "全部"选项传递了错误的值(如0)被当作有效类型过滤 2. 后端未正确处理"全部"情况 #### 修复方案 ```csharp // GoodsService.cs public async Task> GetBoxListAsync(BoxListRequest request) { var query = _dbContext.Boxes.AsQueryable(); // 修复:当类型为0或null时,不添加类型过滤条件 if (request.Type.HasValue && request.Type.Value > 0) { query = query.Where(x => x.Type == request.Type.Value); } // ... 其他过滤和分页逻辑 } ``` ### 3. 商品管理模块 - 自动下架配置 (cs100_5) #### 问题分析 - 开启"自动下架配置"后无法设置参数 - 可能原因: 1. 前端表单联动逻辑问题 2. 后端未返回自动下架相关字段 3. 保存接口未处理这些字段 #### 修复方案 **前端修复:** ```vue ``` **后端修复:** ```csharp // BoxResponse.cs - 确保返回自动下架字段 public class BoxResponse { // ... 其他字段 public bool AutoDelistEnabled { get; set; } public DateTime? AutoDelistTime { get; set; } public string? AutoDelistCondition { get; set; } } ``` ### 4. 商品管理模块 - 奖品等级分类显示 (cs100_6) #### 问题分析 - 奖品等级显示"0级",分类显示"未知" - 可能原因: 1. 未进行关联查询获取等级和分类名称 2. DTO映射时字段未正确赋值 #### 修复方案 ```csharp // GoodsService.cs public async Task> GetPrizeListAsync(PrizeListRequest request) { var query = from p in _dbContext.Prizes join l in _dbContext.PrizeLevels on p.LevelId equals l.Id into levels from level in levels.DefaultIfEmpty() join c in _dbContext.PrizeCategories on p.CategoryId equals c.Id into categories from category in categories.DefaultIfEmpty() select new PrizeResponse { Id = p.Id, Name = p.Name, LevelId = p.LevelId, LevelName = level != null ? level.Name : "未设置", // 修复 CategoryId = p.CategoryId, CategoryName = category != null ? category.Name : "未设置", // 修复 // ... 其他字段 }; // ... 分页逻辑 } ``` ### 5. 营销活动模块 - 领取记录搜索 (cs100_11) #### 问题分析 - 按用户ID搜索领取记录时返回"请求失败" - 与统计报表模块问题类似 #### 修复方案 ```csharp // MarketingService.cs public async Task> GetClaimRecordsAsync( ClaimRecordRequest request) { var query = _dbContext.ClaimRecords.AsQueryable(); // 修复:正确处理用户ID搜索 if (!string.IsNullOrEmpty(request.UserId)) { if (int.TryParse(request.UserId, out var userId)) { query = query.Where(x => x.UserId == userId); } } // ... 分页逻辑 } ``` ### 6. 营销活动模块 - 周榜/月榜记录 (cs100_13, cs100_14) #### 问题分析 - 访问周榜/月榜页面时返回"服务器内部错误" - 可能原因: 1. 日期范围计算错误 2. 数据聚合查询异常 3. 空数据处理异常 #### 修复方案 ```csharp // MarketingService.cs public async Task> GetWeeklyRankAsync(RankRequest request) { try { // 修复:正确计算周起止日期 var startOfWeek = GetStartOfWeek(request.Date ?? DateTime.Now); var endOfWeek = startOfWeek.AddDays(7); var query = _dbContext.RankRecords .Where(x => x.RecordDate >= startOfWeek && x.RecordDate < endOfWeek) .OrderByDescending(x => x.Score); // 修复:处理空数据情况 var result = await query.ToListAsync(); return result ?? new List(); } catch (Exception ex) { _logger.LogError(ex, "获取周榜数据失败"); throw new BusinessException("获取周榜数据失败,请稍后重试"); } } private DateTime GetStartOfWeek(DateTime date) { var diff = (7 + (date.DayOfWeek - DayOfWeek.Monday)) % 7; return date.AddDays(-diff).Date; } ``` ### 7. 内容管理模块 - 单页文章显示 (cs100_15) #### 问题分析 - 文章内容显示原始HTML代码而非渲染内容 - 原因:前端使用 `{{ content }}` 而非 `v-html` #### 修复方案 ```vue ``` ## API Changes ### 统计报表 API 修复 | 方法 | 路径 | 修复内容 | |------|------|----------| | GET | /api/business/statistics/user-profit | 修复用户ID参数处理 | | GET | /api/business/statistics/user-invite | 修复用户ID参数处理 | ### 商品管理 API 修复 | 方法 | 路径 | 修复内容 | |------|------|----------| | GET | /api/business/goods/boxes | 修复类型"全部"过滤逻辑 | | GET | /api/business/goods/boxes/{id} | 添加自动下架字段返回 | | PUT | /api/business/goods/boxes/{id} | 处理自动下架字段保存 | | GET | /api/business/goods/prizes | 修复等级/分类关联查询 | ### 营销活动 API 修复 | 方法 | 路径 | 修复内容 | |------|------|----------| | GET | /api/business/marketing/claim-records | 修复用户ID参数处理 | | GET | /api/business/marketing/weekly-rank | 修复日期计算和异常处理 | | GET | /api/business/marketing/monthly-rank | 修复日期计算和异常处理 | ## Testing Strategy ### 单元测试 - 测试用户ID参数解析逻辑 - 测试类型过滤条件构建 - 测试日期范围计算 - 测试关联查询结果映射 ### 集成测试 - 测试各搜索接口正常返回 - 测试空数据情况处理 - 测试边界条件(无效ID、特殊日期等) ### 前端测试 - 测试表单联动显示 - 测试HTML内容渲染 - 测试XSS防护 ## Security Considerations 1. **XSS防护**: 单页文章内容使用 DOMPurify 进行净化 2. **参数验证**: 所有搜索参数进行类型验证 3. **异常处理**: 统一异常处理,不暴露内部错误信息 ## References - BUG汇总清单: `docs/后台管理bug整理/BUG汇总清单.md` - 各BUG详细文档: `docs/后台管理bug整理/BUG-*.md`