Add update service

This commit is contained in:
2025-06-23 19:42:48 +08:00
parent 4f8272e290
commit ea025e3f5d
19 changed files with 639 additions and 270 deletions

View File

@@ -9,6 +9,7 @@ import {
LanguageType,
SystemThemeType,
TabType,
UpdatesConfig,
} from '@/../bindings/voidraft/internal/models/models';
import {useI18n} from 'vue-i18n';
import {ConfigUtils} from '@/utils/configUtils';
@@ -42,6 +43,10 @@ type AppearanceConfigKeyMap = {
readonly [K in keyof AppearanceConfig]: string;
};
type UpdatesConfigKeyMap = {
readonly [K in keyof UpdatesConfig]: string;
};
type NumberConfigKey = 'fontSize' | 'tabSize' | 'lineHeight';
// 配置键映射
@@ -70,6 +75,11 @@ const APPEARANCE_CONFIG_KEY_MAP: AppearanceConfigKeyMap = {
systemTheme: 'appearance.systemTheme'
} as const;
const UPDATES_CONFIG_KEY_MAP: UpdatesConfigKeyMap = {
version: 'updates.version',
autoUpdate: 'updates.autoUpdate'
} as const;
// 配置限制
const CONFIG_LIMITS = {
fontSize: {min: 12, max: 28, default: 13},
@@ -145,7 +155,6 @@ const DEFAULT_CONFIG: AppConfig = {
updates: {
version: "1.0.0",
autoUpdate: true,
betaChannel: false
},
metadata: {
version: '1.0.0',
@@ -216,6 +225,21 @@ export const useConfigStore = defineStore('config', () => {
state.config.appearance[key] = value;
};
const updateUpdatesConfig = async <K extends keyof UpdatesConfig>(key: K, value: UpdatesConfig[K]): Promise<void> => {
// 确保配置已加载
if (!state.configLoaded && !state.isLoading) {
await initConfig();
}
const backendKey = UPDATES_CONFIG_KEY_MAP[key];
if (!backendKey) {
throw new Error(`No backend key mapping found for updates.${key.toString()}`);
}
await ConfigService.Set(backendKey, value);
state.config.updates[key] = value;
};
// 加载配置
const initConfig = async (): Promise<void> => {
if (state.isLoading) return;
@@ -411,6 +435,9 @@ export const useConfigStore = defineStore('config', () => {
await updateGeneralConfig('startAtLogin', value);
// 再调用系统设置API
await StartupService.SetEnabled(value);
}
},
// 更新配置相关方法
setAutoUpdate: async (value: boolean) => await updateUpdatesConfig('autoUpdate', value)
};
});

View File

@@ -0,0 +1,81 @@
import {defineStore} from 'pinia'
import {computed, ref} from 'vue'
import {CheckForUpdates} from '@/../bindings/voidraft/internal/services/updateservice'
import {UpdateCheckResult} from '@/../bindings/voidraft/internal/services/models'
import {useConfigStore} from './configStore'
export const useUpdateStore = defineStore('update', () => {
// 状态
const isChecking = ref(false)
const updateResult = ref<UpdateCheckResult | null>(null)
const hasCheckedOnStartup = ref(false)
// 计算属性
const hasUpdate = computed(() => updateResult.value?.hasUpdate || false)
const errorMessage = computed(() => updateResult.value?.error || '')
// 检查更新
const checkForUpdates = async (): Promise<boolean> => {
if (isChecking.value) return false
isChecking.value = true
try {
const result = await CheckForUpdates()
updateResult.value = result
return !result.error
} catch (error) {
updateResult.value = new UpdateCheckResult({
hasUpdate: false,
currentVer: '1.0.0',
latestVer: '',
releaseNotes: '',
releaseURL: '',
error: 'Network error'
})
return false
} finally {
isChecking.value = false
}
}
// 启动时检查更新
const checkOnStartup = async () => {
if (hasCheckedOnStartup.value) return
const configStore = useConfigStore()
if (configStore.config.updates.autoUpdate) {
await checkForUpdates()
}
hasCheckedOnStartup.value = true
}
// 打开发布页面
const openReleaseURL = () => {
if (updateResult.value?.releaseURL) {
window.open(updateResult.value.releaseURL, '_blank')
}
}
// 重置状态
const reset = () => {
updateResult.value = null
isChecking.value = false
}
return {
// 状态
isChecking,
updateResult,
hasCheckedOnStartup,
// 计算属性
hasUpdate,
errorMessage,
// 方法
checkForUpdates,
checkOnStartup,
openReleaseURL,
reset
}
})