From 20428e2ac8eca9d0e7051001dae303fe257a83ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E5=BC=95?= Date: Wed, 15 Oct 2025 09:54:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=A3=80=E6=B5=8B=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=8C=85=E6=8B=AC?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=E6=97=B6=E8=87=AA=E5=8A=A8=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E4=BF=A1=E6=81=AF=E5=92=8C=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=97=B6=E5=AE=9A=E6=9C=9F=E6=A3=80=E6=9F=A5=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- public/project.json | 0 public/version.json | 5 ++ src/App.vue | 38 ++++++++- src/api/base-service.ts | 43 +++++----- src/main.ts | 4 +- src/utils/update-version.ts | 57 +++++++++++++ src/utils/versionCheck.ts | 154 ++++++++++++++++++++++++++++++++++++ 8 files changed, 279 insertions(+), 24 deletions(-) delete mode 100644 public/project.json create mode 100644 public/version.json create mode 100644 src/utils/update-version.ts create mode 100644 src/utils/versionCheck.ts diff --git a/package.json b/package.json index f13f6b2..fcec8bb 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "type": "module", "scripts": { "dev": "vite", - "build": "vite build", + "build": "tsx src/utils/update-version.ts && vite build --mode release", "preview": "vite preview" }, "dependencies": { diff --git a/public/project.json b/public/project.json deleted file mode 100644 index e69de29..0000000 diff --git a/public/version.json b/public/version.json new file mode 100644 index 0000000..8e8c38f --- /dev/null +++ b/public/version.json @@ -0,0 +1,5 @@ +{ + "version": "2025-10-15 09:50:32", + "buildTime": "2025-10-15T01:50:32.937Z", + "environment": "production" +} \ No newline at end of file diff --git a/src/App.vue b/src/App.vue index 15f98e7..b6bf554 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,10 +1,46 @@ - + diff --git a/src/api/base-service.ts b/src/api/base-service.ts index f708cba..e48a6c2 100644 --- a/src/api/base-service.ts +++ b/src/api/base-service.ts @@ -1,5 +1,5 @@ import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios' -import { DialogPlugin } from 'tdesign-vue-next' +import { ElMessage, ElMessageBox } from 'element-plus' // 获取浏览器中的url地址和端口号并拼接 /* import { config } from 'public/config.js' const getBaseUrl = () => { @@ -14,7 +14,7 @@ const getBaseUrl = () => { // 创建一个新的axios实例 const instance: AxiosInstance = axios.create({ baseURL: import.meta.env.VITE_BASE_API, - timeout: 60000, + timeout: 30000, withCredentials: false, headers: { 'Content-Type': 'application/json' @@ -45,18 +45,14 @@ instance.interceptors.response.use( console.log(process.env.NODE_ENV, '变量') const data = response.data - + console.log('接口返回', data) // 判断接口返回的 Message 字段是否为 Success - if (data && data.Message !== 'Success') { + if (!data?.Message.includes('Success')) { // 如果不是 Success,则将请求视为失败 - const confirmDia = DialogPlugin({ - header: '错误', - body: `${JSON.stringify(data)}`, - confirmBtn: '确定', - cancelBtn: null, - onConfirm: ({ e }) => { - confirmDia.hide() - } + ElMessageBox.alert(JSON.stringify(data), '错误', { + confirmButtonText: '确定', + type: 'error', + dangerouslyUseHTMLString: false }) return Promise.reject({ response: { @@ -66,7 +62,6 @@ instance.interceptors.response.use( } }) } - // 如果是 Success,则返回数据 return data }, @@ -84,15 +79,21 @@ instance.interceptors.response.use( // 在设置请求时发生了一些事情,触发了一个错误 console.error('错误:', error.message) } - const confirmDia = DialogPlugin({ - header: '错误', - body: `${JSON.stringify(error)}`, - confirmBtn: '确定', - cancelBtn: null, - onConfirm: ({ e }) => { - confirmDia.hide() + + console.error('报错', error) + + ElMessageBox.alert( + `接口:【${error.config.url}】报错 + ${error.message} + ${JSON.stringify(error?.response?.data)} + `, + '报错', + { + confirmButtonText: '确定', + type: 'error', + dangerouslyUseHTMLString: false } - }) + ) return Promise.reject(error) } ) diff --git a/src/main.ts b/src/main.ts index a21fdcf..6dff2bc 100644 --- a/src/main.ts +++ b/src/main.ts @@ -10,10 +10,12 @@ import { createApp } from 'vue' import router from './router/index' //引入vue-router import App from './App.vue' import { createPinia } from 'pinia' - +import { startVersionCheck } from './utils/versionCheck' import TDesign from 'tdesign-vue-next' import 'tdesign-vue-next/es/style/index.css' import 'normalize.css/normalize.css' +// 启动版本检测服务 (20秒检查一次) +startVersionCheck(1000 * 20) // 挂载到app上 createApp(App) .use(router) diff --git a/src/utils/update-version.ts b/src/utils/update-version.ts new file mode 100644 index 0000000..2342871 --- /dev/null +++ b/src/utils/update-version.ts @@ -0,0 +1,57 @@ +/** + * 更新版本信息脚本 + * 在构建过程中自动更新 version.json 文件 + */ +import fs from 'node:fs' +import path, { dirname } from 'node:path' +import { fileURLToPath } from 'node:url' + +// 获取当前文件的目录路径 +const __filename = fileURLToPath(import.meta.url) +const __dirname = dirname(__filename) + +// 版本信息 +const now = new Date() +const dateStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart( + 2, + '0' +)}-${String(now.getDate()).padStart(2, '0')}` +const timeStr = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart( + 2, + '0' +)}:${String(now.getSeconds()).padStart(2, '0')}` + +interface VersionInfo { + version: string + buildTime: string + environment: string +} + +// 不再需要检查构建序号,直接使用时间戳作为版本号 +try { + if (fs.existsSync(path.resolve(__dirname, '../../public/version.json'))) { + const currentVersionInfo = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../../public/version.json'), 'utf8')) + console.log(`当前版本: ${currentVersionInfo.version}, 更新为时间格式版本`) + } +} catch (error) { + console.error('读取当前版本信息失败', error) +} + +// 设置版本格式为 YYYY-MM-DD HH:MM:SS +const versionFormat = `${dateStr} ${timeStr}` + +const versionInfo: VersionInfo = { + version: versionFormat, + buildTime: now.toISOString(), + environment: process.env.NODE_ENV || 'production' +} + +// 版本文件路径 +// 确保路径正确解析到 pc-front/public/version.json +const versionFilePath = path.resolve(__dirname, '../../public/version.json') + +// 写入版本信息 +fs.writeFileSync(versionFilePath, JSON.stringify(versionInfo, null, 2), 'utf8') + +console.log(`版本信息已更新: ${JSON.stringify(versionInfo)}`) +console.log(`当前版本时间戳: ${versionFormat}`) diff --git a/src/utils/versionCheck.ts b/src/utils/versionCheck.ts new file mode 100644 index 0000000..beae384 --- /dev/null +++ b/src/utils/versionCheck.ts @@ -0,0 +1,154 @@ +/** + * 版本检测服务 + * 定期检查应用版本并提示用户更新 + */ + +import { NotifyPlugin } from 'tdesign-vue-next' +import { h } from 'vue' + +interface VersionInfo { + version: string + buildTime: string + environment: string +} + +let currentVersion: string | null = null +let checkInterval: number | null = null +let isUpdateNotificationShown = false + +/** + * 获取当前版本信息 + */ +export const fetchVersionInfo = async (): Promise => { + try { + // 确保使用正确的路径访问version.json + const response = await fetch(`/version.json?t=${new Date().getTime()}`) + if (!response.ok) { + throw new Error('无法获取版本信息') + } + return await response.json() + } catch (error) { + console.error('获取版本信息失败:', error) + return { + version: '0.0.0', + buildTime: new Date().toISOString(), + environment: 'unknown' + } + } +} + +/** + * 检查版本更新 + */ +export const checkVersion = async (): Promise => { + try { + const versionInfo = await fetchVersionInfo() + + // 首次加载,保存当前版本 + if (!currentVersion) { + currentVersion = versionInfo.version + return false + } + + // 版本不一致,需要更新 + if (currentVersion !== versionInfo.version) { + return true + } + + return false + } catch (error) { + console.error('检查版本更新失败:', error) + return false + } +} + +/** + * 显示更新提示 + */ +export const showUpdateNotification = () => { + // 如果已经显示了更新提示,则不再重复显示 + if (isUpdateNotificationShown) { + return + } + + // 标记已显示更新提示 + isUpdateNotificationShown = true + + const notify = NotifyPlugin.warning({ + title: '有新的版本需要更新', + content: '点击后将刷新页面获取最新版本!', + footer: h('div', { class: 't-notification__detail' }, [ + h( + 't-button', + { + class: 't-notification__detail-item', + theme: 'default', + variant: 'text', + onClick: () => window.location.reload() + }, + '立即刷新' + ), + h( + 't-button', + { + class: 't-notification__detail-item', + theme: 'primary', + variant: 'text', + onClick: () => { + isUpdateNotificationShown = false + NotifyPlugin.close(notify) + } + }, + '稍后提醒我' + ) + ]), + duration: 0 + }) +} + +/** + * 启动版本检测服务 + * @param intervalTime 检测间隔时间(毫秒),默认5分钟 + */ +export const startVersionCheck = (intervalTime = 1000) => { + // 重置通知标志 + isUpdateNotificationShown = false + + // 初始化获取当前版本 + fetchVersionInfo().then(info => { + currentVersion = info.version + console.log('当前应用版本:', currentVersion) + }) + + // 清除可能存在的旧定时器 + if (checkInterval) { + window.clearInterval(checkInterval) + } + + // 设置定期检查 + checkInterval = window.setInterval(async () => { + const needUpdate = await checkVersion() + if (needUpdate) { + showUpdateNotification() + } + }, intervalTime) + + return () => { + if (checkInterval) { + window.clearInterval(checkInterval) + checkInterval = null + } + } +} + +/** + * 停止版本检测服务 + */ +export const stopVersionCheck = () => { + if (checkInterval) { + window.clearInterval(checkInterval) + checkInterval = null + } + // 重置通知标志 + isUpdateNotificationShown = false +}