uni项目app版本强制更新

147 阅读2分钟

前言

emmmm,别说这个功能容易被下架,叫我做我就做咯

实现细节

1 对比版本工具函数

utils/index.js

/**
 * 对比版本号
 * 支持比对	("3.0.0.0.0.1.0.1", "3.0.0.0.0.1")	("3.0.0.1", "3.0")	("3.1.1", "3.1.1.1") 之类的
 * @param {Object} v1
 * @param {Object} v2
 * v1 > v2 return 1
 * v1 < v2 return -1
 * v1 == v2 return 0
 */
export const compare = (v1 = '0', v2 = '0') => {
    v1 = String(v1).split('.');
    v2 = String(v2).split('.');
    const minVersionLens = Math.min(v1.length, v2.length);

    let result = 0;

    for (let i = 0; i < minVersionLens; i++) {
        const curV1 = Number(v1[i]);
        const curV2 = Number(v2[i]);

        if (curV1 > curV2) {
            result = 1;
            break;
        } else if (curV1 < curV2) {
            result = -1;
            break;
        }
    }

    if (result === 0 && v1.length !== v2.length) {
        const v1BiggerThenv2 = v1.length > v2.length;
        const maxLensVersion = v1BiggerThenv2 ? v1 : v2;

        for (let i = minVersionLens; i < maxLensVersion.length; i++) {
            const curVersion = Number(maxLensVersion[i]);

            if (curVersion > 0) {
                v1BiggerThenv2 ? result = 1 : result = -1;
                break;
            }
        }
    }

    return result;
};

2 app.vue中检查对比版本

<script>
import { compare } from '@/utils/index';
import { getApkNewVersion } from '@/api/user/index.js';
export default {
    mpType: 'app',
    async onShow () {
        // #ifdef APP-PLUS
        // 检查更新
        // 本地版本
        let localVersion;
        plus.runtime.getProperty(plus.runtime.appid, function (widgetInfo) {
            localVersion = widgetInfo.version;
        });
        // 服务端版本
        let upgradeInfo;
        let res = await getApkNewVersion();
        if (res.code == 1000) {
            upgradeInfo = res.data;
        }
        // 当前是否存在返回值
        if (upgradeInfo.hasOwnProperty('version')) {
            // 版本对比(1 本地版本大于服务端版本 -1 本地版本小于服务端版本 0 版本相同)
            const result = compare(localVersion, upgradeInfo.version);
            // 仅为-1时更新 本API仅App支持。小程序自身不支持自定义动画

            uni.setStorageSync('upgradeInfo_key', JSON.stringify(upgradeInfo));
            if (result == -1) {
                uni.navigateTo({
                    url: '/components/updateVersion/upgrade-popup'
                });
            }
        }
        // #endif
    },
};
</script>

3 更新弹框

/components/updateVersion/upgrade-popup

(1)在pages.json 注册

{
	"pages": [
		    {
			"path": "components/updateVersion/upgrade-popup",
			"style": {
				"disableScroll": true,
				"app-plus": {
					"backgroundColorTop": "transparent",
					"background": "transparent",
					"titleNView": false,
					"scrollIndicator": false,
					"popGesture": "none",
					"animationType": "fade-in",
					"animationDuration": 200
				}
			}
		}
	]
}

(2)更新弹框详细代码

export default {
  data() {
    return {
      upgradeInfo: null,
      token: null,
      downloading: false, // 是否显示下载进度
      downLoadPercent: 0, // 百分比0~100
      downloadedSize: 0, // 下载大小
      packageFileSize: 0, // 包大小
      downLoadingText: '安装包下载中,请稍后',
      downloadSuccess: false, // 是否下载成功
    }
  },
  // 触发返回调用
  onBackPress(options) {
    // 禁止物理返回和强制返回
    if (options.from == 'backbutton') {
      return true;
    } else {
      return false;
    }
  },
  created() {
    this.upgradeInfo = JSON.parse(uni.getStorageSync('upgradeInfo_key'));
    this.token = uni.getStorageSync('token') || null;
  },
  methods: {
    // 更新途径(应用商店)上架后更新
    updateApproach() {
      // #ifdef APP-PLUS
      if (uni.getSystemInfoSync().platform == 'ios') {
        // ios 跳转app Store 更新
        uni.showToast({
          title: 'ios 跳转app Store 更新',
          duration: 2000,
          icon: 'none',
        });
        // let appleId = '1665045016' // 暂无 
        // plus.runtime.launchApplication({
        //   action: `itms-apps://itunes.apple.com/cn/app/id${appleId}?mt=8`
        // });
      } else if (uni.getSystemInfoSync().platform == 'android') {
        uni.showToast({
          title: '跳转安卓应用市场',
          duration: 2000,
          icon: 'none',
        });
        // 跳转安卓应用市场
        //这个是通用应用市场,如果想指定某个应用商店,需要单独查这个应用商店的包名或scheme及参数
        let appurl = "market://details?id=com.tencent.mm"
        plus.runtime.openURL(appurl)
      }
      // #endif
    },
    // 安卓直接下载更新
    downloadPackage() {
      // #ifdef APP-PLUS
      if (uni.getSystemInfoSync().platform == 'android') {
        // 仅在安卓环境执行更新操作
        this.downloading = true;
        //下载包
        downloadTask = uni.downloadFile({
          url: this.upgradeInfo.androidUrl,
          success: res => {
            // 下载完成
            if (res.statusCode == 200) {
              this.downloadSuccess = true;
              this.tempFilePath = res.tempFilePath
              // 强制更新,直接安装
              this.installPackage();
            }
          },
          complete: () => {
            // 下载完毕进度条初始化
            this.downLoadPercent = 0
            this.downloadedSize = 0
            this.packageFileSize = 0
            downloadTask = null;
          }
        });
        // 下载进度条
        downloadTask.onProgressUpdate(res => {
          this.downLoadPercent = res.progress;
          this.downloadedSize = (res.totalBytesWritten / Math.pow(1024, 2)).toFixed(2);
          this.packageFileSize = (res.totalBytesExpectedToWrite / Math.pow(1024, 2)).toFixed(2);
        });
      } else {
        // ios 应用商店更新
        this.updateApproach();
        // uni.showToast({
        //   title: '请在应用商店更新',
        //   duration: 2000,
        //   icon: 'none',
        // });
        // 判断 跳转 login 还是 home
        if (this.token) {
          uni.switchTab({ url: '/pages/workbench/index' });
        } else {
          uni.reLaunch({ url: '/pages/login/login' });
        }

      }
      // #endif
    },
    // 下载安装
    installPackage() {
      // #ifdef APP-PLUS

      // 先暂时只考虑整包更新的情况,后期加入wgt资源包更新
      plus.runtime.install(this.tempFilePath, {
        force: false
      }, async res => {
        plus.nativeUI.toast('最新版本下载完成')
        // 安装成功之后关闭应用重启app
        uni.showLoading({
          icon: 'none',
          title: '安装成功,正在重启……'
        })
        setTimeout(() => {
          uni.hideLoading();
          this.restart();
        }, 1000)
      }, async err => {
        this.downloading = false;
        uni.showModal({
          title: '更新失败,请重新下载',
          content: err.message,
          showCancel: false
        });
      });

      // #endif
    },
    // 重启APP
    restart() {
      // #ifdef APP-PLUS
      plus.runtime.restart();
      // #endif
    },

  }
}
</script>