', $lastProcessedId) ->orderBy('id') ->limit($this->maxRecords) ->get(); } /** * 按时间获取新的记录 * * @param int $lastProcessedTimestamp 上次处理的最大时间戳 * @return \Illuminate\Database\Eloquent\Collection */ protected function getNewRecordsByTime(int $lastProcessedTimestamp) { return FundLogModel::where('create_time', '>', $lastProcessedTimestamp) ->orderBy('create_time') ->orderBy('id') // 相同时间戳时按ID排序 ->limit($this->maxRecords) ->get(); } /** * 获取记录的时间戳 * * @param FundLogModel $record 资金日志记录 * @return int 时间戳 */ protected function getRecordTimestamp($record): int { return $record->create_time; } /** * 根据记录ID获取原始记录的时间戳 * * @param int $recordId 记录ID * @return int 时间戳 */ protected function getOriginalRecordTimestamp(int $recordId): int { try { $record = FundLogModel::find($recordId); return $record ? $record->create_time : 0; } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error("获取资金日志原始时间戳失败", [ 'record_id' => $recordId, 'error' => $e->getMessage() ]); return 0; } } /** * 转换记录为用户日志数据 * * @param FundLogModel $record 资金日志记录 * @return array|null 用户日志数据,null表示跳过 */ protected function convertToUserLog($record): ?array { try { // 获取资金名称 $fundName = $this->getFundName($record->fund_id); // 判断是获得还是消耗 $amount = abs($record->amount); $action = $record->amount > 0 ? '获得' : '消耗'; // 解析备注信息,生成用户友好的消息 $message = $this->buildUserFriendlyMessage($record, $fundName, $action, $amount); // 使用原始记录的时间 $createdAt = date('Y-m-d H:i:s', $record->create_time); return $this->createUserLogData( $record->user_id, $message, $record->id, $createdAt ); } catch (\Exception $e) { \Illuminate\Support\Facades\Log::error("转换资金日志失败", [ 'record_id' => $record->id, 'error' => $e->getMessage() ]); return null; } } /** * 构建用户友好的消息 * * @param FundLogModel $record 资金日志记录 * @param string $fundName 资金名称 * @param string $action 操作类型(获得/消耗) * @param int $amount 金额 * @return string */ private function buildUserFriendlyMessage(FundLogModel $record, string $fundName, string $action, int $amount): string { // 解析备注信息 $remarkInfo = $this->parseRemark($record->remark); // 根据来源类型生成不同的消息格式 if (isset($remarkInfo['source']) && isset($remarkInfo['id'])) { $sourceMessage = $this->getSourceMessage($remarkInfo['source'], $remarkInfo['id'], $action); if ($sourceMessage) { return "{$sourceMessage}{$action}{$fundName} {$amount}"; } } // 如果无法解析来源信息,使用默认格式 return "{$action}{$fundName} {$amount}"; } /** * 获取资金名称 * * @param mixed $fundId 资金ID * @return string */ private function getFundName($fundId): string { try { // 获取资金类型描述 $fundNames = AccountService::getFundsDesc(); // 如果是枚举对象,获取其值 $fundKey = is_object($fundId) ? $fundId->value : $fundId; return $fundNames[$fundKey] ?? "资金{$fundKey}"; } catch (\Exception $e) { return "未知资金"; } } /** * 解析备注信息 * * @param string $remark 备注内容 * @return array 解析后的信息数组 */ private function parseRemark(string $remark): array { $info = []; // 解析格式:币种消耗:2,消耗组:16,来源:shop_buy,ID:7 // 使用更宽松的正则表达式来匹配中文和英文字符 if (preg_match_all('/([^:,]+):([^,]+)/', $remark, $matches)) { for ($i = 0; $i < count($matches[1]); $i++) { $key = trim($matches[1][$i]); $value = trim($matches[2][$i]); // 转换中文键名为英文 switch ($key) { case '来源': $info['source'] = $value; break; case 'ID': $info['id'] = (int)$value; break; case '消耗组': $info['consume_group'] = (int)$value; break; case '币种消耗': $info['fund_type'] = (int)$value; break; default: $info[$key] = $value; } } } return $info; } /** * 根据来源信息获取操作描述 * * @param string $source 来源类型 * @param int $id 来源ID * @param string $action 操作类型 * @return string|null 操作描述,null表示使用默认格式 */ private function getSourceMessage(string $source, int $id, string $action): ?string { switch ($source) { case 'shop_buy': $itemName = $this->getShopItemName($id); return "购买{$itemName}"; case '开启宝箱': case 'chest_open': return "开启宝箱"; case 'house_upgrade': return "房屋升级"; case 'land_upgrade': return "土地升级"; case 'task_reward': return "任务奖励"; case 'system_gift': return "系统赠送"; case 'admin_operation': return "管理员操作"; case 'test_command': return "测试操作"; default: return null; } } /** * 获取商店商品名称 * * @param int $itemId 商品ID * @return string */ private function getShopItemName(int $itemId): string { try { $shopItem = \App\Module\Shop\Models\ShopItem::find($itemId); if ($shopItem && $shopItem->name) { return $shopItem->name; } return "商品{$itemId}"; } catch (\Exception $e) { return "商品{$itemId}"; } } /** * 是否应该记录此日志 * * @param FundLogModel $record * @return bool */ private function shouldLogRecord(FundLogModel $record): bool { // 可以在这里添加过滤规则 // 例如:只记录金额大于某个值的变更 // 跳过金额为0的记录 if ($record->amount == 0) { return false; } // 可以添加更多过滤条件 // 例如:跳过某些操作类型 // if (in_array($record->operate_type, [...])) { // return false; // } return true; } /** * 重写转换方法,添加过滤逻辑 * * @param FundLogModel $record 资金日志记录 * @return array|null 用户日志数据,null表示跳过 */ protected function convertToUserLogWithFilter($record): ?array { // 检查是否应该记录此日志 if (!$this->shouldLogRecord($record)) { return null; } return $this->convertToUserLog($record); } }