第一次接触uniapp,但是当前代码可用作参考,当时测试时可用,后来因为某些原因我们用了整包更新,我们是前后端都一个人搞的,但是我不会前端只能修改一下简单的,所以没有专业的人来搞这个,一个来自后端的无奈,既要后端会干,还要写前端,偶尔还要充当运维,技术不好请各位大佬指导错误。
代码思路如下:
先在服务器中放一个版本控制文件(undate.json)---》通过统一的外部访问地址访问该配置文件,每次APP会在软件启动时自动查询当前项目服务器中的版本号与本地版本号做区别,区别逻辑在第二段代码中,不同逻辑实现不同的热更新及全量更新。当然每次发版本也需要将服务器中的配置文件改动, 配置文件与发布的APP在manifest中的版本号一致,本地已安装的APP版本号会在代码中查到。全部基于前端来做的,不需要后端代码。
{
"versionName": "1.0.27", //版本名称
"versionCode": 336, //版本号
"appPath": "https://xxx.oss.com/apk/app-release.apk", //整包更新地址
"wgtPath": "https://xxx.oss.com/apk/www.wgt" //热更新地址
}
当前代码是放在app.vue文件中
<script>
import routingIntercept from '@/common/permission.js'
import Vue from 'vue'
export default {
// 此处globalData为了演示其作用,不是uView框架的一部分
globalData: {
version: '1.0.1'
},
onShow() {
// 对路由进行统一拦截,实现路由导航守卫 router.beforeEach 功能
routingIntercept();
},
onLaunch() {
uni.getSystemInfo({
success: function(e) {
// #ifndef MP
Vue.prototype.StatusBar = e.statusBarHeight;
if (e.platform == 'android') {
Vue.prototype.CustomBar = e.statusBarHeight + 50;
} else {
Vue.prototype.CustomBar = e.statusBarHeight + 45;
};
// #endif
// #ifdef MP-WEIXIN
Vue.prototype.StatusBar = e.statusBarHeight;
let custom = wx.getMenuButtonBoundingClientRect();
Vue.prototype.Custom = custom;
Vue.prototype.CustomBar = custom.bottom + custom.top - e.statusBarHeight;
// #endif
// #ifdef MP-ALIPAY
Vue.prototype.StatusBar = e.statusBarHeight;
Vue.prototype.CustomBar = e.statusBarHeight + e.titleBarHeight;
// #endif
//热更新or整包更新代码
// #ifdef APP-PLUS
plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) {
console.log(widgetInfo);
uni.request({
//服务器内存放的更新配置文件地址http://xxx.xxx.xxx.xx:xxxx/app-update.json
url: "http://xxx.xxx.xxx.xx:xxxx/app-update.json",
success: (result) => {
let {
versionCode,
versionName,
wgtPath,
appPath
} = result.data
console.log({
versionCode,
versionName,
wgtPath,
appPath
});
const localVersionCode = uni.getStorageSync(
'localVersionCode');
// 判断版本名是否一致
if (versionName === widgetInfo.version) {
if (localVersionCode && localVersionCode ===
versionCode) {
console.log('当前版本已是最新版本,无需更新');
} else {
if (parseInt(widgetInfo.versionCode) < parseInt(
versionCode)) {
uni.showModal({
title: '提示',
content: '有新的更新可用,请升级(wgt更新)',
showCancel: false, // 隐藏取消按钮
success: function(res) {
if (res.confirm) {
let downloadPath =
wgtPath;
uni.downloadFile({
url: downloadPath,
success: (
downloadResult
) => {
if (downloadResult
.statusCode ===
200
) {
plus.runtime
.install(
downloadResult
.tempFilePath, {
force: true // 强制更新
},
function() {
uni.showModal({
title: '提示',
content: '热更新成功,请退出重启应用',
showCancel: false, // 隐藏取消按钮
success: function(
res
) {
if (res
.confirm
) {
plus.runtime
.restart();
}
}
});
console
.log(
'热更新成功'
);
uni.setStorageSync(
'localVersionCode',
versionCode
);
console
.log(
'localVersionCode:' +
versionCode
);
// 这里放后续需要执行的代码
// 比如显示第二个提示框等
}
);
}
}
});
}
}
});
}
}
} else {
console.log('版本名不一致,请使用整包更新');
let downloadPath = appPath
uni.showModal({ //提醒用户更新
title: "更新提示",
content: "有新的更新可用,请升级(apk更新)",
showCancel: false, // 隐藏取消按钮
success: (res) => {
if (res.confirm) {
// 用户点击了确认按钮
uni.downloadFile({
url: downloadPath,
success: (
downloadResult
) => {
if (downloadResult
.statusCode ===
200) {
console
.log(
'正在更新...'
);
plus.runtime
.install(
downloadResult
.tempFilePath, {
force: true // 强制更新
},
function() {
uni.showModal({
title: '提示',
content: '整包更新成功',
showCancel: false // 隐藏取消按钮
});
console
.log(
'整包更新成功'
);
plus.runtime
.restart();
},
function(
e
) {
uni.showModal({
title: '提示',
content: '整包更新失败',
showCancel: false // 隐藏取消按钮
});
console
.error(
'整包更新失败,错误原因:' +
e
);
}
);
}
}
})
}
}
});
}
}
});
});
// #endif
}
});
},
}
</script>
<style lang="scss">
@import "colorui/main.css";
@import "colorui/icon.css";
@import "uview-ui/index.scss";
@import "common/app.scss";
page {
height: 100%;
}
.status_bar {
background-color: #19a8ff;
height: 32rpx;
}
</style>