feat: ✨ 加版本检查功能

This commit is contained in:
cshaptx4869
2026-09-11 16:28:56 +08:00
parent cd6d1f1927
commit 45b7332342
3 changed files with 88 additions and 1 deletions

View File

@@ -15,6 +15,7 @@
import { useAppStore, useSettingsStore } from "@/stores";
import { appConfig } from "@/settings";
import { ThemeMode, ComponentSize } from "@/enums";
import { useVersionCheck } from "@/composables/useVersionCheck";
const appStore = useAppStore();
const settingsStore = useSettingsStore();
@@ -30,4 +31,9 @@ const fontColor = computed(() => {
? "rgba(255, 255, 255, .15)"
: "rgba(0, 0, 0, .15)";
});
// 初始化版本检查
if (!import.meta.env.DEV) {
useVersionCheck(5 * 60_000);
}
</script>

View File

@@ -0,0 +1,66 @@
import { ElNotification } from "element-plus";
import { onMounted, onUnmounted, ref } from "vue";
/** 版本检查 */
export function useVersionCheck(interval = 60_000) {
const hasNewVersion = ref(false);
let notified = false;
const safeInterval = Math.max(10_000, interval);
const checkVersion = async () => {
try {
const base = import.meta.env.BASE_URL;
const baseUrl = base.endsWith("/") ? base : `${base}/`;
// 时间戳防 CDN/代理缓存,no-cache 防浏览器磁盘缓存
const res = await fetch(`${baseUrl}version.json?t=${Date.now()}`, {
cache: "no-cache",
});
if (!res.ok) return; // 非核心功能,网络异常不影响正常使用
const data = await res.json();
if (data.version && data.version !== __APP_INFO__.buildTimestamp) {
hasNewVersion.value = true;
showUpdateNotice();
}
} catch (e) {
console.warn("版本检测失败", e);
}
};
const showUpdateNotice = () => {
if (notified) return;
notified = true;
// 使用 Notification 而非 Modal,不打断用户操作
ElNotification({
title: "🎉 发现新版本",
message: "系统已更新,点击刷新以获取最新功能",
duration: 0, // 不自动关闭
position: "bottom-right",
onClick: () => window.location.reload(),
onClose: () => {
notified = false;
},
customClass: "version-update-notice",
});
};
let timer: ReturnType<typeof setInterval>;
// 用户从其他标签页切回时立即检测,无需等待下一次轮询
const handleVisibilityChange = () => {
if (!document.hidden) checkVersion();
};
onMounted(() => {
checkVersion();
timer = setInterval(checkVersion, safeInterval);
document.addEventListener("visibilitychange", handleVisibilityChange);
});
onUnmounted(() => {
clearInterval(timer);
document.removeEventListener("visibilitychange", handleVisibilityChange);
});
return { hasNewVersion };
}

View File

@@ -9,7 +9,8 @@ import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import { mockDevServerPlugin } from "vite-plugin-mock-dev-server";
import UnoCSS from "unocss/vite";
import { resolve } from "path";
import { join, resolve } from "path";
import { existsSync, mkdirSync, writeFileSync } from "fs";
import { name, version } from "./package.json" with { type: "json" };
// 平台名称、版本信息
@@ -85,6 +86,20 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
dts: false,
//dts: "types/components.d.ts",
}),
// 生成版本号文件
{
name: "dist-version",
closeBundle() {
const distDir = resolve(__dirname, "dist");
if (!existsSync(distDir)) {
mkdirSync(distDir, { recursive: true });
}
writeFileSync(
join(distDir, "version.json"),
JSON.stringify({ version: __APP_INFO__.buildTimestamp })
);
},
},
] as PluginOption[],
// 预加载项目必需的依赖
optimizeDeps: {