# 修复URS推荐关系缓存断代问题 **任务时间**: 2025年07月05日 02:04 **任务类型**: Bug修复 **模块**: UrsPromotion/UrsRelationCacheLogic ## 问题描述 用户反馈"未进入农场,跳过缓存生成"会造成推荐关系的"断代"问题。 ### 问题场景 假设推荐链:A (未进入农场) → B (已进入农场) → C (已进入农场) → D (已进入农场) **原有逻辑问题**: - 当B用户尝试生成关系缓存时,发现推荐人A未进入农场 - 系统直接跳过B的缓存生成 - 导致B、C、D都无法建立与A的关系缓存 - **结果**:整个推荐链断裂,A永远无法获得下级奖励 ### 业务影响 1. **奖励分发断裂**:推荐人无法获得下级奖励 2. **数据不完整**:关系缓存表缺失大量有效推荐关系 3. **用户体验差**:推荐人看不到下级数据 4. **业务逻辑错误**:违背推荐系统基本原则 ## 解决方案 ### 1. 修改缓存生成逻辑 **原有逻辑**: ```php // 如果农场用户ID为0,跳过缓存生成 if ($farmUserId <= 0 || $farmReferrerId <= 0) { Log::info("URS用户 {$ursUserId} 或推荐人 {$ursReferrerId} 未进入农场,跳过缓存生成"); return true; } ``` **新逻辑**: - 如果当前用户未进入农场,跳过缓存生成 - 如果推荐人未进入农场,创建**占位缓存记录**,避免断代 - 通过URS关系链向上查找已进入农场的上级 ### 2. 占位缓存机制 当推荐人未进入农场时: 1. 创建占位的直接关系缓存(`related_user_id = 0`) 2. 通过URS关系链向上递归查找 3. 为已进入农场的上级创建有效缓存 4. 为未进入农场的上级创建占位缓存 ### 3. 推荐人进入农场时的修复机制 当推荐人后来进入农场时: 1. 更新所有占位缓存记录(`related_user_id` 从0更新为实际农场用户ID) 2. 更新路径中的占位符(将路径中的'0'替换为实际农场用户ID) 3. 为该用户的所有下级重新生成缓存,修复断代问题 ## 实现详情 ### 1. 核心方法修改 #### `generateUserRelationCache()` 方法 - 区分当前用户和推荐人的进入农场状态 - 推荐人未进入农场时创建占位缓存 - 调用新的递归方法处理间接关系 #### 新增辅助方法 1. `generateIndirectRelationsFromUrsChain()` - 基于URS关系链生成间接关系 2. `generateIndirectRelationsFromExistingCache()` - 基于已有缓存生成间接关系 3. `updatePlaceholderPaths()` - 更新路径中的占位符 4. `regenerateDownstreamCaches()` - 重新生成下级缓存 ### 2. 路径构建方法 1. `buildFarmUserPath()` - 构建农场用户路径 2. `buildUrsPath()` - 构建URS用户路径 3. `buildCombinedFarmPath()` - 构建组合农场用户路径 4. `buildCombinedUrsPath()` - 构建组合URS用户路径 ### 3. 缓存更新机制 #### `updateFarmUserIdInCache()` 方法增强 - 更新占位缓存记录(`related_user_id` 从0更新为实际ID) - 更新路径中的占位符 - 为所有下级重新生成缓存 ## 测试工具 创建了专门的测试命令 `TestRelationCacheFixCommand`: ```bash # 检查断代问题 php artisan urs:test-relation-cache-fix --check # 修复断代问题 php artisan urs:test-relation-cache-fix --fix # 显示统计信息 php artisan urs:test-relation-cache-fix --stats # 测试特定用户 php artisan urs:test-relation-cache-fix --user-id=24127 ``` ### 测试功能 1. **检查断代问题**:查找有推荐关系但无缓存的用户 2. **修复断代问题**:批量重新生成缺失的缓存 3. **统计信息**:显示缓存完整性统计 4. **特定用户测试**:详细测试单个用户的缓存生成 ## 技术特点 ### 1. 向后兼容 - 保持现有缓存结构不变 - 新增占位机制不影响现有查询逻辑 - 渐进式修复,不需要全量重建 ### 2. 性能优化 - 递归深度限制(最多20代) - 批量更新减少数据库操作 - 智能跳过已处理的记录 ### 3. 数据完整性 - 占位缓存确保关系链完整 - 自动修复机制确保数据一致性 - 详细日志记录便于问题追踪 ### 4. 业务逻辑正确性 - 解决断代问题,确保奖励正常分发 - 保持推荐关系的完整性 - 支持推荐人后续进入农场的场景 ## 预期效果 1. **解决断代问题**:推荐人未进入农场不再导致整个推荐链断裂 2. **完整的关系缓存**:所有有效推荐关系都有对应的缓存记录 3. **正常的奖励分发**:推荐人进入农场后能正常获得下级奖励 4. **良好的用户体验**:推荐数据完整,用户满意度提升 ## 数据库索引优化 ### 问题发现 在实现过程中发现原有的 `idx_user_relation` 唯一索引存在问题: - **原索引**:`UNIQUE KEY idx_user_relation (user_id, related_user_id)` - **问题**:当多个用户的推荐人都未进入农场时,都会产生 `related_user_id = 0` 的占位记录 - **冲突**:违反唯一约束,导致插入失败 ### 解决方案 移除有问题的索引,增加包含深度的组合索引: - **移除**:`idx_user_relation (user_id, related_user_id)` - **新增**:`idx_user_relation_depth (user_id, related_user_id, depth)` ### 优化效果 1. **允许占位记录**:多个用户可以有 `related_user_id = 0` 的记录 2. **防止真正重复**:同一用户、同一上级、同一深度不能重复 3. **保持性能**:索引仍然提供良好的查询性能 4. **业务逻辑正确**:符合推荐关系的实际业务需求 ## 风险控制 1. **占位缓存标识**:使用`related_user_id = 0`明确标识占位记录 2. **递归深度限制**:防止无限递归导致性能问题 3. **异常处理**:完善的错误处理和日志记录 4. **测试工具**:提供完整的测试和验证工具 5. **索引优化**:合理的数据库索引设计,避免约束冲突 ## 总结 本次修复彻底解决了URS推荐关系缓存的断代问题,通过占位缓存机制确保推荐链的完整性,同时提供了完善的修复和测试工具。修复后的系统能够正确处理推荐人未进入农场的场景,确保业务逻辑的正确性和用户体验的完整性。