function normalizeClientIp(rawIp) { const ip = String(rawIp || '').trim(); if (!ip) return ''; if (ip.startsWith('::ffff:')) return ip.slice(7); return ip === '::1' ? '127.0.0.1' : ip; } function detectDeviceTypeFromUserAgent(userAgent = '') { const mobilePattern = /(Mobile|Android|iPhone|iPad|iPod|Windows Phone|HarmonyOS|Mobi)/i; return mobilePattern.test(String(userAgent || '')) ? 'mobile' : 'desktop'; } function inferPlatformFromUserAgent(userAgent = '') { const value = String(userAgent || ''); if (!value) return '未知平台'; if (/windows/i.test(value)) return 'Windows'; if (/macintosh|mac os x/i.test(value)) return 'macOS'; if (/android/i.test(value)) return 'Android'; if (/iphone|ipad|ios/i.test(value)) return 'iOS'; if (/linux/i.test(value)) return 'Linux'; return '未知平台'; } function normalizeClientType(value = '') { const normalized = String(value || '').trim().toLowerCase(); return ['web', 'desktop', 'mobile', 'api'].includes(normalized) ? normalized : ''; } function resolveClientType(clientType, userAgent = '') { const normalized = normalizeClientType(clientType); if (normalized) return normalized; const userAgentValue = String(userAgent || '').toLowerCase(); if ( userAgentValue.includes('tauri') || userAgentValue.includes('electron') || userAgentValue.includes('wanwan-cloud-desktop') || userAgentValue.includes('玩玩云') ) { return 'desktop'; } return detectDeviceTypeFromUserAgent(userAgentValue) === 'mobile' ? 'mobile' : 'web'; } function sanitizeDeviceText(value, maxLength = 120) { return typeof value === 'string' ? value.trim().slice(0, maxLength) : ''; } function buildDeviceName({ clientType, deviceName, platform }) { const preferred = sanitizeDeviceText(deviceName, 120); if (preferred) return preferred; const platformText = sanitizeDeviceText(platform, 80) || '未知平台'; if (clientType === 'desktop') return `桌面客户端 · ${platformText}`; if (clientType === 'mobile') return `移动端浏览器 · ${platformText}`; if (clientType === 'api') return `API 客户端 · ${platformText}`; return `网页端浏览器 · ${platformText}`; } module.exports = { buildDeviceName, detectDeviceTypeFromUserAgent, inferPlatformFromUserAgent, normalizeClientIp, normalizeClientType, resolveClientType, sanitizeDeviceText };