import { loadBackendBaseUrl } from './backendAuth' import { postClientLog, type BackendClientLogInput } from './backendApi' type ClientLogLevel = BackendClientLogInput['level'] type ClientLogEntry = { level: ClientLogLevel category: string message: string eventId?: string releaseId?: string sessionId?: string manifestUrl?: string route?: string details?: Record } const CLIENT_LOG_SOURCE = 'wechat-mini' const MAX_PENDING_CLIENT_LOGS = 100 const pendingClientLogs: BackendClientLogInput[] = [] let clientLogFlushInProgress = false let clientLogSequence = 0 function getCurrentRoute(): string { const pages = getCurrentPages() if (!pages.length) { return '' } const current = pages[pages.length - 1] return current && current.route ? current.route : '' } function enqueueClientLog(payload: BackendClientLogInput) { pendingClientLogs.push(payload) if (pendingClientLogs.length > MAX_PENDING_CLIENT_LOGS) { pendingClientLogs.shift() } } function flushNextClientLog() { if (clientLogFlushInProgress || !pendingClientLogs.length) { return } const baseUrl = loadBackendBaseUrl() if (!baseUrl) { pendingClientLogs.length = 0 return } const payload = pendingClientLogs.shift() if (!payload) { return } clientLogFlushInProgress = true postClientLog({ baseUrl, payload, }).catch(() => { // 联调日志不打断主流程,失败时静默丢弃。 }).finally(() => { clientLogFlushInProgress = false if (pendingClientLogs.length) { flushNextClientLog() } }) } export function reportBackendClientLog(entry: ClientLogEntry) { clientLogSequence += 1 const details = entry.details ? { ...entry.details } : {} details.seq = clientLogSequence const payload: BackendClientLogInput = { source: CLIENT_LOG_SOURCE, level: entry.level, category: entry.category, message: entry.message, eventId: entry.eventId || '', releaseId: entry.releaseId || '', sessionId: entry.sessionId || '', manifestUrl: entry.manifestUrl || '', route: entry.route || getCurrentRoute(), occurredAt: new Date().toISOString(), details, } enqueueClientLog(payload) flushNextClientLog() }