Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
DCloud
hello uni-app x
提交
340d1c92
H
hello uni-app x
项目概览
DCloud
/
hello uni-app x
通知
5995
Star
90
Fork
162
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
18
列表
看板
标记
里程碑
合并请求
1
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello uni-app x
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
18
Issue
18
列表
看板
标记
里程碑
合并请求
1
合并请求
1
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
340d1c92
编写于
11月 04, 2023
作者:
DCloud-yyl
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'dev' into alpha
上级
9846133f
9cfbc0cb
变更
21
隐藏空白更改
内联
并排
Showing
21 changed file
with
2007 addition
and
162 deletion
+2007
-162
pages.json
pages.json
+13
-0
pages/API/element-draw/element-draw.uvue
pages/API/element-draw/element-draw.uvue
+120
-120
pages/CSS/text/line-height.uvue
pages/CSS/text/line-height.uvue
+5
-5
pages/component/form/form.test.js
pages/component/form/form.test.js
+64
-0
pages/component/form/form.uvue
pages/component/form/form.uvue
+124
-0
pages/component/image/image-path.uvue
pages/component/image/image-path.uvue
+11
-1
pages/component/web-view/web-view.uvue
pages/component/web-view/web-view.uvue
+17
-18
pages/tabBar/component.uvue
pages/tabBar/component.uvue
+24
-8
pages/template/custom-tab-bar/custom-tab-bar.uvue
pages/template/custom-tab-bar/custom-tab-bar.uvue
+7
-9
pages/template/long-list/long-list.uvue
pages/template/long-list/long-list.uvue
+1
-1
pages/template/schema/schema.uvue
pages/template/schema/schema.uvue
+35
-0
uni_modules/uni-upgrade-center-app/changelog.md
uni_modules/uni-upgrade-center-app/changelog.md
+72
-0
uni_modules/uni-upgrade-center-app/package.json
uni_modules/uni-upgrade-center-app/package.json
+81
-0
uni_modules/uni-upgrade-center-app/pages/upgrade-popup-uts.uvue
...dules/uni-upgrade-center-app/pages/upgrade-popup-uts.uvue
+437
-0
uni_modules/uni-upgrade-center-app/pages/upgrade-popup.vue
uni_modules/uni-upgrade-center-app/pages/upgrade-popup.vue
+554
-0
uni_modules/uni-upgrade-center-app/readme.md
uni_modules/uni-upgrade-center-app/readme.md
+126
-0
uni_modules/uni-upgrade-center-app/static/app_update_close.png
...odules/uni-upgrade-center-app/static/app_update_close.png
+0
-0
uni_modules/uni-upgrade-center-app/static/bg_top.png
uni_modules/uni-upgrade-center-app/static/bg_top.png
+0
-0
uni_modules/uni-upgrade-center-app/uniCloud/database/db_init.json
...les/uni-upgrade-center-app/uniCloud/database/db_init.json
+1
-0
uni_modules/uni-upgrade-center-app/utils/call-check-version.ts
...odules/uni-upgrade-center-app/utils/call-check-version.ts
+109
-0
uni_modules/uni-upgrade-center-app/utils/check-update.ts
uni_modules/uni-upgrade-center-app/utils/check-update.ts
+206
-0
未找到文件。
pages.json
浏览文件 @
340d1c92
...
...
@@ -37,6 +37,12 @@
"style"
:
{
"navigationBarTitleText"
:
"progress"
}
},
{
"path"
:
"pages/component/form/form"
,
"style"
:
{
"navigationBarTitleText"
:
"form"
}
},
{
"path"
:
"pages/component/button/button"
,
...
...
@@ -1047,6 +1053,13 @@
"navigationBarTitleText"
:
"install-apk"
,
"enablePullDownRefresh"
:
false
}
},
{
"path"
:
"pages/template/schema/schema"
,
"style"
:
{
"navigationBarTitleText"
:
"打开schema示例"
}
}
],
...
...
pages/API/element-draw/element-draw.uvue
浏览文件 @
340d1c92
...
...
@@ -59,66 +59,66 @@
drawText() {
let element = uni.getElementById('draw-text-view')
let ctx = element!.getDrawableContext()
let width = element.getBoundingClientRect().width
let width = element
!
.getBoundingClientRect().width
ctx!.reset()
ctx.font = "15px"
ctx.textAlign = "center"
ctx
!
.font = "15px"
ctx
!
.textAlign = "center"
for (var i = 0; i < this.texts.length; i++) {
let value = this.texts[i]
if (i % 2 == 0) {
ctx.fillText(value, width / 2, (20 * (i + 1)))
ctx
!
.fillText(value, width / 2, (20 * (i + 1)))
} else {
ctx.strokeText(value, width / 2, (20 * (i + 1)))
ctx
!
.strokeText(value, width / 2, (20 * (i + 1)))
}
}
ctx.update()
ctx
!
.update()
},
drawLines() {
let ctx = uni.getElementById('draw-line-view')!.getDrawableContext()
ctx!.reset()
ctx.lineWidth = 10;
ctx
!
.lineWidth = 10;
["round", "bevel", "miter"].forEach((join, i) => {
ctx.lineJoin = join;
ctx.beginPath();
ctx.moveTo(5, 10 + i * 40);
ctx.lineTo(50, 50 + i * 40);
ctx.lineTo(90, 10 + i * 40);
ctx.lineTo(130, 50 + i * 40);
ctx.lineTo(170, 10 + i * 40);
ctx.stroke();
ctx
!
.lineJoin = join;
ctx
!
.beginPath();
ctx
!
.moveTo(5, 10 + i * 40);
ctx
!
.lineTo(50, 50 + i * 40);
ctx
!
.lineTo(90, 10 + i * 40);
ctx
!
.lineTo(130, 50 + i * 40);
ctx
!
.lineTo(170, 10 + i * 40);
ctx
!
.stroke();
});
ctx.lineWidth = 1
ctx
!
.lineWidth = 1
var space = 170
ctx.strokeStyle = '#09f';
ctx.beginPath();
ctx.moveTo(10 + space, 10);
ctx.lineTo(140 + space, 10);
ctx.moveTo(10 + space, 140);
ctx.lineTo(140 + space, 140);
ctx.stroke();
ctx
!
.strokeStyle = '#09f';
ctx
!
.beginPath();
ctx
!
.moveTo(10 + space, 10);
ctx
!
.lineTo(140 + space, 10);
ctx
!
.moveTo(10 + space, 140);
ctx
!
.lineTo(140 + space, 140);
ctx
!
.stroke();
// Draw lines
ctx.strokeStyle = 'black';
ctx
!
.strokeStyle = 'black';
['butt', 'round', 'square'].forEach((lineCap, i) => {
ctx.lineWidth = 15;
ctx.lineCap = lineCap;
ctx.beginPath();
ctx.moveTo(25 + space + i * 50, 10);
ctx.lineTo(25 + space + i * 50, 140);
ctx.stroke();
ctx
!
.lineWidth = 15;
ctx
!
.lineCap = lineCap;
ctx
!
.beginPath();
ctx
!
.moveTo(25 + space + i * 50, 10);
ctx
!
.lineTo(25 + space + i * 50, 140);
ctx
!
.stroke();
});
ctx.lineWidth = 1;
this.drawDashedLine([], ctx);
this.drawDashedLine([2, 2], ctx);
this.drawDashedLine([10, 10], ctx);
this.drawDashedLine([20, 5], ctx);
this.drawDashedLine([15, 3, 3, 3], ctx);
this.drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3], ctx);
ctx.lineDashOffset = 18;
this.drawDashedLine([12, 3, 3], ctx);
ctx.lineDashOffset = 0
ctx.setLineDash([0])
ctx.update()
ctx
!
.lineWidth = 1;
this.drawDashedLine([], ctx
!
);
this.drawDashedLine([2, 2], ctx
!
);
this.drawDashedLine([10, 10], ctx
!
);
this.drawDashedLine([20, 5], ctx
!
);
this.drawDashedLine([15, 3, 3, 3], ctx
!
);
this.drawDashedLine([20, 3, 3, 3, 3, 3, 3, 3], ctx
!
);
ctx
!
.lineDashOffset = 18;
this.drawDashedLine([12, 3, 3], ctx
!
);
ctx
!
.lineDashOffset = 0
ctx
!
.setLineDash([0])
ctx
!
.update()
},
drawDashedLine(pattern : Array<number>, ctx : DrawableContext) {
ctx.beginPath();
...
...
@@ -134,7 +134,7 @@
// Draw shapes
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 3; j++) {
ctx.beginPath();
ctx
!
.beginPath();
var x = 25 + j * 50; // x coordinate
var y = 25 + i * 50; // y coordinate
var radius = 20; // Arc radius
...
...
@@ -142,22 +142,22 @@
var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle
var clockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise
ctx.arc(x, y, radius, startAngle, endAngle, clockwise);
ctx
!
.arc(x, y, radius, startAngle, endAngle, clockwise);
if (i > 1) {
ctx.fill();
ctx
!
.fill();
} else {
ctx.stroke();
ctx
!
.stroke();
}
}
}
ctx.update()
ctx
!
.update()
},
drawStar() {
let ctx = uni.getElementById('draw-dash-line')!.getDrawableContext()
ctx!.reset()
ctx.beginPath();
ctx
!
.beginPath();
var horn = 5; // 画5个角
var angle = 360 / horn; // 五个角的度数
// 两个圆的半径
...
...
@@ -169,45 +169,45 @@
for (var i = 0; i < horn; i++) {
// 角度转弧度:角度/180*Math.PI
// 外圆顶点坐标
ctx.lineTo(Math.cos((18 + i * angle) / 180.0 * Math.PI) * R + x, -Math.sin((18 + i * angle) / 180.0 * Math.PI) * R + y);
ctx
!
.lineTo(Math.cos((18 + i * angle) / 180.0 * Math.PI) * R + x, -Math.sin((18 + i * angle) / 180.0 * Math.PI) * R + y);
// 內圆顶点坐标
ctx.lineTo(Math.cos((54 + i * angle) / 180.0 * Math.PI) * r + x, -Math.sin((54 + i * angle) / 180.0 * Math.PI) * r + y);
ctx
!
.lineTo(Math.cos((54 + i * angle) / 180.0 * Math.PI) * r + x, -Math.sin((54 + i * angle) / 180.0 * Math.PI) * r + y);
}
// closePath:关闭路径,将路径的终点与起点相连
ctx.closePath();
ctx.lineWidth = 3;
ctx.fillStyle = '#E4EF00';
ctx.strokeStyle = "red";
ctx.fill();
ctx.stroke();
ctx
!
.closePath();
ctx
!
.lineWidth = 3;
ctx
!
.fillStyle = '#E4EF00';
ctx
!
.strokeStyle = "red";
ctx
!
.fill();
ctx
!
.stroke();
ctx.lineWidth = 10;
ctx.beginPath()
ctx.moveTo(170, 100)
ctx.lineTo(255, 15)
ctx.lineTo(340, 100)
ctx.closePath()
ctx.fill()
ctx.strokeStyle = "blue"
ctx.stroke()
ctx.beginPath()
ctx.moveTo(170, 145)
ctx.lineTo(255, 45)
ctx.lineTo(340, 145)
ctx.closePath()
ctx.fill()
ctx.strokeStyle = "gray"
ctx.stroke()
ctx
!
.lineWidth = 10;
ctx
!
.beginPath()
ctx
!
.moveTo(170, 100)
ctx
!
.lineTo(255, 15)
ctx
!
.lineTo(340, 100)
ctx
!
.closePath()
ctx
!
.fill()
ctx
!
.strokeStyle = "blue"
ctx
!
.stroke()
ctx
!
.beginPath()
ctx
!
.moveTo(170, 145)
ctx
!
.lineTo(255, 45)
ctx
!
.lineTo(340, 145)
ctx
!
.closePath()
ctx
!
.fill()
ctx
!
.strokeStyle = "gray"
ctx
!
.stroke()
// 未设置beginPath,导致上下表现一致,与前端一致
ctx.moveTo(170, 190)
ctx.lineTo(255, 90)
ctx.lineTo(340, 190)
ctx.closePath()
ctx.fillStyle = "orange"
ctx.fill()
ctx.strokeStyle = "khaki"
ctx.stroke()
ctx.update()
ctx
!
.moveTo(170, 190)
ctx
!
.lineTo(255, 90)
ctx
!
.lineTo(340, 190)
ctx
!
.closePath()
ctx
!
.fillStyle = "orange"
ctx
!
.fill()
ctx
!
.strokeStyle = "khaki"
ctx
!
.stroke()
ctx
!
.update()
},
hex(num : number) : string {
if (num == 0) {
...
...
@@ -228,80 +228,80 @@
drawhouse() {
let ctx = uni.getElementById('draw-house')!.getDrawableContext()
ctx!.reset()
ctx.lineWidth = 10;
ctx
!
.lineWidth = 10;
// Wall
ctx.strokeRect(75, 140, 150, 110);
ctx
!
.strokeRect(75, 140, 150, 110);
// Door
ctx.fillRect(130, 190, 40, 60);
ctx
!
.fillRect(130, 190, 40, 60);
// Roof
ctx.beginPath();
ctx.moveTo(50, 140);
ctx.lineTo(150, 60);
ctx.lineTo(250, 140);
ctx.closePath();
ctx.stroke();
ctx.update()
ctx
!
.beginPath();
ctx
!
.moveTo(50, 140);
ctx
!
.lineTo(150, 60);
ctx
!
.lineTo(250, 140);
ctx
!
.closePath();
ctx
!
.stroke();
ctx
!
.update()
},
drawPoint() {
let ctx = uni.getElementById('draw-style')!.getDrawableContext()
ctx!.reset()
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) {
ctx.strokeStyle = `rgb(0,${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)})`;
ctx.beginPath();
ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
ctx.stroke();
ctx
!
.strokeStyle = `rgb(0,${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)})`;
ctx
!
.beginPath();
ctx
!
.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
ctx
!
.stroke();
}
}
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 6; j++) {
ctx.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)},0)`;
ctx.fillRect(180 + j * 25, i * 25, 25, 25);
ctx
!
.fillStyle = `rgb(${Math.floor(255 - 42.5 * i)},${Math.floor(255 - 42.5 * j)},0)`;
ctx
!
.fillRect(180 + j * 25, i * 25, 25, 25);
}
}
ctx.update()
ctx
!
.update()
},
drawRect() {
let ctx = uni.getElementById('draw-odd')!.getDrawableContext()
ctx!.reset()
// Create path
ctx.moveTo(30, 90);
ctx.lineTo(110, 20);
ctx.lineTo(240, 130);
ctx.lineTo(60, 130);
ctx.lineTo(190, 20);
ctx.lineTo(270, 90);
ctx.closePath();
ctx
!
.moveTo(30, 90);
ctx
!
.lineTo(110, 20);
ctx
!
.lineTo(240, 130);
ctx
!
.lineTo(60, 130);
ctx
!
.lineTo(190, 20);
ctx
!
.lineTo(270, 90);
ctx
!
.closePath();
// Fill path
ctx.fillStyle = "green";
ctx.fill("evenodd");
ctx.update()
ctx
!
.fillStyle = "green";
ctx
!
.fill("evenodd");
ctx
!
.update()
},
drawArcTo() {
let ctx = uni.getElementById('draw-arcto')!.getDrawableContext()
ctx!.reset()
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx.stroke();
ctx
!
.beginPath();
ctx
!
.moveTo(50, 20);
ctx
!
.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx
!
.stroke();
ctx.fillStyle = "blue";
ctx
!
.fillStyle = "blue";
// start point
ctx.fillRect(50, 20, 10, 10);
ctx
!
.fillRect(50, 20, 10, 10);
// end point
ctx.fillRect(50, 100, 10, 10);
ctx
!
.fillRect(50, 100, 10, 10);
ctx.fillStyle = "red";
ctx
!
.fillStyle = "red";
// control point one
ctx.fillRect(230, 30, 10, 10);
ctx
!
.fillRect(230, 30, 10, 10);
// control point two
ctx.fillRect(150, 70, 10, 10);
ctx.update()
ctx
!
.fillRect(150, 70, 10, 10);
ctx
!
.update()
}
}
}
...
...
pages/CSS/text/line-height.uvue
浏览文件 @
340d1c92
<template>
<view style="flex-grow: 1;">
<view style="height: 1000rpx;background-color: gray;justify-content: center;align-items: center;">
<text class="common">CSS测试 CSS测试 CSS测试</text>
<text class="common" style="line-height: 150rpx;">line-height: 150rpx</text>
<text class="common">CSS测试 CSS测试 CSS测试</text>
<text class="common" style="line-height: 3;">line-height: 3</text>
<text class="common">CSS测试 CSS测试 CSS测试</text>
<text class="common" style="line-height: 3em;">line-height: 3em</text>
<text class="common"
>CSS测试 CSS测试 CSS测试
</text>
<text class="common"
style="line-height: 3;">line-height: 3\nline-height: 3\nline-height: 3
</text>
</view>
</view>
</template>
...
...
@@ -19,5 +16,8 @@
<style>
.common {
font-size: 20px;
border: 1px red solid;
margin: 10px 0;
padding: 0 10px;
}
</style>
\ No newline at end of file
</style>
pages/component/form/form.test.js
0 → 100644
浏览文件 @
340d1c92
const
PAGE_PATH
=
'
/pages/component/form/form
'
const
DEFAULT_NICK_NAME
=
'
hello
'
const
DEFAULT_GENDER
=
'
0
'
const
DEFAULT_AGE
=
18
const
DEFAULT_SWITCH
=
true
const
CHANGE_NICK_NAME
=
'
hello
'
const
CHANGE_GENDER
=
'
0
'
const
CHANGE_AGE
=
50
const
CHANGE_SWITCH
=
false
describe
(
'
form
'
,
()
=>
{
let
page
beforeAll
(
async
()
=>
{
page
=
await
program
.
reLaunch
(
PAGE_PATH
)
await
page
.
waitFor
(
500
)
})
it
(
'
submit
'
,
async
()
=>
{
await
page
.
setData
({
nickname
:
CHANGE_NICK_NAME
,
age
:
CHANGE_AGE
,
switch
:
CHANGE_SWITCH
})
await
page
.
waitFor
(
200
)
const
btnSubmit
=
await
page
.
$
(
'
.btn-l
'
)
await
btnSubmit
.
tap
()
await
page
.
waitFor
(
200
)
const
{
formData
}
=
await
page
.
data
()
// expect(formData['nickname']).toBe(CHANGE_NICK_NAME)
expect
(
formData
[
'
gender
'
]).
toBe
(
CHANGE_GENDER
)
expect
(
formData
[
'
loves
'
][
0
]).
toBe
(
'
1
'
)
expect
(
formData
[
'
age
'
]).
toBe
(
CHANGE_AGE
)
expect
(
formData
[
'
switch
'
]).
toBe
(
CHANGE_SWITCH
)
})
it
(
'
reset
'
,
async
()
=>
{
await
page
.
setData
({
nickname
:
CHANGE_NICK_NAME
,
age
:
CHANGE_AGE
,
switch
:
CHANGE_SWITCH
})
await
page
.
waitFor
(
100
)
const
btnReset
=
await
page
.
$
(
'
.btn-r
'
)
await
btnReset
.
tap
()
await
page
.
waitFor
(
100
)
const
{
formData
}
=
await
page
.
data
()
// TODO
// expect(formData['nickname']).toBe(DEFAULT_NICK_NAME)
// expect(formData['gender']).toBe(undefined)
// expect(formData['loves'][0]).toBe(undefined)
// expect(formData['age']).toBe(undefined)
// expect(formData['switch']).toBe(undefined)
})
})
pages/component/form/form.uvue
0 → 100644
浏览文件 @
340d1c92
<template>
<!-- #ifdef APP -->
<scroll-view class="page">
<!-- #endif -->
<form @submit="onFormSubmit" @reset="onFormReset">
<view class="uni-form-item">
<view class="title">姓名</view>
<input class="uni-input" name="nickname" :value="nickname" placeholder="请输入姓名" />
</view>
<view class="uni-form-item">
<view class="title">性别</view>
<radio-group name="gender" class="flex-row">
<view class="group-item">
<radio value="0" :checked="gender=='0'" /><text>男</text>
</view>
<view class="group-item">
<radio value="1" :checked="gender=='1'" /><text>女</text>
</view>
</radio-group>
</view>
<view class="uni-form-item">
<view class="title">爱好</view>
<checkbox-group name="loves" class="flex-row">
<view class="group-item">
<checkbox value="0" /><text>读书</text>
</view>
<view class="group-item">
<checkbox value="1" :checked="true" /><text>写字</text>
</view>
</checkbox-group>
</view>
<view class="uni-form-item">
<view class="title">年龄</view>
<slider name="age" :value="age" :show-value="true"></slider>
</view>
<view class="uni-form-item">
<view class="title">保留选项</view>
<view>
<switch name="switch" :checked="switch" />
</view>
</view>
<view class="uni-btn-v flex-row">
<button class="btn btn-l" form-type="submit" type="primary">Submit</button>
<button class="btn btn-r" type="default" form-type="reset">Reset</button>
</view>
</form>
<view class="result">提交的表单数据</view>
<textarea class="textarea" :value="formDataText"></textarea>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script>
export default {
data() {
return {
nickname: '',
gender: '0',
age: 18,
switch: true,
formData: {} as UTSJSONObject
}
},
computed: {
formDataText() : string {
return JSON.stringify(this.formData)
}
},
methods: {
onFormSubmit: function (e : FormSubmitEvent) {
this.formData = e.detail.value
},
onFormReset: function (_ : FormResetEvent) {
this.formData = {}
}
}
}
</script>
<style>
.page {
flex: 1;
padding: 15px;
}
.flex-row {
flex-direction: row;
}
.uni-form-item {
padding: 15px 0;
}
.title {
margin-bottom: 10px;
}
.group-item {
flex-direction: row;
margin-right: 20px;
}
.btn {
flex: 1;
}
.btn-l {
margin-right: 5px;
}
.btn-r {
margin-left: 5px;
}
.result {
margin-top: 30px;
}
.textarea {
margin-top: 5px;
background-color: #fff;
}
</style>
pages/component/image/image-path.uvue
浏览文件 @
340d1c92
...
...
@@ -11,6 +11,12 @@
<image class="image" mode="widthFix" :src="item.src" @error="imageErrorEvent"></image>
</view>
</view>
<view>
<text class="uni-subtitle-text">非static目录的src静态路径:./logo.png</text>
<view class="uni-center" style="background:#FFFFFF;">
<image class="image" mode="widthFix" src="./logo.png" @error="imageErrorEvent"></image>
</view>
</view>
</view>
</scroll-view>
</template>
...
...
@@ -36,7 +42,7 @@
},
{
src: logo,
description: '
非static目录(需import才能访问)
'
description: '
import方式
'
},
{
// #ifdef APP-ANDROID
...
...
@@ -76,6 +82,10 @@
{
src: 'https://request.dcloud.net.cn/api/http/contentType/404.png',
description: '错误网络地址,不存在的图片'
},
{
src: './logo.png',
description: '非static目录的动态路径(不显示是对的)'
}
] as Array<ImagePath>
}
...
...
pages/component/web-view/web-view.uvue
浏览文件 @
340d1c92
<template>
<view class="uni-flex-item">
<web-view id="web-view" class="uni-flex-item" :src="src" :webview-styles="webview_styles" @message="message"
@error="error" @loading="loading" @loaded="loaded">
@error="error" @loading="loading" @loaded="loaded"
@download="download"
>
</web-view>
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-input-v">
<input class="uni-input" confirmType="go" placeholder="输入网址跳转" @confirm="confirm" />
</view>
<view class="uni-row uni-btn-v">
<view class="uni-flex-item">
<button type="primary" @click="back">后退</button>
</view>
<view class="uni-btn-ml uni-flex-item">
<button type="primary" @click="forward">前进</button>
</view>
<button class="uni-flex-item" type="primary" @click="back">后退</button>
<button class="uni-btn-ml uni-flex-item" type="primary" @click="forward">前进</button>
</view>
<view class="uni-row uni-btn-v">
<view class="uni-flex-item">
<button type="primary" @click="reload">重新加载</button>
</view>
<view class="uni-btn-ml uni-flex-item">
<button type="primary" @click="stop">停止加载</button>
</view>
<button class="uni-flex-item" type="primary" @click="reload">重新加载</button>
<button class="uni-btn-ml uni-flex-item" type="primary" @click="stop">停止加载</button>
</view>
<view class="uni-btn-v">
<button type="primary" @click="nativeToWeb">原生和Web通信</button>
...
...
@@ -64,20 +56,27 @@
this.webviewContext?.evalJS("alert('hello uni-app x')");
},
message(event : WebViewMessageEvent) {
console.log(JSON.stringify(event
.detail
));
console.log(JSON.stringify(event));
},
error(event : WebViewErrorEvent) {
this.loadError = true
console.log(JSON.stringify(event
.detail
));
console.log(JSON.stringify(event));
},
loading(event : WebViewLoadingEvent) {
console.log(JSON.stringify(event
.type
));
console.log(JSON.stringify(event));
},
loaded(event : WebViewLoadedEvent) {
console.log(JSON.stringify(event.type));
console.log(JSON.stringify(event));
},
download(event : WebViewDownloadEvent) {
console.log(JSON.stringify(event));
uni.showModal({
content: "下载链接: " + event.detail.url + "\n文件大小: " + event.detail.contentLength / 1024 + "KB",
showCancel: false
});
},
confirm(event : InputConfirmEvent) {
console.log(
event.detail.value
);
console.log(
JSON.stringify(event)
);
let url = event.detail.value;
if (!url.startsWith('https://') && !url.startsWith('http://')) {
url = 'https://' + url;
...
...
pages/tabBar/component.uvue
浏览文件 @
340d1c92
...
...
@@ -38,14 +38,19 @@
</view>
</uni-collapse-item>
</template>
</uni-collapse>
</uni-collapse>
<upgradePopup ref="upgradePopup" @close="upgradePopupClose" />
</view>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts">
<script lang="uts">
import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update'
import upgradePopup from '@/uni_modules/uni-upgrade-center-app/pages/upgrade-popup-uts.uvue'
type Page = {
name : string
enable ?: boolean
...
...
@@ -119,10 +124,9 @@ export default {
{
name: 'checkbox',
},
/* {
name: 'form',
enable: false
}, */
{
name: 'form',
},
{
name: 'input',
/* }, {
...
...
@@ -266,6 +270,9 @@ export default {
arrowDownIcon: '/static/icons/arrow-down.png',
arrowRightIcon: '/static/icons/arrow-right.png',
}
},
components: {
upgradePopup: upgradePopup
},
methods: {
goDetailPage(e : Page) {
...
...
@@ -281,8 +288,17 @@ export default {
uni.navigateTo({
url,
})
},
},
},
upgradePopupClose() {
console.log('upgradePopup close');
}
},
onReady() {
checkUpdate(this.$refs['upgradePopup'] as ComponentPublicInstance)
},
beforeUnmount() {
uni.showTabBar()?.catch(_ => {})
}
}
</script>
...
...
pages/template/custom-tab-bar/custom-tab-bar.uvue
浏览文件 @
340d1c92
...
...
@@ -18,11 +18,8 @@
</text>
</view>
</view>
<view
@click="onPlusClick"
>
<view>
<image class="concave-image" mode="heightFix" src="/static/template/custom-tab-bar/concave.png"></image>
<view class="btn-plus">
<text class="btn-plus-text">+</text>
</view>
</view>
<view class="tab-item" @click="onTabClick(1)">
<view ref="tab-item2" class="tab-item-content">
...
...
@@ -34,6 +31,9 @@
</view>
</view>
</view>
<view class="btn-plus" @click="onPlusClick">
<text class="btn-plus-text">+</text>
</view>
</view>
</template>
...
...
@@ -179,15 +179,13 @@
.btn-plus {
position: absolute;
left: 43px;
width: 70px;
height: 70px;
bottom: 21px;
border-radius: 50px;
background-color: #FE5722;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
/* margin-left: auto;
margin-right: auto; */
margin-top: -35px;
align-self: center;
align-items: center;
justify-content: center;
overflow: visible;
...
...
@@ -197,4 +195,4 @@
color: #fff;
font-size: 32px;
}
</style>
\ No newline at end of file
</style>
pages/template/long-list/long-list.uvue
浏览文件 @
340d1c92
...
...
@@ -102,7 +102,7 @@
},
methods: {
// TODO
onStartNestedScroll(
event
: StartNestedScrollEvent) : boolean {
onStartNestedScroll(
_
: StartNestedScrollEvent) : boolean {
return true
},
onNestedPreScroll(event : NestedPreScrollEvent) {
...
...
pages/template/schema/schema.uvue
0 → 100644
浏览文件 @
340d1c92
<template>
<view>
<button class="button" @click="openSchema('https://uniapp.dcloud.io/uni-app-x')">使用外部浏览器打开指定URL</button>
<button class="button" @click="openSchema('market://details?id=com.tencent.mm')">使用应用商店打开指定App</button>
<button class="button" @click="openSchema('androidamap://viewMap?sourceApplication=Hello%20uni-app&poiname=DCloud&lat=39.9631018208&lon=116.3406135236&dev=0')">打开地图坐标</button>
</view>
</template>
<script>
import Intent from 'android.content.Intent';
import Uri from 'android.net.Uri';
export default {
data() {
return {
}
},
methods: {
openSchema(url:string) {
const context = UTSAndroid.getUniActivity()!;
const uri = Uri.parse(url)
const intent = new Intent(Intent.ACTION_VIEW, uri)
intent.setData(uri);
context.startActivity(intent);
}
}
}
</script>
<style>
.button {
margin: 30rpx;
}
</style>
uni_modules/uni-upgrade-center-app/changelog.md
0 → 100644
浏览文件 @
340d1c92
## 0.6.5(2023-10-27)
-
修复 安装 wgt 报错 manifest.json 文件不存在的Bug
## 0.6.4(2023-09-01)
chore: 优化代码结构
## 0.6.3(2023-08-30)
-
修复 下载 wgt 时如果后缀名不正确,重命名后安装
## 0.6.2(2022-11-21)
-
处理 cloudfunctions 目录
## 0.6.1(2022-08-17)
-
修复 后台添加应用市场,但都没有启用的情况下报错的Bug (需要 uni-admin 1.9.3+)
## 0.6.0(2022-07-19)
-
新增 支持多应用商店配置(需要 uni-admin 1.9.3+)
## 0.4.1(2022-05-27)
-
修复 上版引出的报错问题
## 0.4.0(2022-05-27)
-
新增 Android 支持跳转手机自带商店,填写升级包地址时请填写跳转商店链接
-
新增 改为云对象调用方式,使用更直观
## 0.3.3(2022-04-14)
-
修复 调用 check-update,当 code 为 0 时没有回调
## 0.3.2(2022-01-12)
-
优化显示逻辑
## 0.3.1(2021-11-24)
-
修复 vue3 上图片不显示的Bug
## 0.3.0(2021-11-18)
-
移除 wgt 安装成功后提示,防止重启过快弹框不消失
## 0.2.2(2021-08-25)
-
兼容vue3.0
## 0.2.1(2021-07-26)
-
修复 使用腾讯云并手动填写地址时,导致下载链接失效的bug
## 0.2.0(2021-07-13)
-
更新文档 关于报错local_storage_key 为空,请不要将页面路径设置为pages.json中第一项
## 0.1.9(2021-06-28)
-
更新文档
-
修复 wgt安装失败时,按钮状态不对
## 0.1.8(2021-06-16)
-
修复 跳转安装时,导致上次下载的apk还没安装就被删掉的bug
## 0.1.7(2021-06-03)
-
修改 移除static中的图片
## 0.1.6(2021-06-03)
-
修改 下载更新按钮使用CSS渐变色
## 0.1.5(2021-04-22)
-
更新check-update函数。现在返回一个Promise,有更新时成功回调,其他情况错误回调
## 0.1.4(2021-04-13)
-
更新文档。明确云函数调用结果
## 0.1.3(2021-04-13)
-
解耦云函数与弹框处理。utils中新增 call-check-version.js,可用于单独检测是否有更新
## 0.1.2(2021-04-07)
-
更新版本对比函数 compare
## 0.1.1(2021-04-07)
-
修复 腾讯云空间下载链接不能下载问题
## 0.1.0(2021-04-07)
-
新增使用uni.showModal提示升级示例
-
修改iOS升级提示方式
## 0.0.7(2021-04-02)
-
修复在iOS上打开弹框报错
## 0.0.6(2021-04-01)
-
兼容旧版本安卓
## 0.0.5(2021-04-01)
-
修复低版本安卓上进度条错位
## 0.0.4(2021-04-01)
-
更新readme
-
修复check-update语法错误
## 0.0.3(2021-04-01)
-
新增前台更新弹框,详见readme
-
更新前台检查更新方法
## 0.0.2(2021-03-29)
-
更新文档
-
移除 dependencies
## 0.0.1(2021-03-25)
-
升级中心前台检查更新
uni_modules/uni-upgrade-center-app/package.json
0 → 100644
浏览文件 @
340d1c92
{
"id"
:
"uni-upgrade-center-app"
,
"displayName"
:
"升级中心 uni-upgrade-center - App"
,
"version"
:
"0.6.5"
,
"description"
:
"uni升级中心 - 客户端检查更新"
,
"keywords"
:
[
"uniCloud"
,
"update"
,
"升级"
,
"wgt"
],
"repository"
:
"https://gitee.com/dcloud/uni-upgrade-center/tree/master/uni_modules/uni-upgrade-center-app"
,
"engines"
:
{
"HBuilderX"
:
"^3.2.14"
},
"dcloudext"
:
{
"sale"
:
{
"regular"
:
{
"price"
:
"0.00"
},
"sourcecode"
:
{
"price"
:
"0.00"
}
},
"contact"
:
{
"qq"
:
""
},
"declaration"
:
{
"ads"
:
"无"
,
"data"
:
"插件不采集任何数据"
,
"permissions"
:
"无"
},
"npmurl"
:
""
,
"type"
:
"unicloud-template-page"
},
"uni_modules"
:
{
"dependencies"
:
[],
"encrypt"
:
[],
"platforms"
:
{
"cloud"
:
{
"tcb"
:
"y"
,
"aliyun"
:
"y"
},
"client"
:
{
"App"
:
{
"app-vue"
:
"y"
,
"app-nvue"
:
"u"
},
"H5-mobile"
:
{
"Safari"
:
"y"
,
"Android Browser"
:
"y"
,
"微信浏览器(Android)"
:
"y"
,
"QQ浏览器(Android)"
:
"y"
},
"H5-pc"
:
{
"Chrome"
:
"y"
,
"IE"
:
"y"
,
"Edge"
:
"y"
,
"Firefox"
:
"y"
,
"Safari"
:
"y"
},
"小程序"
:
{
"微信"
:
"u"
,
"阿里"
:
"u"
,
"百度"
:
"u"
,
"字节跳动"
:
"u"
,
"QQ"
:
"u"
,
"京东"
:
"u"
},
"快应用"
:
{
"华为"
:
"u"
,
"联盟"
:
"u"
},
"Vue"
:
{
"vue2"
:
"y"
,
"vue3"
:
"y"
}
}
}
}
}
uni_modules/uni-upgrade-center-app/pages/upgrade-popup-uts.uvue
0 → 100644
浏览文件 @
340d1c92
<template>
<view v-show="shown" class="mask flex-center">
<view class="content">
<view class="content-top">
<text class="content-top-text">{{title}}</text>
<image class="content-top-image" mode="widthFix"
src="/uni_modules/uni-upgrade-center-app/static/bg_top.png"></image>
</view>
<view class="content-body">
<view class="content-body-title">
<text class="text title">{{subTitle}}</text>
<!-- <text style="padding-left:20rpx;font-size: 0.5em;color: #666;">v.{{version}}</text> -->
</view>
<view class="body">
<scroll-view class="box-des-scroll" scroll-y="true">
<text class="text box-des">
{{contents}}
</text>
</scroll-view>
</view>
<view class="footer flex-center">
<template v-if="isiOS">
uni-app x 暂不支持 iOS
<!-- <button class="content-button" style="border: none;color: #fff;" plain @click="jumpToAppStore">
{{downLoadBtnTextiOS}}
</button> -->
</template>
<template v-else>
<template v-if="!downloadSuccess">
<view class="progress-box flex-column" v-if="downloading">
<progress class="progress" style="width: 90%;height: 40rpx;border-radius: 35px;"
:percent="downLoadPercent" activeColor="#3DA7FF" :show-info="true"
:stroke-width="10" />
<view
style="width:100%;display: flex;justify-content: space-around;flex-direction: row;">
<text class="text" style="font-size: 28rpx;">{{downLoadingText}}</text>
<text class="text"
style="font-size: 28rpx;">({{downloadedSize}}/{{packageFileSize}}M)</text>
</view>
</view>
<button v-else class="content-button"
style="border: none; color: #fff;width: 100%;height: 80rpx;line-height: 80rpx;font-size: 30rpx;font-weight: 400;border-radius: 40rpx;text-align: center;background: #1785ff"
:plain="true" @click="updateApp">
{{downLoadBtnText}}
</button>
</template>
<button v-else-if="downloadSuccess && !installed" class="content-button"
style="border: none; color: #fff;width: 100%;height: 80rpx;line-height: 80rpx;font-size: 30rpx;font-weight: 400;border-radius: 40rpx;text-align: center;background: #1785ff"
:plain="true" :loading="installing" :disabled="installing" @click="installPackage">
{{installing ? '正在安装……' : '下载完成,立即安装'}}
</button>
<button v-else-if="installed" class="content-button"
style="border: none; color: #ccc;width: 100%;height: 80rpx;line-height: 80rpx;font-size: 30rpx;font-weight: 400;border-radius: 40rpx;text-align: center;background: #1785ff"
:plain="true" :disabled="true">
安装完成后,请重启应用
</button>
</template>
</view>
</view>
<view class="content-bottom">
<image v-if="!is_mandatory" class="close-img" mode="widthFix"
src="/uni_modules/uni-upgrade-center-app/static/app_update_close.png" @click="closeUpdate">
</image>
</view>
</view>
</view>
</template>
<script>
import { UniUpgradeCenterResult } from '../utils/call-check-version'
const localFilePathKey = 'UNI_ADMIN_UPGRADE_CENTER_LOCAL_FILE_PATH'
const platform_iOS = 'iOS';
const requiredKey = ['version', 'url', 'type']
let downloadTask : DownloadTask | null = null;
/**
* 对比版本号,如需要,请自行修改判断规则
* 支持比对 ("3.0.0.0.0.1.0.1", "3.0.0.0.0.1") ("3.0.0.1", "3.0") ("3.1.1", "3.1.1.1") 之类的
* @param {Object} v1
* @param {Object} v2
* v1 > v2 return 1
* v1 < v2 return -1
* v1 == v2 return 0
*/
function compare(v1 : string = '0', v2 : string = '0') : number {
const v1_array = v1.split('.')
const v2_array = v2.split('.')
const minVersionLens = Math.min(v1.length, v2.length);
let result = 0;
for (let i = 0; i < minVersionLens; i++) {
const curV1 = parseInt(v1_array[i])
const curV2 = parseInt(v2_array[i])
if (curV1 > curV2) {
result = 1
break;
} else if (curV1 < curV2) {
result = -1
break;
}
}
if (result === 0 && (v1_array.length !== v2_array.length)) {
const v1BiggerThenv2 = v1_array.length > v2_array.length;
const maxLensVersion = v1BiggerThenv2 ? v1_array : v2_array;
for (let i = minVersionLens; i < maxLensVersion.length; i++) {
const curVersion = parseInt(maxLensVersion[i])
if (curVersion > 0) {
v1BiggerThenv2 ? result = 1 : result = -1
break;
}
}
}
return result;
}
export default {
data() {
return {
shown: false,
showTabbar: false,
// 从之前下载安装
installForBeforeFilePath: '',
// 安装
installed: false,
installing: false,
// 下载
downloadSuccess: false,
downloading: false,
downLoadPercent: 0,
downloadedSize: 0,
packageFileSize: 0,
tempFilePath: '', // 要安装的本地包地址
// 默认安装包信息
title: '更新日志',
contents: '',
is_mandatory: false,
// 可自定义属性
subTitle: '发现新版本',
downLoadBtnTextiOS: '立即跳转更新',
downLoadBtnText: '立即下载更新',
downLoadingText: '安装包下载中,请稍后',
url: "",
platform: [] as string[]
}
},
computed: {
isiOS() : boolean {
return this.platform.includes(platform_iOS);
}
},
methods: {
show(shown : boolean, localPackageInfo : UniUpgradeCenterResult | null) {
if (localPackageInfo === null) return;
uni.hideTabBar()?.then(_ => { this.showTabbar = true })?.catch(_ => { })
for (let key in localPackageInfo) {
if (requiredKey.indexOf(key) != -1 && localPackageInfo[key] === null) {
console.error(`参数 ${key} 必填,请检查后重试`)
uni.navigateBack()
return;
}
}
this.title = localPackageInfo.title
this.url = localPackageInfo.url
this.contents = localPackageInfo.contents
this.is_mandatory = localPackageInfo.is_mandatory
this.platform = localPackageInfo.platform
this.shown = shown
},
closeUpdate() {
if (this.downloading) {
if (this.is_mandatory) {
return uni.showToast({
title: '下载中,请稍后……',
icon: 'none',
duration: 500
})
}
uni.showModal({
title: '是否取消下载?',
cancelText: '否',
confirmText: '是',
success: res => {
if (res.confirm) {
if (downloadTask !== null) downloadTask!.abort()
this.closePopup()
}
}
});
return;
}
this.closePopup()
},
closePopup() {
this.shown = false
if (this.showTabbar) {
uni.showTabBar()?.then(_ => { })?.catch(_ => { })
}
this.downloadSuccess = false
this.downloading = false
this.downLoadPercent = 0
this.downloadedSize = 0
this.packageFileSize = 0
this.tempFilePath = ''
this.installing = false;
this.installed = false
this.showTabbar = false
this.$emit('close')
},
updateApp() {
this.downloadPackage()
},
downloadPackage() {
//下载包
downloadTask = uni.downloadFile({
url: this.url,
success: res => {
console.log('downloadFile res: ',res);
if (res.statusCode == 200) {
this.tempFilePath = res.tempFilePath
this.downLoadComplete()
}
},
fail: err => {
console.log('downloadFile err: ', err);
}
});
if (downloadTask !== null) {
this.downloading = true;
downloadTask!.onProgressUpdate(res => {
this.downLoadPercent = parseFloat(res.progress.toFixed(0));
this.downloadedSize = parseFloat((res.totalBytesWritten / Math.pow(1024, 2)).toFixed(2));
this.packageFileSize = parseFloat((res.totalBytesExpectedToWrite / Math.pow(1024, 2)).toFixed(2));
});
}
},
downLoadComplete() {
this.downloadSuccess = true;
this.downloading = false;
this.downLoadPercent = 0
this.downloadedSize = 0
this.packageFileSize = 0
downloadTask = null;
// 强制更新,直接安装
if (this.is_mandatory) {
this.installPackage();
}
},
installPackage() {
this.installing = true;
// #ifdef APP-PLUS
uni.installApk({
filePath: this.tempFilePath,
success: _ => {
console.log('installApk success');
this.installing = false;
this.installed = true;
},
fail: err => {
console.log('installApk fail');
// 安装失败需要重新下载安装包
this.installing = false;
this.installed = false;
uni.showModal({
title: '更新失败,请重新下载',
content: `uni.installApk 错误码 ${err.errCode}`,
showCancel: false
});
}
});
// 非wgt包,安装跳出覆盖安装,此处直接返回上一页
if (!this.is_mandatory) {
uni.navigateBack()
}
// #endif
}
}
}
</script>
<style>
.flex-center {
/* #ifndef APP-NVUE | UNI-APP-X */
display: flex;
/* #endif */
justify-content: center;
align-items: center;
}
.mask {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .65);
}
.content {
position: relative;
top: 0;
width: 600rpx;
background-color: transparent;
}
.text {
font-family: Source Han Sans CN;
}
.content-top {
width: 100%;
border-bottom-color: #fff;
border-bottom-width: 30rpx;
border-bottom-style: solid;
}
.content-top-image {
width: 100%;
position: relative;
bottom: -35rpx;
}
.content-top-text {
font-size: 45rpx;
font-weight: bold;
color: #F8F8FA;
position: absolute;
width: 65%;
top: 155rpx;
left: 50rpx;
z-index: 1;
}
.content-body {
box-sizing: border-box;
padding: 0 50rpx;
width: 100%;
background-color: #fff;
border-bottom-left-radius: 30rpx;
border-bottom-right-radius: 30rpx;
}
.title {
font-size: 32rpx;
font-weight: bold;
color: #3DA7FF;
line-height: 38px;
}
.footer {
height: 150rpx;
display: flex;
align-items: center;
justify-content: space-around;
}
.box-des-scroll {
box-sizing: border-box;
padding: 0 40rpx;
height: 200rpx;
}
.box-des {
font-size: 26rpx;
color: #000000;
line-height: 50rpx;
}
.progress-box {
width: 100%;
}
.progress {
width: 90%;
height: 40rpx;
}
.content-bottom {
height: 150rpx;
}
.close-img {
width: 70rpx;
height: 70rpx;
z-index: 1000;
position: relative;
bottom: -50rpx;
left: 265rpx;
}
.content-button {
width: 100%;
height: 80rpx;
line-height: 80rpx;
font-size: 30rpx;
font-weight: 400;
border-radius: 40rpx;
text-align: center;
background-color: #1785ff;
}
.flex-column {
display: flex;
flex-direction: column;
align-items: center;
}
</style>
\ No newline at end of file
uni_modules/uni-upgrade-center-app/pages/upgrade-popup.vue
0 → 100644
浏览文件 @
340d1c92
<
template
>
<view
class=
"mask flex-center"
>
<view
class=
"content botton-radius"
>
<view
class=
"content-top"
>
<text
class=
"content-top-text"
>
{{
title
}}
</text>
<image
class=
"content-top"
style=
"top: 0;"
width=
"100%"
height=
"100%"
src=
"../images/bg_top.png"
>
</image>
</view>
<view
class=
"content-header"
></view>
<view
class=
"content-body"
>
<view
class=
"title"
>
<text>
{{
subTitle
}}
</text>
<!--
<text
style=
"padding-left:20rpx;font-size: 0.5em;color: #666;"
>
v.
{{
version
}}
</text>
-->
</view>
<view
class=
"body"
>
<scroll-view
class=
"box-des-scroll"
scroll-y=
"true"
>
<text
class=
"box-des"
>
{{
contents
}}
</text>
</scroll-view>
</view>
<view
class=
"footer flex-center"
>
<template
v-if=
"isAppStore"
>
<button
class=
"content-button"
style=
"border: none;color: #fff;"
plain
@
click=
"jumpToAppStore"
>
{{
downLoadBtnTextiOS
}}
</button>
</
template
>
<
template
v-else
>
<template
v-if=
"!downloadSuccess"
>
<view
class=
"progress-box flex-column"
v-if=
"downloading"
>
<progress
class=
"progress"
:percent=
"downLoadPercent"
activeColor=
"#3DA7FF"
show-info
stroke-width=
"10"
/>
<view
style=
"width:100%;font-size: 28rpx;display: flex;justify-content: space-around;"
>
<text>
{{
downLoadingText
}}
</text>
<text>
(
{{
downloadedSize
}}
/
{{
packageFileSize
}}
M)
</text>
</view>
</view>
<button
v-else
class=
"content-button"
style=
"border: none;color: #fff;"
plain
@
click=
"updateApp"
>
{{
downLoadBtnText
}}
</button>
</
template
>
<button
v-else-if=
"downloadSuccess && !installed"
class=
"content-button"
style=
"border: none;color: #fff;"
plain
:loading=
"installing"
:disabled=
"installing"
@
click=
"installPackage"
>
{{installing ? '正在安装……' : '下载完成,立即安装'}}
</button>
<button
v-if=
"installed && isWGT"
class=
"content-button"
style=
"border: none;color: #fff;"
plain
@
click=
"restart"
>
安装完毕,点击重启
</button>
</template>
</view>
</view>
<image
v-if=
"!is_mandatory"
class=
"close-img"
src=
"../images/app_update_close.png"
@
click.stop=
"closeUpdate"
>
</image>
</view>
</view>
</template>
<
script
>
const
localFilePathKey
=
'
UNI_ADMIN_UPGRADE_CENTER_LOCAL_FILE_PATH
'
const
platform_iOS
=
'
iOS
'
;
let
downloadTask
=
null
;
let
openSchemePromise
/**
* 对比版本号,如需要,请自行修改判断规则
* 支持比对 ("3.0.0.0.0.1.0.1", "3.0.0.0.0.1") ("3.0.0.1", "3.0") ("3.1.1", "3.1.1.1") 之类的
* @param {Object} v1
* @param {Object} v2
* v1 > v2 return 1
* v1 < v2 return -1
* v1 == v2 return 0
*/
function
compare
(
v1
=
'
0
'
,
v2
=
'
0
'
)
{
v1
=
String
(
v1
).
split
(
'
.
'
)
v2
=
String
(
v2
).
split
(
'
.
'
)
const
minVersionLens
=
Math
.
min
(
v1
.
length
,
v2
.
length
);
let
result
=
0
;
for
(
let
i
=
0
;
i
<
minVersionLens
;
i
++
)
{
const
curV1
=
Number
(
v1
[
i
])
const
curV2
=
Number
(
v2
[
i
])
if
(
curV1
>
curV2
)
{
result
=
1
break
;
}
else
if
(
curV1
<
curV2
)
{
result
=
-
1
break
;
}
}
if
(
result
===
0
&&
(
v1
.
length
!==
v2
.
length
))
{
const
v1BiggerThenv2
=
v1
.
length
>
v2
.
length
;
const
maxLensVersion
=
v1BiggerThenv2
?
v1
:
v2
;
for
(
let
i
=
minVersionLens
;
i
<
maxLensVersion
.
length
;
i
++
)
{
const
curVersion
=
Number
(
maxLensVersion
[
i
])
if
(
curVersion
>
0
)
{
v1BiggerThenv2
?
result
=
1
:
result
=
-
1
break
;
}
}
}
return
result
;
}
export
default
{
data
()
{
return
{
// 从之前下载安装
installForBeforeFilePath
:
''
,
// 安装
installed
:
false
,
installing
:
false
,
// 下载
downloadSuccess
:
false
,
downloading
:
false
,
downLoadPercent
:
0
,
downloadedSize
:
0
,
packageFileSize
:
0
,
tempFilePath
:
''
,
// 要安装的本地包地址
// 默认安装包信息
title
:
'
更新日志
'
,
contents
:
''
,
is_mandatory
:
false
,
// 可自定义属性
subTitle
:
'
发现新版本
'
,
downLoadBtnTextiOS
:
'
立即跳转更新
'
,
downLoadBtnText
:
'
立即下载更新
'
,
downLoadingText
:
'
安装包下载中,请稍后
'
}
},
onLoad
({
local_storage_key
})
{
if
(
!
local_storage_key
)
{
console
.
error
(
'
local_storage_key为空,请检查后重试
'
)
uni
.
navigateBack
()
return
;
};
const
localPackageInfo
=
uni
.
getStorageSync
(
local_storage_key
);
if
(
!
localPackageInfo
)
{
console
.
error
(
'
安装包信息为空,请检查后重试
'
)
uni
.
navigateBack
()
return
;
};
const
requiredKey
=
[
'
version
'
,
'
url
'
,
'
type
'
]
for
(
let
key
in
localPackageInfo
)
{
if
(
requiredKey
.
indexOf
(
key
)
!==
-
1
&&
!
localPackageInfo
[
key
])
{
console
.
error
(
`参数
${
key
}
必填,请检查后重试`
)
uni
.
navigateBack
()
return
;
}
}
Object
.
assign
(
this
,
localPackageInfo
)
this
.
checkLocalStoragePackage
()
},
onBackPress
()
{
// 强制更新不允许返回
if
(
this
.
is_mandatory
)
{
return
true
}
downloadTask
&&
downloadTask
.
abort
()
},
onHide
()
{
openSchemePromise
=
null
},
computed
:
{
isWGT
()
{
return
this
.
type
===
'
wgt
'
},
isiOS
()
{
return
!
this
.
isWGT
?
this
.
platform
.
includes
(
platform_iOS
)
:
false
;
},
isAppStore
()
{
return
this
.
isiOS
||
(
!
this
.
isiOS
&&
!
this
.
isWGT
&&
this
.
url
.
indexOf
(
'
.apk
'
)
===
-
1
)
}
},
methods
:
{
checkLocalStoragePackage
()
{
// 如果已经有下载好的包,则直接提示安装
const
localFilePathRecord
=
uni
.
getStorageSync
(
localFilePathKey
)
if
(
localFilePathRecord
)
{
const
{
version
,
savedFilePath
,
installed
}
=
localFilePathRecord
// 比对版本
if
(
!
installed
&&
compare
(
version
,
this
.
version
)
===
0
)
{
this
.
downloadSuccess
=
true
;
this
.
installForBeforeFilePath
=
savedFilePath
;
this
.
tempFilePath
=
savedFilePath
}
else
{
// 如果保存的包版本小 或 已安装过,则直接删除
this
.
deleteSavedFile
(
savedFilePath
)
}
}
},
async
closeUpdate
()
{
if
(
this
.
downloading
)
{
if
(
this
.
is_mandatory
)
{
return
uni
.
showToast
({
title
:
'
下载中,请稍后……
'
,
icon
:
'
none
'
,
duration
:
500
})
}
uni
.
showModal
({
title
:
'
是否取消下载?
'
,
cancelText
:
'
否
'
,
confirmText
:
'
是
'
,
success
:
res
=>
{
if
(
res
.
confirm
)
{
downloadTask
&&
downloadTask
.
abort
()
uni
.
navigateBack
()
}
}
});
return
;
}
if
(
this
.
downloadSuccess
&&
this
.
tempFilePath
)
{
// 包已经下载完毕,稍后安装,将包保存在本地
await
this
.
saveFile
(
this
.
tempFilePath
,
this
.
version
)
uni
.
navigateBack
()
return
;
}
uni
.
navigateBack
()
},
updateApp
()
{
this
.
checkStoreScheme
().
catch
(()
=>
{
this
.
downloadPackage
()
})
},
// 跳转应用商店
checkStoreScheme
()
{
const
storeList
=
(
this
.
store_list
||
[]).
filter
(
item
=>
item
.
enable
)
if
(
storeList
&&
storeList
.
length
)
{
storeList
.
sort
((
cur
,
next
)
=>
next
.
priority
-
cur
.
priority
)
.
map
(
item
=>
item
.
scheme
)
.
reduce
((
promise
,
cur
,
curIndex
)
=>
{
openSchemePromise
=
(
promise
||
(
promise
=
Promise
.
reject
())).
catch
(()
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
plus
.
runtime
.
openURL
(
cur
,
(
err
)
=>
{
reject
(
err
)
})
})
})
return
openSchemePromise
},
openSchemePromise
)
return
openSchemePromise
}
return
Promise
.
reject
()
},
downloadPackage
()
{
this
.
downloading
=
true
;
//下载包
downloadTask
=
uni
.
downloadFile
({
url
:
this
.
url
,
success
:
res
=>
{
if
(
res
.
statusCode
==
200
)
{
this
.
downloadSuccess
=
true
;
// fix: wgt 文件下载完成后后缀不是 wgt
if
(
this
.
isWGT
&&
res
.
tempFilePath
.
split
(
'
.
'
).
slice
(
-
1
)[
0
]
!==
'
wgt
'
)
{
const
failCallback
=
(
e
)
=>
{
console
.
log
(
'
[FILE RENAME FAIL]:
'
,
JSON
.
stringify
(
e
));
}
plus
.
io
.
resolveLocalFileSystemURL
(
res
.
tempFilePath
,
(
entry
)
=>
{
entry
.
getParent
((
parent
)
=>
{
const
newName
=
`new_wgt_
${
Date
.
now
()}
.wgt`
entry
.
copyTo
(
parent
,
newName
,
(
res
)
=>
{
this
.
tempFilePath
=
res
.
fullPath
this
.
downLoadComplete
()
},
failCallback
)
},
failCallback
)
},
failCallback
);
}
else
{
this
.
tempFilePath
=
res
.
tempFilePath
this
.
downLoadComplete
()
}
}
}
});
downloadTask
.
onProgressUpdate
(
res
=>
{
this
.
downLoadPercent
=
res
.
progress
;
this
.
downloadedSize
=
(
res
.
totalBytesWritten
/
Math
.
pow
(
1024
,
2
)).
toFixed
(
2
);
this
.
packageFileSize
=
(
res
.
totalBytesExpectedToWrite
/
Math
.
pow
(
1024
,
2
)).
toFixed
(
2
);
});
},
downLoadComplete
()
{
this
.
downloading
=
false
;
this
.
downLoadPercent
=
0
this
.
downloadedSize
=
0
this
.
packageFileSize
=
0
downloadTask
=
null
;
// 强制更新,直接安装
if
(
this
.
is_mandatory
)
{
this
.
installPackage
();
}
},
installPackage
()
{
// #ifdef APP-PLUS
// wgt资源包安装
if
(
this
.
isWGT
)
{
this
.
installing
=
true
;
}
plus
.
runtime
.
install
(
this
.
tempFilePath
,
{
force
:
false
},
async
res
=>
{
this
.
installing
=
false
;
this
.
installed
=
true
;
// wgt包,安装后会提示 安装成功,是否重启
if
(
this
.
isWGT
)
{
// 强制更新安装完成重启
if
(
this
.
is_mandatory
)
{
uni
.
showLoading
({
icon
:
'
none
'
,
title
:
'
安装成功,正在重启……
'
})
setTimeout
(()
=>
{
uni
.
hideLoading
()
this
.
restart
();
},
1000
)
}
}
else
{
const
localFilePathRecord
=
uni
.
getStorageSync
(
localFilePathKey
)
uni
.
setStorageSync
(
localFilePathKey
,
{
...
localFilePathRecord
,
installed
:
true
})
}
},
async
err
=>
{
// 如果是安装之前的包,安装失败后删除之前的包
if
(
this
.
installForBeforeFilePath
)
{
await
this
.
deleteSavedFile
(
this
.
installForBeforeFilePath
)
this
.
installForBeforeFilePath
=
''
;
}
// 安装失败需要重新下载安装包
this
.
installing
=
false
;
this
.
installed
=
false
;
uni
.
showModal
({
title
:
'
更新失败,请重新下载
'
,
content
:
err
.
message
,
showCancel
:
false
});
});
// 非wgt包,安装跳出覆盖安装,此处直接返回上一页
if
(
!
this
.
isWGT
&&
!
this
.
is_mandatory
)
{
uni
.
navigateBack
()
}
// #endif
},
restart
()
{
this
.
installed
=
false
;
// #ifdef APP-PLUS
//更新完重启app
plus
.
runtime
.
restart
();
// #endif
},
saveFile
(
tempFilePath
,
version
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
uni
.
saveFile
({
tempFilePath
,
success
({
savedFilePath
})
{
uni
.
setStorageSync
(
localFilePathKey
,
{
version
,
savedFilePath
})
},
complete
()
{
resolve
()
}
})
})
},
deleteSavedFile
(
filePath
)
{
uni
.
removeStorageSync
(
localFilePathKey
)
return
uni
.
removeSavedFile
({
filePath
})
},
jumpToAppStore
()
{
plus
.
runtime
.
openURL
(
this
.
url
);
}
}
}
</
script
>
<
style
>
page
{
background
:
transparent
;
}
.flex-center
{
/* #ifndef APP-NVUE */
display
:
flex
;
/* #endif */
justify-content
:
center
;
align-items
:
center
;
}
.mask
{
position
:
fixed
;
left
:
0
;
top
:
0
;
right
:
0
;
bottom
:
0
;
background-color
:
rgba
(
0
,
0
,
0
,
.65
);
}
.botton-radius
{
border-bottom-left-radius
:
30
rpx
;
border-bottom-right-radius
:
30
rpx
;
}
.content
{
position
:
relative
;
top
:
0
;
width
:
600
rpx
;
background-color
:
#fff
;
box-sizing
:
border-box
;
padding
:
0
50
rpx
;
font-family
:
Source
Han
Sans
CN
;
}
.text
{
/* #ifndef APP-NVUE */
display
:
block
;
/* #endif */
line-height
:
200px
;
text-align
:
center
;
color
:
#FFFFFF
;
}
.content-top
{
position
:
absolute
;
top
:
-195
rpx
;
left
:
0
;
width
:
600
rpx
;
height
:
270
rpx
;
}
.content-top-text
{
font-size
:
45
rpx
;
font-weight
:
bold
;
color
:
#F8F8FA
;
position
:
absolute
;
top
:
120
rpx
;
left
:
50
rpx
;
z-index
:
1
;
}
.content-header
{
height
:
70
rpx
;
}
.title
{
font-size
:
33
rpx
;
font-weight
:
bold
;
color
:
#3DA7FF
;
line-height
:
38px
;
}
.footer
{
height
:
150
rpx
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-around
;
}
.box-des-scroll
{
box-sizing
:
border-box
;
padding
:
0
40
rpx
;
height
:
200
rpx
;
text-align
:
left
;
}
.box-des
{
font-size
:
26
rpx
;
color
:
#000000
;
line-height
:
50
rpx
;
}
.progress-box
{
width
:
100%
;
}
.progress
{
width
:
90%
;
height
:
40
rpx
;
/* border-radius: 35px; */
}
.close-img
{
width
:
70
rpx
;
height
:
70
rpx
;
z-index
:
1000
;
position
:
absolute
;
bottom
:
-120
rpx
;
left
:
calc
(
50%
-
70
rpx
/
2
);
}
.content-button
{
text-align
:
center
;
flex
:
1
;
font-size
:
30
rpx
;
font-weight
:
400
;
color
:
#FFFFFF
;
border-radius
:
40
rpx
;
margin
:
0
18
rpx
;
height
:
80
rpx
;
line-height
:
80
rpx
;
background
:
linear-gradient
(
to
right
,
#1785ff
,
#3DA7FF
);
}
.flex-column
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
}
</
style
>
\ No newline at end of file
uni_modules/uni-upgrade-center-app/readme.md
0 → 100644
浏览文件 @
340d1c92
## 升级中心 - app插件与 `uni-admin` 版本关系
### `uni-admin >= 1.9.3`:云函数 `checkVersion` 废弃,使用 uni-admin 自带的 `uni-upgrade-center` 云函数。
# uni-upgrade-center - App
### 概述
> 统一管理App及App在`Android`、`iOS`平台上`App安装包`和`wgt资源包`的发布升级
> uni升级中心分为业务插件和后台管理插件。本插件为业务插件,包括uni升级中心客户端检查更新的前后端逻辑。后台管理系统另见 [uni-upgrade-center - Admin](https://ext.dcloud.net.cn/plugin?id=4470)
### uni升级中心 - 客户端检查更新插件
-
一键式检查更新,同时支持整包升级与wgt资源包更新
-
好看、实用、可自定义的客户端提示框
## 安装指引
1.
依赖数据库
`opendb-app-versions`
,如果没有此库,请在云服务空间中创建。
2.
使用
`HBuilderX 3.1.0+`
,因为要使用到
`uni_modules`
3.
在插件市场打开本插件页面,在右侧点击
`使用 HBuilderX 导入插件`
,选择要导入的项目点击确定
4.
绑定一个服务空间。自
`0.6.0`
起,依赖
`uni-admin 1.9.3+`
的
`uni-upgrade-center 云函数`
,请和 uni-admin 项目关联同一个服务空间
5.
找到
`/uni_modules/uni-upgrade-center-app/uniCloud/cloudfunctions/check-version`
,右键上传部署。自
`0.6.0`
起,依赖
`uni-admin 1.9.3+`
的
`uni-upgrade-center 云函数`
,插件不再单独提供云函数,这样可以省下一个云函数名额。
6.
在
`pages.json`
中添加页面路径。
**注:请不要设置为pages.json中第一项**
```
json
"pages"
:
[
//
……其他页面配置
{
"path"
:
"uni_modules/uni-upgrade-center-app/pages/upgrade-popup"
,
"style"
:
{
"disableScroll"
:
true
,
"app-plus"
:
{
"backgroundColorTop"
:
"transparent"
,
"background"
:
"transparent"
,
"titleNView"
:
false
,
"scrollIndicator"
:
false
,
"popGesture"
:
"none"
,
"animationType"
:
"fade-in"
,
"animationDuration"
:
200
}
}
}
]
```
7.
将
`@/uni_modules/uni-upgrade-center-app/utils/check-update`
import到需要用到的地方,调用一下即可
1.
默认使用当前绑定的服务空间,如果要请求其他服务空间,可以使用其他服务空间的
`callFunction`
。
[
详情
](
https://uniapp.dcloud.io/uniCloud/cf-functions.html#call-by-function-cross-space
)
8.
升级弹框可自行编写,也可以使用
`uni.showModal`
,或使用现有的升级弹框样式,如果不满足UI需求请自行替换资源文件。在
`utils/check-update.js`
中都有实例。
9.
wgt更新时,打包前请务必将manifest.json中的版本修改为更高版本。
### 更新下载安装`check-update.js`
*该函数在utils目录下*
1.
如果是静默更新,则不会打开更新弹框,会在后台下载后安装,下次启动应用生效
2.
如果是 iOS,则会直接打开AppStore的链接
3.
其他情况,会将
`check-version`
返回的结果保存在localStorage中,并跳转进入
`upgrade-popup.vue`
打开更新弹框
### 检查更新函数`check-version`
*该函数在uniCloud/cloudfunctions目录下*
1.
使用检查更新需要传递三个参数
`appid`
、
`appVersion`
、
`wgtVersion`
2.
`appid`
使用 plus.runtime.appid 获取,
*注:真机运行时为固定值HBuilder,在调试的时候请使用本地调试云函数*
3.
`appVersion`
使用 plus.runtime.version 获取
4.
`wgtVersion`
使用 plus.runtime.getProperty(plus.runtime.appid,(wgtInfo) => { wgtInfo.version }) 获取
5.
`check-version`
云函数内部会自动获取 App 平台
**Tips**
1.
`check-version`
云函数内部有版本对比函数(compare)。
-
使用多段式版本格式(如:"3.0.0.0.0.1.0.1", "3.0.0.0.0.1")。如果不满足对比规则,请自行修改。
-
如果修改,请将
*pages/upgrade-popup.vue*
中
*compare*
函数一并修改
## 项目代码说明
### 更新弹框
-
`upgrade-popup.vue`
- 更新应用:
-
如果云函数
`check-version`
返回的参数表明需要更新,则将参数保存在localStorage中,带着键值跳转该页面
-
进入时会先从localStorage中尝试取出之前存的安装包路径(此包不会是强制安装类型的包)
-
如果有已经保存的包,则和传进来的
`version`
进行比较,如果相等则安装。大于和小于都不进行安装,因为admin端可能会调整包的版本。不符合更新会将此包删除
-
如果本地没有包或者包不符合安装条件,则进行下载安装包
-
点击下载会有进度条、已下载大小和下载包的大小
-
下载完成会提示安装:
-
如果是 wgt 包,安装时则会提示 正在安装…… 和 安装完成。安装完成会提示是否重启
-
如果是 原生安装包,则直接跳出去覆盖安装
-
下载过程中,如果退出会提示是否取消下载。如果是强制更新,则只会提示正在下载请稍后,此时不可退出
-
如果是下载完成了没有安装就退出,则会将下载完成的包保存在本地。将包的本地路径和包version保存在localStorage中
### 工具类 utils
-
`call-check-version`
-
请求云函数
`check-version`
拿取版本检测结果
-
`check-update`
-
调用
`call-check-version`
并根据结果判断是否显示更新弹框
### 云函数
-
`check-version`
- 检查应用更新:
-
根据传参,先检测传参是否完整,appid appVersion wgtVersion 必传
-
先从数据库取出所有该平台(会从上下文读取平台信息)的所有线上发行更新
-
再从所有线上发行更新中取出版本最大的一版。如果可以,尽量先检测wgt的线上发行版更新
-
使用上一步取出的版本包的版本号 和传参 appVersion、wgtVersion 来检测是否有更新。必须同时大于这两项,因为上一次可能是wgt热更新,否则返回暂无更新
-
如果库中 wgt包 版本大于传参 appVersion,但是不满足 min_uni_version < appVersion,则不会使用wgt更新,会接着判断库中 app包version 是否大于 appVersion
-
返回结果:
|code|message|
|:-:|:-:|
|0|当前版本已经是最新的,不需要更新|
|101|wgt更新|
|102|整包更新|
|-101|暂无更新或检查appid是否填写正确|
|-102|请检查传参是否填写正确|
\ No newline at end of file
uni_modules/uni-upgrade-center-app/static/app_update_close.png
0 → 100644
浏览文件 @
340d1c92
7.5 KB
uni_modules/uni-upgrade-center-app/static/bg_top.png
0 → 100644
浏览文件 @
340d1c92
29.8 KB
uni_modules/uni-upgrade-center-app/uniCloud/database/db_init.json
0 → 100644
浏览文件 @
340d1c92
{}
uni_modules/uni-upgrade-center-app/utils/call-check-version.ts
0 → 100644
浏览文件 @
340d1c92
export
type
StoreListItem
=
{
enable
:
boolean
id
:
string
name
:
string
scheme
:
string
priority
:
number
// 优先级
}
export
type
UniUpgradeCenterResult
=
{
_id
:
string
appid
:
string
name
:
string
title
:
string
contents
:
string
url
:
string
// 安装包下载地址
platform
:
Array
<
string
>
// Array<'Android' | 'iOS'>
version
:
string
// 版本号 1.0.0
uni_platform
:
string
// "android" | "ios" // 版本号 1.0.0
stable_publish
:
boolean
// 是否是稳定版
is_mandatory
:
boolean
// 是否强制更新
is_silently
:
boolean
// 是否静默更新
create_env
:
string
// "upgrade-center"
create_date
:
number
message
:
string
code
:
number
type
:
string
// "native_app" | "wgt"
store_list
:
StoreListItem
[]
|
null
min_uni_version
:
string
|
null
// 升级 wgt 的最低 uni-app 版本
}
export
default
function
():
Promise
<
UniUpgradeCenterResult
>
{
// #ifdef APP
return
new
Promise
<
UniUpgradeCenterResult
>
((
resolve
,
reject
)
=>
{
const
systemInfo
=
uni
.
getSystemInfoSync
()
const
appId
=
systemInfo
.
appId
const
appVersion
=
systemInfo
.
appVersion
// #ifndef UNI-APP-X
if
(
plus
.
runtime
.
appid
&&
plus
.
runtime
.
version
)
{
plus
.
runtime
.
getProperty
(
plus
.
runtime
.
appid
,
function
(
widgetInfo
)
{
if
(
widgetInfo
.
version
)
{
let
data
=
{
action
:
'
checkVersion
'
,
appid
:
plus
.
runtime
.
appid
,
appVersion
:
plus
.
runtime
.
version
,
wgtVersion
:
widgetInfo
.
version
}
uniCloud
.
callFunction
({
name
:
'
uni-upgrade-center
'
,
data
:
data
,
success
:
(
e
)
=>
{
resolve
(
e
.
result
as
UniUpgradeCenterResult
)
},
fail
:
(
error
)
=>
{
reject
(
error
)
}
})
}
else
{
reject
(
'
widgetInfo.version is EMPTY
'
)
}
})
}
else
{
reject
(
'
plus.runtime.appid is EMPTY
'
)
}
// #endif
// // #ifdef UNI-APP-X
if
(
typeof
appId
===
'
string
'
&&
typeof
appVersion
===
'
string
'
&&
appId
.
length
>
0
&&
appVersion
.
length
>
0
)
{
let
data
=
{
action
:
'
checkVersion
'
,
appid
:
appId
,
appVersion
:
appVersion
,
wgtVersion
:
'
0.0.0.0.0.1
'
}
try
{
uniCloud
.
callFunction
({
name
:
'
uni-upgrade-center
'
,
data
:
data
}).
then
(
res
=>
{
const
result
=
JSON
.
parse
<
UniUpgradeCenterResult
>
(
JSON
.
stringify
(
res
.
result
))
if
(
result
===
null
){
reject
({
code
:
res
.
result
[
'
code
'
],
message
:
res
.
result
[
'
message
'
]
})
}
else
{
resolve
(
result
)
}
}).
catch
<
void
>
((
err
:
any
|
null
)
=>
{
console
.
log
(
'
err:
'
,
err
);
const
error
=
err
as
UniCloudError
reject
(
error
.
errMsg
)
})
}
catch
(
e
)
{
reject
(
e
.
message
)
}
}
else
{
reject
(
'
invalid appid or appVersion
'
)
}
// #endif
})
// #endif
// #ifndef APP-PLUS
/* return new Promise((resolve, reject) => {
reject({
message: '请在App中使用'
})
}) */
// #endif
}
uni_modules/uni-upgrade-center-app/utils/check-update.ts
0 → 100644
浏览文件 @
340d1c92
import
callCheckVersion
,
{
UniUpgradeCenterResult
}
from
"
./call-check-version
"
// #ifdef UNI-APP-X
import
{
ComponentPublicInstance
}
from
'
vue
'
// #endif
// 推荐再App.vue中使用
const
PACKAGE_INFO_KEY
=
'
__package_info__
'
// #ifdef UNI-APP-X
export
default
function
(
component
:
ComponentPublicInstance
|
null
=
null
)
:
Promise
<
UniUpgradeCenterResult
>
{
// #endif
// #ifndef UNI-APP-X
export
default
function
()
:
Promise
<
UniUpgradeCenterResult
>
{
// #endif
// #ifdef APP-PLUS
return
new
Promise
<
UniUpgradeCenterResult
>
((
resolve
,
reject
)
=>
{
callCheckVersion
().
then
(
async
(
uniUpgradeCenterResult
)
=>
{
// NOTE uni-app x 3.96 解构有问题
const
code
=
uniUpgradeCenterResult
.
code
const
message
=
uniUpgradeCenterResult
.
message
const
url
=
uniUpgradeCenterResult
.
url
// 安装包下载地址
// const is_silently = uniUpgradeCenterResult.is_silently // 是否静默更新
// const platform = uniUpgradeCenterResult.platform // 安装包平台
// const type = uniUpgradeCenterResult.type // 安装包类型
// 此处逻辑仅为实例,可自行编写
if
(
code
>
0
)
{
// 腾讯云和阿里云下载链接不同,需要处理一下,阿里云会原样返回
const
tcbRes
=
await
uniCloud
.
getTempFileURL
({
fileList
:
[
url
]
});
if
(
typeof
tcbRes
.
fileList
[
0
].
tempFileURL
!==
'
undefined
'
)
uniUpgradeCenterResult
.
url
=
tcbRes
.
fileList
[
0
].
tempFileURL
;
/**
* 提示升级一
* 使用 uni.showModal
*/
// return updateUseModal(uniUpgradeCenterResult)
/**
* 提示升级二
* 官方适配的升级弹窗,可自行替换资源适配UI风格
*/
// #ifndef UNI-APP-X
uni
.
setStorageSync
(
PACKAGE_INFO_KEY
,
uniUpgradeCenterResult
)
uni
.
navigateTo
({
url
:
`/uni_modules/uni-upgrade-center-app/pages/upgrade-popup?local_storage_key=
${
PACKAGE_INFO_KEY
}
`
,
fail
:
(
err
)
=>
{
console
.
error
(
'
更新弹框跳转失败
'
,
err
)
uni
.
removeStorageSync
(
PACKAGE_INFO_KEY
)
}
})
// #endif
// #ifdef UNI-APP-X
component
?.
$callMethod
(
'
show
'
,
true
,
uniUpgradeCenterResult
)
// #endif
return
resolve
(
uniUpgradeCenterResult
)
}
else
if
(
code
<
0
)
{
// TODO 云函数报错处理
console
.
error
(
message
)
return
reject
(
uniUpgradeCenterResult
)
}
return
resolve
(
uniUpgradeCenterResult
)
}).
catch
((
err
)
=>
{
// TODO 云函数报错处理
console
.
error
(
err
)
reject
(
err
)
})
});
// #endif
}
// #ifdef UNI-APP-X
/**
* 使用 uni.showModal 升级
*/
function
updateUseModal
(
packageInfo
:
UniUpgradeCenterResult
)
:
void
{
const
{
title
,
// 标题
contents
,
// 升级内容
is_mandatory
,
// 是否强制更新
url
,
// 安装包下载地址
}
=
packageInfo
;
let
confirmText
=
'
立即下载更新
'
return
uni
.
showModal
({
title
,
content
:
contents
,
showCancel
:
!
is_mandatory
,
confirmText
,
success
:
res
=>
{
if
(
res
.
cancel
)
return
;
uni
.
showToast
({
title
:
'
后台下载中……
'
,
duration
:
1000
});
// wgt 和 安卓下载更新
uni
.
downloadFile
({
url
,
success
:
res
=>
{
if
(
res
.
statusCode
!==
200
)
{
console
.
error
(
'
下载安装包失败
'
);
return
;
}
// 下载好直接安装,下次启动生效
uni
.
installApk
({
filePath
:
res
.
tempFilePath
,
success
:
()
=>
{
uni
.
showModal
({
title
:
'
安装成功请手动重启
'
});
},
fail
:
err
=>
{
uni
.
showModal
({
title
:
'
更新失败
'
,
content
:
err
.
message
,
showCancel
:
false
});
}
});
}
});
}
});
}
// #endif
// #ifndef UNI-APP-X
/**
* 使用 uni.showModal 升级
*/
function
updateUseModal
(
packageInfo
:
UniUpgradeCenterResult
)
:
void
{
const
{
title
,
// 标题
contents
,
// 升级内容
is_mandatory
,
// 是否强制更新
url
,
// 安装包下载地址
platform
,
// 安装包平台
type
// 安装包类型
}
=
packageInfo
;
let
isWGT
=
type
===
'
wgt
'
let
isiOS
=
!
isWGT
?
platform
.
includes
(
'
iOS
'
)
:
false
;
let
confirmText
=
isiOS
?
'
立即跳转更新
'
:
'
立即下载更新
'
return
uni
.
showModal
({
title
,
content
:
contents
,
showCancel
:
!
is_mandatory
,
confirmText
,
success
:
res
=>
{
if
(
res
.
cancel
)
return
;
// 安装包下载
if
(
isiOS
)
{
plus
.
runtime
.
openURL
(
url
);
return
;
}
uni
.
showToast
({
title
:
'
后台下载中……
'
,
duration
:
1000
});
// wgt 和 安卓下载更新
uni
.
downloadFile
({
url
,
success
:
res
=>
{
if
(
res
.
statusCode
!==
200
)
{
console
.
error
(
'
下载安装包失败
'
);
return
;
}
// 下载好直接安装,下次启动生效
plus
.
runtime
.
install
(
res
.
tempFilePath
,
{
force
:
false
},
()
=>
{
if
(
is_mandatory
)
{
//更新完重启app
plus
.
runtime
.
restart
();
return
;
}
uni
.
showModal
({
title
:
'
安装成功是否重启?
'
,
success
:
res
=>
{
if
(
res
.
confirm
)
{
//更新完重启app
plus
.
runtime
.
restart
();
}
}
});
},
err
=>
{
uni
.
showModal
({
title
:
'
更新失败
'
,
content
:
err
.
message
,
showCancel
:
false
});
});
}
});
}
});
}
// #endif
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录