# 修复 getTodayStats 方法使用 mapping_time 时间判定 **任务时间**: 2025年07月05日 04:15 **任务类型**: Bug修复 **模块**: AppGame/Handler/Promotion ## 问题描述 用户反馈 `getTodayStats` 方法不能正确工作,缓存的时间判定有问题,应该使用 `UrsUserMapping` 表的 `mapping_time` 字段进行时间判定,而不是使用缓存表的 `created_at` 字段。 ## 问题分析 ### 原有实现的问题 1. **错误的时间基准**: 原来的实现使用 `UrsUserRelationCache.created_at` 作为今日新增的判定依据 2. **时间语义不符**: `created_at` 表示关系缓存记录的创建时间,而不是用户实际进入农场的时间 3. **数据不准确**: 缓存可能在用户进入农场之前就已经创建(占位记录),导致统计不准确 ### 正确的实现方式 应该使用 `UrsUserMapping.mapping_time` 字段,这个字段才真正表示用户进入农场的时间。 ## 修复方案 ### 1. 修改查询逻辑 将原来基于缓存表 `created_at` 的查询改为基于映射表 `mapping_time` 的关联查询: **修改前**: ```php $todayRelations = UrsUserRelationCache::where('related_user_id', $farmUserId) ->whereDate('created_at', today()) ->selectRaw('...') ->first(); ``` **修改后**: ```php $todayRelations = UrsUserRelationCache::where('related_user_id', $farmUserId) ->join('urs_promotion_user_mappings', 'kku_urs_promotion_user_relation_cache.urs_user_id', '=', 'urs_promotion_user_mappings.urs_user_id') ->where('urs_promotion_user_mappings.status', UrsUserMapping::STATUS_VALID) ->whereDate('urs_promotion_user_mappings.mapping_time', today()) ->selectRaw('...') ->first(); ``` ### 2. 修改的文件 - **文件**: `app/Module/AppGame/Handler/Promotion/InfoHandler.php` - **方法**: `getTodayStats()` - **添加导入**: `use App\Module\UrsPromotion\Models\UrsUserMapping;` ### 3. 核心修改内容 1. 添加 JOIN 查询关联 `urs_promotion_user_mappings` 表 2. 添加状态过滤条件 `status = 1`(有效状态) 3. 将时间过滤条件从 `created_at` 改为 `mapping_time` 4. 更新字段引用,使用完整的表名前缀避免歧义 ## 测试验证 ### 1. 更新测试文件 - **文件**: `tests/Unit/AppGame/Handler/Promotion/TodayStatsLogicTest.php` - **新增测试方法**: `test_optimized_query_logic_with_mapping_time()` - **更新测试方法**: `test_query_bindings_with_mapping_time()` ### 2. 测试结果 ```bash PHPUnit 11.5.20 by Sebastian Bergmann and contributors. ....... 7 / 7 (100%) Time: 00:00.496, Memory: 46.50 MB OK (7 tests, 16 assertions) ``` ### 3. 测试覆盖 - ✅ SQL查询构建逻辑 - ✅ 查询参数绑定验证 - ✅ JOIN关联查询逻辑 - ✅ 时间过滤条件验证 - ✅ 状态过滤条件验证 ## 修复效果 ### 1. 数据准确性 - **时间基准正确**: 基于用户实际进入农场的时间(`mapping_time`) - **状态过滤**: 只统计有效状态的映射关系 - **避免占位数据**: 不会统计到占位的缓存记录 ### 2. 查询性能 - **单次查询**: 通过 JOIN 查询一次性获取结果 - **索引利用**: 利用现有的索引结构 - **查询效率**: 相比原来的多次查询,性能更优 ### 3. 代码质量 - **逻辑清晰**: 查询意图更明确 - **数据一致**: 与业务逻辑保持一致 - **可维护性**: 代码更容易理解和维护 ## 注意事项 ### 1. 数据依赖 - 依赖 `urs_promotion_user_mappings` 表的数据完整性 - 需要确保 `mapping_time` 字段正确记录用户进入农场的时间 ### 2. 兼容性 - 保持返回数据格式不变 - 保持异常处理逻辑不变 - 不影响其他相关功能 ### 3. 监控建议 - 监控查询性能变化 - 验证统计数据的准确性 - 关注 `mapping_time` 字段的数据质量 ## 相关说明 ### getActiveStats 方法 `getActiveStats` 方法没有类似问题,因为它基于用户的活跃时间(`last_activity_time`)进行统计,时间语义是正确的。 ### 缓存机制 此修复不影响关系缓存的生成和维护机制,只是修正了统计查询的时间基准。