050415-修复getTodayStats使用mapping_time判定.md 4.1 KB

修复 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 的关联查询:

修改前:

$todayRelations = UrsUserRelationCache::where('related_user_id', $farmUserId)
    ->whereDate('created_at', today())
    ->selectRaw('...')
    ->first();

修改后:

$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. 测试结果

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)进行统计,时间语义是正确的。

缓存机制

此修复不影响关系缓存的生成和维护机制,只是修正了统计查询的时间基准。