处理下载页的平台判断
All checks were successful
site-dist-deploy / build-and-deploy (push) Successful in 1m32s
All checks were successful
site-dist-deploy / build-and-deploy (push) Successful in 1m32s
This commit is contained in:
parent
ee8ce4c559
commit
4297d5fd29
@ -20,6 +20,11 @@
|
||||
>
|
||||
<component :is="mainButton?.mainIcon" class="h-auto w-full text-black transition-transform" />
|
||||
</div>
|
||||
|
||||
<!-- 主按钮 Loading 状态 -->
|
||||
<div v-if="loadingKey === mainButton?.key" class="absolute inset-0 flex items-center justify-center bg-[#ADFF5B]">
|
||||
<div class="h-6 w-6 animate-spin rounded-full border-4 border-black/20 border-t-black md:h-8 md:w-8"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 其他版本下载 -->
|
||||
@ -30,23 +35,30 @@
|
||||
|
||||
<div class="flex gap-4 items-center justify-center md:justify-start">
|
||||
<template v-for="(item, index) in otherButtons" :key="index">
|
||||
<a
|
||||
v-if="item.link"
|
||||
:href="item.link"
|
||||
target="_blank"
|
||||
:aria-label="item.label"
|
||||
class="transition-transform hover:brightness-110 active:scale-95"
|
||||
>
|
||||
<component :is="item.secondaryIcon" class="h-[24px] md:h-[34px] text-white" />
|
||||
</a>
|
||||
<div
|
||||
v-else
|
||||
:id="item.id"
|
||||
:aria-label="item.label"
|
||||
@click="handleDownload(item.key)"
|
||||
class="cursor-pointer transition-transform hover:brightness-110 active:scale-95"
|
||||
>
|
||||
<component :is="item.secondaryIcon" class="h-[24px] md:h-[34px] text-white" />
|
||||
<div class="relative">
|
||||
<a
|
||||
v-if="item.link"
|
||||
:href="item.link"
|
||||
target="_blank"
|
||||
:aria-label="item.label"
|
||||
class="transition-transform hover:brightness-110 active:scale-95"
|
||||
>
|
||||
<component :is="item.secondaryIcon" class="h-[24px] md:h-[34px] text-white" />
|
||||
</a>
|
||||
<div
|
||||
v-else
|
||||
:id="item.id"
|
||||
:aria-label="item.label"
|
||||
@click="handleDownload(item.key)"
|
||||
class="cursor-pointer transition-transform hover:brightness-110 active:scale-95"
|
||||
>
|
||||
<component :is="item.secondaryIcon" class="h-[24px] md:h-[34px] text-white" />
|
||||
</div>
|
||||
|
||||
<!-- 次要按钮 Loading 状态 -->
|
||||
<div v-if="loadingKey === item.key" class="absolute inset-0 flex items-center justify-center bg-black/40 rounded-lg">
|
||||
<div class="h-4 w-4 animate-spin rounded-full border-2 border-white/20 border-t-white md:h-5 md:w-5"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@ -68,76 +80,118 @@ import request from '@/utils/request'
|
||||
import {computed, ref, onMounted} from "vue";
|
||||
import {getAllQueryString} from "@/utils/url-utils.ts";
|
||||
|
||||
const downLoadWin = ref('')
|
||||
const currentPlatform = ref('win')
|
||||
const loadingKey = ref('')
|
||||
|
||||
// 固定下载链接常量
|
||||
const FIXED_LINKS: Record<string, string> = {
|
||||
android: 'https://api.hifast.biz/v1/common/client/download/file/Hi%E5%BF%ABVPN-android-1.0.0.apk',
|
||||
ios: 'https://apps.apple.com/us/app/hi%E5%BF%ABvpn/id6755683167?l=zh-Hans-CN',
|
||||
mac: 'https://apps.apple.com/us/app/hi%E5%BF%ABvpn/id6755683167?l=zh-Hans-CN',
|
||||
}
|
||||
|
||||
const isAndroid = computed(() => currentPlatform.value === 'android')
|
||||
const isIOS = computed(() => currentPlatform.value === 'ios')
|
||||
|
||||
onMounted(() => {
|
||||
const ua = navigator.userAgent;
|
||||
const platform = navigator.platform || ''; // 辅助判断
|
||||
|
||||
// 1. 先判断 Android (通常比较稳定)
|
||||
if (/Android/i.test(ua)) {
|
||||
currentPlatform.value = 'android';
|
||||
}
|
||||
// 2. 判断 iOS 设备 (iPhone, iPod)
|
||||
else if (/iPhone|iPod/i.test(ua)) {
|
||||
} else if (/iPhone|iPod/i.test(ua)) {
|
||||
currentPlatform.value = 'ios';
|
||||
}
|
||||
// 3. 核心改进:区分 Mac 和 iPad
|
||||
else if (/Macintosh|Mac OS X/i.test(ua)) {
|
||||
// iPadOS 桌面模式下,支持多点触控(通常 > 1)
|
||||
// 而真正的 Mac 电脑通常 maxTouchPoints 为 0 或 undefined
|
||||
} else if (/Macintosh|Mac OS X/i.test(ua)) {
|
||||
if (navigator.maxTouchPoints > 1) {
|
||||
currentPlatform.value = 'ios'; // 归类为 iOS 端(iPad)
|
||||
currentPlatform.value = 'ios'; // iPad
|
||||
} else {
|
||||
currentPlatform.value = 'mac';
|
||||
}
|
||||
}
|
||||
// 4. 其他情况默认为 Windows
|
||||
else {
|
||||
} else {
|
||||
currentPlatform.value = 'win';
|
||||
}
|
||||
|
||||
console.log('Detected Platform:', currentPlatform.value);
|
||||
});
|
||||
|
||||
// request.get('/api/v1/common/client/download', {
|
||||
// invite_code: getAllQueryString('ic'),
|
||||
// platform: 'windows',
|
||||
// }).then((res: any) => {
|
||||
// downLoadWin.value = res.url
|
||||
// })
|
||||
|
||||
/**
|
||||
* 核心下载处理函数
|
||||
* @param key 平台标识 (win, mac, ios, android)
|
||||
*/
|
||||
const handleDownload = async (key: string) => {
|
||||
const platformMap: Record<string, string> = {
|
||||
win: 'windows',
|
||||
mac: 'mac',
|
||||
android: 'android',
|
||||
ios: 'ios',
|
||||
}
|
||||
const platform = platformMap[key] || 'windows'
|
||||
const ic = getAllQueryString('ic') || 'uSSfgY6oAP'
|
||||
const isMain = key === currentPlatform.value;
|
||||
|
||||
try {
|
||||
const res: any = await request.get('/api/v1/common/client/download', {
|
||||
invite_code: getAllQueryString('ic') || 'uSSfgY6oAP',
|
||||
platform: platform,
|
||||
})
|
||||
if (res.url) {
|
||||
if (key === 'win') {
|
||||
downLoadWin.value = res.url
|
||||
// 1. Windows 逻辑:点击时动态请求 API
|
||||
if (key === 'win') {
|
||||
try {
|
||||
const res: any = await request.get('/api/v1/common/client/download', {
|
||||
invite_code: ic,
|
||||
platform: 'windows',
|
||||
})
|
||||
if (res.url) {
|
||||
window.open(res.url, '_blank')
|
||||
}
|
||||
window.open(res.url, '_blank')
|
||||
} catch (error) {
|
||||
console.error('Windows download failed', error)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Download fetch failed', error)
|
||||
return
|
||||
}
|
||||
|
||||
// 2. 移动端主按钮逻辑:调用 OpenInstall 统计
|
||||
if (isMain) {
|
||||
if ((isAndroid.value && key === 'android') || (isIOS.value && (key === 'ios' || key === 'mac'))) {
|
||||
triggerOpenInstall(ic, key)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 其他所有情况(次要按钮或非匹配平台):直接跳转固定链接
|
||||
const url = FIXED_LINKS[key]
|
||||
if (url) {
|
||||
window.open(url, '_blank')
|
||||
}
|
||||
}
|
||||
|
||||
// 触发 OpenInstall 的统一方法
|
||||
const triggerOpenInstall = (ic: string, key: string) => {
|
||||
loadingKey.value = key
|
||||
setTimeout(() => { loadingKey.value = '' }, 3000)
|
||||
|
||||
if (window.OI_SDK?.OI?.wakeupOrInstall) {
|
||||
window.OI_SDK.OI.wakeupOrInstall({
|
||||
data: { platform: 'download', inviteCode: ic }
|
||||
})
|
||||
} else {
|
||||
console.warn('OpenInstall SDK not ready')
|
||||
}
|
||||
}
|
||||
|
||||
const allDownloadOptions = computed(() => [
|
||||
{ key: 'win', mainIcon: Icon1, secondaryIcon: WinIcon, link: downLoadWin.value, label: 'Windows', id: 'downloadButton_win' },
|
||||
{ key: 'mac', mainIcon: Icon3, secondaryIcon: MacIcon, label: 'macOS', id: 'downloadButton_mac' },
|
||||
{ key: 'ios', mainIcon: Icon2, secondaryIcon: AppleIcon, label: 'iOS', id: 'downloadButton_apple' },
|
||||
{ key: 'android', mainIcon: Icon4, secondaryIcon: AndroidIcon, label: 'Android', id: 'downloadButton_android' },
|
||||
{
|
||||
key: 'win',
|
||||
mainIcon: Icon1,
|
||||
secondaryIcon: WinIcon,
|
||||
label: 'Windows',
|
||||
link: '' // Windows 始终点击动态获取
|
||||
},
|
||||
{
|
||||
key: 'mac',
|
||||
mainIcon: Icon3,
|
||||
secondaryIcon: MacIcon,
|
||||
label: 'macOS',
|
||||
link: currentPlatform.value === 'mac' ? '' : FIXED_LINKS.mac
|
||||
},
|
||||
{
|
||||
key: 'ios',
|
||||
mainIcon: Icon2,
|
||||
secondaryIcon: AppleIcon,
|
||||
label: 'iOS',
|
||||
link: currentPlatform.value === 'ios' ? '' : FIXED_LINKS.ios
|
||||
},
|
||||
{
|
||||
key: 'android',
|
||||
mainIcon: Icon4,
|
||||
secondaryIcon: AndroidIcon,
|
||||
label: 'Android',
|
||||
link: currentPlatform.value === 'android' ? '' : FIXED_LINKS.android
|
||||
},
|
||||
])
|
||||
|
||||
const mainButton = computed(() => {
|
||||
|
||||
@ -38,42 +38,42 @@ class OpenInstallSdk {
|
||||
this.OI = new window.OpenInstall({
|
||||
appKey: 'alf57p',
|
||||
onready: function () { // 初始化成功回调方法。当初始化完成后,会自动进入
|
||||
this.schemeWakeup()// 尝试使用scheme打开App(主要用于Android以及iOS的QQ环境中)
|
||||
const m = this
|
||||
const button = document.getElementById('downloadButton_apple')
|
||||
const button_mac = document.getElementById('downloadButton_mac')
|
||||
const button1 = document.getElementById('downloadButton_android')
|
||||
const ic = getAllQueryString('ic') || 'uSSfgY6oAP'
|
||||
if (button) {
|
||||
button.onclick = function () {
|
||||
if (ic) {
|
||||
m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } })
|
||||
} else {
|
||||
m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用(必须调用且不可额外自行跳转下载)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
if(button_mac) {
|
||||
button_mac.onclick = function () {
|
||||
if (ic) {
|
||||
m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } })
|
||||
} else {
|
||||
m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用(必须调用且不可额外自行跳转下载)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
if (button1) {
|
||||
button1.onclick = function () {
|
||||
if (ic) {
|
||||
m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } })
|
||||
} else {
|
||||
m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用(必须调用且不可额外自行跳转下载)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
// this.schemeWakeup()// 尝试使用scheme打开App(主要用于Android以及iOS的QQ环境中)
|
||||
// const m = this
|
||||
// const button = document.getElementById('downloadButton_apple')
|
||||
// const button_mac = document.getElementById('downloadButton_mac')
|
||||
// const button1 = document.getElementById('downloadButton_android')
|
||||
// const ic = getAllQueryString('ic') || 'uSSfgY6oAP'
|
||||
// if (button) {
|
||||
// button.onclick = function () {
|
||||
// if (ic) {
|
||||
// m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } })
|
||||
// } else {
|
||||
// m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用(必须调用且不可额外自行跳转下载)
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
// if(button_mac) {
|
||||
// button_mac.onclick = function () {
|
||||
// if (ic) {
|
||||
// m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } })
|
||||
// } else {
|
||||
// m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用(必须调用且不可额外自行跳转下载)
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
// if (button1) {
|
||||
// button1.onclick = function () {
|
||||
// if (ic) {
|
||||
// m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } })
|
||||
// } else {
|
||||
// m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用(必须调用且不可额外自行跳转下载)
|
||||
// }
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
},
|
||||
}, this.urlQuery)// 初始化时传入data,作为一键拉起/App传参安装时候的参数
|
||||
} catch (e) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user