# 优化自动收获功能,附带铲除枯萎植物 **时间**: 2025-06-06 22:06 **任务类型**: 功能优化 **紧急程度**: 急需 ## 任务背景 在修复自动杀虫技能问题后,用户要求优化自动收获功能,让它能够自动铲除枯萎的植物(不使用道具)。 ## 问题分析 通过测试发现: 1. **枯萎作物无法自动清理**:用户有2个枯萎状态的土地(63、67),但自动收获技能没有处理 2. **作物状态比较问题**:作物的`growth_stage`字段存储的是枚举对象,而不是整数值 3. **功能缺失**:自动收获技能只处理可收获的作物,没有主动清理枯萎作物 ## 解决方案 ### 1. 新增批量清理枯萎作物功能 添加 `clearAllWitheredCrops` 方法,在自动收获开始时主动清理所有枯萎作物: ```php protected function clearAllWitheredCrops(int $userId): int { try { // 获取所有枯萎状态的土地 $witheredLands = \App\Module\Farm\Models\FarmLand::where('user_id', $userId) ->where('status', \App\Module\Farm\Enums\LAND_STATUS::WITHERED->value) ->get(); $clearedCount = 0; foreach ($witheredLands as $land) { try { // 开启事务处理单个土地的清理 DB::beginTransaction(); $cleared = $this->autoClearWitheredCrop($userId, $land->id); if ($cleared) { $clearedCount++; Log::info('自动清理枯萎作物成功', [ 'user_id' => $userId, 'land_id' => $land->id ]); } DB::commit(); } catch (\Exception $e) { DB::rollBack(); Log::warning('自动清理枯萎作物失败', [ 'user_id' => $userId, 'land_id' => $land->id, 'error' => $e->getMessage() ]); } } if ($clearedCount > 0) { Log::info('批量清理枯萎作物完成', [ 'user_id' => $userId, 'cleared_count' => $clearedCount, 'total_withered_lands' => $witheredLands->count() ]); } return $clearedCount; } catch (\Exception $e) { Log::error('批量清理枯萎作物失败', [ 'user_id' => $userId, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString() ]); return 0; } } ``` ### 2. 修复作物状态比较问题 修复 `autoClearWitheredCrop` 方法中的枚举对象比较问题: ```php // 检查作物是否为枯萎状态 $cropStageValue = is_object($crop->growth_stage) ? $crop->growth_stage->value : $crop->growth_stage; if ($cropStageValue !== \App\Module\Farm\Enums\GROWTH_STAGE::WITHERED->value) { return false; } ``` ### 3. 优化自动收获流程 修改 `processAutoHarvest` 方法,在开始时先清理枯萎作物: ```php public function processAutoHarvest(PetActiveSkill $activeSkill): void { try { $pet = $activeSkill->pet; $userId = $pet->user_id; Log::info('开始处理自动收菜技能', [ 'active_skill_id' => $activeSkill->id, 'pet_id' => $pet->id, 'user_id' => $userId ]); // 首先清理所有枯萎的作物(不使用道具) $witheredClearCount = $this->clearAllWitheredCrops($userId); // 获取用户所有可收获的土地 $harvestableLands = LandService::getHarvestableLands($userId); // ... 正常收获逻辑 ... // 记录统计信息 $this->recordSkillStatistics($activeSkill, 'auto_harvest', [ 'harvest_count' => $harvestCount, 'auto_cleared_count' => $autoClearedCount, 'withered_cleared_count' => $witheredClearCount, 'total_lands_checked' => $harvestableLands->count(), 'harvest_results' => $harvestResults ]); } } ``` ## 测试结果 修复后测试结果: 1. **枯萎作物清理成功**: - 土地63:枯萎状态 → 空闲状态 - 土地67:枯萎状态 → 空闲状态 2. **统计信息正确**:`"withered_cleared_count":2` 3. **网页显示更新**: - 土地状态统计:种植中 10,空闲 2 - 灾害统计:虫害 0,干旱 0,杂草 0 - 杀虫剂数量:18个(消耗了1个) 4. **日志记录完整**: ``` [2025-06-06T22:02:54.654324+08:00] laravel.INFO: 宠物自动铲除枯萎作物成功 {"user_id":10002,"land_id":67,"crop_id":180} [2025-06-06T22:02:54.731524+08:00] laravel.INFO: 批量清理枯萎作物完成 {"user_id":10002,"cleared_count":2,"total_withered_lands":2} ``` ## 功能特点 ### 优化后的自动收获功能包括: 1. **主动清理枯萎作物**: - 在收获开始时扫描所有枯萎状态的土地 - 自动铲除枯萎作物,不消耗道具 - 将土地状态恢复为空闲 2. **正常收获流程**: - 收获成熟的作物 - 收获后自动铲除新产生的枯萎作物 3. **完整统计记录**: - `harvest_count`:收获的作物数量 - `auto_cleared_count`:收获后清理的枯萎作物数量 - `withered_cleared_count`:主动清理的枯萎作物数量 ## 技术细节 ### 关键修复点 1. **枚举对象处理**: - 问题:`crop->growth_stage` 存储的是枚举对象 `{"App\\Module\\Farm\\Enums\\GROWTH_STAGE":50}` - 解决:使用 `is_object()` 检查并获取 `->value` 属性 2. **事务管理**: - 每个土地的清理操作独立事务 - 确保单个失败不影响其他土地的处理 3. **不使用道具**: - 直接调用 `CropService::removeCrop()` 方法 - 不消耗铲子等道具 ## 文件修改 - `app/Module/Pet/Logic/PetAutoSkillLogic.php` - 新增 `clearAllWitheredCrops` 方法(第718-757行) - 修改 `processAutoHarvest` 方法(第27-117行) - 修复 `autoClearWitheredCrop` 方法(第786-811行) ## 验证方法 1. 运行命令: `php artisan pet:process-active-skills --sync` 2. 查看用户农场信息: `http://kku_laravel.local.gd/admin/farm-user-summary/10002` 3. 确认枯萎土地变为空闲状态,统计信息正确 ## 提交信息 ``` 优化自动收获功能,附带铲除枯萎植物 - 新增clearAllWitheredCrops方法,在自动收获开始时主动清理所有枯萎作物 - 修复作物growth_stage枚举对象与整数值比较问题 - 优化自动收获流程:先清理枯萎作物,再进行正常收获 - 增加withered_cleared_count统计,记录清理的枯萎作物数量 - 移除调试日志,保持代码整洁 - 自动铲除枯萎作物不使用道具,直接调用CropService::removeCrop 现在自动收获技能可以: 1. 主动清理所有枯萎的作物(不消耗道具) 2. 正常收获成熟的作物 3. 收获后自动铲除新产生的枯萎作物 ```