处理下载页的平台判断
All checks were successful
site-dist-deploy / build-and-deploy (push) Successful in 1m32s

This commit is contained in:
speakeloudest 2026-04-20 04:24:23 +03:00
parent ee8ce4c559
commit 4297d5fd29
2 changed files with 154 additions and 100 deletions

View File

@ -20,6 +20,11 @@
> >
<component :is="mainButton?.mainIcon" class="h-auto w-full text-black transition-transform" /> <component :is="mainButton?.mainIcon" class="h-auto w-full text-black transition-transform" />
</div> </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> </div>
<!-- 其他版本下载 --> <!-- 其他版本下载 -->
@ -30,6 +35,7 @@
<div class="flex gap-4 items-center justify-center md:justify-start"> <div class="flex gap-4 items-center justify-center md:justify-start">
<template v-for="(item, index) in otherButtons" :key="index"> <template v-for="(item, index) in otherButtons" :key="index">
<div class="relative">
<a <a
v-if="item.link" v-if="item.link"
:href="item.link" :href="item.link"
@ -48,6 +54,12 @@
> >
<component :is="item.secondaryIcon" class="h-[24px] md:h-[34px] text-white" /> <component :is="item.secondaryIcon" class="h-[24px] md:h-[34px] text-white" />
</div> </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> </template>
</div> </div>
</div> </div>
@ -68,76 +80,118 @@ import request from '@/utils/request'
import {computed, ref, onMounted} from "vue"; import {computed, ref, onMounted} from "vue";
import {getAllQueryString} from "@/utils/url-utils.ts"; import {getAllQueryString} from "@/utils/url-utils.ts";
const downLoadWin = ref('')
const currentPlatform = ref('win') 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(() => { onMounted(() => {
const ua = navigator.userAgent; const ua = navigator.userAgent;
const platform = navigator.platform || ''; //
// 1. Android ()
if (/Android/i.test(ua)) { if (/Android/i.test(ua)) {
currentPlatform.value = 'android'; currentPlatform.value = 'android';
} } else if (/iPhone|iPod/i.test(ua)) {
// 2. iOS (iPhone, iPod)
else if (/iPhone|iPod/i.test(ua)) {
currentPlatform.value = 'ios'; currentPlatform.value = 'ios';
} } else if (/Macintosh|Mac OS X/i.test(ua)) {
// 3. Mac iPad
else if (/Macintosh|Mac OS X/i.test(ua)) {
// iPadOS > 1
// Mac maxTouchPoints 0 undefined
if (navigator.maxTouchPoints > 1) { if (navigator.maxTouchPoints > 1) {
currentPlatform.value = 'ios'; // iOS iPad currentPlatform.value = 'ios'; // iPad
} else { } else {
currentPlatform.value = 'mac'; currentPlatform.value = 'mac';
} }
} } else {
// 4. Windows
else {
currentPlatform.value = 'win'; currentPlatform.value = 'win';
} }
console.log('Detected Platform:', currentPlatform.value);
}); });
// request.get('/api/v1/common/client/download', { /**
// invite_code: getAllQueryString('ic'), * 核心下载处理函数
// platform: 'windows', * @param key 平台标识 (win, mac, ios, android)
// }).then((res: any) => { */
// downLoadWin.value = res.url
// })
const handleDownload = async (key: string) => { const handleDownload = async (key: string) => {
const platformMap: Record<string, string> = { const ic = getAllQueryString('ic') || 'uSSfgY6oAP'
win: 'windows', const isMain = key === currentPlatform.value;
mac: 'mac',
android: 'android',
ios: 'ios',
}
const platform = platformMap[key] || 'windows'
// 1. Windows API
if (key === 'win') {
try { try {
const res: any = await request.get('/api/v1/common/client/download', { const res: any = await request.get('/api/v1/common/client/download', {
invite_code: getAllQueryString('ic') || 'uSSfgY6oAP', invite_code: ic,
platform: platform, platform: 'windows',
}) })
if (res.url) { if (res.url) {
if (key === 'win') {
downLoadWin.value = res.url
}
window.open(res.url, '_blank') window.open(res.url, '_blank')
} }
} catch (error) { } catch (error) {
console.error('Download fetch failed', error) console.error('Windows download 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(() => [ 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: 'win',
{ key: 'ios', mainIcon: Icon2, secondaryIcon: AppleIcon, label: 'iOS', id: 'downloadButton_apple' }, mainIcon: Icon1,
{ key: 'android', mainIcon: Icon4, secondaryIcon: AndroidIcon, label: 'Android', id: 'downloadButton_android' }, 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(() => { const mainButton = computed(() => {

View File

@ -38,42 +38,42 @@ class OpenInstallSdk {
this.OI = new window.OpenInstall({ this.OI = new window.OpenInstall({
appKey: 'alf57p', appKey: 'alf57p',
onready: function () { // 初始化成功回调方法。当初始化完成后,会自动进入 onready: function () { // 初始化成功回调方法。当初始化完成后,会自动进入
this.schemeWakeup()// 尝试使用scheme打开App主要用于Android以及iOS的QQ环境中 // this.schemeWakeup()// 尝试使用scheme打开App主要用于Android以及iOS的QQ环境中
const m = this // const m = this
const button = document.getElementById('downloadButton_apple') // const button = document.getElementById('downloadButton_apple')
const button_mac = document.getElementById('downloadButton_mac') // const button_mac = document.getElementById('downloadButton_mac')
const button1 = document.getElementById('downloadButton_android') // const button1 = document.getElementById('downloadButton_android')
const ic = getAllQueryString('ic') || 'uSSfgY6oAP' // const ic = getAllQueryString('ic') || 'uSSfgY6oAP'
if (button) { // if (button) {
button.onclick = function () { // button.onclick = function () {
if (ic) { // if (ic) {
m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } }) // m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } })
} else { // } else {
m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用必须调用且不可额外自行跳转下载 // m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用必须调用且不可额外自行跳转下载
} // }
return false // return false
} // }
} // }
if(button_mac) { // if(button_mac) {
button_mac.onclick = function () { // button_mac.onclick = function () {
if (ic) { // if (ic) {
m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } }) // m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } })
} else { // } else {
m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用必须调用且不可额外自行跳转下载 // m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用必须调用且不可额外自行跳转下载
} // }
return false // return false
} // }
} // }
if (button1) { // if (button1) {
button1.onclick = function () { // button1.onclick = function () {
if (ic) { // if (ic) {
m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } }) // m.wakeupOrInstall({ data: { platform: 'download', inviteCode: ic } })
} else { // } else {
m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用必须调用且不可额外自行跳转下载 // m.wakeupOrInstall()// 此方法为scheme、Universal Link唤醒以及引导下载的作用必须调用且不可额外自行跳转下载
} // }
return false // return false
} // }
} // }
}, },
}, this.urlQuery)// 初始化时传入data作为一键拉起/App传参安装时候的参数 }, this.urlQuery)// 初始化时传入data作为一键拉起/App传参安装时候的参数
} catch (e) { } catch (e) {