spring
昨天 eedf75ae97d84a90236e3a365a78266a21377873
fix: 版本管理80%
已添加1个文件
已修改6个文件
571 ■■■■ 文件已修改
src/api/viewIndex.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/config.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/manifest.json 276 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/login.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/works.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/versionUpgrade.js 220 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/viewIndex.js
@@ -100,6 +100,15 @@
    method: "get",
  });
};
// ç‰ˆæœ¬å‡çº§ï¼šæŸ¥è¯¢ç‰ˆæœ¬åˆ—表(取第一条最新数据)
export const getAllVersion = (params) => {
  return request({
    url: "/app/getAllVersion",
    method: "get",
    params,
  });
};
// è´¨æ£€åˆ†æžï¼ˆå¯ä¼  dateType: 1周 2月 3季度)
export const qualityStatistics = (params) => {
  return request({
src/config.js
@@ -6,8 +6,8 @@
   appInfo: {
     // åº”用名称
     name: "ruoyi-app-vue3",
     // åº”用版本
     version: "1.1.0",
    // åº”用版本(与 manifest.json çš„ versionName ä¿æŒä¸€è‡´ï¼‰
    version: "1.0.0",
     // åº”用logo
     logo: "/static/YGCY.png",
     // å®˜æ–¹ç½‘ç«™
src/manifest.json
@@ -1,143 +1,143 @@
{
    "name" : "信息管理",
    "appid" : "__UNI__1F1A548",
    "description" : "",
    "versionName" : "1.0.0",
    "versionCode" : "100",
    "transformPx" : false,
    /* 5+App特有相关 */
    "app-plus" : {
        "compatible" : {
            "usingComponents" : true,
            "ignoreVersion" : true
        },
        "usingComponents" : true,
        "nvueStyleCompiler" : "uni-app",
        "compilerVersion" : 3,
        "splashscreen" : {
            "alwaysShowBeforeRender" : true,
            "waiting" : true,
            "autoclose" : true,
            "delay" : 0
        },
        /* æ¨¡å—配置 */
        "modules" : {
            "Camera" : {},
            "Barcode" : {},
            "Push" : {},
            "Maps" : {}
        },
        /* åº”用发布信息 */
        "distribute" : {
            /* android打包配置 */
            "android" : {
                "permissions" : [
                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                    "<uses-feature android:name=\"android.hardware.camera\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_LOCATION_EXTRA_COMMANDS\"/>",
                    "<uses-feature android:name=\"android.hardware.location\"/>",
                    "<uses-feature android:name=\"android.hardware.location.gps\"/>",
                    "<uses-feature android:name=\"android.hardware.location.network\"/>"
                ]
            },
            /* ios打包配置 */
            "ios" : {
                "dSYMs" : false,
                "plist" : {
                    "NSLocationWhenInUseUsageDescription" : "需要获取您的位置信息来记录客户拜访地点",
                    "NSLocationAlwaysAndWhenInUseUsageDescription" : "需要获取您的位置信息来记录客户拜访地点"
                }
            },
            /* SDK配置 */
            "sdkConfigs" : {
                "push" : {
                    "unipush" : {
                        "icons" : {
                            "small" : {
                                "ldpi" : "D:/xindao/wenjian/img/logo/app.png"
                            }
                        },
                        "offline" : false
                    }
                },
                "maps" : {
                    "amap" : {
                        "name" : "amap_18330707920ae9zOwCD",
                        "appkey_ios" : "c2b4e3889ab4cb9468e9c8ae4f3ab53f",
                        "appkey_android" : "c2b4e3889ab4cb9468e9c8ae4f3ab53f"
                    }
                }
            },
            "icons" : {
                "android" : {
                    "hdpi" : "unpackage/res/icons/72x72.png",
                    "xhdpi" : "unpackage/res/icons/96x96.png",
                    "xxhdpi" : "unpackage/res/icons/144x144.png",
                    "xxxhdpi" : "unpackage/res/icons/192x192.png"
                },
                "ios" : {
                    "appstore" : "unpackage/res/icons/1024x1024.png",
                    "ipad" : {
                        "app" : "unpackage/res/icons/76x76.png",
                        "app@2x" : "unpackage/res/icons/152x152.png",
                        "notification" : "unpackage/res/icons/20x20.png",
                        "notification@2x" : "unpackage/res/icons/40x40.png",
                        "proapp@2x" : "unpackage/res/icons/167x167.png",
                        "settings" : "unpackage/res/icons/29x29.png",
                        "settings@2x" : "unpackage/res/icons/58x58.png",
                        "spotlight" : "unpackage/res/icons/40x40.png",
                        "spotlight@2x" : "unpackage/res/icons/80x80.png"
                    },
                    "iphone" : {
                        "app@2x" : "unpackage/res/icons/120x120.png",
                        "app@3x" : "unpackage/res/icons/180x180.png",
                        "notification@2x" : "unpackage/res/icons/40x40.png",
                        "notification@3x" : "unpackage/res/icons/60x60.png",
                        "settings@2x" : "unpackage/res/icons/58x58.png",
                        "settings@3x" : "unpackage/res/icons/87x87.png",
                        "spotlight@2x" : "unpackage/res/icons/80x80.png",
                        "spotlight@3x" : "unpackage/res/icons/120x120.png"
                    }
                }
            }
  "name": "信息管理",
  "appid": "__UNI__1F1A548",
  "description": "",
  "versionName": "1.0.0",
  "versionCode": 100,
  "transformPx": false,
  /* 5+App特有相关 */
  "app-plus": {
    "compatible": {
      "usingComponents": true,
      "ignoreVersion": true
    },
    "usingComponents": true,
    "nvueStyleCompiler": "uni-app",
    "compilerVersion": 3,
    "splashscreen": {
      "alwaysShowBeforeRender": true,
      "waiting": true,
      "autoclose": true,
      "delay": 0
    },
    /* æ¨¡å—配置 */
    "modules": {
      "Camera": {},
      "Barcode": {},
      "Push": {},
      "Maps": {}
    },
    /* åº”用发布信息 */
    "distribute": {
      /* android打包配置 */
      "android": {
        "permissions": [
          "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
          "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
          "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
          "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
          "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
          "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
          "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
          "<uses-permission android:name=\"android.permission.CAMERA\"/>",
          "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
          "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
          "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
          "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
          "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
          "<uses-feature android:name=\"android.hardware.camera\"/>",
          "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
          "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
          "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
          "<uses-permission android:name=\"android.permission.ACCESS_LOCATION_EXTRA_COMMANDS\"/>",
          "<uses-feature android:name=\"android.hardware.location\"/>",
          "<uses-feature android:name=\"android.hardware.location.gps\"/>",
          "<uses-feature android:name=\"android.hardware.location.network\"/>"
        ]
      },
      /* ios打包配置 */
      "ios": {
        "dSYMs": false,
        "plist": {
          "NSLocationWhenInUseUsageDescription": "需要获取您的位置信息来记录客户拜访地点",
          "NSLocationAlwaysAndWhenInUseUsageDescription": "需要获取您的位置信息来记录客户拜访地点"
        }
    },
    /* å¿«åº”用特有相关 */
    "quickapp" : {},
    /* å°ç¨‹åºç‰¹æœ‰ç›¸å…³ */
    "mp-weixin" : {
        "appid" : "",
        "setting" : {
            "urlCheck" : false
      },
      /* SDK配置 */
      "sdkConfigs": {
        "push": {
          "unipush": {
            "icons": {
              "small": {
                "ldpi": "D:/xindao/wenjian/img/logo/app.png"
              }
            },
            "offline": false
          }
        },
        "usingComponents" : true
        "maps": {
          "amap": {
            "name": "amap_18330707920ae9zOwCD",
            "appkey_ios": "c2b4e3889ab4cb9468e9c8ae4f3ab53f",
            "appkey_android": "c2b4e3889ab4cb9468e9c8ae4f3ab53f"
          }
        }
      },
      "icons": {
        "android": {
          "hdpi": "unpackage/res/icons/72x72.png",
          "xhdpi": "unpackage/res/icons/96x96.png",
          "xxhdpi": "unpackage/res/icons/144x144.png",
          "xxxhdpi": "unpackage/res/icons/192x192.png"
        },
        "ios": {
          "appstore": "unpackage/res/icons/1024x1024.png",
          "ipad": {
            "app": "unpackage/res/icons/76x76.png",
            "app@2x": "unpackage/res/icons/152x152.png",
            "notification": "unpackage/res/icons/20x20.png",
            "notification@2x": "unpackage/res/icons/40x40.png",
            "proapp@2x": "unpackage/res/icons/167x167.png",
            "settings": "unpackage/res/icons/29x29.png",
            "settings@2x": "unpackage/res/icons/58x58.png",
            "spotlight": "unpackage/res/icons/40x40.png",
            "spotlight@2x": "unpackage/res/icons/80x80.png"
          },
          "iphone": {
            "app@2x": "unpackage/res/icons/120x120.png",
            "app@3x": "unpackage/res/icons/180x180.png",
            "notification@2x": "unpackage/res/icons/40x40.png",
            "notification@3x": "unpackage/res/icons/60x60.png",
            "settings@2x": "unpackage/res/icons/58x58.png",
            "settings@3x": "unpackage/res/icons/87x87.png",
            "spotlight@2x": "unpackage/res/icons/80x80.png",
            "spotlight@3x": "unpackage/res/icons/120x120.png"
          }
        }
      }
    }
  },
  /* å¿«åº”用特有相关 */
  "quickapp": {},
  /* å°ç¨‹åºç‰¹æœ‰ç›¸å…³ */
  "mp-weixin": {
    "appid": "",
    "setting": {
      "urlCheck": false
    },
    "mp-alipay" : {
        "usingComponents" : true
    },
    "mp-baidu" : {
        "usingComponents" : true
    },
    "mp-toutiao" : {
        "usingComponents" : true
    },
    "uniStatistics" : {
        "enable" : false
    },
    "vueVersion" : "3"
    "usingComponents": true
  },
  "mp-alipay": {
    "usingComponents": true
  },
  "mp-baidu": {
    "usingComponents": true
  },
  "mp-toutiao": {
    "usingComponents": true
  },
  "uniStatistics": {
    "enable": false
  },
  "vueVersion": "3"
}
src/pages/index.vue
@@ -202,7 +202,9 @@
<script setup>
import { computed, onMounted, ref } from "vue";
import { onShow } from "@dcloudio/uni-app";
import { analysisCustomerContractAmounts, getBusiness } from "@/api/viewIndex";
import { createVersionUpgradeChecker } from "@/utils/versionUpgrade";
const imgNum1 = "/static/images/index/num1.png";
const imgNum2 = "/static/images/index/num2.png";
@@ -240,6 +242,8 @@
const contractSummary = ref({ sum: "0", chain: "0", yny: "0" });
// å®¢æˆ·åˆåŒé‡‘额分析:无需筛选项(按接口默认返回展示)
const { triggerVersionCheck } = createVersionUpgradeChecker({ logPrefix: "[version-index]" });
function toggleOverview() {
  overviewExpanded.value = !overviewExpanded.value;
@@ -465,8 +469,13 @@
  } catch (e) {
    isCanvas2d.value = false;
  }
  triggerVersionCheck("onMounted");
  loadHome();
});
onShow(() => {
  triggerVersionCheck("onShow");
});
</script>
<style scoped lang="scss">
src/pages/login.vue
@@ -37,6 +37,9 @@
      </up-checkbox>
    </view>
  </view>
  <view class="version-wrap">
    <text class="version-text">版本号:{{ versionName }}</text>
  </view>
</template>
<script setup>
@@ -59,9 +62,11 @@
  import { wxLogin } from "@/api/oauth";
  import { setToken } from "@/utils/auth";
  import View from "@/pages/procurementManagement/procurementLedger/view.vue";
  import config from "@/config";
  const userStore = useUserStore();
  const useWxLogin = ref(false); // æ˜¯å¦ä½¿ç”¨å¾®ä¿¡ç™»å½•
  const rememberPassword = ref(false); // è®°ä½å¯†ç 
  const versionName = ref(config?.appInfo?.version || "1.0.0");
  const loginForm = ref({
    userName: "",
    password: "",
@@ -243,6 +248,35 @@
  }
  // é¡µé¢åŠ è½½æ—¶æ£€æŸ¥æ˜¯å¦æœ‰ä¿å­˜çš„å¯†ç 
  onMounted(() => {
    console.log("[login-version] å¼€å§‹èŽ·å–ç™»å½•é¡µç‰ˆæœ¬ï¼Œé»˜è®¤å€¼:", versionName.value);
    // #ifdef MP-WEIXIN
    try {
      const accountInfo = uni.getAccountInfoSync();
      if (accountInfo?.miniProgram?.version) {
        versionName.value = accountInfo.miniProgram.version;
        console.log("[login-version] å½“前环境=MP-WEIXIN,版本=", versionName.value);
      }
    } catch (e) {
      // èŽ·å–å¤±è´¥æ—¶ä½¿ç”¨é»˜è®¤å€¼
      console.log("[login-version] MP-WEIXIN èŽ·å–ç‰ˆæœ¬å¤±è´¥:", e);
    }
    // #endif
    // #ifdef APP-PLUS
    try {
      // @ts-ignore
      if (plus?.runtime?.version) {
        // @ts-ignore
        versionName.value = plus.runtime.version;
        console.log("[login-version] å½“前环境=APP-PLUS,版本=", versionName.value);
      }
    } catch (e) {
      // èŽ·å–å¤±è´¥æ—¶ä½¿ç”¨é»˜è®¤å€¼
      console.log("[login-version] APP-PLUS èŽ·å–ç‰ˆæœ¬å¤±è´¥:", e);
    }
    // #endif
    console.log("[login-version] æœ€ç»ˆç‰ˆæœ¬å·:", versionName.value);
    loadPassword();
    getUserLoginFacotryList();
  });
@@ -346,4 +380,15 @@
      }
    }
  }
  .version-wrap {
    width: 100%;
    text-align: center;
    margin-top: 20px;
  }
  .version-text {
    font-size: 12px;
    color: #999;
  }
</style>
src/pages/works.vue
@@ -269,12 +269,15 @@
<script setup>
  import { ref, onMounted, nextTick, reactive, computed } from "vue";
  import { onShow } from "@dcloudio/uni-app";
  import { userLoginFacotryList } from "@/api/login";
  import { getProductWorkOrderById } from "@/api/productionManagement/productionReporting";
  import { createVersionUpgradeChecker } from "@/utils/versionUpgrade";
  import modal from "@/plugins/modal";
  import useUserStore from "@/store/modules/user";
  const userStore = useUserStore();
  const { triggerVersionCheck } = createVersionUpgradeChecker({ logPrefix: "[version-works]" });
  const show = ref(false);
  const factoryList = ref([]);
  const factoryListTem = ref([]);
@@ -1131,6 +1134,7 @@
  const hasEquipmentItems = computed(() => equipmentItems.length > 0);
  onMounted(() => {
    triggerVersionCheck("onMounted");
    // æ¯æ¬¡è¿›å…¥é¦–页都强制刷新用户信息和路由权限,不做本地缓存判断
    userStore.getInfo().then(() => {
      userStore
@@ -1146,6 +1150,10 @@
    // å¯åŠ¨é€šçŸ¥çŠ¶æ€å®šæ—¶å™¨
    startStatusTimer();
  });
  onShow(() => {
    triggerVersionCheck("onShow");
  });
</script>
src/utils/versionUpgrade.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,220 @@
import config from "@/config";
import { getAllVersion } from "@/api/viewIndex";
function compareVersion(v1, v2) {
  const s1 = String(v1 || "").replace(/[^\d.]/g, "").split(".").map((n) => Number(n) || 0);
  const s2 = String(v2 || "").replace(/[^\d.]/g, "").split(".").map((n) => Number(n) || 0);
  const len = Math.max(s1.length, s2.length);
  for (let i = 0; i < len; i += 1) {
    const n1 = s1[i] || 0;
    const n2 = s2[i] || 0;
    if (n1 > n2) return 1;
    if (n1 < n2) return -1;
  }
  return 0;
}
function formatFileSize(fileSize) {
  const size = Number(fileSize);
  if (!Number.isFinite(size) || size <= 0) return "";
  if (size >= 1024 * 1024 * 1024) return `${(size / (1024 * 1024 * 1024)).toFixed(2)}GB`;
  if (size >= 1024 * 1024) return `${(size / (1024 * 1024)).toFixed(2)}MB`;
  if (size >= 1024) return `${(size / 1024).toFixed(2)}KB`;
  return `${size}B`;
}
function getCurrentVersion(logPrefix) {
  let currentVersion = config?.appInfo?.version || "1.0.0";
  console.log(`${logPrefix} å¼€å§‹èŽ·å–å½“å‰ç‰ˆæœ¬ï¼Œé»˜è®¤å€¼:`, currentVersion);
  // #ifdef MP-WEIXIN
  try {
    const accountInfo = uni.getAccountInfoSync();
    if (accountInfo?.miniProgram?.version) {
      currentVersion = accountInfo.miniProgram.version;
      console.log(`${logPrefix} å½“前环境=MP-WEIXIN,版本=`, currentVersion);
      return currentVersion;
    }
  } catch (e) {
    console.log(`${logPrefix} MP-WEIXIN èŽ·å–ç‰ˆæœ¬å¤±è´¥:`, e);
  }
  // #endif
  // #ifdef APP-PLUS
  try {
    // @ts-ignore
    if (plus?.runtime?.version) {
      // @ts-ignore
      currentVersion = plus.runtime.version;
      console.log(`${logPrefix} å½“前环境=APP-PLUS,版本=`, currentVersion);
      return currentVersion;
    }
  } catch (e) {
    console.log(`${logPrefix} APP-PLUS èŽ·å–ç‰ˆæœ¬å¤±è´¥:`, e);
  }
  // #endif
  console.log(`${logPrefix} æœªè¯»å–到运行时版本,使用配置版本:`, currentVersion);
  return currentVersion;
}
function installPackage(tempFilePath, logPrefix) {
  console.log(`${logPrefix} å¼€å§‹å®‰è£…更新包,临时路径:`, tempFilePath);
  // #ifdef APP-PLUS
  // @ts-ignore
  plus.runtime.install(
    tempFilePath,
    {},
    () => {
      console.log(`${logPrefix} å®‰è£…成功,等待用户确认是否重启`);
      uni.showModal({
        title: "更新完成",
        content: "安装包下载成功,是否立即重启应用生效?",
        success: (res) => {
          if (res.confirm) {
            // @ts-ignore
            plus.runtime.restart();
          }
        },
      });
    },
    (err) => {
      console.log(`${logPrefix} å®‰è£…失败:`, err);
      uni.showToast({ title: err?.message || "安装更新包失败", icon: "none" });
    }
  );
  // #endif
}
function downloadVersionPackage(url, logPrefix) {
  console.log(`${logPrefix} å¼€å§‹ä¸‹è½½æ›´æ–°åŒ…:`, url);
  uni.showLoading({ title: "更新包下载中..." });
  uni.downloadFile({
    url,
    success: (res) => {
      console.log(`${logPrefix} ä¸‹è½½ç»“æžœ:`, res);
      uni.hideLoading();
      if (res.statusCode !== 200 || !res.tempFilePath) {
        console.log(`${logPrefix} ä¸‹è½½å¤±è´¥ï¼ŒçŠ¶æ€ç æˆ–ä¸´æ—¶è·¯å¾„å¼‚å¸¸`);
        uni.showToast({ title: "下载失败,请稍后重试", icon: "none" });
        return;
      }
      const lowerUrl = String(url || "").toLowerCase();
      const isInstallPkg = lowerUrl.endsWith(".wgt") || lowerUrl.endsWith(".wgtu") || lowerUrl.endsWith(".apk");
      console.log(`${logPrefix} æ–‡ä»¶ç±»åž‹åˆ¤æ–­:`, { lowerUrl, isInstallPkg });
      if (isInstallPkg) {
        installPackage(res.tempFilePath, logPrefix);
        return;
      }
      uni.openDocument({
        filePath: res.tempFilePath,
        showMenu: true,
        fail: () => {
          console.log(`${logPrefix} éžå®‰è£…包,openDocument å¤±è´¥ï¼Œæç¤ºç”¨æˆ·æ‰‹åŠ¨æŸ¥çœ‹`);
          uni.showToast({ title: "下载成功,请在文件管理中查看", icon: "none" });
        },
      });
    },
    fail: (err) => {
      console.log(`${logPrefix} ä¸‹è½½è¯·æ±‚失败:`, err);
      uni.hideLoading();
      uni.showToast({ title: "下载失败,请检查网络", icon: "none" });
    },
  });
}
async function checkAppVersionUpgrade(logPrefix, currentVersion) {
  try {
    console.log(`${logPrefix} å¼€å§‹æ£€æŸ¥ç‰ˆæœ¬å‡çº§`);
    const params = {
      records: "",
      total: 1,
      size: 1,
      current: 1,
      orders: "",
      optimizeCountSql: true,
      searchCount: true,
      optimizeJoinOfCountSql: true,
      maxLimit: 1,
      countId: "",
      id: 1,
      name: "",
      version: "",
      createTime: "2026-04-09 10:10:33",
      updateTime: "2026-04-09 10:10:33",
      createUser: 1,
      updateUser: 1,
      tenantId: 1,
    };
    console.log(`${logPrefix} æŸ¥è¯¢å‚æ•°:`, params);
    const res = await getAllVersion(params);
    console.log(`${logPrefix} æŽ¥å£è¿”回:`, res);
    const first = Array.isArray(res?.rows)
      ? res.rows[0]
      : Array.isArray(res?.data?.records)
        ? res.data.records[0]
        : Array.isArray(res?.data)
          ? res.data[0]
          : res?.data;
    if (!first) {
      console.log(`${logPrefix} æœªèŽ·å–åˆ°ç¬¬ä¸€æ¡ç‰ˆæœ¬æ•°æ®ï¼Œç»“æŸæ£€æŸ¥`);
      return;
    }
    console.log(`${logPrefix} ç¬¬ä¸€æ¡ç‰ˆæœ¬æ•°æ®:`, first);
    const latestVersion = String(first?.version || "");
    if (!latestVersion) {
      console.log(`${logPrefix} ç¬¬ä¸€æ¡æ•°æ®æ— ç‰ˆæœ¬å·ï¼Œç»“束检查`);
      return;
    }
    const compareResult = compareVersion(latestVersion, currentVersion);
    console.log(`${logPrefix} ç‰ˆæœ¬æ¯”较:`, { currentVersion, latestVersion, compareResult });
    if (compareResult <= 0) {
      console.log(`${logPrefix} å½“前已是最新版本,无需更新`);
      return;
    }
    const firstFile = Array.isArray(first?.commonFileList) ? first.commonFileList[0] : null;
    const downloadUrl = firstFile?.url || "";
    const fileSizeText = formatFileSize(firstFile?.fileSize);
    console.log(`${logPrefix} æ›´æ–°é™„件信息:`, {
      downloadUrl,
      fileSize: firstFile?.fileSize,
      fileSizeText,
      firstFile,
    });
    const desc = fileSizeText ? `,更新包大小约 ${fileSizeText}` : "";
    uni.showModal({
      title: "发现新版本",
      content: `当前版本 ${currentVersion},最新版本 ${latestVersion}${desc},是否立即下载?`,
      confirmText: "立即下载",
      success: (modalRes) => {
        console.log(`${logPrefix} æ›´æ–°å¼¹çª—操作:`, modalRes);
        if (!modalRes.confirm) return;
        if (!downloadUrl) {
          console.log(`${logPrefix} ç”¨æˆ·ç¡®è®¤æ›´æ–°ï¼Œä½†é™„件地址为空`);
          uni.showToast({ title: "未找到更新附件地址", icon: "none" });
          return;
        }
        downloadVersionPackage(downloadUrl, logPrefix);
      },
    });
  } catch (e) {
    console.log(`${logPrefix} ç‰ˆæœ¬æ£€æŸ¥å¤±è´¥:`, e);
  }
}
export function createVersionUpgradeChecker(options = {}) {
  const throttleMs = Number(options.throttleMs) > 0 ? Number(options.throttleMs) : 3000;
  const logPrefix = options.logPrefix || "[version]";
  let lastVersionCheckAt = 0;
  const triggerVersionCheck = (from = "unknown") => {
    const now = Date.now();
    if (now - lastVersionCheckAt < throttleMs) {
      console.log(`${logPrefix} è·³è¿‡é‡å¤æ£€æŸ¥ï¼Œæ¥æº=${from}`);
      return;
    }
    lastVersionCheckAt = now;
    console.log(`${logPrefix} è§¦å‘版本检查,来源=${from}`);
    const currentVersion = getCurrentVersion(logPrefix);
    checkAppVersionUpgrade(logPrefix, currentVersion);
  };
  return { triggerVersionCheck };
}