Uniapp自动更新
本文介绍了基于rouyi-uniapp的更新包版本自动推送更新。结合minio和网址下载地址两种方式,计算版本号大小后,可选是否强制更新。
主要字段和设计思路:
fileUrl:直接下载地址,用于网址直接下载,uniapp可直接访问(isUrlDownload=”Y“)
filePath:minio下载地址, 存储minio文件管理系统表的关键字,uniapp走本地minio文件下载地址(isUrlDownload=”N“)
version:版本号3位,eg:4.0.1,与uniapp的manifest.Json的versionName对应。
versionValue:版本号值,类似于二进制值转化,在更新版本时,比价用户当前版本信息和发布的有效最高版本号,如果当前版本号低于发布的最高版本号,进行更新提示。
Eg:Version=4.0.1; versionValue = 1*Math.power(10,0)+0*Math.power(10,1)+1*Math.power(10,2)。平方基数值不得小于10,否则值计算的最终大小会不符合。
isUrlDownload:是否使用直接地址下载还是minio,更加灵活
Status:版本是否可用。‘Y’为可用,即使用户安装的是旧版本,也可以不更新。‘N’为版本停用,如果用户当前安装的版本状态为停用,则强制更新到最新版(状态为‘Y’,且版本号值最高)
package com.inspur.factory.factoryAppManage.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.inspur.common.annotation.Excel;
import com.inspur.common.core.domain.BaseEntity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
* app版本管理对象 factory_app_manage
*
*/
@TableName("factory_app_manage")
@Data
public class FactoryAppManage extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键 */
@TableId
private Long id;
/** 版本号名称 */
@Excel(name = "版本号名称")
private String version;
/** 版本号值 */
@Excel(name = "版本号值")
private Long versionValue;
/** 手机品牌 */
@Excel(name = "手机品牌")
private String phoneBrand;
/** 文件名(安装包名称) */
@Excel(name = "文件名(安装包名称)")
private String fileName;
/** 安装包地址 */
@Excel(name = "安装包地址")
private String filePath;
/** 下载地址 */
@Excel(name = "下载地址")
private String fileUrl;
/** 上传时间 */
// @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "上传时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date fileTime;
/** 状态 */
@Excel(name = "状态")
private String status;
/** 更新说明 */
@Excel(name = "更新说明")
private String upgradeDescription;
/** 文件大小 */
@Excel(name = "文件大小")
private String fileSize;
/** 使用临时地址 */
@Excel(name = "使用临时地址",readConverterExp = "Y=是,N=否")
private String isUrlDownload;
}
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("id", getId())
.append("version", getVersion())
.append("versionValue", getVersionValue())
.append("phoneBrand", getPhoneBrand())
.append("fileName", getFileName())
.append("filePath", getFilePath())
.append("fileUrl", getFileUrl())
.append("fileTime", getFileTime())
.append("status", getStatus())
.append("upgradeDescription", getUpgradeDescription())
.append("fileSize", getFileSize())
.append("createTime", getCreateTime())
.append("createBy", getCreateBy())
.append("updateTime", getUpdateTime())
.append("updateBy", getUpdateBy())
.append("remark", getRemark())
.toString();
}
}
检查用户当前的版本是否可用。‘Y’为可用,即使用户安装的是旧版本,也可以不更新。‘N’为版本停用,如果用户当前安装的版本状态为停用,则强制更新到最新版(状态为‘Y’,且版本号值最高)。
//获取应当安装的app版本
@Override
public FactoryAppManage getAppVersion(FactoryAppManage factoryAppManage){
//传入版本号、手机系统类型
List oldVersion = factoryAppManageMapper.selectFactoryAppManageList(factoryAppManage);
if(oldVersion!=null && oldVersion.size()!=0){
//如果当前版本还可使用,返回当前版本
if(oldVersion.get(0).getStatus().equals("Y")){
return oldVersion.get(0);
}else{
//如果当前版本不可使用强制更新,返回最新版本
FactoryAppManage factoryAppManageQuery = new FactoryAppManage();
factoryAppManageQuery.setStatus("Y");
factoryAppManageQuery.setPhoneBrand(factoryAppManage.getPhoneBrand());
List newVersion = factoryAppManageMapper.selectFactoryAppManageList(factoryAppManageQuery);
if(newVersion!=null){
return newVersion.get(0);
}
}
}
return null;
}
版本号比较后,更新包安装提示弹窗,点击确认下载文件。
文件下载和打开主要方法如下:
uni.saveFile({})
Url为本地接口地址
plus.downloader.createDownload(url, {})
plus.io.convertLocalFileSystemURL
plus.runtime.openFile(d.filename); //选择软件打开文件
主要用于电脑调试,BLOB转化,具体不做解释
uni.getSystemInfoSync()
获取:phoneBrand(版本)version(版本号)
App.vue根组件,每次打开任何页面都会执行到,在此文件下检测版本和更新包安装。
当前版本号为参数,后台请求对比最新版本号(版本号值最大为最新版本),返回应当安装的版本。
如果需要更新,则弹窗显示,点击确定进行安装。
根据web前台配置的是否用直接地址下载,进入安装包下载安装。
checkUploadVersion(){
//检测更新
let server = config.baseUrl +'/factory/factoryAppManage/getAppVersion'; //检查更新地址(minio检测地址)
let info = uni.getSystemInfoSync()
uni.request({
url: server,
data: {
phoneBrand: info.platform,
version: info.appVersion
},
success: (res) => {
if (res.data.data.version != info.appVersion) {
// if (1) {
let upgradeDescription = res.data.data.upgradeDescription
uni.showModal({ //提醒用户更新
title: "更新提示",
content: '版本更新内容:'+ upgradeDescription,
showCancel:false,
success: (e) => {
if (e.confirm) {
if(info.uniPlatform=='web'){
//h5平台调用后端minio接口下载
this.downloadApp2(res.data.data)
}else if(info.platform!='windows' && info.uniPlatform!='web' && res.data.data.isUrlDownload == 'Y'){
//app手机端使用临时地址下载
this.downloadApp1(res.data.data)
}else if(info.platform!='windows' && info.uniPlatform!='web' && res.data.data.isUrlDownload == 'N'){
//app手机端调用后端minio接口下载
this.downloadApp3(res.data.data)
}
}
}
})
}
}
})
},
此方式具有参考意义,可以不用购买云空间存放安装包文件,直接使用minio文件存储。
/** app安装包下载-(下载方式3-APP调用后端minio下载接口下载)*/
downloadApp3(appVersionInfo) {
var url = config.baseUrl +'/fileManage/downloadFile'+'?filePath=' + appVersionInfo.filePath+'&fileName=' + appVersionInfo.fileName; //请求下载接口地址
var name = appVersionInfo.fileName;
// console.log('method', reqMethod)
uni.showLoading({
title: '正在下载'
});
// 本地路径开头使用file://,跟上手机文件本地目录storage/emulated/0,
// 这时用户文件管理器能看到的了,之后创建 京唐港app 作为文件夹,
let dtask = plus.downloader.createDownload(url, {
filename: "file://storage/emulated/0/京唐港app/" + name //利用保存路径,实现下载文件的重命名
},(d, status)=> {
//d为下载的文件对象
if (status == 200) {
uni.hideLoading();
uni.showToast({
icon: 'none',
mask: true,
title: '已保存到文件夹:/京唐港app/' + name, //保存路径
duration: 3000,
});
//下载成功,d.filename是文件在保存在本地的相对路径,使用下面的API可转为平台绝对路径
let fileSaveUrl = plus.io.convertLocalFileSystemURL(d.filename);
setTimeout(()=>{
plus.runtime.openFile(d.filename); //选择软件打开文件
},1500)
} else {
//下载失败
uni.hideLoading();
plus.downloader.clear(); //清除下载任务
uni.showToast({
icon:'none',
mask:true,
title: '下载失败,请稍后重试',
});
}
})
dtask.start();
},
此方式需要云空间
/** app安装包下载-(下载方式1-APP指定url下载)*/
downloadApp1(appVersionInfo){
//下载方式1:指定url下载
let downloadUrl = appVersionInfo.fileUrl
// let downloadUrl = 'https://mp-fdbd529e-1d38-4f4a-bf37-72ba880de14a.cdn.bspapp.com/cloudstorage/00b0e017-b375-4758-88c8-4acfab810d7a.apk'
uni.downloadFile({
url: downloadUrl,
/* data:{
filePath:'mnQ0lCrayctz3TkHxB4rB0PeVTD7fbXNhULFZo4g+iPK0KXkzzzYJWCIJ5vxfiu1a8fzsYOb07weXbcXd92dkw==',
fileName: '3.jpg'
},
method: 'POST',*/
success: (res) => {
console.log('downloadFile success, res is', res)
//文件保存到本地
uni.saveFile({
tempFilePath: res.tempFilePath, //临时路径
success: function(re) {
uni.showToast({
icon: 'none',
mask: true,
title: '文件已保存:' + re.savedFilePath, //保存路径
duration: 3000,
});
setTimeout(() => {
//打开查看
uni.openDocument({
filePath: re.savedFilePath,
success: function(res) {
// console.log('打开成功');
}
});
}, 3000)
}
});
uni.hideLoading();
},
fail: (err) => {
console.log('downloadFile fail, err is:', err)
uni.hideLoading();
}
})
},
/** app安装包下载-(下载方式2-h5平台web使用后端minio后端接口下载)*/
downloadApp2(appVersionInfo){
//下载方式2:请求接口下载
let server = config.baseUrl +'/fileManage/downloadFile'+'?filePath=' + appVersionInfo.filePath+'&fileName=' + appVersionInfo.fileName; //请求下载接口地址
uni.request({
url: server,
method: 'post',
success: (res) => {
/** h5 平台下载*/
try {
// const res = await exportOrderById({ id });//获取返回的二进制数据
const blob = new Blob([res.data]); // 通过返回的流数据 手动构建blob 流
const reader = new FileReader();
reader.readAsDataURL(blob); // 转换为base64,可以直接放入a标签的href
reader.onload = (e) => {
// 转换完成,创建一个a标签用于下载
const a = document.createElement("a");
a.download = appVersionInfo.fileName; // 构建 下载的文件名称以及下载的文件格式(可通过传值输入)
if (typeof e.target.result === "string") {
a.href = e.target.result;
}
a.click();
};
} catch (err) {
this.$message.error("遇到错误!");
}
}
})
},
高级查询
搜索
重置
新增
导出
删除
{{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}
{{ parseTime(scope.row.fileTime) }}
停用
启用
下载
详情
修改
删除
0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
{{ title }}
app版本管理信息
{{form.fileTime}}
{{form.phoneBrand}}
{{form.fileName}}
{{form.filePath}}
{{form.version}}
计算版本号值
{{form.versionValue}}
{{form.fileUrl}}
{{form.upgradeDescription}}
{{ dict.label }}
停用
启用
点击上传