Selaa lähdekoodia

✨ feat(app): 优先处理 APK 整包更新

- 增加 APK 更新数据及文件类型校验
- APK 和 WGT 同时存在时优先执行 APK 更新
- 修正 APK 更新使用原生应用版本进行比较
- 无 APK 更新时继续执行 WGT 热更新
Zimo 6 päivää sitten
vanhempi
commit
6ceef4e2ba
4 muutettua tiedostoa jossa 129 lisäystä ja 14 poistoa
  1. 22 2
      components/upgrade.vue
  2. 0 1
      config/env.dev.js
  3. 86 7
      utils/hot-update.js
  4. 21 4
      utils/upgrade.js

+ 22 - 2
components/upgrade.vue

@@ -59,8 +59,18 @@ import { getAppVersion } from "@/api/app.js";
 import { checkVersion, downloadApp, installApp } from "@/utils/upgrade.js";
 // 引用全局变量$t
 import { getCurrentInstance } from "vue";
-
-export default {
+
+const isApkPackageUrl = (url = "") => {
+  const normalizedUrl = String(url)
+    .trim()
+    .split("#")[0]
+    .split("?")[0]
+    .toLowerCase();
+
+  return normalizedUrl.endsWith(".apk");
+};
+
+export default {
   data() {
     return {
       isForceUpdate: true, //是否强制更新
@@ -168,6 +178,16 @@ export default {
     },
     async appCheckVersion() {
       const { data: remote } = await getAppVersion();
+
+      // 后端找不到 APK 时会返回 data: null,此时不需要整包更新。
+      if (!remote?.appVersion || !remote?.url) return;
+
+      // 整包更新入口只处理 APK,避免将 WGT 误送到 APK 安装流程。
+      if (!isApkPackageUrl(remote.url)) {
+        console.warn("[app-upgrade] 忽略非 APK 更新地址", remote.url);
+        return;
+      }
+
       const up = await checkVersion({
         name: remote.appVersion, //最新版本名称
         code: remote.appVersion, //最新版本号

+ 0 - 1
config/env.dev.js

@@ -1,7 +1,6 @@
 // 开发环境配置
 export default {
   apiUrl: "https://iot.deepoil.cc:5443",
-  // 本地组态预览服务;电脑局域网 IP 变化后需要同步更新
   webUrl: "https://iot.deepoil.cc:5443",
   // apiUrl: "http://192.168.188.86:48080",
   apiUrlSuffix: "/admin-api",

+ 86 - 7
utils/hot-update.js

@@ -40,6 +40,8 @@ const HOT_UPDATE_SKIP_VERSION_KEY = "__APP_WGT_HOT_UPDATE_SKIP_VERSION__";
  */
 const HOT_UPDATE_API_URL =
   config.default.apiUrl + config.default.apiUrlSuffix + "/rq/iot-app/newWgt";
+const APP_UPGRADE_API_URL =
+  config.default.apiUrl + config.default.apiUrlSuffix + "/rq/iot-app/new";
 
 /**
  * 读取当前进程的热更新运行状态。
@@ -193,6 +195,59 @@ const isWgtPackageUrl = (url = "") => {
   return normalizedUrl.endsWith(".wgt");
 };
 
+const isApkPackageUrl = (url = "") => {
+  const normalizedUrl = String(url)
+    .trim()
+    .split("#")[0]
+    .split("?")[0]
+    .toLowerCase();
+
+  return normalizedUrl.endsWith(".apk");
+};
+
+/**
+ * 启动时先检查整包更新。只有 Android 端存在比当前原生版本更新的 APK 时,
+ * 才中止 WGT 流程并通知原有整包升级组件。
+ */
+const requestAppUpgradeInfo = () => {
+  return new Promise((resolve, reject) => {
+    uni.request({
+      url: APP_UPGRADE_API_URL,
+      method: "GET",
+      header: {
+        "Content-Type": "application/json",
+        "tenant-id": "1",
+      },
+      timeout: 10000,
+      success: (response) => {
+        if (response.statusCode !== 200) {
+          reject(
+            new Error(
+              `整包更新检查接口请求失败,HTTP 状态码:${response.statusCode}`
+            )
+          );
+          return;
+        }
+
+        resolve(response.data || {});
+      },
+      fail: (error) => {
+        reject(new Error(error?.errMsg || "整包更新检查接口请求失败"));
+      },
+    });
+  });
+};
+
+const shouldPrioritizeAppUpgrade = (response, currentAppVersion) => {
+  const data = response?.code === 0 ? response?.data : null;
+
+  if (!data?.appVersion || !isApkPackageUrl(data.url)) {
+    return false;
+  }
+
+  return compareVersion(data.appVersion, currentAppVersion) > 0;
+};
+
 /**
  * 请求服务端检查是否存在新的 .wgt 资源包。
  *
@@ -567,13 +622,14 @@ const showHotUpdateError = (error, title = "更新失败") => {
  *
  * 整体执行顺序:
  * 1. 等待 plus 就绪
- * 2. 获取当前资源版本
- * 3. 请求服务端检查更新
- * 4. 判断是否存在新的 .wgt 包
- * 5. 提示用户确认
- * 6. 下载 .wgt
- * 7. 安装 .wgt
- * 8. 重启应用
+ * 2. Android 端先检查是否存在新的 APK
+ * 3. 没有 APK 更新时获取当前资源版本
+ * 4. 请求服务端检查 WGT 更新
+ * 5. 判断是否存在新的 .wgt 包
+ * 6. 提示用户确认
+ * 7. 下载 .wgt
+ * 8. 安装 .wgt
+ * 9. 重启应用
  *
  * 返回值:
  * - Promise<{ status: string, ... }>
@@ -588,6 +644,29 @@ const executeWgtHotUpdate = async () => {
     currentStage = "plus-ready";
     await waitForPlusReady();
 
+    if (uni.getSystemInfoSync().platform === "android") {
+      currentStage = "request-app-upgrade";
+      try {
+        const appUpgradeResponse = await requestAppUpgradeInfo();
+        if (
+          shouldPrioritizeAppUpgrade(
+            appUpgradeResponse,
+            plus.runtime.version
+          )
+        ) {
+          finalResult = {
+            status: "fallback-app-check-version",
+            message: "检测到新的 APK,优先执行整包更新",
+            data: appUpgradeResponse.data,
+          };
+          return finalResult;
+        }
+      } catch (error) {
+        // APK 检查失败时不阻断原有 WGT 更新能力。
+        console.warn("[hot-update] APK 更新检查失败,继续检查 WGT", error);
+      }
+    }
+
     currentStage = "read-local-version";
     const wgtInfo = await getCurrentWgtInfo();
 

+ 21 - 4
utils/upgrade.js

@@ -1,4 +1,22 @@
-import { getCurrentWgtInfo } from "./hot-update";
+const compareVersion = (a = "", b = "") => {
+  const aList = String(a)
+    .split(".")
+    .map((item) => Number(item || 0));
+  const bList = String(b)
+    .split(".")
+    .map((item) => Number(item || 0));
+  const length = Math.max(aList.length, bList.length);
+
+  for (let i = 0; i < length; i += 1) {
+    const aNum = aList[i] || 0;
+    const bNum = bList[i] || 0;
+
+    if (aNum > bNum) return 1;
+    if (aNum < bNum) return -1;
+  }
+
+  return 0;
+};
 
 /**
  * @description 检查app版本是否需要升级
@@ -15,9 +33,8 @@ export const checkVersion = async ({
   url, //下载链接
   forceUpdate, //是否强制升级
 }) => {
-  // const selfVersionCode = uni.getAppBaseInfo().appVersion;
-  const info = await getCurrentWgtInfo();
-  if (code > info.version) {
+  const currentAppVersion = plus.runtime.version;
+  if (compareVersion(code, currentAppVersion) > 0) {
     let platform = uni.getSystemInfoSync().platform; //手机平台
     if (platform === "android") {
       uni.$emit("upgrade-app", {