| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 |
- <?php
- namespace App\Module\Game\Logics\UserLogCollectors;
- use App\Module\Farm\Models\FarmHarvestLog;
- use App\Module\Farm\Models\FarmUpgradeLog;
- /**
- * 农场日志收集器
- *
- * 收集农场相关日志表的新增记录,转换为用户友好的日志消息
- */
- class FarmLogCollector extends BaseLogCollector
- {
- /**
- * 源表名
- *
- * @var string
- */
- protected string $sourceTable = 'farm_harvest_logs';
- /**
- * 源类型
- *
- * @var string
- */
- protected string $sourceType = 'farm';
- /**
- * 获取新的记录
- *
- * @param int $lastProcessedId 上次处理的最大ID
- * @return \Illuminate\Database\Eloquent\Collection
- */
- protected function getNewRecords(int $lastProcessedId)
- {
- // 收集收获日志
- $harvestLogs = FarmHarvestLog::where('id', '>', $lastProcessedId)
- ->orderBy('id')
- ->limit($this->maxRecords / 2) // 分配一半给收获日志
- ->get()
- ->map(function ($log) {
- $log->log_type = 'harvest';
- return $log;
- });
- // 收集升级日志
- $upgradeLogs = FarmUpgradeLog::where('id', '>', $lastProcessedId)
- ->orderBy('id')
- ->limit($this->maxRecords / 2) // 分配一半给升级日志
- ->get()
- ->map(function ($log) {
- $log->log_type = 'upgrade';
- return $log;
- });
- // 合并并按ID排序
- return $harvestLogs->concat($upgradeLogs)->sortBy('id');
- }
- /**
- * 按时间获取新的记录
- *
- * @param int $lastProcessedTimestamp 上次处理的最大时间戳
- * @return \Illuminate\Database\Eloquent\Collection
- */
- protected function getNewRecordsByTime(int $lastProcessedTimestamp)
- {
- $lastTime = date('Y-m-d H:i:s', $lastProcessedTimestamp);
- // 收集收获日志
- $harvestLogs = FarmHarvestLog::where('created_at', '>', $lastTime)
- ->orderBy('created_at')
- ->orderBy('id')
- ->limit($this->maxRecords / 2) // 分配一半给收获日志
- ->get()
- ->map(function ($log) {
- $log->log_type = 'harvest';
- return $log;
- });
- // 收集升级日志
- $upgradeLogs = FarmUpgradeLog::where('created_at', '>', $lastTime)
- ->orderBy('created_at')
- ->orderBy('id')
- ->limit($this->maxRecords / 2) // 分配一半给升级日志
- ->get()
- ->map(function ($log) {
- $log->log_type = 'upgrade';
- return $log;
- });
- // 合并并按时间排序
- return $harvestLogs->concat($upgradeLogs)->sortBy(['created_at', 'id']);
- }
- /**
- * 获取记录的时间戳
- *
- * @param mixed $record 农场日志记录
- * @return int 时间戳
- */
- protected function getRecordTimestamp($record): int
- {
- return strtotime($record->created_at);
- }
- /**
- * 根据记录ID获取原始记录的时间戳
- * 由于农场收集器处理多个表,需要特殊处理
- *
- * @param int $recordId 记录ID
- * @return int 时间戳
- */
- protected function getOriginalRecordTimestamp(int $recordId): int
- {
- try {
- // 先尝试从收获日志表查找
- $harvestRecord = FarmHarvestLog::find($recordId);
- if ($harvestRecord) {
- return strtotime($harvestRecord->created_at);
- }
- // 再尝试从升级日志表查找
- $upgradeRecord = FarmUpgradeLog::find($recordId);
- if ($upgradeRecord) {
- return strtotime($upgradeRecord->created_at);
- }
- return 0;
- } catch (\Exception $e) {
- \Illuminate\Support\Facades\Log::error("获取农场日志原始时间戳失败", [
- 'record_id' => $recordId,
- 'error' => $e->getMessage()
- ]);
- return 0;
- }
- }
- /**
- * 转换记录为用户日志数据
- *
- * @param mixed $record 农场日志记录
- * @return array|null 用户日志数据,null表示跳过
- */
- protected function convertToUserLog($record): ?array
- {
- try {
- if ($record->log_type === 'harvest') {
- return $this->convertHarvestLog($record);
- } elseif ($record->log_type === 'upgrade') {
- return $this->convertUpgradeLog($record);
- }
- return null;
- } catch (\Exception $e) {
- \Illuminate\Support\Facades\Log::error("转换农场日志失败", [
- 'record_id' => $record->id,
- 'log_type' => $record->log_type ?? 'unknown',
- 'error' => $e->getMessage()
- ]);
- return null;
- }
- }
- /**
- * 转换收获日志
- *
- * @param FarmHarvestLog $record
- * @return array|null
- */
- private function convertHarvestLog(FarmHarvestLog $record): ?array
- {
- // 获取作物名称
- $cropName = $this->getCropName($record->seed_id);
-
- // 构建收获消息
- $message = "收获{$record->land_id}号土地的{$cropName}";
-
- // 添加收获数量信息
- if ($record->harvest_quantity > 0) {
- $message .= ",获得{$record->harvest_quantity}个";
- }
-
- // 添加经验信息
- if ($record->exp_gained > 0) {
- $message .= ",获得经验{$record->exp_gained}";
- }
- return $this->createUserLogData(
- $record->user_id,
- $message,
- $record->id,
- $record->created_at
- );
- }
- /**
- * 转换升级日志
- *
- * @param FarmUpgradeLog $record
- * @return array|null
- */
- private function convertUpgradeLog(FarmUpgradeLog $record): ?array
- {
- $message = $this->buildUpgradeMessage($record);
- return $this->createUserLogData(
- $record->user_id,
- $message,
- $record->id,
- $record->created_at
- );
- }
- /**
- * 构建升级消息
- *
- * @param FarmUpgradeLog $record
- * @return string
- */
- private function buildUpgradeMessage(FarmUpgradeLog $record): string
- {
- // 使用UPGRADE_TYPE枚举判断升级类型
- switch ($record->upgrade_type) {
- case \App\Module\Farm\Enums\UPGRADE_TYPE::HOUSE->value:
- return "房屋升级到{$record->new_level}级";
- case \App\Module\Farm\Enums\UPGRADE_TYPE::LAND->value:
- $oldLandType = $this->getLandTypeName($record->old_level);
- $newLandType = $this->getLandTypeName($record->new_level);
- return "土地{$record->target_id}从{$oldLandType}升级为{$newLandType}";
- default:
- return "升级类型{$record->upgrade_type}从{$record->old_level}级升级到{$record->new_level}级";
- }
- }
- /**
- * 获取作物名称
- *
- * @param int $seedId 种子ID
- * @return string
- */
- private function getCropName(int $seedId): string
- {
- try {
- // 尝试从配置中获取种子信息
- $seedConfig = \App\Module\Farm\Models\FarmSeed::find($seedId);
- if ($seedConfig) {
- return $seedConfig->name;
- }
-
- return "作物{$seedId}";
-
- } catch (\Exception $e) {
- return "作物{$seedId}";
- }
- }
- /**
- * 静态缓存:土地类型名称映射
- *
- * @var array|null
- */
- private static ?array $landTypeNames = null;
- /**
- * 获取土地类型名称
- *
- * @param int $typeId 土地类型ID
- * @return string
- */
- private function getLandTypeName(int $typeId): string
- {
- // 初始化静态缓存
- if (self::$landTypeNames === null) {
- $this->initLandTypeNamesCache();
- }
- return self::$landTypeNames[$typeId] ?? "未知土地类型{$typeId}";
- }
- /**
- * 初始化土地类型名称缓存
- *
- * @return void
- */
- private function initLandTypeNamesCache(): void
- {
- try {
- // 从数据库读取所有土地类型
- $landTypes = \App\Module\Farm\Models\FarmLandType::select('id', 'name')
- ->get()
- ->pluck('name', 'id')
- ->toArray();
- self::$landTypeNames = $landTypes;
- \Illuminate\Support\Facades\Log::info("土地类型缓存初始化完成", [
- 'count' => count($landTypes),
- 'types' => $landTypes
- ]);
- } catch (\Exception $e) {
- // 如果数据库查询失败,使用默认值
- self::$landTypeNames = [
- 1 => '普通土地',
- 2 => '红土地',
- 3 => '黑土地',
- 4 => '金色特殊土地',
- 5 => '蓝色特殊土地',
- 6 => '紫色特殊土地',
- ];
- \Illuminate\Support\Facades\Log::warning("土地类型缓存初始化失败,使用默认值", [
- 'error' => $e->getMessage(),
- 'default_types' => self::$landTypeNames
- ]);
- }
- }
- /**
- * 清除土地类型名称缓存(用于测试或数据更新后)
- *
- * @return void
- */
- public static function clearLandTypeNamesCache(): void
- {
- self::$landTypeNames = null;
- }
- /**
- * 格式化消耗物品信息
- *
- * @param mixed $costItems 消耗物品数据
- * @return string
- */
- private function formatCostItems($costItems): string
- {
- try {
- if (is_string($costItems)) {
- $costItems = json_decode($costItems, true);
- }
- if (!is_array($costItems)) {
- return '';
- }
- $costDesc = [];
- foreach ($costItems as $item) {
- if (isset($item['name']) && isset($item['quantity'])) {
- $costDesc[] = "{$item['name']} {$item['quantity']}";
- }
- }
- return implode('、', $costDesc);
- } catch (\Exception $e) {
- return '';
- }
- }
- /**
- * 是否应该记录此日志
- *
- * @param mixed $record
- * @return bool
- */
- private function shouldLogRecord($record): bool
- {
- // 对于收获日志,跳过收获数量为0的记录
- if ($record->log_type === 'harvest' && $record->harvest_quantity <= 0) {
- return false;
- }
- return true;
- }
- /**
- * 重写获取最后处理ID的方法,因为要处理多个表
- * 从user_logs表中查询农场相关的最后处理记录
- *
- * @return int
- */
- protected function getLastProcessedId(): int
- {
- try {
- // 查询农场相关的最后处理记录
- $lastLog = \App\Module\Game\Models\UserLog::where('source_type', $this->sourceType)
- ->whereIn('source_table', ['farm_harvest_logs', 'farm_upgrade_logs'])
- ->orderBy('source_id', 'desc')
- ->first();
- return $lastLog ? $lastLog->source_id : 0;
- } catch (\Exception $e) {
- \Illuminate\Support\Facades\Log::error("获取农场日志最后处理ID失败", [
- 'collector' => $this->collectorName,
- 'error' => $e->getMessage()
- ]);
- return 0;
- }
- }
- /**
- * 重写更新最后处理ID的方法
- * 不再需要手动更新,因为进度通过user_logs表自动追踪
- *
- * @param int $id
- * @return void
- */
- protected function updateLastProcessedId(int $id): void
- {
- // 不再需要手动更新,进度通过user_logs表自动追踪
- // 这个方法保留是为了兼容性
- }
- }
|