2026-08-07 11:44:20 +08:00
|
|
|
|
<script>
|
|
|
|
|
|
import { getNotifications } from "./api/notification";
|
2026-08-05 15:01:46 +08:00
|
|
|
|
|
2026-08-07 11:44:20 +08:00
|
|
|
|
export default {
|
|
|
|
|
|
onLaunch() {
|
2026-08-07 13:22:10 +08:00
|
|
|
|
console.log("生产流转 T1.0.2 启动");
|
2026-08-07 11:49:59 +08:00
|
|
|
|
|
2026-08-07 17:05:00 +08:00
|
|
|
|
// 🚦 路由守卫:首页已是 scan,未登录才跳登录页(零闪烁)
|
2026-08-07 16:50:00 +08:00
|
|
|
|
const token = uni.getStorageSync("access_token") || uni.getStorageSync("refresh_token");
|
|
|
|
|
|
const user = uni.getStorageSync("user");
|
2026-08-07 17:01:55 +08:00
|
|
|
|
|
2026-08-07 17:05:00 +08:00
|
|
|
|
if (!token || !user) {
|
2026-08-07 11:44:20 +08:00
|
|
|
|
uni.reLaunch({ url: "/pages/login/login" });
|
|
|
|
|
|
}
|
2026-08-07 17:05:00 +08:00
|
|
|
|
// 已登录 → 原地渲染 scan 页,不需任何跳转
|
2026-08-07 11:49:59 +08:00
|
|
|
|
|
|
|
|
|
|
// 🚀 OTA 热更新检测(仅 App 端生效)
|
|
|
|
|
|
// #ifdef APP-PLUS
|
|
|
|
|
|
this.checkUpdate();
|
|
|
|
|
|
// #endif
|
2026-08-07 11:44:20 +08:00
|
|
|
|
},
|
|
|
|
|
|
onShow() {
|
|
|
|
|
|
console.log("App 显示");
|
|
|
|
|
|
this.updateTabBarBadge();
|
2026-08-11 16:56:22 +08:00
|
|
|
|
// 🚀 每次回到前台也检查更新,用户无需杀后台就能感知新版本
|
|
|
|
|
|
// #ifdef APP-PLUS
|
|
|
|
|
|
this.checkUpdate();
|
|
|
|
|
|
// #endif
|
2026-08-07 11:44:20 +08:00
|
|
|
|
},
|
|
|
|
|
|
onHide() {
|
|
|
|
|
|
console.log("App 隐藏");
|
|
|
|
|
|
},
|
|
|
|
|
|
methods: {
|
2026-08-07 11:49:59 +08:00
|
|
|
|
// ==========================================================
|
2026-08-07 12:35:00 +08:00
|
|
|
|
// OTA 热更新雷达 — 版本检测 + WGT 下载 + 静默安装
|
2026-08-07 11:49:59 +08:00
|
|
|
|
// ==========================================================
|
|
|
|
|
|
checkUpdate() {
|
2026-08-11 16:56:22 +08:00
|
|
|
|
// 🚀 节流:5分钟内不重复检查,避免 onShow 频繁触发弹窗骚扰
|
|
|
|
|
|
const now = Date.now();
|
|
|
|
|
|
if (this._lastUpdateCheck && now - this._lastUpdateCheck < 5 * 60 * 1000) {
|
|
|
|
|
|
console.log("[OTA] 距上次检查不足5分钟,跳过");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
this._lastUpdateCheck = now;
|
|
|
|
|
|
|
2026-08-10 14:22:36 +08:00
|
|
|
|
// 🔧 appWgtVersion 跟随 WGT 更新,解析算法: major*100 + lastNum
|
|
|
|
|
|
// "T1.0.1"→101, "T1.0.10"→110, "T1.0.99"→199
|
|
|
|
|
|
const sysInfo = uni.getSystemInfoSync();
|
|
|
|
|
|
const wgtVer = sysInfo.appWgtVersion || sysInfo.appVersion || "0";
|
|
|
|
|
|
const currentVersionCode = this.parseVersionCode(wgtVer);
|
2026-08-07 14:45:30 +08:00
|
|
|
|
const baseUrl = uni.getStorageSync("env_base_url") || "http://track_back.iris-rs.cn/api/v1";
|
2026-08-07 11:49:59 +08:00
|
|
|
|
|
2026-08-10 14:22:36 +08:00
|
|
|
|
console.log("[OTA] 本地版本:", wgtVer, "→ 数字:", currentVersionCode);
|
2026-08-07 11:49:59 +08:00
|
|
|
|
|
|
|
|
|
|
uni.request({
|
2026-08-07 12:35:00 +08:00
|
|
|
|
url: `${baseUrl}/app/check-update`,
|
2026-08-07 11:49:59 +08:00
|
|
|
|
method: "GET",
|
|
|
|
|
|
timeout: 8000,
|
|
|
|
|
|
success: (res) => {
|
|
|
|
|
|
if (res.statusCode !== 200) return;
|
|
|
|
|
|
const data = res.data;
|
2026-08-07 12:35:00 +08:00
|
|
|
|
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] 已是最新版本,无需更新");
|
2026-08-07 11:49:59 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console.log("[OTA] 发现新版本:", data.version);
|
|
|
|
|
|
this.downloadAndInstall(data.wgt_url, data.version, data.description);
|
|
|
|
|
|
},
|
|
|
|
|
|
fail: () => {
|
|
|
|
|
|
console.log("[OTA] 版本检测网络失败,跳过");
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-08-10 14:22:36 +08:00
|
|
|
|
/** 版本号→数字: "T1.0.10" → 1*100+10 = 110 */
|
|
|
|
|
|
parseVersionCode(v) {
|
|
|
|
|
|
if (!v) return 0;
|
|
|
|
|
|
const nums = v.match(/\d+/g);
|
|
|
|
|
|
if (!nums || nums.length < 2) return 0;
|
|
|
|
|
|
return parseInt(nums[0], 10) * 100 + parseInt(nums[nums.length - 1], 10);
|
|
|
|
|
|
},
|
|
|
|
|
|
|
2026-08-07 11:49:59 +08:00
|
|
|
|
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;
|
|
|
|
|
|
|
2026-08-12 12:04:51 +08:00
|
|
|
|
// 🚀 静默更新:无进度条、无 toast、不监听 onProgressUpdate
|
|
|
|
|
|
uni.downloadFile({
|
2026-08-07 11:49:59 +08:00
|
|
|
|
url: wgtUrl,
|
|
|
|
|
|
success: (downloadRes) => {
|
|
|
|
|
|
if (downloadRes.statusCode !== 200) {
|
2026-08-12 12:04:51 +08:00
|
|
|
|
console.error("[OTA] 下载失败, statusCode:", downloadRes.statusCode);
|
2026-08-07 11:49:59 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
plus.runtime.install(
|
|
|
|
|
|
downloadRes.tempFilePath,
|
2026-08-07 13:55:24 +08:00
|
|
|
|
{ force: true },
|
2026-08-07 11:49:59 +08:00
|
|
|
|
() => {
|
2026-08-12 12:04:51 +08:00
|
|
|
|
console.log("[OTA] 安装成功,3秒后自动重启");
|
2026-08-11 16:53:35 +08:00
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
plus.runtime.restart();
|
2026-08-12 12:04:51 +08:00
|
|
|
|
}, 3000);
|
2026-08-07 11:49:59 +08:00
|
|
|
|
},
|
|
|
|
|
|
(err) => {
|
|
|
|
|
|
console.error("[OTA] 安装失败:", err.message);
|
|
|
|
|
|
}
|
|
|
|
|
|
);
|
|
|
|
|
|
},
|
|
|
|
|
|
fail: (err) => {
|
|
|
|
|
|
console.error("[OTA] 下载失败:", err.errMsg);
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// ==========================================================
|
|
|
|
|
|
// TabBar 消息红点
|
|
|
|
|
|
// ==========================================================
|
2026-08-07 11:44:20 +08:00
|
|
|
|
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;
|
2026-08-05 15:01:46 +08:00
|
|
|
|
|
2026-08-07 11:44:20 +08:00
|
|
|
|
const res = await getNotifications(userId, 0, 1);
|
|
|
|
|
|
const unreadCount = res.unread_count || 0;
|
2026-08-05 15:01:46 +08:00
|
|
|
|
|
2026-08-07 11:44:20 +08:00
|
|
|
|
if (unreadCount > 0) {
|
|
|
|
|
|
uni.setTabBarBadge({
|
|
|
|
|
|
index: 2,
|
|
|
|
|
|
text: unreadCount > 99 ? "99+" : String(unreadCount),
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
uni.removeTabBarBadge({ index: 2 });
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
// 静默失败
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
2026-08-05 15:01:46 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
|
page {
|
|
|
|
|
|
background-color: #f3f4f6;
|
|
|
|
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #1f2937;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|