一、需求描述
基于uni-app开发的PDA扫码APP需要新增自动检测版本并升级的功能,通过调研发现官方也提供了 App 升级的支持,升级中心 uni-upgrade-center,但是由于需要使用云端基于 uniCloud 云函数实现,对于项目来说,又多了一个服务端,管理起来较为麻烦,考虑再三最终选择自行开发前后端代码用于实现APP版本升级,这样也方便实际开发中进行调整。
实现流程概述:
第一步: 开发可用于获取APP最新版本信息的后端接口以及一套可以管理APP版本信息的PC管理系统
- 客户端调用后端接口传递APP当前版本及系统平台(IOS/Android)等信息,后端从数据库加载APP最新版本信息与客户端进行比较,如果大于客户端版本则提示更新升级,否则不升级。
- PC管理系统可上传apk文件,维护APP版本、更新说明等信息。
第二步: 基于uniapp开发客户端程序,并将打包后的apk文件上传到服务器
-
通过HBuilderX进行云打包前,要设置应用版本名称,并且保证设置的应用版本名称必须大于上一次的版本。
-
apk文件上传成功后,需要将文件访问地址保存至数据库,后续APP更新升级时要使用到。
-
本文的Demo程序是基于应用版本名称来判定APP是否需要更新升级的,实际实现时也可以使用不同的方式,例如:基于应用版本号。
二、系统环境
- 前端:uni-app、Vue.js
- 后端:Java、SpringBoot、Mybatis
- 数据库:MySQL
- JDK1.8
- APP在线升级插件:https://ext.dcloud.net.cn/plugin?id=3931
三、系统实现
3.1 uni-app客户端实现
客户端实现主要依托于第三方插件,本示例只做了最基础的应用,有关该插件的详细介绍详见 APP在线升级 https://ext.dcloud.net.cn/plugin?id=3931
index.vue
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<text>当前版本:V1.0.1</text>
<view>
<zy-update @showupdateTips="showupdatetips" :autocheckupdate="false" :noticeflag="false" ref="zyupgrade" theme="green" :h5preview="false" :appstoreflag="false" :updateurl="update_url"></zy-update>
</view>
</view>
</template>
<script>
//引用组件
import ZyUpdate from '../../components/zy-upgrade/zy-upgrade.vue'
export default {
data() {
return {
update_url: ''
}
},
components: {
ZyUpdate
},
onLoad() {
},
onShow() {
},
mounted() {
this.checkupdate();
},
methods: {
checkupdate:function(){
this.$nextTick( () => {
this.update_url = this.$baseURL + '/app/versionUpdate'
this.$refs.zyupgrade.check_update()
} )
},
showupdatetips:function(flag){
if(flag == 0){
uni.showToast({
title: '已经是最新版本了',
icon:'none'
});
}
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
3.2 后端实现
VersionUpdateController.java
package cn.com.catgod.hey_update.controller;
import cn.com.catgod.hey_update.entity.AppConfig;
import cn.com.catgod.hey_update.entity.R;
import cn.com.catgod.hey_update.entity.VersionInfo;
import cn.com.catgod.hey_update.mapper.AppConfigMapper;
import cn.com.catgod.hey_update.service.AppConfigService;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/app")
@CrossOrigin("*")
public class VersionUpdateController {
@Autowired
private AppConfigService appConfigService;
/**
* APP版本更新
* 请求参数中其实不止传递了一下四个,更多请看插件市场作者的文档,https://ext.dcloud.net.cn/plugin?id=3931
* @param platform 平台(android/ios)
* @param name 应用名称
* @param version 应用版本名称 主版本号.次版本号.修订号
* @param code 应用版本号
* @return
*/
@RequestMapping("/versionUpdate")
public R check(String platform,String name,String version,String code) {
Map<String, Object> map = new HashMap<>();
VersionInfo info = new VersionInfo();
info.setUpdate_flag(0);
map.put("code", 100);
map.put("data", info);
AppConfig appConfig = appConfigService.findLastVersionInfo();
if(appConfig ==null) {
map.put("msg", "无版本配置信息");
return R.ok(map);
}
if(!StrUtil.isEmptyIfStr(version) && !StrUtil.isEmptyIfStr(platform)) {
int[] oldVers = StrUtil.splitToInt(version, ".");
int[] newVers = StrUtil.splitToInt(appConfig.getVersionCode(), ".");
boolean isUpdateFlag = false;
int length = oldVers.length > newVers.length ? newVers.length : oldVers.length;
for (int i = 0; i < length; i++) {
if(newVers[i] > oldVers[i]) {
isUpdateFlag = true;
break;
}
}
if(isUpdateFlag) {
info.setUpdate_flag(1);//0:不需要更新,1:需要更新
info.setVersion(appConfig.getVersionCode());
info.setUpdate_url(appConfig.getVersionUrl());
info.setUpdate_tips(appConfig.getUpdateTrips());
info.setForceupdate(appConfig.getIsForceUpdate());
map.put("code", 100);
map.put("msg", "应用程序需要更新");
map.put("data", info);
}
return R.ok(map);
}else {
map.put("code", 500);
map.put("msg", "请求参数不含版本号、平台");
map.put("data", info);
return R.ok(map);
}
}
}
3.3 实现效果
四、 源代码
百度网盘下载链接:https://pan.baidu.com/s/19GQfYdk0m7PUqE2Wg5-gKQ?pwd=0703
提取码:0703
- hey_update:客户端程序
- hey_update_server:服务端程序
- hey_app.sql:数据库脚本
源码使用时需要修改的地方详见项目README.md文件