提交 4af581f6 编写于 作者: D DCloud_LXH

Merge branch 'qq_40649554/unidocs-zh-qq_40649554-master-patch-06506' into pr

......@@ -375,10 +375,28 @@ App nvue 3.6.9+ 支持
const markers = []
positions.forEach((p, i) => {
const newMarker = Object.assign({},marker, p)
newMarker.id = i + 1
newMarker.label.content = `label ${i + 1}`
markers.push(newMarker)
console.log(i)
markers.push({
latitude: p.latitude,
longitude: p.longitude,
id: i + 1,
iconPath: img,
width: 50,
height: 50,
joinCluster: true, // 指定了该参数才会参与聚合
label: {
width: 50,
height: 30,
borderWidth: 1,
borderRadius: 10,
bgColor: '#ffffff',
content: i + ""
}
})
// const newMarker = Object.assign({},marker, p)
// newMarker.id = i + 1
// newMarker.label.content = `label ${i + 1}`
// markers.push(newMarker)
})
this._mapContext.addMarkers({
markers,
......
......@@ -726,6 +726,89 @@ exports.main = async (event, context) => {
}
```
### 阿里云云函数费用说明@aliyun-cf-fee
激励视频服务器回调业务涉及费用的部分主要是云函数的使用量、调用次数、出网流量(可选)。 接下来,我们对不同资源,分别进行费用评估。
#### 云函数介绍
1. uniAdCallback:uni-AD自动部署,用于接收广告商服务器的 HTTP 请求并抹平参数差异,然后调用开发者云函数
2. userAdCallback: 开发者创建的云函数,用于接收 uniAdCallback。如果业务系统不在uniCloud,可以通过 HTTP 的方式将回调数据发送到已有服务器,将产生出网流量
#### 流量费
我们按照uniCloud官网列出的[按量计费](https://uniapp.dcloud.net.cn/uniCloud/price.html#aliyun-postpay)规则,可以简单得出如下公式:
- 云函数费用(业务系统在uniCloud) = 资源使用量 * 0.000110592 + 调用次数 * 0.0133 / 10000
- 云函数费用(业务系统不在uniCloud) = 资源使用量 * 0.000110592 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8
其中:
- 资源使用量 = 云函数内存(单位为G) * 云函数平均单次执行时长(单位为秒) * 调用次数
- 云函数调用次数 = 每次激励视频回调触发2次云函数调用 (uniAdCallback + userAdCallback)
我们假设如下数据模型:
- 云函数内存:512M,即0.5G (云函数内存默认为512M,用户可以自定义设置,最低可设置为128M)
- 云函数平均单次执行时长:200毫秒,即0.2秒
- 出网流量:单次请求 1KB
云函数费用分2种情况
1. 业务系统在uniCloud
`1`次激励视频回调费用为:
```
云函数费用 = 资源使用量 * 0.000110592 + 调用次数 * 0.0133 / 10000
= 云函数内存(单位为G) * 云函数平均单次执行时长(单位为秒) * 调用次数 + 调用次数 * 0.0133 / 10000
= 0.5G * 0.2S * 2 * 0.000110592 + 2 * 0.0133/10000
= 0.0000221184 + 0.00000266
= 0.0000247784(元)
```
2. 业务系统不在uniCloud
业务不在 uniCloud 时通过 HTTP 方式将回调数据发送到传统服务器,将产生出网流量费用
`1`次激励视频回调费用为:
```
云函数费用 = 资源使用量 * 0.000110592 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8
= 云函数内存(单位为G) * 云函数平均单次执行时长(单位为秒) * 调用次数 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8
= 0.5G * 0.2S * 2 * 0.000110592 + 2 * 0.0133/10000 + 1KB * 0.8 / (1024 * 1024)
= 0.0000221184 + 0.00000266 + 7.62939453125e-7
= 0.000025541339453125(元)
```
注意:在实际业务中云函数费用可能会出现稍微偏高,如:开发者的服务器响应过慢时,广告商的服务器会重试,导致调用次数增加
#### 总结
1. 业务系统在[uniCloud](https://uniapp.dcloud.net.cn/uniCloud/)
|广告回调次数 |云函数费用(元) |
|:-: |:-: |
|1 |0.0000247784 |
|10 |0.000247784 |
|100 |0.00247784 |
|1000 |0.0247784 |
|10000 |0.247784 |
2. 业务系统不在[uniCloud](https://uniapp.dcloud.net.cn/uniCloud/),包含出网流量费用
|广告回调次数 |云函数费用+出网流量费用(元) |
|:-: |:-: |
|1 |0.000025541339453125 |
|10 |0.00025541339453125 |
|100 |0.0025541339453125003 |
|1000 |0.025541339453125 |
|10000 |0.25541339453125 |
这个费用非常非常低,相比于广告收益,可以忽略。请开发者放心使用。
### 注意事项
- iOS平台配置应用使用广告标识(IDFA)详见:[https://ask.dcloud.net.cn/article/36107](https://ask.dcloud.net.cn/article/36107)
- 测试期间请使用测试 `adpid`,参考测试代码,如果无法显示换个时间再试
......
......@@ -36,6 +36,7 @@
|random-number|Boolean|false|当 type 为 number, digit, idcard 数字键盘是否随机排列|支付宝小程序 1.9.0+|
|controlled|Boolean|false|是否为受控组件。为 true 时,value 内容会完全受 setData 控制|支付宝小程序 1.9.0+|
|always-system|Boolean|false|是否强制使用系统键盘和 Web-view 创建的 input 元素。为 true 时,confirm-type、confirm-hold 可能失效|支付宝小程序 2.7.3+|
|inputmode|String|"text"|是一个枚举属性,它提供了用户在编辑元素或其内容时可能输入的数据类型的提示。[详情](#inputmode)|H5(3.6.16+)|
|@input|EventHandle||当键盘输入时,触发input事件,event.detail = {value}|差异见下方 Tips|
|@focus|EventHandle||输入框聚焦时触发,event.detail = { value, height },height 为键盘高度|仅微信小程序、京东小程序、App(2.2.3+) 、QQ小程序支持 height|
|@blur|EventHandle||输入框失去焦点时触发,event.detail = {value: value}|快手小程序不支持|
......@@ -101,6 +102,18 @@
- App平台的vue页面及 H5平台 的弹出键盘使用的是浏览器控制的键盘,在Chrome81+、Safari13.7+之前,键盘右下角文字只能设置完成和搜索,从Chrome81+、Safari13.7+起支持设置发送、下一个。
- App平台涉及聊天的建议使用nvue,一方面因为app-vue控制键盘右下角按键文字为“发送”对webview内核有要求,另一方面聊天记录如使用scroll-view,过长的内容在app-vue上会有性能问题。
### inputmode 有效值 @inputmode
|值|说明|
|:-|:-|
|none|无虚拟键盘。在应用程序或者站点需要实现自己的键盘输入控件时很有用。|
|text|使用用户本地区域设置的标准文本输入键盘。|
|decimal|小数输入键盘,包含数字和分隔符(通常是“ . ”或者“ , ”),设备可能也可能不显示减号键。|
|numeric|数字输入键盘,所需要的就是 0 到 9 的数字,设备可能也可能不显示减号键。|
|tel|电话输入键盘,包含 0 到 9 的数字、星号(*)和井号(#)键。表单输入里面的电话输入通常应该使用 \<input type="tel"\> 。|
|search|为搜索输入优化的虚拟键盘,比如,返回键可能被重新标记为“搜索”,也可能还有其他的优化。|
|email|为邮件地址输入优化的虚拟键盘,通常包含"@"符号和其他优化。表单里面的邮件地址输入应该使用 \<input type="email"\> 。|
|url|为网址输入优化的虚拟键盘,比如,“/”键会更加明显、历史记录访问等。表单里面的网址输入通常应该使用 \<input type="url"\> 。|
#### App平台iOS端软键盘上方横条去除方案
App平台在iOS上,webview中的软键盘弹出时,默认在软键盘上方有一个横条,显示着:上一项、下一项和完成等按钮。如不想显示这个横条,可以配置softinputNavBar: 'none'
......
......@@ -40,6 +40,7 @@
- app-nvue 平台只有纯nvue项目(render为native)才支持 `<navigator>`。非render为native的情况下,nvue暂不支持navigator组件,请使用API跳转。
- app下退出应用,Android平台可以使用[plus.runtime.quit](https://www.html5plus.org/doc/zh_cn/runtime.html#plus.runtime.quit)。iOS没有退出应用的概念。
- [uLink组件](https://ext.dcloud.net.cn/plugin?id=1182)是navigator组件的增强版,样式上自带下划线,功能上支持打开在线网页、其他App的schema、mailto发邮件、tel打电话。
- Vue3 项目因 SSR 需要,H5 端会在外层嵌套 a 标签
**示例** [查看示例](https://hellouniapp.dcloud.net.cn/pages/component/navigator/navigator)
......
......@@ -144,7 +144,7 @@ export default {
**Tips**
- nodes 不推荐使用 String 类型,性能会有所下降。
- rich-text 组件内屏蔽所有节点的事件。所以如果内容中有链接、图片需要点击,则不能使用rich-text,此时可在[uni-app插件市场](https://ext.dcloud.net.cn/search?q=parse)搜索parse插件使用。app-nvue的rich-text组件支持链接图片点击。
- rich-text 组件内屏蔽所有节点的事件。所以如果内容中有链接、图片需要点击,则不能使用rich-text,此时可在[uni-app插件市场](https://ext.dcloud.net.cn/search?q=parse)搜索parse插件使用。app-vue的rich-text组件支持链接图片点击。
- attrs 属性不支持 id ,支持 class 。
- name 属性大小写不敏感。
- 如果使用了不受信任的HTML节点,该节点及其所有子节点将会被移除。
......
......@@ -44,27 +44,12 @@ UTS组件的优势在于,它秉承了UTS的跨平台特性,统一的UTS语
为了降低前端开发者的开发门槛,UTS组件采用了类Vue组件的语法,[关于Vue组件](https://cn.vuejs.org/guide/essentials/component-basics.html),但是具体的函数上会有定制,我们会在下一个章节详细介绍
## 如何开发UTS组件
#### 创建UTS组件
HBuilderX 3.6.16 版本之后,支持一键创建
选中 项目目录/uni_modules 右键 新建组件
TODO
至此,我们已经得到了一个最基本的UTS插件目录,下个章节我们介绍其中各文件的作用
## UTS组件结构解析
#### UTS组件目录结构
![目录结构](https://native-res.dcloud.net.cn/images/uts/component/image1.png)
<pre v-pre="" data-lang="">
<code class="lang-" style="padding:0">
┌─common // 可跨端公用的uts代码。推荐,不强制
......@@ -104,152 +89,180 @@ TODO
</pre>
如上所示,UTS组件的目录结构与UTS插件基本相同
如上所示,UTS组件的目录结构与UTS插件基本相同
唯一的差别在于,UTS组件入口文件有两个,一个必选的index.vue 组件入口,和一个可选的index.uts 函数能力入口
用户如果在开发组件的同时,存在一些与组件无关的能力需要对外暴露,可以在index.uts中进行实现
用户如果在开发组件的同时,存在一些与组件无关的能力需要对外暴露,则可以同时开发两个入口。
大多数情况下,我们只需要开发一个index.vue 即可,如果存在多个组件,可以新建多个 *.vue文件
关于index.vue 的源码规范会在下一个章节介绍
大多数情况下,组件其实我们只需要开发一个index.vue 即可,关于index.vue 的具体规范会在下一个章节介绍
#### UTS组件源码解析
#### UTS组件 代码格式解析
下面是一个组件源码 index.vue 完整示例:
**注意**
下面是一个组件源码 index.vue 完整示例:
- 目前UTS组件仅支持`export default {}`的选项式API,vue3的组合式API暂未支持。
```ts
export default {
<template>
<view class="defaultStyles">
</view>
</template>
<script lang="uts">
import TextUtils from 'android.text.TextUtils'
import Button from 'android.widget.Button'
import LinearLayout from 'android.widget.LinearLayout'
import Color from 'android.graphics.Color'
import View from 'android.view.View'
class ButtonClickListsner extends View.OnClickListener {
constructor() {}
override onClick(v ? : View) {
console.log(v)
}
}
//原生提供以下属性或方法的实现
export default {
/**
* 组件名称,也就是开发者使用的标签
*/
name: "xxx-view",
/**
* 组件涉及的事件声明,只有声明过的事件,才能被正常发送
*/
emits: ['bindended'],
name: "uts-hello-view",
/**
* 组件涉及的事件声明,只有声明过的事件,才能被正常发送
*/
emits: ['buttonClick'],
/**
* 属性声明,组件的使用者会传递这些属性值到组件
*/
props: {
/**
* 字符串类型 属性:path 默认值:""
*/
"path": {
type: String,
default: ""
},
},
props: {
/**
* 字符串类型 属性:buttonText 需要设置默认值
*/
"buttonText": {
type: String,
default: "点击触发"
}
},
/**
* 组件内部变量声明
*/
data() {
return {
}
},
data() {
return {}
},
/**
* 属性变化监听器实现
*/
watch: {
"path": {
handler(newPath: string) {
// 这里处理属性newPath 的更新逻辑
},
//创建时是否通过此方法更新属性,默认值为false
immediate: false
},
},
watch: {
"buttonText": {
/**
* 这里监听属性变化,并进行组件内部更新
*/
handler(newButtonText: string) {
if (this.$el != null) {
let button = this.$el!.findViewWithTag("centerButton") as Button
if (!TextUtils.isEmpty(newButtonText)) {
button.setText(newButtonText)
}
}
},
immediate: false //创建时是否通过此方法更新属性,默认值为false
},
},
/**
* 规则:如果没有配置expose,则methods中的方法均对外暴露,如果配置了expose,则以expose的配置为准向外暴露
* ['publicMethod'] 含义为:只有 `publicMethod` 在实例上可用
*/
expose: ['publicMethod'],
methods: {
expose: ['doSth'],
methods: {
/**
* 对外公开的组件方法
*/
publicMethod() {
doSth(paramA: string) {
// 这是组件的自定义方法
}
doSth(paramA: string) {
// 这是组件的自定义方法
console.log("paramA")
},
/**
* 内部使用的组件方法
*/
privateMethod() {
doSthInner(paramA: string) {
// 这是组件的自定义方法
}
}
},
},
/**
* 组件被创建,组件第一个生命周期,
* 在内存中被占用的时候被调用,开发者可以在这里执行一些需要提前执行的初始化逻辑
* [可选实现]
*/
created() {
created() {
},
},
/**
* 对应平台的view载体即将被创建,对应前端beforeMount
* [可选实现]
*/
NVBeforeLoad() {
},
NVBeforeLoad() {
},
/**
* 创建原生View,必须定义返回值类型
* 开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型
* (Android需要明确知道View类型,需特殊校验)
* todo 补充IOS平台限制
* [必须实现]
* [必须实现]
*/
NVLoad(): View {
let viewInstance = new View($androidContext)
return aView
},
NVLoad(): LinearLayout {
//必须实现
let contentLayout = new LinearLayout($androidContext)
let button = new Button($androidContext)
button.setText("点击触发");
button.setTag("centerButton");
contentLayout.addView(button, LinearLayout.LayoutParams(500, 500));
button.setOnClickListener(new ButtonClickListsner())
return contentLayout
},
/**
* 原生View已创建
* [可选实现]
*/
NVLoaded() {
},
NVLoaded() {
},
/**
* 原生View布局完成
* [可选实现]
*/
NVLayouted() {
},
NVLayouted() {
},
/**
* 原生View将释放
* [可选实现]
*/
NVBeforeUnload() {
},
NVBeforeUnload() {},
/**
* 原生View已释放,这里可以做释放View之后的操作
* [可选实现]
*/
NVUnloaded() {
},
NVUnloaded() {
},
/**
* 组件销毁
* [可选实现]
*/
unmounted() {
}
unmounted() {}
/**
* 自定组件布局尺寸
* [可选实现]
......@@ -259,10 +272,20 @@ TODO
size.height = 800.0.toFloat()
return size
}
}
}
</script>
<style>
/* 定义默认样式值, 组件使用者没有配置时使用 */
.defaultStyles {
width: 750rpx;
height: 240rpx;
background-color: blue;
}
</style>
```
index.vue可以分为以下几类:
+ 配置:
......@@ -301,77 +324,205 @@ index.vue可以分为以下几类:
组件开发者需要重点关注生命周期
```mermaid
graph TD;
Create-->NVBeforeLoad;
subgraph View生命周期
NVBeforeLoad-->NVLoad;
NVLoad-->NVLoaded;
NVLoaded-->NVLayouted;
NVLayouted-->NVBeforeUnload;
end
NVBeforeUnload-->unmounted;
```
![生命周期](https://native-res.dcloud.net.cn/images/uts/component/image2.png)
|函数名 |描述 |建议行为 |是否可选 |
|:---- |:--- |:--- |:--- |
|created |组件在内存中被创建 |开发者可以在这里执行一些需要最早执行的初始化逻辑|可选|
|NVBeforeLoad |组件对应平台的view载体,即将被创建|开发者可以在这里执行一些需要在View创建前初始化的逻辑|可选|
|NVLoad |组件view载体正在被创建实现|开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型|必须实现|
|NVLayouted |组件对应平台的view载体已布局结束 |需要在view布局结束后执行的逻辑 |可选|
|NVBeforeUnload |view载体即将被卸载 |View卸载前,需要回收资源的逻辑 |可选|
|NVUnloaded |view载体已经被卸载 |View卸载后,需要回收资源的逻辑 |可选|
|unmounted |组件在内存被销毁 |资源回收逻辑 |可选|
+ created:
组件被创建,组件第一个生命周期,在内存中被占用的时候被调用,开发者可以在这里执行一些需要提前执行的初始化逻辑
除上述生命周期外,还存在下列可选周期函数:
+ NVBeforeLoad
+ doMeasure
组件对应平台的view载体 即将被创建
doMeasure 用于告诉排版系统,组件自身需要的宽高,具体的调用时机由排版系统决定。
+ NVLoad:
一般情况下,组件的宽高应该是由终端系统的排版引擎决定,组件开发者不需要实现此函数。
[必须实现]
但是部分场景下,组件开发者需要自己维护宽高,则需要开发者重写此函数
组件 view载体的创建实现
开发者需要重点实现这个函数,声明原生组件被创建出来的过程,以及最终生成的原生组件类型
#### 内置对象和函数
+ NVLayouted
为了方便组件开发者使用,UTS 组件内部内置了下列对象
组件对应平台的view载体,布局完成
|变量名 |类型 |简介 |平台限制 |方法&属性 |
|:------- |:-------- |:-------- |:--- |:--- |
|$el |对象 |当前View实例对象 |全部平台 |开发者在NVLoad返回的对象类型|
|$androidContext|对象 |当前组件上下文 |仅android |android平台对应Context对象|
|emit("event") |函数 |发送已注册的事件 |全部平台 ||
+ NVBeforeUnload:
view载体即将被卸载
资源回收
+ NVUnloaded:
## 简单View的示例
view载体已经被卸载
#### 创建插件
资源回收
在HBuilder X 中选中Uni-App项目下 uni_modules目录
+ unmounted:
todo 目前还没有创建界面
view载体被回收
资源回收
这是创建后的目录结构
+ doMeasure:
![目录结构](https://native-res.dcloud.net.cn/images/uts/component/image1.png)
doMeasure 用于告诉排版系统,组件自身需要的宽高,具体的调用时机由排版系统决定。
一般情况下,组件的宽高应该是由终端系统的排版引擎决定,组件开发者不需要实现此函数。
#### 编写逻辑
但是部分场景下,组件开发者需要自己维护宽高,则需要开发者重写此函数
打开index.vue,键入下面的组件源码:
```ts
<template>
<view class="defaultStyles">
</view>
</template>
<script lang="uts">
import TextUtils from 'android.text.TextUtils'
import Button from 'android.widget.Button'
import LinearLayout from 'android.widget.LinearLayout'
import Color from 'android.graphics.Color'
import View from 'android.view.View'
class ButtonClickListsner extends View.OnClickListener {
constructor() {}
override onClick(v ? : View) {
console.log(v)
}
}
//原生提供以下属性或方法的实现
export default {
/**
* 组件名称,也就是开发者使用的标签
*/
name: "uts-hello-view",
/**
* 组件涉及的事件声明,只有声明过的事件,才能被正常发送
*/
emits: ['buttonClick'],
/**
* 属性声明,组件的使用者会传递这些属性值到组件
*/
props: {
/**
* 字符串类型 属性:buttonText 需要设置默认值
*/
"buttonText": {
type: String,
default: "点击触发"
}
},
/**
* 属性变化监听器实现
*/
watch: {
"buttonText": {
/**
* 这里监听属性变化,并进行组件内部更新
*/
handler(newButtonText: string) {
if (this.$el != null) {
let button = this.$el!.findViewWithTag("centerButton") as Button
if (!TextUtils.isEmpty(newButtonText)) {
button.setText(newButtonText)
}
}
}
},
},
NVLoad(): LinearLayout {
//必须实现
let contentLayout = new LinearLayout($androidContext)
let button = new Button($androidContext)
button.setText("点击触发");
button.setTag("centerButton");
contentLayout.addView(button, LinearLayout.LayoutParams(500, 500));
button.setOnClickListener(new ButtonClickListsner())
return contentLayout
},
}
</script>
<style>
/* 定义默认样式值, 组件使用者没有配置时使用 */
.defaultStyles {
width: 750rpx;
height: 240rpx;
background-color: blue;
}
</style>
```
#### 使用组件
#### 内置对象和函数
打开任意 componet.nvue文件
```js
<uts-hello-view buttonText="点击按钮内容" style="width:375px;height: 375px;background-color: aqua;"></uts-hello-view>
```
为了方便组件开发者使用,UTS 组件内部内置了下列对象:
|变量名 |类型 |简介 |平台限制 |
|:------- |:-------- |:-------- |:--- |
|$el |对象 |当前View实例对象 |全部平台 |
|$androidContext|对象 |当前组件上下文 |仅android |
|emit("event") |函数 |发送已注册的事件 |全部平台 |
## 包含第三方SDK的示例
#### 创建插件
在HBuilder X 中选中Uni-App项目下 uni_modules目录
todo 目前还没有创建界面
这是创建后的目录结构
![目录结构](https://native-res.dcloud.net.cn/images/uts/component/image1.png)
#### 引入依赖
打开 ~/uni_modules/uts-animation-view/utssdk/app-android/config.json
键入如下代码:
```
"dependencies": [
"com.airbnb.android:lottie:3.4.0"
]
```
UTS组件建议使用远程依赖的方式集成,如果需要以AAR的形式添加SDK,可以添加到
## UTS组件开发使用示例
~/uni_modules/uts-animation-view/utssdk/app-android/libs目录
#### 编写逻辑
## 包含第三方功能的 UTS组件开发使用示例
#### 使用组件
#### 使用组件的注意事项
......
#### 3.6.16.20230109-alpha
* 【uni-app】
* App平台、Web平台 优化 input 组件支持 inputmode 属性 [详情](https://uniapp.dcloud.net.cn/component/input.html#inputmode)
* App平台 修复 Vue3 项目 nvue 页面 webview 组件 onPostMessage 事件无效的Bug [详情](https://ask.dcloud.net.cn/question/158925)
* App平台 修复 Vue3 项目 image 组件使用 base64 显示异常的Bug [详情](https://ask.dcloud.net.cn/question/158368)
* App-Android平台 修复 nvue 页面 live-pusher 组件拒绝相机权限后再手动开启,回到应用后可能无法调用相机预览的Bug [详情](https://ask.dcloud.net.cn/question/158518)
* App-iOS平台 修复 nvue 页面 ad-content-page 组件拉取广告配置失败后无法重新拉取的Bug
* App-iOS平台 修复 nvue 页面 map 组件使用自定义地图样式后切换卫星图无效的Bug [详情](https://ask.dcloud.net.cn/question/159316)
* App-iOS平台 修复 使用模拟器开启调试后启动应用白屏的Bug [详情](https://ask.dcloud.net.cn/question/160363)
* App-iOS平台 修复 Vue3 项目中 input 组件 disabled 无法动态修改的Bug [详情](https://ask.dcloud.net.cn/question/157958)
* Web平台、小程序平台 修复 uni-push2.0 WebSocket连接不稳定的Bug [详情](https://ask.dcloud.net.cn/question/159690)
* Web平台 修复 input 组件输入负数带出上次结果的Bug [详情](https://ask.dcloud.net.cn/question/159447)
* Web平台 修复 Vue3 项目 uni.navigateTo eventChannel 只会调用一次的Bug [详情](https://ask.dcloud.net.cn/question/155922)
* Web平台 修复 Vue3 项目 scroll-view 组件滚动频繁触发视图更新的Bug [详情](https://ask.dcloud.net.cn/question/149557)
* Web平台 修复 Vue3 项目 picker 组件 end 属性读取错误的Bug [详情](https://github.com/dcloudio/uni-app/issues/4075)
* Web平台 修复 uni.setTabBarItem 导致 tab 切换生命周期异常的Bug [详情](https://ask.dcloud.net.cn/question/160739)
* 微信小程序平台 修复 Vue2 项目 模板中无法观测数组长度变化的Bug [详情](https://github.com/dcloudio/uni-app/issues/1827)
* 支付宝小程序平台 修复 Vue3 项目运行报错的Bug [详情](https://ask.dcloud.net.cn/question/159362)
* 【uniCloud】
* JQL语法 修复 使用 setUser 方法未传 permission 参数且使用触发器时报错的Bug
* JQL语法 修复 add 方法传递的字段值为对象且其中包含null值时报错的Bug
* JQL语法 新增 数据库触发器增加 triggerContext 参数,用于在 before 和 after 内共享数据 [详情](https://uniapp.dcloud.net.cn/uniCloud/jql-schema-ext.html#trigger-context)
* 阿里云 调整 正式版云存储单文件100MB限制调整为5GB
* 【App插件(含5+App和uni-app的App端)】
* Android平台 更新 fastjson SDK为 1.2.83 版,解决安全检测可能报`Fastjson反序列化远程代码执行漏洞`的问题
* Android平台 更新 一键登录使用的个验SDK为 3.1.0.0 版,优化初始化和预登录速度
* Android平台 更新 UniPush 使用的个推核心组件SDK为 3.2.1.0 版;谷歌渠道个推 sdk-for-gj 为 4.4.3.1 版;解决发布到 Google Play 商店可能被下架的问题 [详情](https://ask.dcloud.net.cn/question/160249)
* Android平台 修复 3.6.12版引出的 从系统相册中选择文件在部分鸿蒙设备可能引起崩溃的Bug [详情](https://ask.dcloud.net.cn/question/159556)
* Android平台 修复 3.6.7版引出的 一键登录 登录完成后自动关闭登录界面,以及登录按钮 loading 动画效果缺失的Bug [详情](https://ask.dcloud.net.cn/question/159898)
* Android平台 修复 设置 targetSdkVersion 值大于或等于 30 时使用高德地图引起应用崩溃的Bug [详情](https://ask.dcloud.net.cn/question/159801)
* iOS平台 更新 UniPush 使用的个推SDK为 2.7.2.0 版,需支持 Swift 环境可能导致 ipa 包变大 [详情](https://uniapp.dcloud.net.cn/tutorial/app-push-unipush.html#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)
* iOS平台 修复 设置应用语言为英文时部分系统界面可能会显示为回退语言的Bug [详情](https://ask.dcloud.net.cn/question/159445)
* iOS平台 修复 自定义基座真机运行可能导致 setStorage 保存的数据丢失的Bug [详情](https://ask.dcloud.net.cn/question/159903)
* iOS平台 修复 plus.nativeUI.toast 设置 style 为 inline 时 iconWidth/iconHeight 属性失效的Bug [详情](https://ask.dcloud.net.cn/question/160192)
* iOS平台 修复 uni-AD 优量汇开屏广告展示期间弹出提示框可能导致开屏界面不会关闭的Bug
* iOS平台 修复 startBluetoothDevicesDiscovery 搜索附近蓝牙设备返回数据没有 advertisData 字段的Bug [详情](https://ask.dcloud.net.cn/question/160178)
#### 3.6.14.20221216-alpha
* 【uni-app】
* App-Android平台 修复 使用 canvas 模块后 wgt 升级提示没有配置 canvas 模块的Bug [详情](https://ask.dcloud.net.cn/question/159283)
......
......@@ -176,5 +176,12 @@ UniPush和个推推送模块支持设置自定义推送图标,包括push图标
- **5+ App、Wap2App项目详细使用教程请参考 [UniPush使用指南](https://ask.dcloud.net.cn/article/35622)**
### 常见问题
- **iOS勾选推送并且基于HBuilderX 3.6.14+打包ipa变大的问题** 原因是推送SDK升级需要支持Swift环境,用生产证书+AppStore类型的描述文件打出来的ipa会增大60-70M左右,苹果为了兼容iOS12之前的Swift版本,打包AppStore的ipa需要将全部版本的Swift环境添加到ipa的根目录,上传的AppStore后苹果会处理这些Swift环境,用户实际下载的安装包不会大特别多
- **iOS勾选推送并且基于HBuilderX 3.6.14+打包ipa变大的问题**
1. 为什么会变大?
原因是推送SDK升级需要支持Swift环境,之前工程如果不包含Swift环境需要添加Swift环境(打包使用Swift语言开发的原生插件同样有类似问题)。
2. 为什么只有生产包变大?
只有用生产证书+AppStore类型的描述文件打出来的ipa会增大60-70M左右,苹果为了兼容iOS12之前的Swift版本,打包AppStore类型的ipa需要将全部版本的Swift环境添加到ipa的根目录,而测试证书以及adhoc描述文件打的包不会添加多个版本的Swift环境。
另:设置支持系统大于iOS12也可解决以上问题 [设置iOS支持的最低版本](https://uniapp.dcloud.net.cn/collocation/manifest-app.html#ios)
3. ipa变大会导致用户下载的应用变大吗?
会大一点,但不会特别多。ipa上传的AppStore后苹果会根据用户手机系统最终只会保留一份Swift环境,用户实际下载的安装包不会大特别多。
......@@ -281,11 +281,14 @@ HBuilderX 3.5.3之后的版本,App真机运行 使用Node运行,不再依赖
- HBuilderX 云打包自定义基座
- 离线SDK Android Studio制作的自定义基座
> 如果以下解决方法,没有解决问题,请到 [Ask论坛](https://ask.dcloud.net.cn/)详细说明问题(需要包含操作系统、HBuilderX版本、项目信息、基座信息、手机信息、控制台截图等,详细的信息有助于我们排查问题)
**尝试以下解决方法**
- Android手机上,找到应用App,删除,重新运行。
- 关闭开发者模式,usb调试,重新打开试试
- 关闭开发者模式,usb调试,重新打开试试。手机USB设置,各个选项尝试一下
- 如果是`离线SDK Android Studio制作的自定义基座`, 检查下是否缺少`implementation 'com.squareup.okhttp3:okhttp:3.12.12'`, `implementation 'com.squareup.okio:okio:1.15.0'`, 如果缺少请添加它们。
- 如果是`离线SDK Android Studio制作的自定义基座`, 可以尝试使用HBuilderX 云打包自定义基座,看下是否正常。
- 手机USB设置,各个选项尝试一下
- 更多参考下这个帖子 [详情](https://ask.dcloud.net.cn/question/154229), 如上上述方法没有解决问题,请到 [Ask论坛](https://ask.dcloud.net.cn/)详细说明问题(需要包含操作系统、HBuilderX版本、项目信息、基座信息、手机信息等,详细的信息有助于我们排查问题)
\ No newline at end of file
- 手机系统分身的原因。[具体详情参考](https://ask.dcloud.net.cn/question/161130)
- 如果手机是华为鸿蒙系统,排查下是否是手机自身的原因,换个其它品牌手机试试,如小米、oppo。
- 更多参考下这个帖子 [详情](https://ask.dcloud.net.cn/question/154229)
\ No newline at end of file
......@@ -466,31 +466,90 @@ uni统计深入uni-app和uniCloud框架底层,提供了众多其他统计平
uni统计开源且基于[uni-admin](/uniCloud/admin)的插件规范提供了插件机制,会有更多插件作者提供各种丰富的统计插件(如电商统计、内容统计等)。见[插件市场](https://ext.dcloud.net.cn/?cat1=7&cat2=74&type=HotList)
## 群发短信@batch-sms <Badge text="uni-admin 2.1.0+" />
**前提准备**
1.[开发者中心](https://dev.dcloud.net.cn)开通短信验证码服务
2.```uni-config-center/uni-sms-co/config.json```中配置短信 API 密钥
```json
{
"smsKey": "your smsKey",
"smsSecret": "your smsSecret"
}
```
**功能介绍**
> 第一次使用此功能,请在[开发者中心](https://dev.dcloud.net.cn) - "短信" - "模板配置" 导出短信模板,在群发短信界面上传短信模板后使用。
## 营销短信群发@batch-sms <Badge text="uni-admin 2.1.0+" />
如有客户关怀、会员服务、电商活动、新品上线等场景需要给用户发送短信时,无需开发,在uni-admin控制台选择用户/标签即可向用户群发短信,省时高效。
同时支持动态替换短信模板变量,使短信更加个性化。
### 功能介绍
- 支持 给指定用户、全部用户、指定标签用户群发短信
- 指定用户:在用户列表中勾选要接收短信的用户(必须有手机号)后,点击“群发信息”创建短信任务。
- 全部用户:在用户列表界面直接点击“群发短信”创建短信任务。
- 指定标签用户:在用户标签列表中勾选标签(如标签关联的用户没有手机号将不会发送短信)后,点击“群发短信”创建短信任务。
- 指定用户:在用户列表中勾选要接收短信的用户(必须有手机号)后,点击“群发信息”创建短信任务。
- 全部用户:在用户列表界面直接点击“群发短信”创建短信任务。
- 指定标签用户:在用户标签列表中勾选标签(如标签关联的用户没有手机号将不会发送短信)后,点击“群发短信”创建短信任务。
- 支持 短信模板中的变量替换为“固定文本”与“数据库字段”
- 固定文本:固定字符串,所有用户会接收同样的内容,例如:```DCloud```
- 数据库字段:可以关联数据库中指定字段,内容较为个性化。格式为 ```{数据库表名.字段}```,例如: ```{uni-id-users.username}``` 目前仅支持```uni-id-users```
- 固定文本:固定字符串,所有用户会接收同样的内容,例如:```DCloud```
- 数据库字段:可以关联数据库中指定字段,内容较为个性化。格式为 ```{数据库表名.字段}```,例如: ```{uni-id-users.username}``` 目前仅支持```uni-id-users```
- 支持 发送前预览前5人短信内容,用于检测模板变量是否配置正确,提高发送成功率。
![群发短信](https://web-assets.dcloud.net.cn/unidoc/zh/86928cf2-2f69-4c0f-a46f-a617e3fc1c83.png)
详细操作流程参考[营销短信群发](send-sms.md#batch-sms)
### 使用方式
**步骤一:开通短信服务**
如您首次使用请登录[DCloud开发者中心](https://dev.dcloud.net.cn/)开通短信服务
**步骤二:添加签名与模板**
[签名配置页面](https://dev.dcloud.net.cn/pages/sms/sign)添加短信签名
[模板配置页面](https://dev.dcloud.net.cn/pages/sms/template)中添加短信模板
例如:`【测试】亲爱的${username}, 祝您生日快乐!感谢您长期以来对xx商城的信任与支持,会员生日月畅享购物双倍积分,期待您的光临!`
**步骤三:导出短信模板**
在短信模板页面-点击”导出模板“按钮,导出短信模板。
![导出短信模板](https://web-assets.dcloud.net.cn/unidoc/zh/20230107203307.png)
**步骤四:通过uni-admin控制台发送短信**
如您未部署过uni-admin,请在插件市场中安装[uni-admin](https://ext.dcloud.net.cn/plugin?id=3268)
首次使用,在 ```uni-config-center/uni-sms-co/config.json```中配置短信 API 密钥
```json
{
"smsKey": "your smsKey",
"smsSecret": "your smsSecret"
}
```
配置完成后,登录uni-admin控制台,打开用户管理页面,请按照图示步骤上传短信模板(步骤三导出的短信模板):
![上传短信模板](https://web-assets.dcloud.net.cn/unidoc/zh/20230107201145.png)
短信模板上传成功后,短信模板即可显示,如下:
![短信模板上传成功](https://web-assets.dcloud.net.cn/unidoc/zh/20230107202329.png)
选择要接收短信的用户,如下:
![群发用户](https://web-assets.dcloud.net.cn/unidoc/zh/20230107202752.png)
或者如果已经对用户进行了分组,可以在标签管理中选择标签后发送短信,如下:
![群发用户标签](https://web-assets.dcloud.net.cn/unidoc/zh/20230107203019.png)
目前短信支持固定文本发送与关联数据表字段发送,以下介绍两种方式如何发送
**固定文本发送**
选择短信模板,如果没有出现变量模板配置就是固定文本模式,如下:
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230107204518.png)
可以在发送前点击预览,可以预览发送的第一条短信,用来检查短信内容是否正确,如下:
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230107204807.png)
确认短信内容无误后,点击提交即可发送短信,发送短信之后可以在[DCloud开发者中心](https://dev.dcloud.net.cn/)-查看[短信发送记录](https://dev.dcloud.net.cn/pages/sms/sendLog)
**使用数据表字段作为模板变量发送**
选择短信模板,如果出现变量模板配置就是数据表查询模式,如下:
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230107205208.png)
如上,短信变量字段为”username“,配置替换字段为uni-id-users表中username字段,在发送短信时会替换掉短信变量。
短信变量支持固定值和数据表查询两种方式;固定值如:各位同事,数据表查询如:{uni-id-users.username};请注意,若使用数据表查询方式,目前仅支持查询 uni-id-users 表;并注意确保数据库中查询字段值不为空,否则短信将发送失败。
在发送之前可以点击预览,查看第一条短信的内容,确保变量模板配置正确,如下,username将替换为“张三”:
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230107205823.png)
确认短信内容无误后,点击提交即可发送短信,发送短信之后可以在[DCloud开发者中心](https://dev.dcloud.net.cn/)-查看[短信发送记录](https://dev.dcloud.net.cn/pages/sms/sendLog)
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230107210406.png)
如有任何问题可在[论坛发帖](https://ask.dcloud.net.cn)咨询或加uniCloud短信服务交流QQ群(695645208)咨询
## 用户-角色-权限
......
......@@ -85,6 +85,7 @@ ext.js里引入公共模块的机制:
|userInfo |object |- |是 |用户信息 |
|result |object |- |afterXxx内必备 |本次请求结果 |
|isEqualToJql |function |- |是 |用于判断当前执行的jql语句和执行语句是否相等 |
|triggerContext |object |- |是 |用于在before和after内共享数据 |
#### where@where
......@@ -221,6 +222,32 @@ module.exports {
}
```
#### triggerContext@trigger-context
> 新增于 HBuilderX 3.6.16
此参数为一个空对象,仅用于在before内挂载数据并在after内获取使用
**示例**
```js
// article.schema.ext.js
module.exports {
trigger: {
beforeUpdate: async function({
triggerContext
} = {}) {
triggerContext.shareVar = 1
},
afterUpdate: async function(){
if (triggerContext.shareVar === 1) {
console.log('获取到的triggerContext.shareVar为1')
}
}
}
}
```
### 触发时机@trigger-timing
|触发时机 |说明 |
......
注:本更新日志仅限uniCloud,包括uniCloud web控制台、uniCloud 云端运行环境。这些更新不跟随HBuilderX发版更新。
#### 2023-01-09
* JQL语法 修复 使用 setUser 方法未传 permission 参数且使用触发器时报错的Bug
* JQL语法 修复 add 方法传递的字段值为对象且其中包含null值时报错的Bug
* JQL语法 新增 数据库触发器增加 triggerContext 参数,用于在 before 和 after 内共享数据 [详情](https://uniapp.dcloud.net.cn/uniCloud/jql-schema-ext.html#trigger-context)
* 阿里云 调整 正式版云存储单文件100MB限制调整为5GB
#### 2023-01-06
* 阿里云 正式版云存储单文件100MB限制调整为5GB
......
......@@ -217,76 +217,61 @@ exports.main = async (event, context) => {
- 短信费用为:0.036元/条。
但在实际使用中需要依赖`uniCloud`云服务。如使用uniCloud阿里云商业版,每条大约需要多花0.0000139元,几乎可以忽略不计。您也可以粗略认为每条短信的费用为0.0360139元/条。费用计算详见[短信及一键登录资源消耗评估](uniCloud/aliyun-migrate-business.md#sms-unilogin-fee)
但在实际使用中需要依赖`uniCloud`云服务。如使用uniCloud阿里云商业版,每条大约需要多花0.0000139元,几乎可以忽略不计。您也可以粗略认为每条短信的费用为0.0360139元/条。费用计算规则如下:
- 计费条数计算方法:短信内容少于70个字符(每个汉字、标点、空格、字母均算一个字符)算作1条短信,短信内容多于70个字符时,每67个字符算作一条短信,并向上取整(不足67个字符的部分也算做1条)。 例: 短信内容有 100个字符时计费短信条数应为 100 / 67 ≈ 1.49 向上取整后算作2条。
- 最终按照成功回执状态为"成功"的短信条数计费,成功回执状态可在"发送记录"页面查看。
特别注意:短信成功回执最长延迟为72小时。
## 营销短信群发@batch-sms
如有客户关怀、会员服务、电商活动、新品上线等场景需要给用户发送短信时,不再需要开发,在uni-admin控制台选择用户/标签即可向用户群发短信,省时高效。
同时支持动态替换短信模板变量,使短信更加个性化。
**步骤一:开通短信服务**
如您首次使用请登录[DCloud开发者中心](https://dev.dcloud.net.cn/)开通短信服务
**步骤二:添加签名与模板**
[签名配置页面](https://dev.dcloud.net.cn/pages/sms/sign)添加短信签名
`短信`业务涉及费用的部分主要是云函数/云对象的使用量、调用次数、和出网流量(如:使用`uni-id-co`或自定义的云函数/云对象来发送短信)。
接下来,我们对不同资源,分别进行费用评估。
[模板配置页面](https://dev.dcloud.net.cn/pages/sms/template)中添加短信模板
我们按照uniCloud官网列出的[按量计费](https://uniapp.dcloud.net.cn/uniCloud/price.html#aliyun-postpay)规则,可以简单得出如下公式:
例如:`【测试】亲爱的${username}, 祝您生日快乐!感谢您长期以来对xx商城的信任与支持,会员生日月畅享购物双倍积分,期待您的光临!`
`云函数/云对象费用 = 资源使用量 * 0.000110592 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8`
**步骤三:导出短信模板**
其中:
- 资源使用量 = 云函数内存(单位为G) * 云函数平均单次执行时长(单位为秒) * 调用次数
- 调用次数 = 发送短信条数(一般情况下发送条数 = 调用次数,特殊情况除外)
在短信模板页面-点击”导出模板“按钮,导出短信模板。
![导出短信模板](https://web-assets.dcloud.net.cn/unidoc/zh/20230107203307.png)
**步骤四:通过uni-admin控制台发送短信**
我们假设如下数据模型:
如您未部署过uni-admin,请在插件市场中安装[uni-admin](https://ext.dcloud.net.cn/plugin?id=3268)
- 云函数内存:512M,即0.5G (云函数内存默认为512M,用户可以自定义设置,最低可设置为128M。如果您仅发送短信,没有其他复杂业务,那么内存设为128M可以进一步的降低费用)
- 云函数平均单次执行时长:200毫秒,即0.2秒
- 短信业务平均每日调用次数:10000次
- 出网流量:单次请求 2 KB
首次使用,请在`uni-config-center/uni-sms-co/config.json`中配置短信`smsKey``smsSecret`,具体配置方式参考[uni-admin群发短信文档](uniCloud/admin.md#batch-sms)
按照如上公式,其`短信`业务云函数每天的费用为:
配置完成后,登录uni-admin控制台,打开用户管理页面,请按照图示步骤上传短信模板(步骤三导出的短信模板):
![上传短信模板](https://web-assets.dcloud.net.cn/unidoc/zh/20230107201145.png)
短信模板上传成功后,短信模板即可显示,如下:
![短信模板上传成功](https://web-assets.dcloud.net.cn/unidoc/zh/20230107202329.png)
选择要接收短信的用户,如下:
![群发用户](https://web-assets.dcloud.net.cn/unidoc/zh/20230107202752.png)
或者如果已经对用户进行了分组,可以在标签管理中选择标签后发送短信,如下:
![群发用户标签](https://web-assets.dcloud.net.cn/unidoc/zh/20230107203019.png)
目前短信支持固定文本发送与关联数据表字段发送,以下介绍两种方式如何发送
**固定文本发送**
```
云函数费用(天) = 资源使用量 * 0.000110592 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8
= 云函数内存(单位为G) * 云函数平均单次执行时长(单位为秒) * 调用次数 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8
= 0.5G * 0.2S * 10000 * 0.000110592 + 10000 * 0.0133/10000 + 10000 * 2 * 0.8 / (1024 * 1024)
= 0.110592 + 0.0133 + 0.0152587890625
= 0.1391507890625(元)
≈ 0.139(元)
```
选择短信模板,如果没有出现变量模板配置就是固定文本模式,如下:
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230107204518.png)
可以在发送前点击预览,可以预览发送的第一条短信,用来检查短信内容是否正确,如下:
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230107204807.png)
确认短信内容无误后,点击提交即可发送短信,发送短信之后可以在[DCloud开发者中心](https://dev.dcloud.net.cn/)-查看[短信发送记录](https://dev.dcloud.net.cn/pages/sms/sendLog)
结论:如果你的`短信`业务平均每天发送条数为10000条,使用阿里云正式版云服务空间后,对应云函数每天大概消耗0.139元,对比之前的短信费用,平均每次调用多花0.0000139元,几乎可忽略不计。
**使用数据表字段作为模板变量发送**
选择短信模板,如果出现变量模板配置就是数据表查询模式,如下:
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230107205208.png)
如上,短信变量字段为”username“,配置替换字段为uni-id-users表中username字段,在发送短信时会替换掉短信变量。
- 计费条数计算方法:短信内容少于70个字符(每个汉字、标点、空格、字母均算一个字符)算作1条短信,短信内容多于70个字符时,每67个字符算作一条短信,并向上取整(不足67个字符的部分也算做1条)。 例: 短信内容有 100个字符时计费短信条数应为 100 / 67 ≈ 1.49 向上取整后算作2条。
- 最终按照成功回执状态为"成功"的短信条数计费,成功回执状态可在"发送记录"页面查看。
短信变量支持固定值和数据表查询两种方式;固定值如:各位同事,数据表查询如:{uni-id-users.username};请注意,若使用数据表查询方式,目前仅支持查询 uni-id-users 表;并注意确保数据库中查询字段值不为空,否则短信将发送失败
特别注意:短信成功回执最长延迟为72小时
在发送之前可以点击预览,查看第一条短信的内容,确保变量模板配置正确,如下,username将替换为“张三”:
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230107205823.png)
## 营销短信群发@batch-sms
如有客户关怀、会员服务、电商活动、新品上线等场景需要给用户发送短信时,通过uni-admin群发短信功能,无需开发,及时送达用户。
[营销短信群发配置](uniCloud/admin.md#batch-sms)
确认短信内容无误后,点击提交即可发送短信,发送短信之后可以在[DCloud开发者中心](https://dev.dcloud.net.cn/)-查看[短信发送记录](https://dev.dcloud.net.cn/pages/sms/sendLog)
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230107210406.png)
**功能亮点**
如有任何问题可在[论坛发帖](https://ask.dcloud.net.cn)咨询或加uniCloud短信服务交流QQ群(695645208)咨询
支持给用户打标签分组,按照分组群发短信,可以同时给多个分组群发
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230109154350.png)
短信模板变量支持从数据库表字段中读取
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230109194715.png)
发送前预览短信内容;防止内容错误,提高发送成功率
![](https://web-assets.dcloud.net.cn/unidoc/zh/20230109155202.png)
如何使用?查看[营销短信群发配置](uniCloud/admin.md#batch-sms)
<style>
.join-group-chat{
......
......@@ -241,8 +241,39 @@ exports.main = async function (event){
- 0.02元/次,失败不计费。
实际使用中需要依赖`uniCloud`云服务,这方面费用如下:在使用阿里云正式版后,每次一键登陆请求大约需要消耗uniCloud费用0.0000139元,几乎可以忽略不计。也可以粗略认为每次使用一键登陆的成本为0.0200139元/次。
实际使用中需要依赖`uniCloud`云服务,这方面费用如下:在使用阿里云正式版后,每次一键登陆请求大约需要消耗uniCloud费用0.0000139元,几乎可以忽略不计。也可以粗略认为每次使用一键登陆的成本为0.0200139元/次。费用计算规则如下:
`一键登录`业务涉及费用的部分主要是云函数/云对象的使用量、调用次数、和出网流量(如:使用自定义的云函数/云对象来获取手机号)。
接下来,我们对不同资源,分别进行费用评估。
我们按照uniCloud官网列出的[按量计费](https://uniapp.dcloud.net.cn/uniCloud/price.html#aliyun-postpay)规则,可以简单得出如下公式:
`云函数/云对象费用 = 资源使用量 * 0.000110592 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8`
其中:
- 资源使用量 = 云函数内存(单位为G) * 云函数平均单次执行时长(单位为秒) * 调用次数
- 调用次数 = 一键登录调用次数
我们假设如下数据模型:
- 云函数内存:512M,即0.5G (云函数内存默认为512M,用户可以自定义设置,最低可设置为128M。如果您仅使用一键登录,没有其他复杂业务,那么内存设为128M可以进一步的降低费用)
- 云函数平均单次执行时长:200毫秒,即0.2秒
- 一键登录业务平均每日调用次数:10000次
- 出网流量:单次请求 2 KB
按照如上公式,其`一键登录`业务云函数每天的费用为:
```
云函数费用(天) = 资源使用量 * 0.000110592 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8
= 云函数内存(单位为G) * 云函数平均单次执行时长(单位为秒) * 调用次数 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8
= 0.5G * 0.2S * 10000 * 0.000110592 + 10000 * 0.0133/10000 + 10000 * 2 * 0.8 / (1024 * 1024)
= 0.110592 + 0.0133 + 0.0152587890625
= 0.1391507890625(元)
≈ 0.139(元)
```
结论:如果你的`一键登录`业务平均每天获取手机号次数为10000次,使用阿里云正式版云服务空间后,对应云函数每天大概消耗0.139元,对比之前的一键登录费用,平均每次调用多花0.0000139元,几乎可忽略不计。
费用计算详见[短信及一键登录资源消耗评估](uniCloud/aliyun-migrate-business.md#sms-unilogin-fee)
很明显一键登陆是比短信验证码更便宜的用户身份验证方式。
......@@ -148,4 +148,255 @@ App升级中心 uni-upgrade-center,提供了 App 的版本更新服务。包
在插件市场安装,根据 readme 部署即可。[插件地址](https://ext.dcloud.net.cn/plugin?id=4542)
**关于应用转让后升级中心(uni-upgrade-center)的使用问题** [详情](https://ask.dcloud.net.cn/article/40112)
\ No newline at end of file
**关于应用转让后升级中心(uni-upgrade-center)的使用问题** [详情](https://ask.dcloud.net.cn/article/40112)
### 费用评测@upgrade-center-fee
近期,uniCloud阿里云版开始正式商用,部分开发者对基于uniCloud的`uni-upgrade-center`等云端一体业务,开始纠结,不清楚这些业务预计会花费多少钱,不清楚相比传统服务器而言,何种方案性价比更好。
本文尝试算细账、算总账,以阿里云[按量计费](https://uniapp.dcloud.net.cn/uniCloud/price.html#aliyun-postpay)为例,详细预测`uni-upgrade-center`在不同用户规模下的资源消耗及对应费用,帮助大家明智选择,无忧开发。
本文主要分为三个部分:
- `uni-upgrade-center`消耗的资源费用测算(云函数、云数据库、云存储、前端网页托管分别测算)
- `uni-upgrade-center`给你带来的收益
- 综合考虑,你该如何选择
`uni-upgrade-center`升级中心涉及费用的部分主要分为:
- 云函数:`uni-upgrade-center`云函数,将客户端版本和服务端最新版本进行对比,返回是否需升级的逻辑
- 云数据库:`opendb-app-versions`表,存储版本信息
- 云存储:放置近期的升级包资源(apk/ipa/wgt)
- 前端网站托管:部署`uni-admin`,管理员发布新版本
接下来,我们对不同资源,分别进行费用评估。
#### 云函数
启用`uni-upgrade-center`升级中心后,你的App每次启动,会请求一次`uni-upgrade-center`云函数。
我们按照uniCloud官网列出的[按量计费](https://uniapp.dcloud.net.cn/uniCloud/price.html#aliyun-postpay)规则,可以得出如下云函数资源消耗计算公式:
`云函数费用 = 资源使用量 * 0.000110592 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8`
其中:
- 资源使用量 = 云函数内存(单位为G) * 云函数平均单次执行时长(单位为秒) * 调用次数
- 调用次数 = App日活 * 每日活用户平均每天启动App次数,因为App每次启动,均会执行检查更新逻辑
我们假设如下数据模型:
- 云函数内存:256M,即0.25G;注意云函数内存默认为512M,`uni-upgrade-center`云函数建议设置为256M
- 云函数平均单次执行时长:100毫秒,即0.1秒
- 每日活用户平均每天启动App次数:2次
- 出网流量:0,升级中心无需链接外网
按照如上公式,你的App若有100个日活用户,其升级中心云函数每天的费用为:
```
云函数费用(天) = 资源使用量 * 0.000110592 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8
= 云函数内存(单位为G) * 云函数平均单次执行时长(单位为秒) * 调用次数 + 调用次数 * 0.0133 / 10000 + 出网流量 * 0.8
= 0.25G * 0.1S * 100 * 2 * 0.000110592 + 100 * 2 * 0.0133/10000 + 0
= 0.00081896(元)
```
即:你的App日活为100,使用`uni-upgrade-center`商业版后,对应云函数每天大概消耗0.00081896元。
据此,可计算其每月的费用为:0.00081896 * 30 = 0.0245688,即每月只需2分钱;
同理,我们可推导出日活为1000、10000、10万的App,其升级中心云函数每月费用如下表:
|日活 |资源使用量计费(元) |调用次数计费(元) |出网流量计费(元) |合计(元) |
|:-: |:-: |:-: |:-: |:-: |
|100 |0.0165888 |0.00798 |0 |0.0245688 |
|1000 |0.165888 |0.0798 |0 |0.245688 |
|10000 |1.65888 |0.798 |0 |2.45688 |
|100000 |16.5888 |7.98 |0 |24.5688 |
日活1000的App,云函数月度消耗才两毛五(0.25元),真是毛毛雨了。
#### 云数据库
按照[uniCloud官网](https://uniapp.dcloud.net.cn/uniCloud/price.html#aliyun-postpay)介绍,云数据库费用 = `容量费用 + 读操作次数费用 + 写操作次数费用`,其中:
- 容量费用:数据库存储容量(单位为G) * 0.07
- 读操作次数费用:读操作次数(万次) * 0.015
- 写操作次数:写操作次数(万次) * 0.015;
##### 容量费用
我们以`hello uni-app`为例,`opendb-app-versions`数据表中共存储30条升级记录,容量大小为8K。
据此可计算出`opendb-app-versions`表的日存储费用为:`8/1024/1024 * 0.07 = 0.000000534`
> 容量计费单位是G,故需先将8K折算成M,再折算成G,故上述公式中连续除了两个1024
1月按30天算,则月存储费用为`0.000000534 * 30 = 0.000016`,还不到1分钱,可忽略。
注意:数据库容量仅跟发布版本多少有关系,跟日活用户无关。
##### 读操作次数
在uni升级中心业务中,云函数`uni-upgrade-center`每次执行,仅调用一次数据库读取(读取一次`opendb-app-versions`表),故数据库的读操作次数等同于云函数的`调用次数`,前文有过公式,云函数调用次数 = `App日活 * 每日活用户平均每天启动App次数`,每日活用户平均每天启动App次数我们假设为2次。
我们即可推算,如果一个App的日活为100,则uni升级中心每日云数据库读操作次数费用计算如下:
```
读操作次数费用 = 读操作次数(万次) * 0.015
= 云函数调用次数(万次) * 0.015
= App日活 * 每日活用户平均每天启动App次数 / 10000 * 0.015
= 100 * 2 / 10000 * 0.015
= 0.0003
```
1月按30天算,则每月云数据库读操作次数费用为`0.0003 * 30 = 0.009`,还不到1分钱。
同理,我们可推导出日活为1000、10000的App,其uni升级中心每月云数据库读操作次数费用为9分钱、9毛钱。
##### 写操作次数
`uni-upgrade-center`升级中心,写数据库操作很少;管理员仅在每次发布新版时,通过`uni-admin``opendb-app-versions`表插入一条新版本信息;用户端App每次启动检查升级,无需数据表的写入操作,故写操作次数可忽略为0;
##### 小结
因为容量费和写操作次数费用均可忽略为0,根据公式:
```
云数据库费用 = 容量费(忽略为0) + 读操作费用 + 写操作费用(忽略为0)
= 读操作费用
```
可推导,uni升级中心的云数据库计费主要是读操作次数计费,因此我们进一步得出如下预测:
|日活 |容量费(元) |读操作次数费用(元) |写操作次数费用(元) |合计(元) |
|:-: |:-: |:-: |:-: |:-: |
|100 |0 |0.009 |0 |0.009 |
|1000 |0 |0.09 |0 |0.09 |
|10000 |0 |0.9 |0 |0.9 |
|100000 |0 |9 |0 |9 |
#### 云存储
按照[uniCloud官网](https://uniapp.dcloud.net.cn/uniCloud/price.html#aliyun-postpay)介绍,云存储费用 = `容量费 + 下载操作次数计费点 + 上传操作次数计费点 + CDN流量费`
如果您的应用每次均上架到apple store或安卓各应用商店,升级时从应用商店下载安装,则云存储费用为0,因为使用的是应用商店的存储和CDN下载流量,本计费点测评章节可直接跳过。
> uni-upgrade-center 支持设置应用新版安装包下载地址为应用商店地址,这样就可以使用应用商店的存储和CDN,不消耗uniCloud的云存储资源。
现阶段,iOS平台均需上架apple store,我们可以忽略iOS平台的云存储消耗。
如果您的安卓apk安装包及wgt差量升级包全部托管在uniCloud云存储中,我们也可以算算这笔账。
##### 容量费
容量费主要是存储费用,我们可以定期将过期版本删除,从而节省容量费。
假设我们在云存储中保留最近5个版本的文件,apk/wgt全部保留,大小假设分别为:40M、10M。
>如前所言,ipa需上架apple store,不使用云存储,测评可忽略。
则每天容量费用为:`5 * (40+10)/1024 * 0.0043 = 0.0010498`
据此,可计算其每月30天的容量费用为:`0.0010498 * 30 = 0.031494`,即只需3分钱;
注意:云存储容量仅跟保留的历史升级包多少有关系,跟日活用户无关。
##### 下载操作次数计费点
下载操作次数计费点:仅触发文件下载时会触发,若无新版本下载,则不会触发。
假设你的App日活为100、月活为1500,每月发一次版本;月活用户中,50%会选择升级到新版本,我们可计算下载次数为:`1500*50% = 750次`
而云存储的下载操作次数计费规则为:每万次0.01元,即每万次下载1分钱,750次下载远还不到1分钱,故下载操作计费点可直接忽略。
##### 上传操作次数计费点
每次App发版,仅需管理员上传一次新的资源包,用户App端检查升级时,不涉及上传操作,故上传操作次数计费点亦可忽略。
##### CDN流量费
CDN流量费:我们假设50%概率启用wgt资源包升级(升级包为10M),50%概率为整包升级;而整包升级中,20%为苹果用户(使用apple store流量),80%为安卓用户(升级包为40M)。
则按照如上数据模型,日活为100的App,假期其月活为1500,而月活用户中,50%会选择升级到新版本,即750人选择升级,不同升级包消耗CDN流量如下:
- wgt资源包CDN流量:750 * 50% * 10 / 1024 = 3.662G
- 苹果整包升级CDN流量:使用apple store流量,uniCloud云存储流量为0
- 安卓整包升级CDN流量:750 * 50% * 80% * 40 /1024 = 11.719G
即:日活为100的App,月度CDN流量为:`3.662 + 0 + 11.719 = 15.381G`,对应费用则为:`15.381 * 0.18 = 2.76858` (元)
同理,我们可推导出日活为1000的App,其升级中心云存储每月的CDN费用为27.6858元。
##### 和传统 OSS + CDN 对比
如果你不用`uni-upgrade-center`,选择如阿里云的传统`OSS + CDN` 方案,同样按量计费的情况下,1PB流量以内,传统CDN都没有价格优势;传统CDN每GB的起步价为0.24元,而uniCloud云存储CDN每GB的费用为0.18元。
![](https://mp-8ca8132b-2139-4831-aff2-582d4c8385da.cdn.bspapp.com/cloudstorage/d9ff593a-fb54-43fd-a58e-bbcb3294a82c.jpg)
详见:[阿里云官网CDN定价详情](https://www.aliyun.com/price/product?spm=a2c4g.11186623.0.0.4a6f31c9cwW5vQ#/cdn/detail/cdn)
1PB流量是什么概念?我们以每个安卓安装包为40M为例,需要 `1 * 1024 * 1024 * 1024 / 40 = 26843546`,即需要2600万人次安装包下载才能达到1PB流量,你可以评估一下你的App何时可以达到这个量级。
> 具体解释一下:1PB = 1024TB,1TB = 1024G,1G = 1024M,故上面公式连乘3个1024
也有人说了,购买阿里云CDN资源包可以更便宜。确实,购买大额资源包会更便宜,但这个方案有两个缺点:
- 这个资源包仅仅是CDN流量包,你还需要购买OSS回源流量包,而uniCloud直接将回源流量费用包在CDN费用之内了,无需额外购买回源流量。
- 预付费,在业务发展不明朗的情况下,一次性投入太多钱;一旦业务失败,CDN资源包未消耗完毕,也不能退款,浪费资金;而按量计费则没有这个问题,真实用多少资源,就花多少钱;
综合来看,uniCloud云存储相比传统云厂商的`OSS + CDN` 方案:
- 都选择按量计费,uniCloud版CDN默认0.18元更具价格优势;
- 预付费方式,选购云厂商CDN资源包,需额外购买回源流量包,对普通开发者,特别是中小开发者,并不友好,此时依然是uniCloud按量计费的云存储更具性价比。
#### 前端网页托管
`uni-upgrade-center`需要和`uni-admin`配合使用,`uni-admin`需要部署在前端网页托管中。`uni-admin`主要是管理员使用,使用频次较少,流量也较低。
按照[uniCloud官网](https://uniapp.dcloud.net.cn/uniCloud/price.html#aliyun-postpay)介绍,前端网页托管费用 = `容量费 + 流量费`
##### 容量费
`uni-admin`编译后为4.7M,按照官网每GB每天0.0043元的规则,`uni-admin`的月度容量费为:`4.7 / 1024 * 0.0043 * 30 = 0.00059`,不到1分钱,可忽略。
##### 流量费
管理员登录`uni-admin`,到升级中心管理页面浏览并发布新版,所需流量不超过3M,即使每月发布2次更新,流量费预估为:`3 / 1024 * 0.18 * 2 = 0.00105`,也不到1分钱,也可忽略。
#### 合并计算
细项对比完了,我们来合并看看,使用uniCloud升级中心,到底需要花多少钱,相比传统自己研发升级逻辑、搭建升级中心,哪些地方都需要花钱,差异点在哪里?
不管是开发者自研的升级方案,还是`uni-upgrade-center`,存储+CDN的费用都是必需的,前文也将传统`OSS+CDN`和uniCloud云存储的性价比进行了对比,均按量计费的模式下,uniCloud更具性价比;以资源包方式购买传统CDN模式下,各有优劣。
既然两个方案,都绕不开云存储,那我们暂时抛开云存储对比,将其他各项按照日活用户规模罗列一下,看看`uni-upgrade-center`在其他维度所需费用。
|日活 |云函数(元) |云数据库(元) |云存储(元) |前端网页托管(元) |合计(元) |
|:-: |:-: |:-: |:-: |:-: |:-: |
|100 |0.0245688 |0.009 |忽略 |0 |0.0335688 |
|1000 |0.245688 |0.09 |忽略 |0 |0.335688 |
|10000 |2.45688 |0.9 |忽略 |0 |3.35688 |
|100000 |24.5688 |9 |忽略 |0 |33.5688 |
#### uni-upgrade-center 给你带来的收益
使用`uni-upgrade-center`,免费获取、一键安装,你将获得:
- 经受大量App验证的、完备的检查升级逻辑,同时支持整包/资源包升级,支持静默升级,支持强制升级;
- 完备的管理功能,分平台发布新版、下线老版,关联应用商店,分渠道发布等。
- 代码开源,随意定制
如上功能,如果你使用传统模式自研,需要前后端配合开发,后端使用php/java做接口,前端发起Ajax请求,处理服务端的各种响应和错误码,处理升级弹窗提醒,这些功能做完善至少需要4个工作日。
假设工程师月薪18K,社保等综合管理成本是薪资的1.4倍,则4个工作日的综合成本为:`18*1000*1.4/22 * 4 = 4582元`
#### 总结
再次说回`uni-upgrade-center`,相比传统方式自研升级中心,存储+CDN的钱都是要花的,我们忽略它。
其它云函数、云数据库等,虽然看起来是额外增加的费用,但实际上你使用传统php/java自研升级逻辑,除了自研人力费用,后期也是需要消耗CPU、内存、带宽资源的,只是这些费用合并到虚拟机的整体租用成本中,你无法拆出来计算罢了。
再看回刚才的计算表,以1000日活用户来说,云函数、云数据库每月才多了0.34元,每年才多了4块钱(不考虑云存储CDN的情况下),一年多花4块钱,可以省掉自研的4500多元人工费用,可以让工程师将更多精力投入核心业务中。这5块钱的买卖,不划算吗?它不香吗?
|日活 |云函数(元) |云数据库(元) |云存储(元) |前端网页托管(元) |合计(元) |
|:-: |:-: |:-: |:-: |:-: |:-: |
|100 |0.0245688 |0.009 |忽略 |0 |0.0335688 |
|1000 |0.245688 |0.09 |忽略 |0 |0.335688 |
|10000 |2.45688 |0.9 |忽略 |0 |3.35688 |
|100000 |24.5688 |9 |忽略 |0 |33.5688 |
不重复制造轮子,聚焦业务,快速验证模式,实现商业增长,才应该是聪明工程师的追求。
......@@ -76,6 +76,20 @@ DCloud与个推深度合作,为uni-app的开发者提供了比传统方案便
`uni-push`即降低了开发成本,又提高了push送达率,还支持全平台,并且免费,是当前推送的最佳解决方案。
## uni-push2.0费用说明
uni-push本身并不收费,实际使用中需要依赖uniCloud云服务,而uniCloud价格很实惠:
- 调用10000次云函数仅需0.0133元
- 调用10000次数据库查询仅需0.015元
可见价格之低,几乎可以忽略不计。
一次消息推送 = 1次云函数请求 + 最高3次数据库查询(最常用的基于user_id推送仅需一次查询,详情参考:[推送接口查库详解](https://uniapp.dcloud.net.cn/uniCloud/uni-cloud-push/mate.html#%E6%8E%A8%E9%80%81%E6%8E%A5%E5%8F%A3%E6%9F%A5%E5%BA%93%E8%AF%A6%E8%A7%A3) )
即:最高(1 x 0.0133 + 3 x 0.015)/10000 = 0.00000583元/每次(注:给你的应用的所有注册用户群发消息算一次)
详细的计费参考:[阿里云版uniCloud按量计费文档](https://uniapp.dcloud.net.cn/uniCloud/price.html#aliyun-postpay)
# 常见问题
有了uni-push,开发者不应该再使用其他push方案了。但我们发现很多开发者有误解,导致还在错误使用其他推送。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册