mac不强制更新
This commit is contained in:
@@ -14,7 +14,8 @@
|
|||||||
<!-- 配置页面 - 使用 v-show 保持状态 -->
|
<!-- 配置页面 - 使用 v-show 保持状态 -->
|
||||||
<div class="h-full w-full animate-fadeIn" v-show="currentPage === 'config'">
|
<div class="h-full w-full animate-fadeIn" v-show="currentPage === 'config'">
|
||||||
<ConfigPage @go-to-browser="handleGoToBrowser" @logout="handleLogout" />
|
<ConfigPage @go-to-browser="handleGoToBrowser" @logout="handleLogout" />
|
||||||
<UpdateNotification />
|
<!-- 更新通知组件:启动时已在 UpdateChecker 检查,此处暂不显示 -->
|
||||||
|
<!-- <UpdateNotification /> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 浏览器页面 -->
|
<!-- 浏览器页面 -->
|
||||||
|
|||||||
@@ -38,10 +38,31 @@
|
|||||||
<p v-if="updateInfo.releaseNotes" class="text-gray-500 text-xs bg-gray-50 p-2 rounded-lg line-clamp-3">
|
<p v-if="updateInfo.releaseNotes" class="text-gray-500 text-xs bg-gray-50 p-2 rounded-lg line-clamp-3">
|
||||||
{{ updateInfo.releaseNotes }}
|
{{ updateInfo.releaseNotes }}
|
||||||
</p>
|
</p>
|
||||||
<button @click="downloadUpdate"
|
|
||||||
class="w-full py-2 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-lg font-medium hover:from-blue-600 hover:to-blue-700 transition-all shadow-md hover:shadow-lg">
|
<!-- Mac 用户:跳转下载页面 -->
|
||||||
下载更新
|
<template v-if="isMac">
|
||||||
</button>
|
<p class="text-amber-600 text-sm bg-amber-50 p-2 rounded-lg">
|
||||||
|
Mac 版本请前往官网下载最新安装包
|
||||||
|
</p>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<button @click="openDownloadPage"
|
||||||
|
class="flex-1 py-2 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-lg font-medium hover:from-blue-600 hover:to-blue-700 transition-all shadow-md hover:shadow-lg">
|
||||||
|
前往下载
|
||||||
|
</button>
|
||||||
|
<button @click="dismissUpdate"
|
||||||
|
class="px-4 py-2 bg-gray-100 text-gray-600 rounded-lg font-medium hover:bg-gray-200 transition-all">
|
||||||
|
稍后提醒
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Windows 用户:正常下载更新 -->
|
||||||
|
<template v-else>
|
||||||
|
<button @click="downloadUpdate"
|
||||||
|
class="w-full py-2 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-lg font-medium hover:from-blue-600 hover:to-blue-700 transition-all shadow-md hover:shadow-lg">
|
||||||
|
下载更新
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 下载中 -->
|
<!-- 下载中 -->
|
||||||
@@ -107,6 +128,7 @@ const {
|
|||||||
progress,
|
progress,
|
||||||
error,
|
error,
|
||||||
currentVersion,
|
currentVersion,
|
||||||
|
isMac,
|
||||||
checkForUpdates,
|
checkForUpdates,
|
||||||
downloadUpdate,
|
downloadUpdate,
|
||||||
installUpdate,
|
installUpdate,
|
||||||
@@ -120,4 +142,13 @@ function formatBytes(bytes) {
|
|||||||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||||||
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`
|
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 打开下载页面
|
||||||
|
const openDownloadPage = () => {
|
||||||
|
if (isElectronEnv) {
|
||||||
|
window.electronAPI.openExternal?.('https://yolozs.com/')
|
||||||
|
} else {
|
||||||
|
window.open('https://yolozs.com/', '_blank')
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,94 +1,141 @@
|
|||||||
import { ref, onMounted, onUnmounted } from 'vue'
|
import { ref, onMounted, onUnmounted, computed } from 'vue'
|
||||||
import { isElectron } from '../utils/electronBridge'
|
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)
|
* 应用更新 Hook (Vue Composable)
|
||||||
* 管理更新状态、进度和操作
|
* 单例模式:所有组件共享同一个状态和监听器
|
||||||
* 注意:此 Composable 仅在 Electron 环境中有效
|
* 注意:此 Composable 仅在 Electron 环境中有效
|
||||||
*/
|
*/
|
||||||
export function useUpdate() {
|
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(() => {
|
onMounted(() => {
|
||||||
|
// 检测平台(确保只设置一次)
|
||||||
|
if (isElectron() && platform.value === 'unknown') {
|
||||||
|
platform.value = getPlatformInfo()
|
||||||
|
console.log('[useUpdate] 平台检测结果:', platform.value)
|
||||||
|
}
|
||||||
fetchVersion()
|
fetchVersion()
|
||||||
setupListeners()
|
setupListeners()
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
// 注意:不在这里清理监听器,因为是单例模式
|
||||||
unsubList.forEach(unsub => unsub && unsub())
|
// 只在最后一个组件卸载时才清理(这里简化处理,不清理)
|
||||||
unsubList = []
|
// 如果需要严格清理,可以使用引用计数
|
||||||
})
|
|
||||||
|
|
||||||
const checkForUpdates = () => {
|
const checkForUpdates = () => {
|
||||||
if (!isElectron()) return
|
if (!isElectron()) return
|
||||||
@@ -132,6 +179,9 @@ export function useUpdate() {
|
|||||||
progress,
|
progress,
|
||||||
error,
|
error,
|
||||||
currentVersion,
|
currentVersion,
|
||||||
|
platform,
|
||||||
|
isMac,
|
||||||
|
isWindows,
|
||||||
checkForUpdates,
|
checkForUpdates,
|
||||||
downloadUpdate,
|
downloadUpdate,
|
||||||
installUpdate,
|
installUpdate,
|
||||||
|
|||||||
@@ -76,10 +76,24 @@
|
|||||||
<p class="text-gray-600 text-sm whitespace-pre-wrap">{{ updateInfo.releaseNotes }}</p>
|
<p class="text-gray-600 text-sm whitespace-pre-wrap">{{ updateInfo.releaseNotes }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button @click="downloadUpdate"
|
<!-- Mac 用户:跳转下载页面 -->
|
||||||
class="w-full py-3 bg-gradient-to-r from-blue-600 to-blue-500 text-white rounded-lg font-medium hover:from-blue-700 hover:to-blue-600 transition-all shadow-sm">
|
<template v-if="isMac">
|
||||||
立即下载更新
|
<p class="text-amber-600 text-sm bg-amber-50 p-3 rounded-lg text-center">
|
||||||
</button>
|
Mac 版本请前往官网下载最新安装包
|
||||||
|
</p>
|
||||||
|
<button @click="openDownloadPage"
|
||||||
|
class="w-full py-3 bg-gradient-to-r from-blue-600 to-blue-500 text-white rounded-lg font-medium hover:from-blue-700 hover:to-blue-600 transition-all shadow-sm">
|
||||||
|
前往下载
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- Windows 用户:正常下载更新 -->
|
||||||
|
<template v-else>
|
||||||
|
<button @click="downloadUpdate"
|
||||||
|
class="w-full py-3 bg-gradient-to-r from-blue-600 to-blue-500 text-white rounded-lg font-medium hover:from-blue-700 hover:to-blue-600 transition-all shadow-sm">
|
||||||
|
立即下载更新
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
<p class="text-center text-gray-400 text-xs">
|
<p class="text-center text-gray-400 text-xs">
|
||||||
必须更新后才能使用程序
|
必须更新后才能使用程序
|
||||||
@@ -185,6 +199,7 @@ const {
|
|||||||
progress,
|
progress,
|
||||||
error,
|
error,
|
||||||
currentVersion,
|
currentVersion,
|
||||||
|
isMac,
|
||||||
checkForUpdates,
|
checkForUpdates,
|
||||||
downloadUpdate,
|
downloadUpdate,
|
||||||
installUpdate
|
installUpdate
|
||||||
@@ -304,6 +319,15 @@ function formatBytes(bytes) {
|
|||||||
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`
|
return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 打开下载页面(Mac 用户)
|
||||||
|
function openDownloadPage() {
|
||||||
|
if (isElectronEnv) {
|
||||||
|
window.electronAPI.openExternal?.('https://yolozs.com/')
|
||||||
|
} else {
|
||||||
|
window.open('https://yolozs.com/', '_blank')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (timeoutTimer) clearTimeout(timeoutTimer)
|
if (timeoutTimer) clearTimeout(timeoutTimer)
|
||||||
if (countdownTimer) clearInterval(countdownTimer)
|
if (countdownTimer) clearInterval(countdownTimer)
|
||||||
|
|||||||
25
vite.config.js.timestamp-1773392797167-9352ce3e637ed.mjs
Normal file
25
vite.config.js.timestamp-1773392797167-9352ce3e637ed.mjs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// vite.config.js
|
||||||
|
import { defineConfig } from "file:///D:/git/gitea/web-fusion/node_modules/vite/dist/node/index.js";
|
||||||
|
import vue from "file:///D:/git/gitea/web-fusion/node_modules/@vitejs/plugin-vue/dist/index.mjs";
|
||||||
|
import { resolve } from "path";
|
||||||
|
var __vite_injected_original_dirname = "D:\\git\\gitea\\web-fusion";
|
||||||
|
var vite_config_default = defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@": resolve(__vite_injected_original_dirname, "src")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
port: 5173,
|
||||||
|
host: true
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
outDir: "dist",
|
||||||
|
sourcemap: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
export {
|
||||||
|
vite_config_default as default
|
||||||
|
};
|
||||||
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcuanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFxnaXRcXFxcZ2l0ZWFcXFxcd2ViLWZ1c2lvblwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiRDpcXFxcZ2l0XFxcXGdpdGVhXFxcXHdlYi1mdXNpb25cXFxcdml0ZS5jb25maWcuanNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL0Q6L2dpdC9naXRlYS93ZWItZnVzaW9uL3ZpdGUuY29uZmlnLmpzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHZ1ZSBmcm9tICdAdml0ZWpzL3BsdWdpbi12dWUnXHJcbmltcG9ydCB7IHJlc29sdmUgfSBmcm9tICdwYXRoJ1xyXG5cclxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cclxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcclxuICAgIHBsdWdpbnM6IFt2dWUoKV0sXHJcbiAgICByZXNvbHZlOiB7XHJcbiAgICAgICAgYWxpYXM6IHtcclxuICAgICAgICAgICAgJ0AnOiByZXNvbHZlKF9fZGlybmFtZSwgJ3NyYycpXHJcbiAgICAgICAgfVxyXG4gICAgfSxcclxuICAgIHNlcnZlcjoge1xyXG4gICAgICAgIHBvcnQ6IDUxNzMsXHJcbiAgICAgICAgaG9zdDogdHJ1ZVxyXG4gICAgfSxcclxuICAgIGJ1aWxkOiB7XHJcbiAgICAgICAgb3V0RGlyOiAnZGlzdCcsXHJcbiAgICAgICAgc291cmNlbWFwOiBmYWxzZVxyXG4gICAgfVxyXG59KVxyXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQStQLFNBQVMsb0JBQW9CO0FBQzVSLE9BQU8sU0FBUztBQUNoQixTQUFTLGVBQWU7QUFGeEIsSUFBTSxtQ0FBbUM7QUFLekMsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDeEIsU0FBUyxDQUFDLElBQUksQ0FBQztBQUFBLEVBQ2YsU0FBUztBQUFBLElBQ0wsT0FBTztBQUFBLE1BQ0gsS0FBSyxRQUFRLGtDQUFXLEtBQUs7QUFBQSxJQUNqQztBQUFBLEVBQ0o7QUFBQSxFQUNBLFFBQVE7QUFBQSxJQUNKLE1BQU07QUFBQSxJQUNOLE1BQU07QUFBQSxFQUNWO0FBQUEsRUFDQSxPQUFPO0FBQUEsSUFDSCxRQUFRO0FBQUEsSUFDUixXQUFXO0FBQUEsRUFDZjtBQUNKLENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==
|
||||||
Reference in New Issue
Block a user