更新下载链接
All checks were successful
site-dist-deploy / build-and-deploy (push) Successful in 1m25s

This commit is contained in:
speakeloudest 2026-01-23 05:39:59 -08:00
parent 3f61439a96
commit 0c8afb05e3
5 changed files with 242 additions and 31 deletions

View File

@ -116,28 +116,61 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { computed, ref } from 'vue'
// Help page logic
import Logo from '@/pages/Home/logo.svg?component'
import MobileLogo from '@/pages/Home/mobile-logo.svg?component'
import RightText from './right-text.svg?component'
import ChatIcon from './Vector.svg?component'
import MacosIcon from './macos.svg?component'
import WindowsIcon from './windows.svg?component'
import AndroidIcon from './android.svg?component'
import request from '@/utils/request'
import { getAllQueryString } from '@/utils/url-utils.ts'
import DownloadMethodList from './DownloadMethodList/DownloadMethodList.vue'
import FAQAccordion from './FAQAccordion/index.vue'
import { Button } from '@/components/ui/button'
import { downLoadAndroid, downLoadWin, downLoadMac, downLoadIos } from '@/utils/constant.ts'
import { downLoadIos } from '@/utils/constant.ts'
const downLoadWin = ref('')
const downLoadMac = ref('')
const downLoadAndroid = ref('')
request
.get('/api/v1/common/client/download', {
invite_code: getAllQueryString('ic'),
platform: 'mac',
})
.then((res) => {
downLoadMac.value = res.url
})
request
.get('/api/v1/common/client/download', {
invite_code: getAllQueryString('ic'),
platform: 'windows',
})
.then((res) => {
downLoadWin.value = res.url
})
request
.get('/api/v1/common/client/download', {
invite_code: getAllQueryString('ic'),
platform: 'android',
})
.then((res) => {
downLoadWin.value = res.url
})
const activeIndex = ref(0)
const otherClients = [
{ icon: WindowsIcon, link: downLoadWin, type: 'window' },
{ icon: MacosIcon, link: downLoadMac, type: 'mac' },
{ icon: AndroidIcon, link: downLoadAndroid, type: 'android' },
]
const otherClients = computed(() => {
return [
{ icon: WindowsIcon, link: downLoadWin.value, type: 'window' },
{ icon: MacosIcon, link: downLoadMac.value, type: 'mac' },
{ icon: AndroidIcon, link: downLoadAndroid.value, type: 'android' },
]
})
function changeActiveIndex(index) {
activeIndex.value = index
@ -145,14 +178,4 @@ function changeActiveIndex(index) {
}
</script>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
<style scoped></style>

View File

@ -31,12 +31,47 @@ 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 { downLoadAndroid, downLoadWin, downLoadMac } from '@/utils/constant.ts'
import { ref, computed } from 'vue'
import request from '@/utils/request'
import { getAllQueryString } from '@/utils/url-utils.ts'
const downLoadWin = ref('')
const downLoadMac = ref('')
const downLoadAndroid = ref('')
request
.get('/api/v1/common/client/download', {
invite_code: getAllQueryString('ic'),
platform: 'mac',
})
.then((res) => {
downLoadMac.value = res.url
})
request
.get('/api/v1/common/client/download', {
invite_code: getAllQueryString('ic'),
platform: 'windows',
})
.then((res) => {
downLoadWin.value = res.url
console.log(downLoadWin.value)
})
request
.get('/api/v1/common/client/download', {
invite_code: getAllQueryString('ic'),
platform: 'android',
})
.then((res) => {
downLoadWin.value = res.url
})
//
const downloadLinks = [
{ icon: Icon2, link: '/help', isInternal: true, label: '查看帮助中心' },
{ icon: Icon1, link: downLoadWin, label: '下载 Windows 版客户端' },
{ icon: Icon3, link: downLoadMac, label: '下载 macOS 版客户端' },
{ icon: Icon4, link: downLoadAndroid, label: '下载 Android 版客户端' },
]
const downloadLinks = computed(() => {
return [
{ icon: Icon2, link: '/help', isInternal: true, label: '查看帮助中心' },
{ icon: Icon1, link: downLoadWin.value, label: '下载 Windows 版客户端' },
{ icon: Icon3, link: downLoadMac.value, label: '下载 macOS 版客户端' },
{ icon: Icon4, link: downLoadAndroid.value, label: '下载 Android 版客户端' },
]
})
</script>

View File

@ -50,7 +50,7 @@
<img
:src="ScreenshotMobile"
alt="App Screenshot"
class="h-auto w-full drop-shadow-2xl"
class="h-auto min-h-[284px] w-full drop-shadow-2xl"
/>
<div class="absolute right-[8%] bottom-[97px] z-50 aspect-square w-[58%]">
<!-- Ripple Animation (Background) -->

View File

@ -1,7 +1,3 @@
// utils/constant.ts
const BASE_URL = window.location.origin // 自动获取当前域名
export const downLoadAndroid = `${BASE_URL}/download/app-arm64-v8a-release.apk`
export const downLoadMac = `${BASE_URL}/download/HiFastVPN-1.0.0+100-macos.dmg`
export const downLoadWin = `${BASE_URL}/download/HiFastVPN-0.0.2-windows-setup.exe`
export const downLoadIos = 'https://apps.apple.com/us/app/hi%E5%BF%ABvpn/id6755683167'

157
src/utils/url-utils.ts Normal file
View File

@ -0,0 +1,157 @@
/**
*
* @param {Object} data
*/
export const param = (data) => {
if (!data) {
return ''
}
let url = ''
for (const k in data) {
const value = data[k] !== undefined ? data[k] : ''
url += `&${k}=${encodeURIComponent(value)}`
}
return url ? url.substr(1) : ''
}
/**
*
*/
export const paramToObj = (data) => {
if (!data) {
return ''
}
let url = ''
for (const k in data) {
const value = data[k] !== undefined ? data[k] : ''
if (typeof value === 'object') {
url += `&${k}=${encodeURIComponent(JSON.stringify(value))}`
} else {
url += `&${k}=${encodeURIComponent(value)}`
}
}
return url ? url.substr(1) : ''
}
/**
* code
* @param {string} name
*/
export const getQueryString = (name) => {
const reg = `(^|&)${name}=([^&]*)(&|$)`
const query = window.location.search.substr(1) || window.location.hash.split('?')[1]
const r = query ? query.match(reg) : null
if (r != null) return decodeURIComponent(r[2])
return null
}
/**
* URL上的值
* @param {*} name key
* @param {*} isMerge hash和search,search优先级高
*/
export const getAllQueryString = (name, isMerge = true) => {
const reg = `(?:^|&)${name}=([^&]*)(?:&|$)`
const search = window.location.search.substr(1)
const hash = window.location.hash.split('?')[1]
const searchR = search ? search.match(reg) && search.match(reg)![1] : null
const hashR = hash ? hash.match(reg) && hash.match(reg)![1] : null
if (isMerge) {
const result = searchR || hashR
return result ? unescape(result) : null
}
return {
search: searchR ? unescape(searchR) : null,
hash: hashR ? unescape(hashR) : null,
}
}
/**
* code情况
* @param {string} url
*/
export function parseURL(url) {
const a = document.createElement('a')
a.href = url
const protocol = a.protocol.replace(':', '')
const host = a.hostname
const path = a.pathname.replace(/^([^\/])/, '/$1')
return {
href: `${protocol}://${host}${path}?`,
source: url,
protocol,
host,
port: a.port,
query: a.search,
params: (function () {
const params = {}
const seg = a.search.replace(/^\?/, '').split('&')
const len = seg.length
let p
for (let i = 0; i < len; i++) {
if (seg[i]) {
p = seg[i].split('=')
params[p[0]] = p[1]
}
}
return params
})(),
hash: a.hash.replace('#', ''),
path,
}
}
/**
* url query对象
*/
export function urlGetParam() {
const t = location.search
.substring(1)
.split('&')
.filter((item) => !!item)
const f = {}
for (let i = 0; i < t.length; i++) {
const x = t[i].split('=')
f[x[0]] = x[1]
}
return f
}
/**
*
* @param {array} removes
* @param {boolean} hash hash值
*/
export function removeUrlQuery(removes, isHash = false) {
const currentParam = urlGetParam()
removes.forEach((removeItem) => {
delete currentParam[removeItem]
})
return `${location.origin}${location.pathname}?${param(currentParam)}${
isHash ? location.hash : ''
}`
}
/**
* keyValue
*/
export function hrefKeyValue(key, url) {
const reg = new RegExp(/(\w+)=(\w+)/, 'gi')
const currentUrl = url || location.href
const results = currentUrl.match(reg)
if (results) {
const resultKeyValues = results.map((o) => ({
[o.split('=')[0]]: o.split('=')[1],
}))
const result = resultKeyValues.find((o) => o.hasOwnProperty(key))
return (result && result[key]) || null
}
return null
}
/**
* url中的参数
*/
export function replaceQueryString(url, name, value) {
const re = new RegExp(name + '=[^&]*', 'gi')
return url.replace(re, name + '=' + value)
}