app更新

2022-11-30  本文已影响0人  白衣诗人

uniapp自动更新

本文只讲述Android的更新。静默更新,市场更新,静默下载等都可参照思路发挥。

配置更新页面路由

pages.json 配置更新弹出层,注意它不能在第一个,path为你自己的路径

"pages":[
  //其他页面
         {
            "path": "pages/upgrade/index",
            "style": {
                "disableScroll": true,
                "app-plus": {
                    "backgroundColorTop": "transparent",
                    "background": "transparent",
                    "titleNView": false,
                    "scrollIndicator": false,
                    "popGesture": "none",
                    "animationType": "fade-in",
                    "animationDuration": 200
    
                }
            }
        }
]

配置更新的js

store,request,引入。API和uni.request的封装自行封装。不喜欢封装也可以直接替换request.getAppUpdate()

import Store from '@/store/index.js'
import request from '@/requset/api.js'
/**
 * 检查版本是否存在更新
 */

const update = () => {
    request.getAppUpdate().then(res => {
        // #ifdef APP-PLUS
        plus.runtime.getProperty(plus.runtime.appid, (info) => {
            if(info.versionCode < res.data.version_code){
                Store.commit('setAppUploadInfo', res.data)
                uni.navigateTo({
                    url: `/pages/upgrade/index`,
                    fail: (err) => {
                        console.error('更新弹框跳转失败', err)
                    }
                })
            }
        }) 
        // #endif
    }).catch(err => {
        
    })
}

export default {
    update
}

更新页面和交互

<template>
    <view class="mask">
        <view class="mask-content">
            <view class="top">
                <image src="/static/bg_top.png" mode="widthFix"></image>
                <view class="text">版本更新</view>
            </view>
            <view class="mask-body">
                <view class="content">
                    <view class="title">{{title}}</view>
                    <view class="desc" v-if="$store.state.appUploadInfo && $store.state.appUploadInfo.explain">{{$store.state.appUploadInfo.explain}}</view>
                </view>
                <view class="mask-foor">
                    <template v-if="!downloadSuccess">
                        <view class="btn" v-if="!downloading" @click="updateApp">立即下载更新</view>
                        <view class="progress-box flex-column" v-if="downloading">
                            <progress class="progress" border-radius="6" :percent="downLoadPercent"
                                activeColor="#3DA7FF" show-info stroke-width="6" />
                            <view style="width:100%;font-size: 28rpx;display: flex;justify-content: space-around;">
                                <text>{{downLoadingText}}</text>
                                <text>({{downloadedSize}}/{{packageFileSize}}M)</text>
                            </view>
                        </view>
                    </template>
                    <template v-else>
                        <view class="btn" v-if="installed" @click="restart">安装完毕,点击重启</view>
                        <button class="btn" style="border: none;color: #fff;" plain :loading="installing" :disabled="installing" @click="installPackage" v-else>{{installing ? '正在安装……' : '下载完成,立即安装'}}</button>
                    </template>
                </view>
            </view>
            <image class="close-img" src="/static/app_update_close.png" @click.stop="closeUpdate" mode="aspectFit"></image>
        </view>
    </view>
</template>

<script>
    
    let downloadTask = null;
    export default {
        data() {
            return {
                title:"发现新版本!", //标题
                content:'更新了',//更新说明
                downloading:false, //是否处于下载中
                downLoadPercent:20, //进度条比例
                downLoadingText: '安装包下载中,请稍后', //提示语
                packageFileSize:50, //下载包的大小
                downloadedSize:20, //下载大小
                downloadSuccess:false,//是否下载完成
                installing:false,//是否处于安装中
                tempFilePath: '', // 要安装的本地包地址
            }
        },
        onBackPress() {
            // 强制更新不允许返回
            if (this.$store.state.appUploadInfo && this.$store.state.appUploadInfo.is_force) {
                return true
            }
        
            downloadTask && downloadTask.abort()
        },
        methods: {
            /**
             * 检测是否存在安装包
             */
            checkLocalStoragePackage(){
                
            },
            /**
             * 点击下载安装包
             */
            updateApp(){
                this.downloadPackage()
            },
            
            /**
             * 下载安装包
             */
            downloadPackage(){
                const _this = this;
                //设置下载状态
                _this.downloading = true;
                //下载包
                downloadTask = uni.downloadFile({
                    url:_this.$store.state.appUploadInfo.package_url,
                    success:(res) => {
                        if (res.statusCode == 200) {
                            this.downloadSuccess = true;
                            this.tempFilePath = res.tempFilePath
                        
                            // 强制更新,直接安装
                            if (this.$store.state.appUploadInfo.is_force) {
                                this.installPackage();
                            }
                        }
                    },
                    complete: () => {
                        this.downloading = false;
                    
                        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);
                });
            },
            /**
             * 安装app
             */
            installPackage(){
                const _this = this;
                this.installing = true;
                // #ifdef APP-PLUS
                plus.runtime.install(this.tempFilePath, {
                    force: false
                }, async res => {
                    this.installing = false;
                    this.installed = true;
                    if (this.$store.state.appUploadInfo.is_force) {
                        uni.showLoading({
                            icon: 'none',
                            title: '安装成功,正在重启……'
                        })
                                    
                        setTimeout(() => {
                            uni.hideLoading()
                            this.restart();
                        }, 1000)
                    }
                }, async err => {
                    // 如果是安装之前的包,安装失败后删除之前的包
                    if (this.installForBeforeFilePath) {
                        await this.deleteSavedFile(this.installForBeforeFilePath)
                        this.installForBeforeFilePath = '';
                    }
                
                    // 安装失败需要重新下载安装包
                    this.installing = false;
                    this.installed = false;
                
                    uni.showModal({
                        title: '更新失败,请重新下载',
                        content: err.message,
                        showCancel: false
                    });
                });
                // #endif
            },
            async closeUpdate() {
                if (this.downloading) {
                    if (this.$store.state.appUploadInfo.is_force) {
                        return uni.showToast({
                            title: '下载中,请稍后……',
                            icon: 'none',
                            duration: 500
                        })
                    }
                    uni.showModal({
                        title: '是否取消下载?',
                        cancelText: '否',
                        confirmText: '是',
                        success: res => {
                            if (res.confirm) {
                                downloadTask && downloadTask.abort()
                                uni.navigateBack()
                            }
                        }
                    });
                    return;
                }
            
                if (this.downloadSuccess && this.tempFilePath) {
                    // 包已经下载完毕,稍后安装,将包保存在本地
                    await this.saveFile(this.tempFilePath, this.version)
                    uni.navigateBack()
                    return;
                }
            
                uni.navigateBack()
            },
            /**
             * 删除安装包
             */
            deleteSavedFile(filePath) {
                // uni.removeStorageSync(localFilePathKey)
                return uni.removeSavedFile({
                    filePath
                })
            },
            
            
            /**
             * 重启
             */
            restart() {
                this.installed = false;
                // #ifdef APP-PLUS
                //更新完重启app
                plus.runtime.restart();
                // #endif
            },
        }
    }
</script>

<style lang="scss">
    page{
        background: transparent;
    }
    .mask {
        position: fixed;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
        background-color: rgba(0, 0, 0, .65);
        display: flex;
        justify-content: center;
        align-items: center;
        .mask-content{
            position: relative;
            top: 0;
            width: 600rpx;
            .top{
                position: absolute;
                top: -195rpx;
                left: 0;
                width: 600rpx;
                height: 270rpx;
                .text {
                    /* #ifndef APP-NVUE */
                    display: block;
                    /* #endif */
                    line-height: 160px;
                    text-align: center;
                    font-size: 45rpx;
                    font-weight: bold;
                    color: #F8F8FA;
                    position: absolute;
                    top: 0;
                    left: 50rpx;
                    z-index: 1;
                }
                image{
                    width: 100%;
                    display: block;
                }
            }
            .mask-body{
                background-color: #fff;
                box-sizing: border-box;
                min-height: 30vh;
                padding: 100rpx 50rpx 30rpx;
                box-sizing: border-box;
                font-family: Source Han Sans CN;
                border-bottom-right-radius: 30rpx;
                border-bottom-left-radius: 30rpx;
                display: flex;
                flex-direction: column;
                .content{
                    flex:1;
                    .title{
                        font-size: 30rpx;
                        font-weight: 600;
                        color:#1785ff;
                    }
                    .desc{
                        padding-top: 20rpx;
                        font-size: 24rpx;
                        color:#1a1a1a;
                    }
                }
                
                .uni-progress{
                    border-radius: 50%;
                }
                .mask-foor{
                    .btn{
                        text-align: center;
                        font-size: 30rpx;
                        font-weight: 400;
                        color: #FFFFFF;
                        border-radius: 40rpx;
                        margin: 0 18rpx;
                        height: 80rpx;
                        line-height: 80rpx;
                        background: linear-gradient(to right, #1785ff, #3DA7FF);
                    }
                }
            }
            .close-img{
                width: 70rpx;
                height: 70rpx;
                display: block;
                margin: 60rpx auto 0;
            }
        }
    }
</style>

app_update_close.png bg_top.png
上一篇 下一篇

猜你喜欢

热点阅读