feat: 优化应用更新检查逻辑;在生产环境中延迟检查更新并重构状态管理

This commit is contained in:
2025-12-30 19:34:34 +07:00
parent b6132ea30d
commit 72e7c77003
3 changed files with 40 additions and 40 deletions

View File

@@ -19,9 +19,11 @@ onMounted(() => {
userStore.updateProfile(); userStore.updateProfile();
} }
}); });
if (import.meta.env.MODE === "production") {
useTimeoutFn(() => { useTimeoutFn(() => {
checkAndPromptUpdate(); checkAndPromptUpdate();
}, 3000); }, 3000);
}
}); });
onBeforeMount(() => { onBeforeMount(() => {

View File

@@ -38,13 +38,15 @@ const updateUrls = {
* 应用更新检查 * 应用更新检查
*/ */
export function useAppUpdate() { export function useAppUpdate() {
const isChecking = ref(false); const state = reactive({
const hasUpdate = ref(false); isChecking: false,
const latestVersion = ref(""); hasUpdate: false,
const currentVersion = ref(""); latestVersion: "",
const forceUpdate = ref(false); currentVersion: "",
const updateMessage = ref(""); forceUpdate: false,
const updateUrl = ref(""); updateMessage: "",
updateUrl: "",
});
const platform = usePlatform(); const platform = usePlatform();
/** /**
@@ -78,12 +80,11 @@ export function useAppUpdate() {
updateMessage?: string; updateMessage?: string;
updateUrl?: string; updateUrl?: string;
}> { }> {
isChecking.value = true; state.isChecking = true;
try { try {
// 1. 获取当前版本 // 1. 获取当前版本
const current = await getCurrentVersion(); const current = await getCurrentVersion();
currentVersion.value = current; state.currentVersion = current;
// 2. 从服务器检查最新版本 // 2. 从服务器检查最新版本
// TODO: 后端接口实现后替换为真实 API 调用 // TODO: 后端接口实现后替换为真实 API 调用
// const response = await client.api.app.version.get({ // const response = await client.api.app.version.get({
@@ -117,17 +118,16 @@ export function useAppUpdate() {
const isNewVersion = compareVersion(current, versionInfo.version) < 0; const isNewVersion = compareVersion(current, versionInfo.version) < 0;
// 更新状态 // 更新状态
latestVersion.value = versionInfo.version; state.latestVersion = versionInfo.version;
hasUpdate.value = isNewVersion; state.hasUpdate = isNewVersion;
forceUpdate.value = versionInfo.forceUpdate || false; state.forceUpdate = versionInfo.forceUpdate || false;
updateMessage.value = versionInfo.updateMessage || ""; state.updateMessage = versionInfo.updateMessage || "";
updateUrl.value = versionInfo.updateUrl || ""; state.updateUrl = versionInfo.updateUrl || "";
// 4. 检查是否低于最低支持版本(强制更新) // 4. 检查是否低于最低支持版本(强制更新)
if (versionInfo.minSupportVersion) { if (versionInfo.minSupportVersion) {
const isBelowMinVersion = compareVersion(current, versionInfo.minSupportVersion) < 0; const isBelowMinVersion = compareVersion(current, versionInfo.minSupportVersion) < 0;
if (isBelowMinVersion) { if (isBelowMinVersion) {
forceUpdate.value = true; state.forceUpdate = true;
} }
} }
@@ -135,21 +135,21 @@ export function useAppUpdate() {
hasUpdate: isNewVersion, hasUpdate: isNewVersion,
currentVersion: current, currentVersion: current,
latestVersion: versionInfo.version, latestVersion: versionInfo.version,
forceUpdate: forceUpdate.value, forceUpdate: state.forceUpdate,
updateMessage: updateMessage.value, updateMessage: state.updateMessage,
updateUrl: updateUrl.value, updateUrl: state.updateUrl,
}; };
} }
catch (error) { catch (error) {
console.error("检查更新失败:", error); console.error("检查更新失败:", error);
const current = currentVersion.value || await getCurrentVersion(); const current = state.currentVersion || await getCurrentVersion();
return { return {
hasUpdate: false, hasUpdate: false,
currentVersion: current, currentVersion: current,
}; };
} }
finally { finally {
isChecking.value = false; state.isChecking = false;
} }
} }
@@ -157,18 +157,18 @@ export function useAppUpdate() {
* 打开应用商店更新页面 * 打开应用商店更新页面
*/ */
async function openStoreUpdate(): Promise<void> { async function openStoreUpdate(): Promise<void> {
if (!updateUrl.value) { if (!state.updateUrl) {
console.warn("没有提供更新链接"); console.warn("没有提供更新链接");
return; return;
} }
// 在原生平台打开外部链接 // 在原生平台打开外部链接
if (platform !== "browser") { if (platform !== "browser") {
window.open(updateUrl.value, "_system"); window.open(state.updateUrl, "_system");
} }
else { else {
// Web 平台直接打开链接 // Web 平台直接打开链接
window.open(updateUrl.value, "_blank"); window.open(state.updateUrl, "_blank");
} }
} }
@@ -178,9 +178,9 @@ export function useAppUpdate() {
async function showUpdateDialog(): Promise<void> { async function showUpdateDialog(): Promise<void> {
const alert = await alertController.create({ const alert = await alertController.create({
header: i18n.global.t("app.update.title"), header: i18n.global.t("app.update.title"),
message: updateMessage.value || i18n.global.t("app.update.message"), message: state.updateMessage || i18n.global.t("app.update.message"),
backdropDismiss: !forceUpdate.value, // 强制更新时不允许关闭 backdropDismiss: !state.forceUpdate, // 强制更新时不允许关闭
buttons: forceUpdate.value buttons: state.forceUpdate
? [ ? [
{ {
text: i18n.global.t("app.update.now"), text: i18n.global.t("app.update.now"),
@@ -213,7 +213,7 @@ export function useAppUpdate() {
*/ */
async function applyUpdate(): Promise<void> { async function applyUpdate(): Promise<void> {
// 如果是原生应用且有更新链接,打开应用商店 // 如果是原生应用且有更新链接,打开应用商店
if (platform !== "browser" && updateUrl.value) { if (platform !== "browser" && state.updateUrl) {
await openStoreUpdate(); await openStoreUpdate();
return; return;
} }
@@ -260,13 +260,7 @@ export function useAppUpdate() {
} }
return { return {
isChecking, ...toRefs(state),
hasUpdate,
currentVersion,
latestVersion,
forceUpdate,
updateMessage,
updateUrl,
checkForUpdate, checkForUpdate,
applyUpdate, applyUpdate,
forceReload, forceReload,

View File

@@ -5,7 +5,7 @@ import { checkbox, close, contrastOutline, information, languageOutline, refresh
const { t } = useI18n(); const { t } = useI18n();
const router = useIonRouter(); const router = useIonRouter();
const { cacheSize, calculateCacheSize, clearCache } = useCacheSize(); const { cacheSize, calculateCacheSize, clearCache } = useCacheSize();
const { isChecking, checkAndPromptUpdate } = useAppUpdate(); const { isChecking, getCurrentVersion, checkAndPromptUpdate } = useAppUpdate();
const { currentLanguage } = useLanguage(); const { currentLanguage } = useLanguage();
const { theme } = useTheme(); const { theme } = useTheme();
const themeNames = { const themeNames = {
@@ -13,6 +13,7 @@ const themeNames = {
dark: t("settings.themeDark"), dark: t("settings.themeDark"),
auto: t("settings.themeAuto"), auto: t("settings.themeAuto"),
}; };
const currentVersion = await getCurrentVersion();
function handleClearCache() { function handleClearCache() {
clearCache(); clearCache();
@@ -115,6 +116,9 @@ onMounted(() => {
{{ t("settings.checkUpdate") }} {{ t("settings.checkUpdate") }}
</div> </div>
</div> </div>
<div class="end">
{{ currentVersion }}
</div>
</div> </div>
</ion-item> </ion-item>
</ion-list> </ion-list>