APP热更新
This commit is contained in:
1 parent
692b521453
commit
93997ea8b1
21 files changed
+8130
-4
No files matched your search
@@ -0,0 +1,93 @@
|
||||
import { Capacitor } from '@capacitor/core'
|
||||
import { CapacitorUpdater } from '@capgo/capacitor-updater'
|
||||
import { ElNotification } from 'element-plus'
|
||||
import http from '../api/http'
|
||||
|
||||
interface AppUpdateCheckResponse {
|
||||
available: boolean
|
||||
version?: string
|
||||
nativeVersion: string
|
||||
platform: 'Android' | 'Ios'
|
||||
channel: 'Production' | 'Staging'
|
||||
downloadUrl?: string
|
||||
releaseNotes?: string
|
||||
fileSize?: number
|
||||
sha256?: string
|
||||
publishedAt?: string
|
||||
}
|
||||
|
||||
const updateChannel =
|
||||
import.meta.env.VITE_APP_UPDATE_CHANNEL?.trim() || 'production'
|
||||
|
||||
function absoluteApiUrl(relativePath: string) {
|
||||
const configuredBase = String(http.defaults.baseURL ?? '/api')
|
||||
const publicBase =
|
||||
import.meta.env.VITE_PUBLIC_BASE_URL?.trim() || window.location.origin
|
||||
const apiBase = new URL(
|
||||
configuredBase.endsWith('/') ? configuredBase : `${configuredBase}/`,
|
||||
publicBase,
|
||||
)
|
||||
return new URL(relativePath, apiBase).toString()
|
||||
}
|
||||
|
||||
export async function initializeAppUpdates() {
|
||||
if (!Capacitor.isNativePlatform()) return
|
||||
|
||||
try {
|
||||
// Only confirm the bundle after Vue has mounted successfully. If a newly
|
||||
// installed bundle cannot reach this point, the native plugin rolls back.
|
||||
await CapacitorUpdater.notifyAppReady()
|
||||
|
||||
const platform = Capacitor.getPlatform()
|
||||
if (platform !== 'android' && platform !== 'ios') return
|
||||
|
||||
const [current, builtin, next] = await Promise.all([
|
||||
CapacitorUpdater.current(),
|
||||
CapacitorUpdater.getBuiltinVersion(),
|
||||
CapacitorUpdater.getNextBundle(),
|
||||
])
|
||||
const currentVersion =
|
||||
current.bundle.id === 'builtin'
|
||||
? builtin.version
|
||||
: current.bundle.version
|
||||
|
||||
const { data } = await http.get<AppUpdateCheckResponse>(
|
||||
'/app-updates/latest',
|
||||
{
|
||||
params: {
|
||||
platform,
|
||||
channel: updateChannel,
|
||||
nativeVersion: current.native,
|
||||
currentVersion,
|
||||
},
|
||||
timeout: 15000,
|
||||
},
|
||||
)
|
||||
if (
|
||||
!data.available ||
|
||||
!data.version ||
|
||||
!data.downloadUrl ||
|
||||
!data.sha256 ||
|
||||
next?.version === data.version
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const downloaded = await CapacitorUpdater.download({
|
||||
url: absoluteApiUrl(data.downloadUrl),
|
||||
version: data.version,
|
||||
checksum: data.sha256,
|
||||
})
|
||||
await CapacitorUpdater.next({ id: downloaded.id })
|
||||
|
||||
ElNotification({
|
||||
title: `新版本 ${data.version} 已就绪`,
|
||||
message: data.releaseNotes || '更新将在下次启动应用时自动生效。',
|
||||
type: 'success',
|
||||
duration: 6000,
|
||||
})
|
||||
} catch (error) {
|
||||
// OTA failure must never stop users from entering the bundled application.
|
||||
console.warn('[app-update] update check failed', error)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user