/** * 微信环境检测 Hook * 用于判断当前运行环境,选择合适的小程序跳转方式 */ import { useMemo } from 'react'; /** * 跳转方式枚举 */ export const LAUNCH_METHOD = { OPEN_TAG: 'openTag', // 微信内使用开放标签 URL_SCHEME: 'urlScheme', // 外部浏览器使用 URL Scheme QR_CODE: 'qrCode', // PC 端显示小程序码 }; /** * 检测是否在微信浏览器内 */ export const isWeChatBrowser = () => { if (typeof window === 'undefined') return false; const ua = navigator.userAgent.toLowerCase(); return ua.includes('micromessenger'); }; /** * 检测是否为移动端设备 * 使用多种检测方式,确保 Safari 兼容性 */ export const isMobileDevice = () => { if (typeof window === 'undefined') return false; const ua = navigator.userAgent; // 方式1:User Agent 检测 const uaCheck = /iPhone|iPad|iPod|Android|webOS|BlackBerry|IEMobile|Opera Mini/i.test(ua); // 方式2:触摸屏检测(Safari 兼容) const touchCheck = 'ontouchstart' in window || navigator.maxTouchPoints > 0; // 方式3:屏幕宽度检测(作为备用) const screenCheck = window.innerWidth <= 768; // 方式4:Safari 特定检测(iOS Safari 不会在 UA 中包含 "Mobile" 但会有 "Safari") const isSafariMobile = /Safari/i.test(ua) && /Apple/i.test(navigator.vendor) && touchCheck; const result = uaCheck || (touchCheck && screenCheck) || isSafariMobile; // 调试日志(仅在开发环境) if (process.env.NODE_ENV === 'development') { console.log('[isMobileDevice] UA:', ua); console.log('[isMobileDevice] uaCheck:', uaCheck, 'touchCheck:', touchCheck, 'screenCheck:', screenCheck, 'isSafariMobile:', isSafariMobile); console.log('[isMobileDevice] result:', result); } return result; }; /** * 检测是否为 iOS 设备 */ export const isIOSDevice = () => { if (typeof window === 'undefined') return false; const ua = navigator.userAgent; return /iPhone|iPad|iPod/i.test(ua); }; /** * 检测是否为 Android 设备 */ export const isAndroidDevice = () => { if (typeof window === 'undefined') return false; const ua = navigator.userAgent; return /Android/i.test(ua); }; /** * 获取微信版本号 * @returns {string|null} 版本号字符串,如 "7.0.12" */ export const getWeChatVersion = () => { if (typeof window === 'undefined') return null; const ua = navigator.userAgent.toLowerCase(); const match = ua.match(/micromessenger\/(\d+\.\d+\.\d+)/i); return match ? match[1] : null; }; /** * 检测微信版本是否支持开放标签 * 开放标签需要微信 7.0.12 及以上版本 */ export const isOpenTagSupported = () => { const version = getWeChatVersion(); if (!version) return false; const [major, minor, patch] = version.split('.').map(Number); // 7.0.12 及以上支持 if (major > 7) return true; if (major === 7) { if (minor > 0) return true; if (minor === 0 && patch >= 12) return true; } return false; }; /** * 微信环境检测 Hook * @returns {Object} 环境信息对象 */ export const useWechatEnvironment = () => { const environment = useMemo(() => { const isWechat = isWeChatBrowser(); const isMobile = isMobileDevice(); const isIOS = isIOSDevice(); const isAndroid = isAndroidDevice(); const wechatVersion = getWeChatVersion(); const openTagSupported = isOpenTagSupported(); // 确定跳转方式 let launchMethod; if (isWechat && openTagSupported) { launchMethod = LAUNCH_METHOD.OPEN_TAG; } else if (isMobile) { launchMethod = LAUNCH_METHOD.URL_SCHEME; } else { launchMethod = LAUNCH_METHOD.QR_CODE; } return { isWechat, // 是否在微信内 isMobile, // 是否移动端 isIOS, // 是否 iOS isAndroid, // 是否 Android wechatVersion, // 微信版本 openTagSupported, // 是否支持开放标签 launchMethod, // 推荐的跳转方式 }; }, []); return environment; }; export default useWechatEnvironment;