Files
vf_react/src/components/MiniProgramLauncher/hooks/useWechatEnvironment.js
2025-12-14 14:16:37 +08:00

143 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 微信环境检测 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;
// 方式1User 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;
// 方式4Safari 特定检测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;