All checks were successful
site-dist-deploy / build-and-deploy (push) Successful in 2m9s
180 lines
5.5 KiB
Vue
180 lines
5.5 KiB
Vue
<template>
|
||
<div class="flex w-full flex-col items-center justify-center md:justify-start">
|
||
<!-- 主下载按钮 -->
|
||
<div
|
||
class="mx-auto h-[60px] w-[210px] rounded-full bg-[#ADFF5B] md:-ml-2 md:h-[100px] md:w-[360px]"
|
||
>
|
||
<router-link
|
||
v-if="mainButton?.link && !mainButton.link.startsWith('http')"
|
||
:to="mainButton.link"
|
||
class="block transition-transform hover:brightness-110 active:scale-95"
|
||
>
|
||
<component :is="mainButton.mainIcon" class="h-full text-black" />
|
||
</router-link>
|
||
<a
|
||
v-else-if="mainButton?.link"
|
||
:href="mainButton.link"
|
||
target="_blank"
|
||
:aria-label="mainButton.label"
|
||
class="block transition-transform hover:brightness-110 active:scale-95"
|
||
>
|
||
<component :is="mainButton.mainIcon" class="h-full text-black" />
|
||
</a>
|
||
<div
|
||
v-else
|
||
:id="mainButton?.id"
|
||
:aria-label="mainButton?.label"
|
||
class="cursor-pointer transition-transform hover:brightness-110 active:scale-95"
|
||
>
|
||
<component :is="mainButton?.mainIcon" class="h-full text-black" />
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 其他版本下载 -->
|
||
<div class="mt-2 w-full">
|
||
<div class="mb-3 text-center md:text-left">
|
||
<span class="text-xs whitespace-nowrap md:text-sm">其他版本下载</span>
|
||
</div>
|
||
|
||
<div class="flex items-center justify-center gap-4 md:justify-start">
|
||
<template v-for="(item, index) in otherButtons" :key="index">
|
||
<router-link
|
||
v-if="item.link && !item.link.startsWith('http')"
|
||
:to="item.link"
|
||
class="transition-transform hover:brightness-110 active:scale-95"
|
||
>
|
||
<component :is="item.secondaryIcon" class="h-[24px] text-white md:h-[34px]" />
|
||
</router-link>
|
||
<a
|
||
v-else-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] text-white md:h-[34px]" />
|
||
</a>
|
||
<div
|
||
v-else
|
||
:id="item.id"
|
||
:aria-label="item.label"
|
||
class="cursor-pointer transition-transform hover:brightness-110 active:scale-95"
|
||
>
|
||
<component :is="item.secondaryIcon" class="h-[24px] text-white md:h-[34px]" />
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import Icon1 from './Group 105.svg?component'
|
||
import Icon2 from './Group 106.svg?component'
|
||
import Icon3 from './Group 107.svg?component'
|
||
import Icon4 from './Group 108.svg?component'
|
||
import WinIcon from './WinIcon.svg?component'
|
||
import MacIcon from './MacIcon.svg?component'
|
||
import AppleIcon from './AppleIcon.svg?component'
|
||
import AndroidIcon from './AndroidIcon.svg?component'
|
||
|
||
import request from '@/utils/request'
|
||
import { computed, ref, onMounted } from 'vue'
|
||
import { getAllQueryString } from '@/utils/url-utils.ts'
|
||
|
||
const currentPlatform = ref('win')
|
||
|
||
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)) {
|
||
currentPlatform.value = 'ios'
|
||
}
|
||
// 3. 核心改进:区分 Mac 和 iPad
|
||
else if (/Macintosh|Mac OS X/i.test(ua)) {
|
||
// iPadOS 桌面模式下,支持多点触控(通常 > 1)
|
||
// 而真正的 Mac 电脑通常 maxTouchPoints 为 0 或 undefined
|
||
if (navigator.maxTouchPoints > 1) {
|
||
currentPlatform.value = 'ios' // 归类为 iOS 端(iPad)
|
||
} else {
|
||
currentPlatform.value = 'mac'
|
||
}
|
||
}
|
||
// 4. 其他情况默认为 Windows
|
||
else {
|
||
currentPlatform.value = 'win'
|
||
}
|
||
|
||
console.log('Detected Platform:', currentPlatform.value)
|
||
})
|
||
|
||
// request.get('/api/v1/common/client/download', {
|
||
// invite_code: getAllQueryString('ic'),
|
||
// platform: 'mac',
|
||
// }).then((res: any) => {
|
||
// downLoadMac.value = res.url
|
||
// })
|
||
|
||
const ADJ_BASE_URL = 'https://hifastvpn.go.link/?adj_t=1xf6e7ru'
|
||
const getTrackedUrl = (target: string) => {
|
||
if (!target) return ''
|
||
return `${ADJ_BASE_URL}&adj_redirect=${encodeURIComponent(target)}`
|
||
}
|
||
|
||
const allDownloadOptions = computed(() => [
|
||
{
|
||
key: 'win',
|
||
mainIcon: Icon1,
|
||
secondaryIcon: WinIcon,
|
||
link: getTrackedUrl(
|
||
'https://api.hifast.biz/v1/common/client/download/file/Hi快VPN-windows-1.0.0.exe',
|
||
),
|
||
label: 'Windows',
|
||
id: 'downloadButton_win',
|
||
},
|
||
{
|
||
key: 'mac',
|
||
mainIcon: Icon3,
|
||
secondaryIcon: MacIcon,
|
||
link: getTrackedUrl('https://apps.apple.com/us/app/hi%E5%BF%ABvpn/id6755683167'),
|
||
label: 'macOS',
|
||
id: 'downloadButton_mac',
|
||
},
|
||
{
|
||
key: 'ios',
|
||
mainIcon: Icon2,
|
||
secondaryIcon: AppleIcon,
|
||
link: '/help',
|
||
label: 'iOS',
|
||
id: 'downloadButton_apple',
|
||
},
|
||
{
|
||
key: 'android',
|
||
mainIcon: Icon4,
|
||
secondaryIcon: AndroidIcon,
|
||
link: getTrackedUrl(
|
||
'https://api.hifast.biz/v1/common/client/download/file/Hi%E5%BF%ABVPN-android-1.0.0.apk',
|
||
),
|
||
label: 'Android',
|
||
id: 'downloadButton_android',
|
||
},
|
||
])
|
||
|
||
const mainButton = computed(() => {
|
||
return (
|
||
allDownloadOptions.value.find((opt) => opt.key === currentPlatform.value) ||
|
||
allDownloadOptions.value[0]
|
||
)
|
||
})
|
||
|
||
const otherButtons = computed(() => {
|
||
return allDownloadOptions.value.filter((opt) => opt.key !== currentPlatform.value)
|
||
})
|
||
</script>
|