202 lines
6.5 KiB
Vue
202 lines
6.5 KiB
Vue
<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>
|