stellar-ui-v2 1.40.32 → 1.40.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ste-app-update/README.md +52 -5
- package/components/ste-app-update/method.js +188 -28
- package/components/ste-app-update/ste-app-update.vue +170 -4
- package/components/ste-checkbox/ste-checkbox.vue +57 -55
- package/components/ste-checkbox-group/ste-checkbox-group.vue +21 -6
- package/components/ste-drag-sort/README.md +124 -0
- package/components/ste-drag-sort/config.json +5 -0
- package/components/ste-drag-sort/ste-drag-sort.vue +706 -0
- package/components/ste-message-box/README.md +1 -1
- package/components/ste-message-box/ste-message-box.js +7 -5
- package/components/ste-message-box/ste-message-box.vue +364 -364
- package/components/ste-page-container/README.md +83 -83
- package/components/ste-page-container/WORKLOG-2026-03-12.md +229 -229
- package/components/ste-page-container/ste-page-container.vue +190 -190
- package/components/ste-popup/README.md +16 -16
- package/components/ste-popup/ste-popup.vue +392 -392
- package/components/ste-price/ste-price.vue +256 -256
- package/components/ste-radio/ste-radio.vue +53 -55
- package/components/ste-radio-group/ste-radio-group.vue +24 -9
- package/components/ste-search/ste-search.vue +576 -576
- package/components/ste-swipe-action/ste-swipe-action.vue +8 -8
- package/components/ste-swipe-action-group/ste-swipe-action-group.vue +5 -2
- package/components/ste-toast/README.md +1 -1
- package/components/ste-toast/ste-toast.js +67 -67
- package/components/ste-video/ste-video.vue +756 -756
- package/package.json +2 -2
- package/utils/System.js +19 -4
- package/utils/mixin.js +150 -0
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
- 此组件用于APP更新功能
|
|
4
4
|
- 仅支持APP端
|
|
5
|
+
- 支持整包升级(apk)和资源包升级(wgt)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
---
|
|
7
8
|
|
|
8
9
|
### 基础用法
|
|
9
10
|
|
|
10
11
|
- 属性`clientId`用于设置APP的应用编码
|
|
11
12
|
- 属性`clientSecret`用于设置APP的应用密钥
|
|
12
13
|
- 属性`fallbackApiUrl`用于设置兜底检查接口地址
|
|
14
|
+
- 属性`strictVersionCheck`用于设置严格版本检查模式
|
|
13
15
|
- 函数`start`用于开始检查更新
|
|
14
16
|
- 函数`getSkippedVersions`用于获取跳过版本列表
|
|
15
17
|
- 函数`clearSkippedVersions`用于清空跳过版本记录
|
|
@@ -59,6 +61,7 @@ export default {
|
|
|
59
61
|
clientId="workbench_android"
|
|
60
62
|
clientSecret="gkS6lEEncqAocYK2qsrvPQZykm3ISeMx"
|
|
61
63
|
fallbackApiUrl="https://example.com/api/app-update/check"
|
|
64
|
+
:strictVersionCheck="true"
|
|
62
65
|
@skip-version="onSkipVersion"
|
|
63
66
|
@fallback="onFallback"
|
|
64
67
|
></ste-app-update>
|
|
@@ -68,7 +71,7 @@ export default {
|
|
|
68
71
|
</template>
|
|
69
72
|
```
|
|
70
73
|
|
|
71
|
-
|
|
74
|
+
---
|
|
72
75
|
|
|
73
76
|
### API
|
|
74
77
|
|
|
@@ -82,7 +85,8 @@ export default {
|
|
|
82
85
|
| `btnText` | 立即体验按钮文本 | `string` | `立即体验` | - | - |
|
|
83
86
|
| `appVersion` | 应用当前版本 | `string` | - | - | `1.40.9`|
|
|
84
87
|
| `zIndex` | 弹窗层级 | `string/number` | `998` | - | `1.40.9`|
|
|
85
|
-
| `fallbackApiUrl`| 兜底检查接口地址 | `string` | -
|
|
88
|
+
| `fallbackApiUrl`| 兜底检查接口地址 | `string` | `https://stellar-public-prd.intecloud.com.cn/api/app-update/check` | - | `1.41.0`|
|
|
89
|
+
| `strictVersionCheck`| 严格版本检查,设为true时只有新版本大于当前版本才触发更新 | `boolean` | `false` | `true/false` | - |
|
|
86
90
|
|
|
87
91
|
|
|
88
92
|
#### Events
|
|
@@ -101,7 +105,50 @@ export default {
|
|
|
101
105
|
| `start(callback)` | 开始检查更新 | - | - |
|
|
102
106
|
| `getSkippedVersions()` | 获取已跳过的版本列表 | string[] | `1.41.0` |
|
|
103
107
|
| `clearSkippedVersions()` | 清空跳过版本记录 | - | `1.41.0` |
|
|
108
|
+
| `cancelDownload()` | 取消当前下载任务 | - | - |
|
|
109
|
+
| `install()` | 安装已下载的更新包(仅整包升级时可用) | - | - |
|
|
104
110
|
|
|
105
111
|
|
|
106
|
-
|
|
107
|
-
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### API 返回数据格式
|
|
115
|
+
|
|
116
|
+
更新接口(`apiUrl`)返回数据格式:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"code": 200,
|
|
121
|
+
"data": {
|
|
122
|
+
"code": "101",
|
|
123
|
+
"name": "1.0.1",
|
|
124
|
+
"desc": "更新内容描述",
|
|
125
|
+
"isForce": false,
|
|
126
|
+
"entireFile": "https://example.com/app.apk",
|
|
127
|
+
"updateFile": "https://example.com/app.wgt"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
| 字段 | 类型 | 说明 |
|
|
133
|
+
| ----- | ----- | ----- |
|
|
134
|
+
| `code` | string | 版本号 |
|
|
135
|
+
| `name` | string | 版本名称 |
|
|
136
|
+
| `desc` | string | 更新内容描述 |
|
|
137
|
+
| `isForce` | boolean | 是否强制更新 |
|
|
138
|
+
| `entireFile` | string | 整包升级文件地址(apk) |
|
|
139
|
+
| `updateFile` | string | 资源包升级文件地址(wgt) |
|
|
140
|
+
|
|
141
|
+
> 当 `entireFile` 存在时,优先使用整包升级(`package_type=0`),否则使用资源包升级(`package_type=1`)
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### 更新流程说明
|
|
146
|
+
|
|
147
|
+
1. 调用 `start()` 方法开始检查更新
|
|
148
|
+
2. 先检查兜底接口(`fallbackApiUrl`),命中则触发兜底更新流程
|
|
149
|
+
3. 调用正常更新接口(`apiUrl`)获取版本信息
|
|
150
|
+
4. 检查是否已跳过该版本
|
|
151
|
+
5. 检查版本是否需要更新(根据 `strictVersionCheck` 决定比较方式)
|
|
152
|
+
6. 检查是否存在未完成的下载任务,有则恢复下载
|
|
153
|
+
7. 弹出更新弹窗,用户可选择立即更新、跳过版本或取消
|
|
154
|
+
8. 下载完成后自动安装(wgt)或提示安装(apk)
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export function download(data,
|
|
2
|
-
const
|
|
3
|
-
|
|
1
|
+
export function download(data, options) {
|
|
2
|
+
const success = options.success;
|
|
3
|
+
const error = options.error;
|
|
4
|
+
const downloadSuccess = options.downloadSuccess;
|
|
5
|
+
const onProgressUpdate = options.onProgressUpdate;
|
|
4
6
|
|
|
5
|
-
// 参数验证
|
|
6
7
|
if (!data.updateFile) {
|
|
7
8
|
const errorMsg = '更新文件地址不能为空';
|
|
8
9
|
uni.showToast({ title: errorMsg, icon: 'none' });
|
|
@@ -10,13 +11,111 @@ export function download(data, { success, error, onProgressUpdate, downloadSucce
|
|
|
10
11
|
throw new Error(errorMsg);
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
const package_type = data.package_type;
|
|
15
|
+
|
|
16
|
+
// #ifdef APP-PLUS
|
|
17
|
+
let timeout;
|
|
18
|
+
|
|
19
|
+
const task = plus.downloader.createDownload(
|
|
20
|
+
data.updateFile,
|
|
21
|
+
{
|
|
22
|
+
filename: '_downloads/stellar_update/',
|
|
23
|
+
},
|
|
24
|
+
function(download, status) {
|
|
25
|
+
clearTimeout(timeout);
|
|
26
|
+
|
|
27
|
+
if (status === 200) {
|
|
28
|
+
if (!download.filename) {
|
|
29
|
+
const errorMsg = '下载文件路径为空';
|
|
30
|
+
uni.showToast({ title: errorMsg, icon: 'none' });
|
|
31
|
+
error && error(new Error(errorMsg));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
downloadSuccess && downloadSuccess(download.filename);
|
|
36
|
+
|
|
37
|
+
plus.runtime.install(
|
|
38
|
+
download.filename,
|
|
39
|
+
{ force: true },
|
|
40
|
+
function() {
|
|
41
|
+
if (package_type == 1) {
|
|
42
|
+
uni.showModal({
|
|
43
|
+
title: '提示',
|
|
44
|
+
content: '升级成功,请重新启动!',
|
|
45
|
+
confirmText: '确定',
|
|
46
|
+
showCancel: false,
|
|
47
|
+
success: function() {
|
|
48
|
+
success && success();
|
|
49
|
+
plus.runtime.restart();
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
} else {
|
|
53
|
+
success && success();
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
function(e) {
|
|
57
|
+
const errorMsg = e.message || '安装失败';
|
|
58
|
+
uni.showModal({
|
|
59
|
+
title: '提示',
|
|
60
|
+
content: errorMsg,
|
|
61
|
+
showCancel: false,
|
|
62
|
+
success: function() {
|
|
63
|
+
error && error(e);
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
} else {
|
|
69
|
+
const errorMsg = '下载失败,状态码:' + status;
|
|
70
|
+
uni.showToast({ title: errorMsg, icon: 'none' });
|
|
71
|
+
error && error(new Error(errorMsg));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
task.addEventListener('statechanged', function(download) {
|
|
77
|
+
if (download.state === 3 && download.totalSize > 0) {
|
|
78
|
+
const progress = Math.round((download.downloadedSize / download.totalSize) * 100);
|
|
79
|
+
onProgressUpdate && onProgressUpdate({
|
|
80
|
+
progress: progress,
|
|
81
|
+
totalBytesWritten: download.downloadedSize,
|
|
82
|
+
totalBytesExpectedToWrite: download.totalSize,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
clearTimeout(timeout);
|
|
86
|
+
timeout = setTimeout(function() {
|
|
87
|
+
task.abort();
|
|
88
|
+
const errorMsg = '下载超时,请检查网络连接';
|
|
89
|
+
uni.showToast({ title: errorMsg, icon: 'none' });
|
|
90
|
+
error && error(new Error(errorMsg));
|
|
91
|
+
}, 300000);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (download.state === 4 || download.state === -1) {
|
|
95
|
+
clearTimeout(timeout);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
timeout = setTimeout(function() {
|
|
100
|
+
task.abort();
|
|
101
|
+
const errorMsg = '下载超时,请检查网络连接';
|
|
102
|
+
uni.showToast({ title: errorMsg, icon: 'none' });
|
|
103
|
+
error && error(new Error(errorMsg));
|
|
104
|
+
}, 300000);
|
|
105
|
+
|
|
106
|
+
task.start();
|
|
107
|
+
return task;
|
|
108
|
+
// #endif
|
|
109
|
+
|
|
110
|
+
// #ifndef APP-PLUS
|
|
111
|
+
let timeoutFallback;
|
|
112
|
+
|
|
13
113
|
const downloadTask = uni.downloadFile({
|
|
14
114
|
url: data.updateFile,
|
|
15
|
-
success: (res)
|
|
16
|
-
clearTimeout(
|
|
115
|
+
success: function(res) {
|
|
116
|
+
clearTimeout(timeoutFallback);
|
|
17
117
|
|
|
18
118
|
if (res.statusCode === 200) {
|
|
19
|
-
// 文件完整性检查
|
|
20
119
|
if (!res.tempFilePath) {
|
|
21
120
|
const errorMsg = '下载文件路径为空';
|
|
22
121
|
uni.showToast({ title: errorMsg, icon: 'none' });
|
|
@@ -29,70 +128,63 @@ export function download(data, { success, error, onProgressUpdate, downloadSucce
|
|
|
29
128
|
plus.runtime.install(
|
|
30
129
|
res.tempFilePath,
|
|
31
130
|
{ force: true },
|
|
32
|
-
()
|
|
33
|
-
// wgt升级
|
|
131
|
+
function() {
|
|
34
132
|
if (package_type == 1) {
|
|
35
133
|
uni.showModal({
|
|
36
134
|
title: '提示',
|
|
37
135
|
content: '升级成功,请重新启动!',
|
|
38
136
|
confirmText: '确定',
|
|
39
137
|
showCancel: false,
|
|
40
|
-
success: ()
|
|
138
|
+
success: function() {
|
|
41
139
|
success && success();
|
|
42
140
|
plus.runtime.restart();
|
|
43
141
|
},
|
|
44
142
|
});
|
|
45
143
|
} else {
|
|
46
|
-
// 整包升级
|
|
47
144
|
success && success();
|
|
48
145
|
}
|
|
49
146
|
},
|
|
50
|
-
(e)
|
|
51
|
-
// 提示部分wgt包无法安装的问题
|
|
147
|
+
function(e) {
|
|
52
148
|
const errorMsg = e.message || '安装失败';
|
|
53
149
|
uni.showModal({
|
|
54
150
|
title: '提示',
|
|
55
151
|
content: errorMsg,
|
|
56
152
|
showCancel: false,
|
|
57
|
-
success: ()
|
|
153
|
+
success: function() {
|
|
58
154
|
error && error(e);
|
|
59
155
|
},
|
|
60
156
|
});
|
|
61
157
|
}
|
|
62
158
|
);
|
|
63
159
|
} else {
|
|
64
|
-
const errorMsg =
|
|
160
|
+
const errorMsg = '下载失败,状态码:' + res.statusCode;
|
|
65
161
|
uni.showToast({ title: errorMsg, icon: 'none' });
|
|
66
162
|
error && error(new Error(errorMsg));
|
|
67
163
|
}
|
|
68
164
|
},
|
|
69
|
-
fail: (err)
|
|
70
|
-
clearTimeout(
|
|
71
|
-
const errorMsg =
|
|
165
|
+
fail: function(err) {
|
|
166
|
+
clearTimeout(timeoutFallback);
|
|
167
|
+
const errorMsg = '网络请求失败:' + (err.errMsg || '未知错误');
|
|
72
168
|
uni.showToast({ title: errorMsg, icon: 'none' });
|
|
73
169
|
error && error(err);
|
|
74
|
-
}
|
|
170
|
+
},
|
|
75
171
|
});
|
|
76
172
|
|
|
77
|
-
|
|
78
|
-
downloadTask.onProgressUpdate((res) => {
|
|
79
|
-
// 添加进度验证
|
|
173
|
+
downloadTask.onProgressUpdate(function(res) {
|
|
80
174
|
if (res.progress >= 0 && res.progress <= 100) {
|
|
81
175
|
onProgressUpdate && onProgressUpdate(res);
|
|
82
176
|
}
|
|
83
177
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
timeout = setTimeout(() => {
|
|
178
|
+
clearTimeout(timeoutFallback);
|
|
179
|
+
timeoutFallback = setTimeout(function() {
|
|
87
180
|
downloadTask.abort();
|
|
88
181
|
const errorMsg = '下载超时,请检查网络连接';
|
|
89
182
|
uni.showToast({ title: errorMsg, icon: 'none' });
|
|
90
183
|
error && error(new Error(errorMsg));
|
|
91
|
-
}, 300000);
|
|
184
|
+
}, 300000);
|
|
92
185
|
});
|
|
93
186
|
|
|
94
|
-
|
|
95
|
-
timeout = setTimeout(() => {
|
|
187
|
+
timeoutFallback = setTimeout(function() {
|
|
96
188
|
downloadTask.abort();
|
|
97
189
|
const errorMsg = '下载超时,请检查网络连接';
|
|
98
190
|
uni.showToast({ title: errorMsg, icon: 'none' });
|
|
@@ -100,6 +192,7 @@ export function download(data, { success, error, onProgressUpdate, downloadSucce
|
|
|
100
192
|
}, 300000);
|
|
101
193
|
|
|
102
194
|
return downloadTask;
|
|
195
|
+
// #endif
|
|
103
196
|
}
|
|
104
197
|
|
|
105
198
|
// 获取设备唯一标识
|
|
@@ -144,3 +237,70 @@ export const getVersion = (appVersion) => {
|
|
|
144
237
|
}
|
|
145
238
|
});
|
|
146
239
|
};
|
|
240
|
+
|
|
241
|
+
const DOWNLOAD_STATE_KEY = 'app_update_download_state';
|
|
242
|
+
export const DOWNLOAD_TIMEOUT = 30 * 60 * 1000;
|
|
243
|
+
|
|
244
|
+
export const saveDownloadState = (state) => {
|
|
245
|
+
try {
|
|
246
|
+
uni.setStorageSync(DOWNLOAD_STATE_KEY, JSON.stringify(state));
|
|
247
|
+
} catch (e) {
|
|
248
|
+
console.warn('保存下载状态失败:', e);
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
export const getDownloadState = () => {
|
|
253
|
+
try {
|
|
254
|
+
const stored = uni.getStorageSync(DOWNLOAD_STATE_KEY);
|
|
255
|
+
if (stored) {
|
|
256
|
+
return JSON.parse(stored);
|
|
257
|
+
}
|
|
258
|
+
} catch (e) {
|
|
259
|
+
console.warn('读取下载状态失败:', e);
|
|
260
|
+
}
|
|
261
|
+
return null;
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
export const clearDownloadState = () => {
|
|
265
|
+
try {
|
|
266
|
+
uni.removeStorageSync(DOWNLOAD_STATE_KEY);
|
|
267
|
+
} catch (e) {
|
|
268
|
+
console.warn('清除下载状态失败:', e);
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
export const isDownloadStateExpired = (state) => {
|
|
273
|
+
return Date.now() - state.startTime > DOWNLOAD_TIMEOUT;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
export const findExistingDownloadTask = (url) => {
|
|
277
|
+
return new Promise(function(resolve) {
|
|
278
|
+
// #ifdef APP-PLUS
|
|
279
|
+
plus.downloader.enumerate(function(tasks) {
|
|
280
|
+
if (!tasks || !tasks.length) {
|
|
281
|
+
resolve(null);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
for (let i = tasks.length - 1; i >= 0; i--) {
|
|
285
|
+
const task = tasks[i];
|
|
286
|
+
if (task.url === url) {
|
|
287
|
+
if (task.state === 0 || task.state === 1 || task.state === 2 || task.state === 3 || task.state === 4) {
|
|
288
|
+
resolve({ task: task, state: task.state, filename: task.filename || '' });
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
if (task.state === -1) {
|
|
292
|
+
try {
|
|
293
|
+
task.abort();
|
|
294
|
+
} catch (_) {}
|
|
295
|
+
}
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
resolve(null);
|
|
300
|
+
});
|
|
301
|
+
// #endif
|
|
302
|
+
// #ifndef APP-PLUS
|
|
303
|
+
resolve(null);
|
|
304
|
+
// #endif
|
|
305
|
+
});
|
|
306
|
+
};
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
</view>
|
|
40
40
|
</template>
|
|
41
41
|
<script>
|
|
42
|
-
import { download, getDeviceId, getPlatform, getAppId, getVersion } from './method';
|
|
42
|
+
import { download, getDeviceId, getPlatform, getAppId, getVersion, saveDownloadState, getDownloadState, clearDownloadState, isDownloadStateExpired, findExistingDownloadTask } from './method';
|
|
43
43
|
|
|
44
44
|
const STORAGE_KEY = 'skipped_app_versions';
|
|
45
45
|
|
|
@@ -86,6 +86,11 @@ export default {
|
|
|
86
86
|
type: String,
|
|
87
87
|
default: 'https://stellar-public-prd.intecloud.com.cn/api/app-update/check',
|
|
88
88
|
},
|
|
89
|
+
/** 严格版本检查,设为true时只有新版本大于当前版本才触发更新 */
|
|
90
|
+
strictVersionCheck: {
|
|
91
|
+
type: Boolean,
|
|
92
|
+
default: false,
|
|
93
|
+
},
|
|
89
94
|
},
|
|
90
95
|
data() {
|
|
91
96
|
return {
|
|
@@ -107,6 +112,9 @@ export default {
|
|
|
107
112
|
skippedVersions: [], // 跳过的版本列表
|
|
108
113
|
timeoutTimer: null, // 超时计时器
|
|
109
114
|
downloadTask: null, // 下载任务引用
|
|
115
|
+
nativeDownloadTask: null, // 原生下载任务引用
|
|
116
|
+
nativeDownloadListener: null, // 原生下载监听器
|
|
117
|
+
progressPollTimer: null, // 进度轮询计时器
|
|
110
118
|
};
|
|
111
119
|
},
|
|
112
120
|
methods: {
|
|
@@ -134,6 +142,19 @@ export default {
|
|
|
134
142
|
isVersionSkipped(versionCode) {
|
|
135
143
|
return this.skippedVersions.includes(versionCode);
|
|
136
144
|
},
|
|
145
|
+
// 版本比较函数
|
|
146
|
+
compareVersions(newVersion, currentVersion) {
|
|
147
|
+
const newParts = newVersion.split('.').map(function(v) { return parseInt(v) || 0; });
|
|
148
|
+
const currentParts = currentVersion.split('.').map(function(v) { return parseInt(v) || 0; });
|
|
149
|
+
const maxLength = Math.max(newParts.length, currentParts.length);
|
|
150
|
+
for (let i = 0; i < maxLength; i++) {
|
|
151
|
+
const newPart = newParts[i] || 0;
|
|
152
|
+
const currentPart = currentParts[i] || 0;
|
|
153
|
+
if (newPart > currentPart) return 1;
|
|
154
|
+
if (newPart < currentPart) return -1;
|
|
155
|
+
}
|
|
156
|
+
return 0;
|
|
157
|
+
},
|
|
137
158
|
// 跳过当前版本
|
|
138
159
|
skipVersion() {
|
|
139
160
|
if (!this.data.code) return;
|
|
@@ -152,7 +173,100 @@ export default {
|
|
|
152
173
|
clearTimeout(this.timeoutTimer);
|
|
153
174
|
this.timeoutTimer = null;
|
|
154
175
|
}
|
|
176
|
+
this.stopProgressPolling();
|
|
177
|
+
// #ifdef APP-PLUS
|
|
178
|
+
if (this.nativeDownloadTask && this.nativeDownloadListener) {
|
|
179
|
+
try {
|
|
180
|
+
this.nativeDownloadTask.removeEventListener('statechanged', this.nativeDownloadListener);
|
|
181
|
+
} catch (_) {}
|
|
182
|
+
}
|
|
183
|
+
// #endif
|
|
155
184
|
this.downloadTask = null;
|
|
185
|
+
this.nativeDownloadTask = null;
|
|
186
|
+
this.nativeDownloadListener = null;
|
|
187
|
+
},
|
|
188
|
+
// 停止进度轮询
|
|
189
|
+
stopProgressPolling() {
|
|
190
|
+
if (this.progressPollTimer) {
|
|
191
|
+
clearInterval(this.progressPollTimer);
|
|
192
|
+
this.progressPollTimer = null;
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
// 恢复下载进度
|
|
196
|
+
resumeDownloadProgress(task) {
|
|
197
|
+
// #ifdef APP-PLUS
|
|
198
|
+
if (this.nativeDownloadTask && this.nativeDownloadListener) {
|
|
199
|
+
this.nativeDownloadTask.removeEventListener('statechanged', this.nativeDownloadListener);
|
|
200
|
+
}
|
|
201
|
+
this.stopProgressPolling();
|
|
202
|
+
|
|
203
|
+
this.nativeDownloadTask = task;
|
|
204
|
+
|
|
205
|
+
var self = this;
|
|
206
|
+
var updateProgress = function() {
|
|
207
|
+
if (task.downloadedSize !== undefined && task.totalSize > 0) {
|
|
208
|
+
self.percent = Math.round((task.downloadedSize / task.totalSize) * 100);
|
|
209
|
+
self.downloadedSize = (task.downloadedSize / Math.pow(1024, 2)).toFixed(2);
|
|
210
|
+
self.packageFileSize = (task.totalSize / Math.pow(1024, 2)).toFixed(2);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
updateProgress();
|
|
214
|
+
|
|
215
|
+
this.nativeDownloadListener = function(download) {
|
|
216
|
+
if (download.state === 4) {
|
|
217
|
+
self.stopProgressPolling();
|
|
218
|
+
self.percent = 100;
|
|
219
|
+
self.downloadedSize = self.packageFileSize;
|
|
220
|
+
self.tempFilePath = download.filename;
|
|
221
|
+
if (self.open && self.data.package_type === 1 && download.filename) {
|
|
222
|
+
self.installWgt(download.filename);
|
|
223
|
+
}
|
|
224
|
+
} else if (download.state === -1) {
|
|
225
|
+
self.stopProgressPolling();
|
|
226
|
+
self.updateBtn = true;
|
|
227
|
+
clearDownloadState();
|
|
228
|
+
self.cleanup();
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
task.addEventListener('statechanged', this.nativeDownloadListener);
|
|
233
|
+
|
|
234
|
+
if (task.state === 3) {
|
|
235
|
+
this.progressPollTimer = setInterval(updateProgress, 500);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (task.state === 0) {
|
|
239
|
+
task.start();
|
|
240
|
+
}
|
|
241
|
+
// #endif
|
|
242
|
+
},
|
|
243
|
+
// 安装wgt包
|
|
244
|
+
installWgt(filePath) {
|
|
245
|
+
// #ifdef APP-PLUS
|
|
246
|
+
plus.runtime.install(
|
|
247
|
+
filePath,
|
|
248
|
+
{ force: true },
|
|
249
|
+
function() {
|
|
250
|
+
uni.showModal({
|
|
251
|
+
title: '提示',
|
|
252
|
+
content: '升级成功,请重新启动!',
|
|
253
|
+
confirmText: '确定',
|
|
254
|
+
showCancel: false,
|
|
255
|
+
success: function() {
|
|
256
|
+
clearDownloadState();
|
|
257
|
+
plus.runtime.restart();
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
},
|
|
261
|
+
function(e) {
|
|
262
|
+
uni.showModal({
|
|
263
|
+
title: '安装失败',
|
|
264
|
+
content: e.message || '安装过程中出现错误',
|
|
265
|
+
showCancel: false,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
);
|
|
269
|
+
// #endif
|
|
156
270
|
},
|
|
157
271
|
// 获取跳过版本列表
|
|
158
272
|
getSkippedVersions() {
|
|
@@ -237,7 +351,7 @@ export default {
|
|
|
237
351
|
header: {
|
|
238
352
|
Authorization: `Basic ${btoa(this.clientId + ':' + this.clientSecret)}`,
|
|
239
353
|
},
|
|
240
|
-
success: (res) => {
|
|
354
|
+
success: async (res) => {
|
|
241
355
|
try {
|
|
242
356
|
const _data = res.data;
|
|
243
357
|
if (_data.code == 200 && _data.data) {
|
|
@@ -278,7 +392,40 @@ export default {
|
|
|
278
392
|
nvs.splice(nvs.length - 1);
|
|
279
393
|
this.data.name = nvs.join('.');
|
|
280
394
|
}
|
|
281
|
-
|
|
395
|
+
const shouldUpdate = this.strictVersionCheck
|
|
396
|
+
? this.compareVersions(this.data.name, this.version) > 0
|
|
397
|
+
: this.data.code !== this.version;
|
|
398
|
+
if (this.data.updateFile && shouldUpdate) {
|
|
399
|
+
const downloadState = getDownloadState();
|
|
400
|
+
const hasValidDownloadState = downloadState
|
|
401
|
+
&& downloadState.versionCode === this.data.code
|
|
402
|
+
&& downloadState.updateFile === this.data.updateFile
|
|
403
|
+
&& !isDownloadStateExpired(downloadState);
|
|
404
|
+
|
|
405
|
+
if (hasValidDownloadState) {
|
|
406
|
+
const existing = await findExistingDownloadTask(this.data.updateFile);
|
|
407
|
+
|
|
408
|
+
if (existing) {
|
|
409
|
+
this.open = true;
|
|
410
|
+
this.$emit('update');
|
|
411
|
+
if (existing.state === 0 || existing.state === 1 || existing.state === 2 || existing.state === 3) {
|
|
412
|
+
this.updateBtn = false;
|
|
413
|
+
this.resumeDownloadProgress(existing.task);
|
|
414
|
+
} else if (existing.state === 4) {
|
|
415
|
+
this.updateBtn = false;
|
|
416
|
+
this.tempFilePath = existing.filename;
|
|
417
|
+
if (this.data.package_type === 1 && existing.filename) {
|
|
418
|
+
this.installWgt(existing.filename);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (downloadState) {
|
|
426
|
+
clearDownloadState();
|
|
427
|
+
}
|
|
428
|
+
|
|
282
429
|
this.open = true;
|
|
283
430
|
this.$emit('update');
|
|
284
431
|
// 如果是强制更新,直接开始下载
|
|
@@ -330,7 +477,7 @@ export default {
|
|
|
330
477
|
}
|
|
331
478
|
},
|
|
332
479
|
|
|
333
|
-
confirm() {
|
|
480
|
+
async confirm() {
|
|
334
481
|
// 先清理之前的任务
|
|
335
482
|
this.cleanup();
|
|
336
483
|
|
|
@@ -340,6 +487,20 @@ export default {
|
|
|
340
487
|
return;
|
|
341
488
|
}
|
|
342
489
|
|
|
490
|
+
// #ifdef APP-PLUS
|
|
491
|
+
var self = this;
|
|
492
|
+
var stale = await findExistingDownloadTask(this.data.updateFile);
|
|
493
|
+
if (stale) {
|
|
494
|
+
try { stale.task.abort(); } catch (_) {}
|
|
495
|
+
}
|
|
496
|
+
// #endif
|
|
497
|
+
|
|
498
|
+
saveDownloadState({
|
|
499
|
+
versionCode: this.data.code,
|
|
500
|
+
updateFile: this.data.updateFile,
|
|
501
|
+
startTime: Date.now(),
|
|
502
|
+
});
|
|
503
|
+
|
|
343
504
|
if (this.data.package_type == 0) {
|
|
344
505
|
// apk整包升级 下载地址必须以.apk结尾
|
|
345
506
|
if (this.data.updateFile.includes('.apk')) {
|
|
@@ -349,9 +510,11 @@ export default {
|
|
|
349
510
|
downloadSuccess: (path) => (this.tempFilePath = path),
|
|
350
511
|
error: () => {
|
|
351
512
|
this.updateBtn = true;
|
|
513
|
+
clearDownloadState();
|
|
352
514
|
this.cleanup();
|
|
353
515
|
},
|
|
354
516
|
success: () => {
|
|
517
|
+
clearDownloadState();
|
|
355
518
|
this.cleanup();
|
|
356
519
|
},
|
|
357
520
|
});
|
|
@@ -370,9 +533,11 @@ export default {
|
|
|
370
533
|
downloadSuccess: (path) => (this.tempFilePath = path),
|
|
371
534
|
error: () => {
|
|
372
535
|
this.updateBtn = true;
|
|
536
|
+
clearDownloadState();
|
|
373
537
|
this.cleanup();
|
|
374
538
|
},
|
|
375
539
|
success: () => {
|
|
540
|
+
clearDownloadState();
|
|
376
541
|
this.cleanup();
|
|
377
542
|
},
|
|
378
543
|
});
|
|
@@ -430,6 +595,7 @@ export default {
|
|
|
430
595
|
if (this.downloadTask) {
|
|
431
596
|
this.downloadTask.abort();
|
|
432
597
|
}
|
|
598
|
+
clearDownloadState();
|
|
433
599
|
this.cleanup();
|
|
434
600
|
this.updateBtn = true;
|
|
435
601
|
this.percent = 0;
|