26日1841-施肥失败问题修复.md 4.6 KB

施肥失败问题修复

任务时间: 2025年05月26日 18:41
任务类型: Bug修复
涉及模块: Farm

问题描述

施肥操作失败,错误日志显示:

[2025-05-26T17:40:10.489443+08:00] laravel.ERROR: 施肥失败:使用化肥失败 {"exception":"[object] (UCore\\Exception\\LogicException(code: 0): 施肥失败:使用化肥失败 at /var/www/html/app/Module/AppGame/Handler/Land/FertilizerHandler.php:77)"} []

问题分析

通过代码分析,发现问题出现在CropLogic::useFertilizer方法中:

1. Carbon对象修改问题

问题位置: app/Module/Farm/Logics/CropLogic.php 第377行

问题代码:

$crop->stage_end_time = $endTime->subSeconds($reducedTime);

问题原因:

  • 直接修改了从数据库获取的Carbon对象$endTime
  • subSeconds()方法会修改原始对象,导致后续使用时出现问题
  • 这可能导致时间计算错误或对象状态异常

2. 枚举类型处理问题

问题位置: app/Module/Farm/Logics/CropLogic.php calculateNextStage方法

问题代码:

if ($currentStage === GROWTH_STAGE::MATURE->value) {
// ...
return $stageMap[$currentStage->value()] ?? GROWTH_STAGE::WITHERED->value;

问题原因:

  • $currentStage可能是枚举对象或整数值
  • 直接调用->value()方法可能导致错误
  • 需要统一处理枚举类型

修复方案

1. 修复Carbon对象修改问题

修复前:

$crop->stage_end_time = $endTime->subSeconds($reducedTime);

修复后:

// 使用copy()方法创建副本,避免修改原始对象
$newEndTime = $endTime->copy()->subSeconds($reducedTime);
$crop->stage_end_time = $newEndTime;

修复效果:

  • 避免修改原始Carbon对象
  • 确保时间计算的准确性
  • 防止对象状态异常

2. 添加剩余时间检查

新增逻辑:

if ($remainingTime > 0) {
    // 正常处理
} else {
    Log::warning('作物已经到达或超过结束时间,无法减少生长时间', [
        'crop_id' => $crop->id,
        'current_time' => $currentTime->toDateTimeString(),
        'stage_end_time' => $endTime->toDateTimeString(),
        'remaining_time' => $remainingTime
    ]);
}

修复效果:

  • 处理作物已经成熟或超时的情况
  • 提供详细的警告日志
  • 避免负数时间计算

3. 修复枚举类型处理

修复前:

if ($currentStage === GROWTH_STAGE::MATURE->value) {
// ...
return $stageMap[$currentStage->value()] ?? GROWTH_STAGE::WITHERED->value;

修复后:

$currentStageValue = is_object($currentStage) ? $currentStage->value : $currentStage;
if ($currentStageValue === GROWTH_STAGE::MATURE->value) {
// ...
return $stageMap[$currentStageValue] ?? GROWTH_STAGE::WITHERED->value;

修复效果:

  • 统一处理枚举对象和整数值
  • 避免类型错误
  • 提高代码健壮性

技术细节

Carbon对象处理最佳实践

  1. 使用copy()方法: 在修改Carbon对象前创建副本
  2. 避免链式调用: 分步骤处理时间计算
  3. 检查时间有效性: 确保时间计算结果合理

枚举类型处理

  1. 类型检查: 使用is_object()检查是否为枚举对象
  2. 统一取值: 统一获取枚举的整数值
  3. 默认值处理: 提供合理的默认值

错误处理改进

  1. 详细日志: 记录关键参数和状态
  2. 边界条件: 处理异常情况
  3. 优雅降级: 在非关键错误时继续执行

预防措施

1. 时间处理规范

  • 修改Carbon对象前必须使用copy()方法
  • 进行时间计算前检查时间有效性
  • 记录时间变更的详细日志

2. 枚举处理规范

  • 统一枚举值的获取方式
  • 添加类型检查避免运行时错误
  • 提供合理的默认值

3. 测试覆盖

  • 添加边界条件测试
  • 测试时间计算的准确性
  • 验证枚举类型处理的正确性

完成状态

  • 修复 Carbon 对象修改问题,使用 copy() 方法创建副本
  • 添加剩余时间检查,处理作物超时情况
  • 修复枚举类型处理,统一值获取方式
  • 添加详细的警告日志记录
  • 代码提交和推送

总结

本次修复解决了施肥操作中的关键问题:

  1. Carbon对象修改问题: 通过使用copy()方法避免修改原始对象
  2. 时间计算问题: 添加边界条件检查,处理异常情况
  3. 枚举类型问题: 统一处理枚举对象和整数值
  4. 错误处理: 提供详细的日志记录和优雅降级

这些修复提高了施肥功能的稳定性和可靠性,避免了因时间计算错误导致的系统异常。