mac不强制更新

This commit is contained in:
2026-03-13 17:48:00 +08:00
parent 1dd64988ba
commit 44df456240
5 changed files with 218 additions and 87 deletions

View File

@@ -1,94 +1,141 @@
import { ref, onMounted, onUnmounted } from 'vue'
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { isElectron } from '../utils/electronBridge'
// NOTE: Since we are using JS, we don't have interfaces, but structure remains same.
// ============== 单例状态 ==============
// 在函数外部定义,确保所有组件共享同一个状态
const status = ref('idle')
const updateInfo = ref(null)
const progress = ref(null)
const error = ref(null)
const currentVersion = ref('')
const platform = ref('unknown')
let listenersSetup = false // 标记是否已设置监听器
let unsubList = [] // 取消订阅列表
const isMac = computed(() => platform.value === 'mac')
const isWindows = computed(() => platform.value === 'windows')
// 平台判断
const getPlatformInfo = () => {
const navPlatform = navigator.platform || ''
const ua = navigator.userAgent || ''
const appVersion = navigator.appVersion || ''
console.log('[useUpdate] 平台检测信息:', {
navPlatform,
userAgent: ua,
appVersion
})
const p = navPlatform.toLowerCase()
if (p.includes('mac')) return 'mac'
if (p.includes('win')) return 'windows'
if (p.includes('linux')) return 'linux'
const u = ua.toLowerCase()
if (u.includes('macintosh') || u.includes('mac os') || u.includes('macintel')) return 'mac'
if (u.includes('windows') || u.includes('win32') || u.includes('win64')) return 'windows'
if (u.includes('linux')) return 'linux'
const av = appVersion.toLowerCase()
if (av.includes('mac')) return 'mac'
if (av.includes('win')) return 'windows'
if (av.includes('linux')) return 'linux'
return 'unknown'
}
// 获取当前版本
const fetchVersion = () => {
if (!isElectron()) {
currentVersion.value = 'web'
return
}
window.electronAPI.getAppVersion().then(v => {
currentVersion.value = v
}).catch(console.error)
}
// 设置监听器(只执行一次)
const setupListeners = () => {
if (!isElectron() || listenersSetup) return
listenersSetup = true
const api = window.electronAPI
// 正在检查
if (api.onUpdateChecking) {
unsubList.push(api.onUpdateChecking(() => {
status.value = 'checking'
}))
}
// 发现新版本
unsubList.push(api.onUpdateAvailable((info) => {
updateInfo.value = info
status.value = 'available'
error.value = null
}))
// 无可用更新
if (api.onUpdateNotAvailable) {
unsubList.push(api.onUpdateNotAvailable(() => {
status.value = 'idle'
}))
}
unsubList.push(api.onUpdateProgress((prog) => {
progress.value = prog
status.value = 'downloading'
}))
unsubList.push(api.onUpdateDownloaded(() => {
status.value = 'downloaded'
progress.value = null
}))
unsubList.push(api.onUpdateError((err) => {
error.value = err.message
status.value = 'error'
}))
// macOS 手动安装提示
if (api.onUpdateManualInstall) {
unsubList.push(api.onUpdateManualInstall((info) => {
console.log('macOS 需要手动安装更新:', info.path)
alert(`更新已下载完成!\n\n请手动安装更新文件:\n${info.path}\n\n应用将退出。`)
}))
}
}
// 清理监听器
const cleanupListeners = () => {
unsubList.forEach(unsub => unsub && unsub())
unsubList = []
listenersSetup = false
}
/**
* 应用更新 Hook (Vue Composable)
* 管理更新状态、进度和操作
* 单例模式:所有组件共享同一个状态和监听器
* 注意:此 Composable 仅在 Electron 环境中有效
*/
export function useUpdate() {
const status = ref('idle')
const updateInfo = ref(null)
const progress = ref(null)
const error = ref(null)
const currentVersion = ref('')
// 获取当前版本
const fetchVersion = () => {
if (!isElectron()) {
currentVersion.value = 'web'
return
}
window.electronAPI.getAppVersion().then(v => {
currentVersion.value = v
}).catch(console.error)
}
let unsubList = []
// 监听更新事件
const setupListeners = () => {
if (!isElectron()) return
const api = window.electronAPI
// 正在检查
if (api.onUpdateChecking) {
unsubList.push(api.onUpdateChecking(() => {
status.value = 'checking'
}))
}
// 发现新版本
unsubList.push(api.onUpdateAvailable((info) => {
updateInfo.value = info
status.value = 'available'
error.value = null
}))
// 无可用更新
if (api.onUpdateNotAvailable) {
unsubList.push(api.onUpdateNotAvailable(() => {
status.value = 'idle'
}))
}
unsubList.push(api.onUpdateProgress((prog) => {
progress.value = prog
status.value = 'downloading'
}))
unsubList.push(api.onUpdateDownloaded(() => {
status.value = 'downloaded'
progress.value = null
}))
unsubList.push(api.onUpdateError((err) => {
error.value = err.message
status.value = 'error'
}))
// macOS 手动安装提示
if (api.onUpdateManualInstall) {
unsubList.push(api.onUpdateManualInstall((info) => {
console.log('macOS 需要手动安装更新:', info.path)
// 显示提示让用户知道需要手动安装
alert(`更新已下载完成!\n\n请手动安装更新文件:\n${info.path}\n\n应用将退出。`)
}))
}
}
// 每个组件挂载时的初始化逻辑
onMounted(() => {
// 检测平台(确保只设置一次)
if (isElectron() && platform.value === 'unknown') {
platform.value = getPlatformInfo()
console.log('[useUpdate] 平台检测结果:', platform.value)
}
fetchVersion()
setupListeners()
})
onUnmounted(() => {
unsubList.forEach(unsub => unsub && unsub())
unsubList = []
})
// 注意:不在这里清理监听器,因为是单例模式
// 只在最后一个组件卸载时才清理(这里简化处理,不清理)
// 如果需要严格清理,可以使用引用计数
const checkForUpdates = () => {
if (!isElectron()) return
@@ -132,6 +179,9 @@ export function useUpdate() {
progress,
error,
currentVersion,
platform,
isMac,
isWindows,
checkForUpdates,
downloadUpdate,
installUpdate,