自动下载添加

This commit is contained in:
谢宇宁
2026-11-13 14:20:14 +07:00
parent 4c0c79a2cd
commit 469b4074d7
2 changed files with 59 additions and 13 deletions
+3 -1
View File
@@ -214,7 +214,7 @@ const menus = [
{ key: 'about', label: '关于我们' },
]
const { isIos, hasIosStore, download, init } = useAppDownload()
const { isIos, hasIosStore, download, init, autoDownloadChannelApk } = useAppDownload()
const scroller = ref(null)
const header = ref(null)
@@ -361,6 +361,8 @@ function doCopy() {
onMounted(() => {
init()
// 渠道包:安卓端进页面 3 秒后自动下载 APK(无 channelApkAndDownUrl 时不触发)
autoDownloadChannelApk()
centerNav()
nextTick(() => {
centerNav()
+56 -12
View File
@@ -5,6 +5,7 @@
* - 点下载:bottonclick 返回 data.link(地址数组),跳 link[index];同一请求后端记点击
* - iOS 轻量版:点击直接调 h5/config 下载描述文件(不看开关);社媒内置浏览器装不了描述文件,只弹「复制到 Safari」引导
* - iOS 商店版:iosStore(packageType 2) 走 bottonclick 拿 link
* - 渠道包自动下载:bottonlist 返回 channelApkAndDownUrl 时,安卓端进页面 3 秒后自动拉起该 APK
* - 下载前把 { ...query, tid } 写入剪贴板供 App 首启归因
*
* 组件接入:
@@ -30,6 +31,8 @@ export interface ButtonList {
iosLink?: string
androidButton?: number
hasChannelApk?: boolean
// 渠道包地址:有值说明该渠道有专属 APK,安卓端进页面自动下载
channelApkAndDownUrl?: string
[key: string]: unknown
}
@@ -42,6 +45,10 @@ const ip = ref('')
const ready = ref(false)
let initPromise: Promise<void> | null = null
// 渠道包自动下载:延迟时长(从进页面算起)+ 单页生命周期内只触发一次
const AUTO_DOWNLOAD_DELAY = 3000
let autoDownloadFired = false
const isIos = /iphone|ipad|ipod/i.test(navigator.userAgent)
const isWeiXin = /MicroMessenger/i.test(navigator.userAgent)
@@ -151,15 +158,59 @@ export function useAppDownload() {
return true
}
function buildParam(terminal: Terminal): donwloadParam {
return {
appId: APP_ID,
ip: ip.value,
channel: filterChannel(route.query),
domain: window.location.host || '',
// bili 默认值,安卓请求同样带 iosH5
type: 'iosH5',
terminal,
}
}
// 下载前写剪贴板,供 App 首次启动读取做安装归因(整包 URL 参数 + tid)
function writeAttribution() {
const trace_id = renewSessionTraceId()
try {
copyToClipboard(JSON.stringify({ ...route.query, tid: trace_id }))
} catch (err) {
console.log('写入归因剪贴板失败' + err)
}
}
/**
* 渠道包自动下载:bottonlist 返回 channelApkAndDownUrl 有值时,
* 安卓端进页面 delay 毫秒后自动拉起该 APK(整个页面生命周期只触发一次)。
* iOS 装不了 APK、社媒内置浏览器会被拦截跳出,这两种情况都跳过,交给用户手动点。
*/
function autoDownloadChannelApk(delay = AUTO_DOWNLOAD_DELAY) {
if (autoDownloadFired || isIos || isSocialInAppBrowser()) return
autoDownloadFired = true
// 计时与拉接口并行:3 秒从进页面算起,接口慢就等接口回来再下
const waiting = new Promise((resolve) => setTimeout(resolve, delay))
Promise.all([init(), waiting])
.then(() => {
const url = String(buttonList.value.channelApkAndDownUrl || '').trim()
if (!url) return
writeAttribution()
// 自动下载同样记一次点击,统计口径与手动点下载一致
bottonclick(buildParam('android')).catch((err) =>
console.log('自动下载埋点失败' + JSON.stringify(err)),
)
jumpToLink(url)
})
.catch((err) => console.log('渠道包自动下载失败' + err))
}
/**
* 点击下载,返回是否拿到并开始下载(false 时页面可提示稍后重试)
* @param index iOS:0 = 轻量版,1 = 商店包;Android:下载地址下标
* @param terminal 默认按 UA;PC 端弹窗里的 iOS / Android 按钮显式传入
*/
async function download(index = 0, terminal: Terminal = isIos ? 'ios' : 'android') {
const trace_id = renewSessionTraceId()
// 写剪贴板供 App 首次启动读取做安装归因:整包 URL 参数 + tid(黄果 App 按 tid 读)
copyToClipboard(JSON.stringify({ ...route.query, tid: trace_id }))
writeAttribution()
if (terminal === 'ios' && index !== 1) {
try {
@@ -171,15 +222,7 @@ export function useAppDownload() {
}
await init()
const param: donwloadParam = {
appId: APP_ID,
ip: ip.value,
channel: filterChannel(route.query),
domain: window.location.host || '',
// bili 默认值,安卓请求同样带 iosH5
type: 'iosH5',
terminal,
}
const param = buildParam(terminal)
try {
return terminal === 'ios'
? await downloadIosStore(param)
@@ -205,5 +248,6 @@ export function useAppDownload() {
iosInstallUrl,
init,
download,
autoDownloadChannelApk,
}
}