feat: 支持忽略更新

This commit is contained in:
cc
2026-02-01 20:50:01 +08:00
committed by xuncha
parent cb37f534ac
commit 123a088a39
9 changed files with 96 additions and 2 deletions

View File

@@ -552,6 +552,11 @@ function registerIpcHandlers() {
} }
}) })
ipcMain.handle('app:ignoreUpdate', async (_, version: string) => {
configService?.set('ignoredUpdateVersion', version)
return { success: true }
})
// 窗口控制 // 窗口控制
ipcMain.on('window:minimize', (event) => { ipcMain.on('window:minimize', (event) => {
BrowserWindow.fromWebContents(event.sender)?.minimize() BrowserWindow.fromWebContents(event.sender)?.minimize()
@@ -1159,7 +1164,16 @@ function checkForUpdatesOnStartup() {
if (result && result.updateInfo) { if (result && result.updateInfo) {
const currentVersion = app.getVersion() const currentVersion = app.getVersion()
const latestVersion = result.updateInfo.version const latestVersion = result.updateInfo.version
// 检查是否有新版本
if (latestVersion !== currentVersion && mainWindow) { if (latestVersion !== currentVersion && mainWindow) {
// 检查该版本是否被用户忽略
const ignoredVersion = configService?.get('ignoredUpdateVersion')
if (ignoredVersion === latestVersion) {
console.log(`版本 ${latestVersion} 已被用户忽略,跳过更新提示`)
return
}
// 通知渲染进程有新版本 // 通知渲染进程有新版本
mainWindow.webContents.send('app:updateAvailable', { mainWindow.webContents.send('app:updateAvailable', {
version: latestVersion, version: latestVersion,

View File

@@ -34,6 +34,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
getVersion: () => ipcRenderer.invoke('app:getVersion'), getVersion: () => ipcRenderer.invoke('app:getVersion'),
checkForUpdates: () => ipcRenderer.invoke('app:checkForUpdates'), checkForUpdates: () => ipcRenderer.invoke('app:checkForUpdates'),
downloadAndInstall: () => ipcRenderer.invoke('app:downloadAndInstall'), downloadAndInstall: () => ipcRenderer.invoke('app:downloadAndInstall'),
ignoreUpdate: (version: string) => ipcRenderer.invoke('app:ignoreUpdate', version),
onDownloadProgress: (callback: (progress: any) => void) => { onDownloadProgress: (callback: (progress: any) => void) => {
ipcRenderer.on('app:downloadProgress', (_, progress) => callback(progress)) ipcRenderer.on('app:downloadProgress', (_, progress) => callback(progress))
return () => ipcRenderer.removeAllListeners('app:downloadProgress') return () => ipcRenderer.removeAllListeners('app:downloadProgress')

View File

@@ -33,6 +33,9 @@ interface ConfigSchema {
authEnabled: boolean authEnabled: boolean
authPassword: string // SHA-256 hash authPassword: string // SHA-256 hash
authUseHello: boolean authUseHello: boolean
// 更新相关
ignoredUpdateVersion: string
} }
export class ConfigService { export class ConfigService {
@@ -67,7 +70,9 @@ export class ConfigService {
authEnabled: false, authEnabled: false,
authPassword: '', authPassword: '',
authUseHello: false authUseHello: false,
ignoredUpdateVersion: ''
} }
}) })
} }

View File

@@ -203,6 +203,18 @@ function App() {
} }
} }
const handleIgnoreUpdate = async () => {
if (!updateInfo || !updateInfo.version) return
try {
await window.electronAPI.app.ignoreUpdate(updateInfo.version)
setShowUpdateDialog(false)
setUpdateInfo(null)
} catch (e: any) {
console.error('忽略更新失败:', e)
}
}
const dismissUpdate = () => { const dismissUpdate = () => {
setUpdateInfo(null) setUpdateInfo(null)
} }
@@ -383,6 +395,7 @@ function App() {
updateInfo={updateInfo} updateInfo={updateInfo}
onClose={() => setShowUpdateDialog(false)} onClose={() => setShowUpdateDialog(false)}
onUpdate={handleUpdateNow} onUpdate={handleUpdateNow}
onIgnore={handleIgnoreUpdate}
isDownloading={isDownloading} isDownloading={isDownloading}
progress={downloadProgress} progress={downloadProgress}
/> />

View File

@@ -171,6 +171,29 @@
.actions { .actions {
display: flex; display: flex;
justify-content: center; justify-content: center;
gap: 12px;
.btn-ignore {
background: transparent;
color: #666666;
border: 1px solid #d0d0d0;
padding: 16px 32px;
border-radius: 20px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
&:hover {
background: #f5f5f5;
border-color: #999999;
color: #333333;
}
&:active {
transform: scale(0.98);
}
}
.btn-update { .btn-update {
background: #000000; background: #000000;

View File

@@ -12,6 +12,7 @@ interface UpdateDialogProps {
updateInfo: UpdateInfo | null updateInfo: UpdateInfo | null
onClose: () => void onClose: () => void
onUpdate: () => void onUpdate: () => void
onIgnore?: () => void
isDownloading: boolean isDownloading: boolean
progress: number | { progress: number | {
percent: number percent: number
@@ -27,6 +28,7 @@ const UpdateDialog: React.FC<UpdateDialogProps> = ({
updateInfo, updateInfo,
onClose, onClose,
onUpdate, onUpdate,
onIgnore,
isDownloading, isDownloading,
progress progress
}) => { }) => {
@@ -118,6 +120,11 @@ const UpdateDialog: React.FC<UpdateDialogProps> = ({
</div> </div>
) : ( ) : (
<div className="actions"> <div className="actions">
{onIgnore && (
<button className="btn-ignore" onClick={onIgnore}>
</button>
)}
<button className="btn-update" onClick={onUpdate}> <button className="btn-update" onClick={onUpdate}>
</button> </button>

View File

@@ -316,6 +316,19 @@ function SettingsPage() {
} }
} }
const handleIgnoreUpdate = async () => {
if (!updateInfo || !updateInfo.version) return
try {
await window.electronAPI.app.ignoreUpdate(updateInfo.version)
setShowUpdateDialog(false)
setUpdateInfo(null)
showMessage(`已忽略版本 ${updateInfo.version}`, true)
} catch (e: any) {
showMessage(`操作失败: ${e}`, false)
}
}
const showMessage = (text: string, success: boolean) => { const showMessage = (text: string, success: boolean) => {

View File

@@ -35,7 +35,10 @@ export const CONFIG_KEYS = {
// 安全 // 安全
AUTH_ENABLED: 'authEnabled', AUTH_ENABLED: 'authEnabled',
AUTH_PASSWORD: 'authPassword', AUTH_PASSWORD: 'authPassword',
AUTH_USE_HELLO: 'authUseHello' AUTH_USE_HELLO: 'authUseHello',
// 更新
IGNORED_UPDATE_VERSION: 'ignoredUpdateVersion'
} as const } as const
export interface WxidConfig { export interface WxidConfig {
@@ -399,3 +402,17 @@ export async function getAuthUseHello(): Promise<boolean> {
export async function setAuthUseHello(useHello: boolean): Promise<void> { export async function setAuthUseHello(useHello: boolean): Promise<void> {
await config.set(CONFIG_KEYS.AUTH_USE_HELLO, useHello) await config.set(CONFIG_KEYS.AUTH_USE_HELLO, useHello)
} }
// === 更新相关 ===
// 获取被忽略的更新版本
export async function getIgnoredUpdateVersion(): Promise<string | null> {
const value = await config.get(CONFIG_KEYS.IGNORED_UPDATE_VERSION)
return (value as string) || null
}
// 设置被忽略的更新版本
export async function setIgnoredUpdateVersion(version: string): Promise<void> {
await config.set(CONFIG_KEYS.IGNORED_UPDATE_VERSION, version)
}

View File

@@ -32,6 +32,7 @@ export interface ElectronAPI {
getVersion: () => Promise<string> getVersion: () => Promise<string>
checkForUpdates: () => Promise<{ hasUpdate: boolean; version?: string; releaseNotes?: string }> checkForUpdates: () => Promise<{ hasUpdate: boolean; version?: string; releaseNotes?: string }>
downloadAndInstall: () => Promise<void> downloadAndInstall: () => Promise<void>
ignoreUpdate: (version: string) => Promise<{ success: boolean }>
onDownloadProgress: (callback: (progress: number) => void) => () => void onDownloadProgress: (callback: (progress: number) => void) => () => void
onUpdateAvailable: (callback: (info: { version: string; releaseNotes: string }) => void) => () => void onUpdateAvailable: (callback: (info: { version: string; releaseNotes: string }) => void) => () => void
} }