191 lines
5.2 KiB
JavaScript
191 lines
5.2 KiB
JavaScript
import { ref, onMounted, onUnmounted, computed } from 'vue'
|
|
import { isElectron } from '../utils/electronBridge'
|
|
|
|
// ============== 单例状态 ==============
|
|
// 在函数外部定义,确保所有组件共享同一个状态
|
|
|
|
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() {
|
|
// 每个组件挂载时的初始化逻辑
|
|
onMounted(() => {
|
|
// 检测平台(确保只设置一次)
|
|
if (isElectron() && platform.value === 'unknown') {
|
|
platform.value = getPlatformInfo()
|
|
console.log('[useUpdate] 平台检测结果:', platform.value)
|
|
}
|
|
fetchVersion()
|
|
setupListeners()
|
|
})
|
|
|
|
// 注意:不在这里清理监听器,因为是单例模式
|
|
// 只在最后一个组件卸载时才清理(这里简化处理,不清理)
|
|
// 如果需要严格清理,可以使用引用计数
|
|
|
|
const checkForUpdates = () => {
|
|
if (!isElectron()) return
|
|
|
|
status.value = 'checking'
|
|
error.value = null
|
|
window.electronAPI.checkForUpdates().then((hasUpdate) => {
|
|
if (!hasUpdate) {
|
|
status.value = 'idle'
|
|
}
|
|
}).catch((e) => {
|
|
error.value = e.message
|
|
status.value = 'error'
|
|
})
|
|
}
|
|
|
|
const downloadUpdate = () => {
|
|
if (!isElectron()) return
|
|
|
|
status.value = 'downloading'
|
|
progress.value = { percent: 0, bytesPerSecond: 0, transferred: 0, total: 0 }
|
|
window.electronAPI.downloadUpdate().catch((e) => {
|
|
error.value = e.message
|
|
status.value = 'error'
|
|
})
|
|
}
|
|
|
|
const installUpdate = () => {
|
|
if (!isElectron()) return
|
|
window.electronAPI.installUpdate()
|
|
}
|
|
|
|
const dismissUpdate = () => {
|
|
status.value = 'idle'
|
|
updateInfo.value = null
|
|
}
|
|
|
|
return {
|
|
status,
|
|
updateInfo,
|
|
progress,
|
|
error,
|
|
currentVersion,
|
|
platform,
|
|
isMac,
|
|
isWindows,
|
|
checkForUpdates,
|
|
downloadUpdate,
|
|
installUpdate,
|
|
dismissUpdate
|
|
}
|
|
}
|