104 lines
2.8 KiB
TypeScript
104 lines
2.8 KiB
TypeScript
/**
|
||
* 应用更新检查组合式函数
|
||
*/
|
||
export function useAppUpdate() {
|
||
const isChecking = ref(false);
|
||
const hasUpdate = ref(false);
|
||
const latestVersion = ref("");
|
||
const currentVersion = ref("1.0.0"); // 从 package.json 或环境变量读取
|
||
|
||
/**
|
||
* 检查是否有新版本
|
||
*/
|
||
async function checkForUpdate(): Promise<{
|
||
hasUpdate: boolean;
|
||
currentVersion: string;
|
||
latestVersion?: string;
|
||
}> {
|
||
isChecking.value = true;
|
||
try {
|
||
// 方案1: 从服务器检查版本(需要后端 API)
|
||
// const response = await fetch('/api/version');
|
||
// const { version } = await response.json();
|
||
// latestVersion.value = version;
|
||
|
||
// 方案2: 检查 Service Worker 更新(PWA 应用)
|
||
if ("serviceWorker" in navigator) {
|
||
const registration = await navigator.serviceWorker.getRegistration();
|
||
if (registration) {
|
||
await registration.update();
|
||
const hasNewWorker = registration.waiting !== null || registration.installing !== null;
|
||
hasUpdate.value = hasNewWorker;
|
||
|
||
if (hasNewWorker) {
|
||
return {
|
||
hasUpdate: true,
|
||
currentVersion: currentVersion.value,
|
||
latestVersion: "新版本可用",
|
||
};
|
||
}
|
||
}
|
||
}
|
||
|
||
// 模拟检查(实际应用中需要替换为真实的 API 调用)
|
||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||
|
||
// 暂时返回无更新
|
||
return {
|
||
hasUpdate: false,
|
||
currentVersion: currentVersion.value,
|
||
};
|
||
}
|
||
catch (error) {
|
||
console.error("检查更新失败:", error);
|
||
throw error;
|
||
}
|
||
finally {
|
||
isChecking.value = false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 应用更新(重新加载应用)
|
||
*/
|
||
async function applyUpdate(): Promise<void> {
|
||
if ("serviceWorker" in navigator) {
|
||
const registration = await navigator.serviceWorker.getRegistration();
|
||
if (registration?.waiting) {
|
||
// 通知 Service Worker 跳过等待,立即激活
|
||
registration.waiting.postMessage({ type: "SKIP_WAITING" });
|
||
|
||
// 等待 Service Worker 激活后重新加载页面
|
||
navigator.serviceWorker.addEventListener("controllerchange", () => {
|
||
window.location.reload();
|
||
});
|
||
return;
|
||
}
|
||
}
|
||
|
||
// 如果没有 Service Worker,直接重新加载
|
||
window.location.reload();
|
||
}
|
||
|
||
/**
|
||
* 强制刷新应用(清除缓存后重新加载)
|
||
*/
|
||
async function forceReload(): Promise<void> {
|
||
if ("caches" in window) {
|
||
const cacheNames = await caches.keys();
|
||
await Promise.all(cacheNames.map(name => caches.delete(name)));
|
||
}
|
||
window.location.reload();
|
||
}
|
||
|
||
return {
|
||
isChecking,
|
||
hasUpdate,
|
||
currentVersion,
|
||
latestVersion,
|
||
checkForUpdate,
|
||
applyUpdate,
|
||
forceReload,
|
||
};
|
||
}
|