Files
track/track-uniapp/src/App.vue

202 lines
6.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script>
import { getNotifications } from "./api/notification";
export default {
onLaunch() {
console.log("生产流转 T1.0.1 启动");
// 无 Token 跳转登录页
const token = uni.getStorageSync("access_token");
if (!token) {
uni.reLaunch({ url: "/pages/login/login" });
return;
}
// 🚀 OTA 热更新检测(仅 App 端生效)
// #ifdef APP-PLUS
this.checkUpdate();
// #endif
},
onShow() {
console.log("App 显示");
this.updateTabBarBadge();
},
onHide() {
console.log("App 隐藏");
},
methods: {
// ==========================================================
// OTA 热更新雷达 — 版本检测 + WGT 下载 + 静默安装
// ==========================================================
checkUpdate() {
// 获取当前 App 的 WGT 资源版本号uni-app 编译后的版本标识)
const sysInfo = uni.getSystemInfoSync();
const currentWgtVersion = sysInfo.appWgtVersion || sysInfo.appVersion || "0";
const currentVersionCode = this.parseVersionCode(currentWgtVersion);
const baseUrl = uni.getStorageSync("env_base_url") || "http://172.16.0.198:8011/api/v1";
console.log("[OTA] 本地WGT版本:", currentWgtVersion, "| 数字版本:", currentVersionCode);
uni.request({
url: `${baseUrl}/app/check-update`,
method: "GET",
timeout: 8000,
success: (res) => {
if (res.statusCode !== 200) return;
const data = res.data;
if (!data || !data.wgt_url) {
console.log("[OTA] 服务端无可用更新包");
return;
}
const serverVersionCode = data.version_code || 0;
console.log("[OTA] 服务端版本:", data.version, "| 数字版本:", serverVersionCode);
// 客户端自行对比:服务端 > 本地 = 需要更新
if (serverVersionCode <= currentVersionCode) {
console.log("[OTA] 已是最新版本,无需更新");
return;
}
console.log("[OTA] 发现新版本:", data.version);
this.downloadAndInstall(data.wgt_url, data.version, data.description);
},
fail: () => {
console.log("[OTA] 版本检测网络失败,跳过");
},
});
},
/** 从版本字符串提取数字版本号用于对比 */
parseVersionCode(versionStr) {
if (!versionStr) return 0;
const nums = versionStr.match(/\d+/g);
if (!nums) return 0;
// 取后三位拼成整数: "T1.0.1" → [1,0,1] → 101
return parseInt(nums.slice(-3).join("").padEnd(3, "0").slice(0, 3), 10);
},
downloadAndInstall(wgtUrl, newVersion, description) {
if (!wgtUrl) {
console.log("[OTA] 无 WGT 下载地址");
return;
}
// 弹窗询问用户是否更新
const content = description
? `发现新版本 ${newVersion}\n\n${description}\n\n是否立即更新`
: `发现新版本 ${newVersion},是否立即更新?`;
uni.showModal({
title: "版本更新",
content,
confirmText: "立即更新",
cancelText: "稍后再说",
success: (modalRes) => {
if (!modalRes.confirm) return;
// 显示下载进度
uni.showLoading({ title: "下载中 0%", mask: true });
const downloadTask = uni.downloadFile({
url: wgtUrl,
success: (downloadRes) => {
if (downloadRes.statusCode !== 200) {
uni.hideLoading();
uni.showToast({ title: "下载失败", icon: "none" });
return;
}
uni.showLoading({ title: "安装中...", mask: true });
// 调用 plus.runtime.install 安装 WGT
plus.runtime.install(
downloadRes.tempFilePath,
{ force: false },
() => {
uni.hideLoading();
console.log("[OTA] WGT 安装成功");
uni.showModal({
title: "更新完成",
content: "新版本已安装,重启后生效。是否立即重启?",
confirmText: "立即重启",
cancelText: "稍后",
success: (restartRes) => {
if (restartRes.confirm) {
plus.runtime.restart();
}
},
});
},
(err) => {
uni.hideLoading();
console.error("[OTA] 安装失败:", err.message);
uni.showToast({
title: "更新失败: " + (err.message || "未知错误"),
icon: "none",
duration: 4000,
});
}
);
},
fail: (err) => {
uni.hideLoading();
console.error("[OTA] 下载失败:", err.errMsg);
uni.showToast({ title: "下载失败,请检查网络", icon: "none" });
},
});
// 下载进度回调
if (downloadTask && downloadTask.onProgressUpdate) {
downloadTask.onProgressUpdate((res) => {
const pct = res.progress;
uni.showLoading({ title: `下载中 ${pct}%`, mask: true });
if (pct >= 100) {
uni.showLoading({ title: "安装中...", mask: true });
}
});
}
},
});
},
// ==========================================================
// TabBar 消息红点
// ==========================================================
async updateTabBarBadge() {
try {
let user = uni.getStorageSync("user");
if (typeof user === "string" && user) {
try { user = JSON.parse(user); } catch (e) { user = null; }
}
const userId = user?.username || user?.id || "";
if (!userId) return;
const res = await getNotifications(userId, 0, 1);
const unreadCount = res.unread_count || 0;
if (unreadCount > 0) {
uni.setTabBarBadge({
index: 2,
text: unreadCount > 99 ? "99+" : String(unreadCount),
});
} else {
uni.removeTabBarBadge({ index: 2 });
}
} catch {
// 静默失败
}
},
},
};
</script>
<style>
page {
background-color: #f3f4f6;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
font-size: 14px;
color: #1f2937;
}
</style>