效果预览

大致效果:

打开App,进入首页(首次),检测线上是否存在新版本,如果存在,弹窗提示用户是否进行版本更新。Android 有热更新整包更新,若为热更新,更新完会自动重启;若为整包更新,则进入浏览器(如果上架了应用市场,对应逻辑可以写成跳转到应用市场)进行下载。ios 则只能跳转到App Store进行更新。

如果用户点了取消按钮,在使用 App 的过程中不会再进行弹窗提示,等到用户下次进入 App 才会重新提示。

步骤

客户端版本管理

字段 解释
更新包名称 更新包名称,例如:HK-IOS-1.0.0
更新包文件 上传的 apk、ipa、wgt 文件
更新包版本号 更新包版本号,必须大于上一次更新的版本号
客户群体 1 普通用户 、 2 会员
更新包类型 ANDROID 、 IOS
更新类型 否 、 整包更新 、 热更新
发行地区 港澳台 、 印尼 、 大陆
更新包描述 zh(中文) 、 en(英文) 、 in(印尼语)

这里的字段可根据自己的需求进行设计。

APP

version 组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<template>
<view class="tzy-version">
<u-modal
:value="updateVsb"
:title="$t('version.versionUpdateTips')"
:show-cancel-button="isShowCancelBtn"
:cancel-text="$t('btn.cancel')"
:confirm-text="$t('version.update')"
@cancel="cancelUpdate"
@confirm="updateConfirm">
<view class="version-online">V {{ updateObj.version }}</view>
<view class="model-version" slot-name="content">
<scroll-view scroll-y="true" class="content-text">
<view class="content-text">
<u-input
v-model="targetDesc"
type="textarea"
:border="false"
:disabled="true"
:auto-height="true"
:customStyle="{ 'font-size': '14px', color: '#96a0b5',
'word-break': 'break-word !important' }"
/>
</view>
</scroll-view>
</view>
</u-modal>
</view>
</template>
<script>
import config from '@/common/js/config.js';
import phoneInfo from '@/common/js/phone-info.js';
export default {
props: {
// 页面来源
pageFrom: {
type: String,
default: 'Home'
},
// 是否显示弹窗
updateVsb: {
type: Boolean,
default: false
},
// 是否显示取消按钮
isShowCancelBtn: {
type: Boolean,
default: true
},
updateObj: {
type: Object,
default: () => {}
},
targetDesc: {
type: String,
default: ''
}
},
methods: {
cancelUpdate() {
if (this.pageFrom == 'Home') {
uni.setStorageSync('cancelUpdate', 'true');
}
this.$emit('cancelClickEvent');
},
updateConfirm() {
// 下载更新包
const platform = phoneInfo.systemInfo.platform.toLowerCase();
const url = config.uploadUrl + this.updateObj.url;
const type = this.updateObj.type;
// type仅为我司定义
if (type == 1) {
this.$emit('cancelClickEvent');
uni.setStorageSync('cancelUpdate', 'true');
uni.setStorageSync('widgetInfo', {});
// 整包
if (platform == 'android') {
// 安卓打开网页下载
plus.runtime.openURL(url);
} else {
// ios打开应用商店 https://appstoreconnect.apple.com/
// apple id 在 app conection 上传的位置可以看到
const appleId = 'xxxxxx'; // 这里替换成你的 apple id
plus.runtime.launchApplication({
action: `itms-apps://itunes.apple.com/cn/app/id${appleId}?mt=8`
},
function(e) {
console.log('Open system default browser failed: ' + e.message);
}
);
}
} else if (type == 2) {
//热更新
console.log('热更新。。。。。。。。', url);
plus.nativeUI.showWaiting(this.$t('dataDesc.updating'));
uni.downloadFile({
url: url,
success: downloadResult => {
if (downloadResult.statusCode === 200) {
plus.runtime.install(
downloadResult.tempFilePath, {
force: false
},
function() {
console.log('install success...');
plus.nativeUI.closeWaiting();
// 更新版本信息
uni.setStorageSync('widgetInfo', {});
plus.runtime.restart();
},
function(e) {
console.error('install fail...');
plus.nativeUI.closeWaiting();
}
);
}
},
fail: error => {
console.log(error);
}
});
}
}
}
};
</script>
<style lang="scss" scoped>
.version-online {
text-align: center;
font-size: 14px;
font-weight: 600;
margin-top: 10px;
}

.content-text {
max-height: 280px;
}

.model-version {
padding: 12px 24px 30px;
font-size: 14px;
color: $cat_text_normal;
}

.desc-font {
font-size: 14px !important;
color: #96a0b5 !important;
word-break: break-all !important;
}
</style>

首页中引用 version 组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<template>
<view>
<!-- 热更新组件 仅APP显示-->
<!-- #ifdef APP-PLUS -->
<versionUpdate
pageFrom="Home"
:updateVsb="updateVsb"
:updateObj="updateObj"
:targetDesc="targetDesc"
@cancelClickEvent="cancelClickEvent">
</versionUpdate>
<!-- #endif -->
</view>
</template>
<script>
import { clientVersionQuery } from '@/api/client.js';
import versionUpdate from '@/components/muudah-version/index.vue';
export default {
name: 'Home',
components: {
versionUpdate
},
data() {
return {
updateObj: {
url: '',
type: '',
version: ''
},
updateVsb: false,
targetDesc: '', // 版本更新描述
};
},
methods: {
getUpdate() {
//当前版本号 转化为数字
const tar_version = versionToNum(phoneInfo.manifestInfo.version);
// android || ios
const platform = phoneInfo.systemInfo.platform.toLowerCase() == 'ios' ? 'IOS' : 'ANDROID';
const version_to = this.versionTo; // 发行地区
// 这里调接口 是否检测到版本更新
clientVersion({
client_type: platform,
client_area: version_to
}).then(res => {
const {
Code,
data,
sdk_path
} = res;
if (Code == 0 && sdk_path != '' && data.client_version != '') {
// 线上的版本 转化为数字
const versin_online = versionToNum(data.client_version);
if (versin_online > tar_version && data.update_status > 0) {
this.updateObj.url = sdk_path;
this.updateObj.type = data.update_status;
this.updateObj.version = data.client_version;
// "update_status": 更新类型. 0: 否, 1: 整包更新, 2: 热更新
const desc_str = eval('(' + data.desc + ')');
// 这里根据语言包显示语言
this.targetDesc = desc_str[this.language];
this.updateVsb = true;
}
}
});
},
cancelClickEvent() {
this.updateVsb = false;
}
}
}
</script>

APP.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<script>
import phoneInfo from '@/common/js/phone-info.js'; // 这里面保存了 设备的基本信息
export default {
onLaunch: function() {
// 获取设备基本信息
uni.getSystemInfo({
success: res => {
phoneInfo.systemInfo = res;
}
});
// #ifdef APP-PLUS
plus.screen.lockOrientation('portrait-primary'); //锁定屏幕方向
uni.setStorageSync('cancelUpdate', 'false'); // 进来APP 重置更新弹窗
// 获取App 当前版本号
if (Object.keys(uni.getStorageSync('widgetInfo')).length == 0) {
plus.runtime.getProperty(plus.runtime.appid, widgetInfo => {
phoneInfo.manifestInfo = widgetInfo;
uni.setStorageSync('widgetInfo', widgetInfo);
});
}
//#endif
}
};
</script>

最后,你还可以尝试了解 App升级中心 uni-upgrade-center