|
|
@@ -304,6 +304,9 @@ class PetAutoSkillLogic
|
|
|
// 检查事务是否已开启
|
|
|
\UCore\Db\Helper::check_tr();
|
|
|
|
|
|
+ // 记录开始时间用于性能监控
|
|
|
+ $startTime = microtime(true);
|
|
|
+
|
|
|
$pet = $activeSkill->pet;
|
|
|
$userId = $pet->user_id;
|
|
|
|
|
|
@@ -328,35 +331,27 @@ class PetAutoSkillLogic
|
|
|
$disasterType = \App\Module\Farm\Enums\DISASTER_TYPE::WEED->value;
|
|
|
|
|
|
foreach ($landsWithCrops as $land) {
|
|
|
- // 检查土地是否有杂草灾害
|
|
|
- $hasWeedDisaster = $this->checkSpecificDisaster($land, $disasterType);
|
|
|
-
|
|
|
- if ($hasWeedDisaster) {
|
|
|
- // 自动清除杂草灾害
|
|
|
- $cleared = $this->autoClearSpecificDisaster($userId, $land, $disasterType);
|
|
|
+ $landResult = $this->processLandDisasters($userId, $pet, $land, $disasterType, 'weed');
|
|
|
+ $weedingCount += $landResult['cleared_count'];
|
|
|
|
|
|
- if ($cleared) {
|
|
|
- $weedingCount++;
|
|
|
- Log::info('自动除草成功', [
|
|
|
- 'user_id' => $userId,
|
|
|
- 'pet_id' => $pet->id,
|
|
|
- 'land_id' => $land->id
|
|
|
- ]);
|
|
|
- } else {
|
|
|
- Log::warning('自动除草处理失败', [
|
|
|
- 'user_id' => $userId,
|
|
|
- 'pet_id' => $pet->id,
|
|
|
- 'land_id' => $land->id,
|
|
|
- 'error' => '清除杂草灾害失败'
|
|
|
- ]);
|
|
|
- }
|
|
|
+ // 如果遇到道具不足,记录并可能提前结束
|
|
|
+ if ($landResult['stopped_reason'] === 'insufficient_items') {
|
|
|
+ Log::warning('自动除草因道具不足停止', [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'pet_id' => $pet->id,
|
|
|
+ 'land_id' => $land->id,
|
|
|
+ 'cleared_count' => $landResult['cleared_count']
|
|
|
+ ]);
|
|
|
+ // 可以选择继续处理其他土地或者停止
|
|
|
+ // 这里选择继续处理其他土地
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 记录统计信息
|
|
|
$this->recordSkillStatistics($activeSkill, 'auto_weeding', [
|
|
|
'weeding_count' => $weedingCount,
|
|
|
- 'total_lands_checked' => $landsWithCrops->count()
|
|
|
+ 'total_lands_checked' => $landsWithCrops->count(),
|
|
|
+ 'processing_time_ms' => (microtime(true) - $startTime) * 1000
|
|
|
]);
|
|
|
|
|
|
Log::info('自动除草技能处理完成', [
|
|
|
@@ -364,7 +359,8 @@ class PetAutoSkillLogic
|
|
|
'pet_id' => $pet->id,
|
|
|
'user_id' => $userId,
|
|
|
'weeding_count' => $weedingCount,
|
|
|
- 'total_lands' => $landsWithCrops->count()
|
|
|
+ 'total_lands' => $landsWithCrops->count(),
|
|
|
+ 'processing_time_ms' => round((microtime(true) - $startTime) * 1000, 2)
|
|
|
]);
|
|
|
}
|
|
|
|
|
|
@@ -379,6 +375,9 @@ class PetAutoSkillLogic
|
|
|
// 检查事务是否已开启
|
|
|
\UCore\Db\Helper::check_tr();
|
|
|
|
|
|
+ // 记录开始时间用于性能监控
|
|
|
+ $startTime = microtime(true);
|
|
|
+
|
|
|
try {
|
|
|
$pet = $activeSkill->pet;
|
|
|
$userId = $pet->user_id;
|
|
|
@@ -408,30 +407,16 @@ class PetAutoSkillLogic
|
|
|
$disasterType = \App\Module\Farm\Enums\DISASTER_TYPE::DROUGHT->value;
|
|
|
|
|
|
foreach ($landsWithCrops as $land) {
|
|
|
- try {
|
|
|
- // 检查土地是否有干旱灾害
|
|
|
- $hasDroughtDisaster = $this->checkSpecificDisaster($land, $disasterType);
|
|
|
+ $landResult = $this->processLandDisasters($userId, $pet, $land, $disasterType, 'watering');
|
|
|
+ $wateringCount += $landResult['cleared_count'];
|
|
|
|
|
|
- if ($hasDroughtDisaster) {
|
|
|
- // 自动清除干旱灾害
|
|
|
- $cleared = $this->autoClearSpecificDisaster($userId, $land, $disasterType);
|
|
|
-
|
|
|
- if ($cleared) {
|
|
|
- $wateringCount++;
|
|
|
- Log::info('自动浇水成功', [
|
|
|
- 'user_id' => $userId,
|
|
|
- 'pet_id' => $pet->id,
|
|
|
- 'land_id' => $land->id
|
|
|
- ]);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- } catch (\Exception $e) {
|
|
|
- Log::warning('自动浇水处理失败', [
|
|
|
+ // 如果遇到道具不足,记录并可能提前结束
|
|
|
+ if ($landResult['stopped_reason'] === 'insufficient_items') {
|
|
|
+ Log::warning('自动浇水因道具不足停止', [
|
|
|
'user_id' => $userId,
|
|
|
'pet_id' => $pet->id,
|
|
|
'land_id' => $land->id,
|
|
|
- 'error' => $e->getMessage()
|
|
|
+ 'cleared_count' => $landResult['cleared_count']
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
@@ -439,7 +424,8 @@ class PetAutoSkillLogic
|
|
|
// 记录统计信息
|
|
|
$statistics = [
|
|
|
'watering_count' => $wateringCount,
|
|
|
- 'total_lands_checked' => $landsWithCrops->count()
|
|
|
+ 'total_lands_checked' => $landsWithCrops->count(),
|
|
|
+ 'processing_time_ms' => (microtime(true) - $startTime) * 1000
|
|
|
];
|
|
|
|
|
|
$this->recordSkillStatistics($activeSkill, 'auto_watering', $statistics);
|
|
|
@@ -449,7 +435,8 @@ class PetAutoSkillLogic
|
|
|
'pet_id' => $pet->id,
|
|
|
'user_id' => $userId,
|
|
|
'watering_count' => $wateringCount,
|
|
|
- 'total_lands' => $landsWithCrops->count()
|
|
|
+ 'total_lands' => $landsWithCrops->count(),
|
|
|
+ 'processing_time_ms' => round((microtime(true) - $startTime) * 1000, 2)
|
|
|
]);
|
|
|
|
|
|
return $statistics;
|
|
|
@@ -478,6 +465,9 @@ class PetAutoSkillLogic
|
|
|
*/
|
|
|
public function processAutoPestControl(PetActiveSkill $activeSkill): void
|
|
|
{
|
|
|
+ // 记录开始时间用于性能监控
|
|
|
+ $startTime = microtime(true);
|
|
|
+
|
|
|
try {
|
|
|
$pet = $activeSkill->pet;
|
|
|
$userId = $pet->user_id;
|
|
|
@@ -505,30 +495,16 @@ class PetAutoSkillLogic
|
|
|
$disasterType = \App\Module\Farm\Enums\DISASTER_TYPE::PEST->value;
|
|
|
|
|
|
foreach ($landsWithCrops as $land) {
|
|
|
- try {
|
|
|
- // 检查土地是否有虫害灾害
|
|
|
- $hasPestDisaster = $this->checkSpecificDisaster($land, $disasterType);
|
|
|
-
|
|
|
- if ($hasPestDisaster) {
|
|
|
- // 自动清除虫害灾害
|
|
|
- $cleared = $this->autoClearSpecificDisaster($userId, $land, $disasterType);
|
|
|
+ $landResult = $this->processLandDisasters($userId, $pet, $land, $disasterType, 'pest_control');
|
|
|
+ $pestControlCount += $landResult['cleared_count'];
|
|
|
|
|
|
- if ($cleared) {
|
|
|
- $pestControlCount++;
|
|
|
- Log::info('自动杀虫成功', [
|
|
|
- 'user_id' => $userId,
|
|
|
- 'pet_id' => $pet->id,
|
|
|
- 'land_id' => $land->id
|
|
|
- ]);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- } catch (\Exception $e) {
|
|
|
- Log::warning('自动杀虫处理失败', [
|
|
|
+ // 如果遇到道具不足,记录并可能提前结束
|
|
|
+ if ($landResult['stopped_reason'] === 'insufficient_items') {
|
|
|
+ Log::warning('自动杀虫因道具不足停止', [
|
|
|
'user_id' => $userId,
|
|
|
'pet_id' => $pet->id,
|
|
|
'land_id' => $land->id,
|
|
|
- 'error' => $e->getMessage()
|
|
|
+ 'cleared_count' => $landResult['cleared_count']
|
|
|
]);
|
|
|
}
|
|
|
}
|
|
|
@@ -536,7 +512,8 @@ class PetAutoSkillLogic
|
|
|
// 记录统计信息
|
|
|
$this->recordSkillStatistics($activeSkill, 'auto_pest_control', [
|
|
|
'pest_control_count' => $pestControlCount,
|
|
|
- 'total_lands_checked' => $landsWithCrops->count()
|
|
|
+ 'total_lands_checked' => $landsWithCrops->count(),
|
|
|
+ 'processing_time_ms' => (microtime(true) - $startTime) * 1000
|
|
|
]);
|
|
|
|
|
|
Log::info('自动杀虫技能处理完成', [
|
|
|
@@ -544,7 +521,8 @@ class PetAutoSkillLogic
|
|
|
'pet_id' => $pet->id,
|
|
|
'user_id' => $userId,
|
|
|
'pest_control_count' => $pestControlCount,
|
|
|
- 'total_lands' => $landsWithCrops->count()
|
|
|
+ 'total_lands' => $landsWithCrops->count(),
|
|
|
+ 'processing_time_ms' => round((microtime(true) - $startTime) * 1000, 2)
|
|
|
]);
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
@@ -556,6 +534,122 @@ class PetAutoSkillLogic
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 处理单块土地上的特定类型灾害
|
|
|
+ *
|
|
|
+ * @param int $userId 用户ID
|
|
|
+ * @param mixed $pet 宠物对象
|
|
|
+ * @param LandInfoDto $land 土地对象
|
|
|
+ * @param int $disasterType 灾害类型
|
|
|
+ * @param string $disasterName 灾害名称(用于日志)
|
|
|
+ * @return array 处理结果
|
|
|
+ */
|
|
|
+ protected function processLandDisasters(int $userId, $pet, LandInfoDto $land, int $disasterType, string $disasterName): array
|
|
|
+ {
|
|
|
+ $clearedCount = 0;
|
|
|
+ $maxAttempts = 10; // 防止无限循环的最大尝试次数
|
|
|
+ $attempts = 0;
|
|
|
+ $stoppedReason = 'completed'; // completed, insufficient_items, max_attempts, error
|
|
|
+
|
|
|
+ while ($attempts < $maxAttempts) {
|
|
|
+ $attempts++;
|
|
|
+
|
|
|
+ // 检查土地是否还有该类型的灾害
|
|
|
+ if (!$this->checkSpecificDisaster($land, $disasterType)) {
|
|
|
+ // 没有该类型灾害了,正常完成
|
|
|
+ $stoppedReason = 'completed';
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 尝试清除灾害
|
|
|
+ try {
|
|
|
+ $cleared = $this->autoClearSpecificDisaster($userId, $land, $disasterType);
|
|
|
+
|
|
|
+ if ($cleared) {
|
|
|
+ $clearedCount++;
|
|
|
+
|
|
|
+ // 重新获取土地信息以确保数据最新
|
|
|
+ $land = $this->refreshLandInfo($land);
|
|
|
+ } else {
|
|
|
+ // 清除失败,通常是道具不足
|
|
|
+ $stoppedReason = 'insufficient_items';
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::error("自动{$disasterName}处理异常", [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'pet_id' => $pet->id,
|
|
|
+ 'land_id' => $land->id,
|
|
|
+ 'disaster_type' => $disasterType,
|
|
|
+ 'attempts' => $attempts,
|
|
|
+ 'cleared_count' => $clearedCount,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+ $stoppedReason = 'error';
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果达到最大尝试次数
|
|
|
+ if ($attempts >= $maxAttempts) {
|
|
|
+ $stoppedReason = 'max_attempts';
|
|
|
+ Log::warning("自动{$disasterName}达到最大尝试次数", [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'pet_id' => $pet->id,
|
|
|
+ 'land_id' => $land->id,
|
|
|
+ 'max_attempts' => $maxAttempts,
|
|
|
+ 'cleared_count' => $clearedCount
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 记录土地处理结果
|
|
|
+ if ($clearedCount > 0) {
|
|
|
+ Log::info("土地{$disasterName}处理完成", [
|
|
|
+ 'user_id' => $userId,
|
|
|
+ 'pet_id' => $pet->id,
|
|
|
+ 'land_id' => $land->id,
|
|
|
+ 'cleared_count' => $clearedCount,
|
|
|
+ 'attempts' => $attempts,
|
|
|
+ 'stopped_reason' => $stoppedReason
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'cleared_count' => $clearedCount,
|
|
|
+ 'attempts' => $attempts,
|
|
|
+ 'stopped_reason' => $stoppedReason
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 刷新土地信息
|
|
|
+ *
|
|
|
+ * @param LandInfoDto $land 土地对象
|
|
|
+ * @return LandInfoDto 刷新后的土地对象
|
|
|
+ */
|
|
|
+ protected function refreshLandInfo(LandInfoDto $land): LandInfoDto
|
|
|
+ {
|
|
|
+ try {
|
|
|
+ // 重新从服务层获取土地信息
|
|
|
+ $refreshedLands = LandService::getLandsWithCrops($land->userId);
|
|
|
+
|
|
|
+ foreach ($refreshedLands as $refreshedLand) {
|
|
|
+ if ($refreshedLand->id === $land->id) {
|
|
|
+ return $refreshedLand;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果没找到,返回原对象
|
|
|
+ return $land;
|
|
|
+ } catch (\Exception $e) {
|
|
|
+ Log::warning('刷新土地信息失败', [
|
|
|
+ 'land_id' => $land->id,
|
|
|
+ 'error' => $e->getMessage()
|
|
|
+ ]);
|
|
|
+ return $land;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 检查特定类型的灾害
|
|
|
*
|