提交 07ee6bbc 编写于 作者: D DCloud_LXH

Merge branch 'master' into vuepress

......@@ -9,8 +9,8 @@ pageClass: custom-page-class
`uni-app`在手,做啥都不愁。即使不跨端,```uni-app```也是更好的小程序开发框架([详见](https://ask.dcloud.net.cn/article/35947))、更好的App跨平台框架、更方便的H5开发框架。不管领导安排什么样的项目,你都可以快速交付,不需要转换开发思维、不需要更改开发习惯。
<div class="quick">
<h3 id="快速体验"><a href="/#%e5%bf%ab%e9%80%9f%e4%bd%93%e9%aa%8c" data-id="快速体验" class="anchor"><span>快速体验</span></a></h3>
<p>一套代码编到13个平台,这不是梦想。眼见为实,扫描13个二维码,亲自体验最全面的跨平台效果!</p>
<h3 id="快速体验"><a href="/README?id=%e5%bf%ab%e9%80%9f%e4%bd%93%e9%aa%8c" data-id="快速体验" class="anchor"><span>快速体验</span></a></h3>
<p>一套代码编到14个平台,这不是梦想。眼见为实,扫描14个二维码,亲自体验最全面的跨平台效果!</p>
<div class="flex-img-group-view">
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box">
......@@ -86,9 +86,11 @@ pageClass: custom-page-class
</div>
<b>钉钉小程序版</b>
</a>
<a href="javascript:void(0)" οnclick="js_method()" class="clear-style barcode-view">
<div class="barcode-img-box" style="width: 160px;"></div>
<b></b>
<a href="//m3w.cn/uniapp" target="_blank" class="clear-style barcode-view">
<div class="barcode-img-box">
<img src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-a90b5f95-90ba-4d30-a6a7-cd4d057327db/96e072fe-f338-46bd-b2d7-7b3aac7df501.png" width="160" />
</div>
<b>京东小程序版</b>
</a>
<a href="javascript:void(0)" οnclick="js_method()" class="clear-style barcode-view">
<div class="barcode-img-box" style="width: 160px;"></div>
......
......@@ -19,4 +19,4 @@
* [案例](case.md)
* 更新日志
* [正式版](release.md)
* [Alpha版](release-note-alpha.md)
\ No newline at end of file
* [Alpha版](release-note-alpha.md)
......@@ -71,6 +71,7 @@ options 为 object 类型,属性如下:
|offLoad|Function|解除绑定 load 事件的监听器|QQ0.1.26+,字节跳动1.57.0+|
|load|Function|当广告素材加载出现错误时,可以通过 load 方法手动加载|App 2.5.11+, 微信小程序2.6.0+, QQ0.1.26+,字节跳动1.57.0+|
|onError|Function|绑定 error 事件的监听器 |App 2.5.11+, 微信小程序2.6.0+, QQ0.1.26+,字节跳动1.57.0+|
|onAdClicked|Function|绑定广告可点击屏幕区域事件的监听器 |App 2.5.11+|
|offError|Function|解除绑定 error 事件的监听器|QQ0.1.26+,字节跳动1.57.0+|
|onClose|Function|绑定 close 事件的监听器|App 2.5.11+, 微信小程序2.6.0+, QQ0.1.26+,字节跳动1.57.0+|
|offClose|Function|解除绑定 close 事件的监听器|QQ0.1.26+,字节跳动1.57.0+|
......
## uniIDHasRole
新增于`HBuilderX 3.1.15-alpha`,判断当前用户是否拥有某角色。
新增于`HBuilderX 3.1.15`,判断当前用户是否拥有某角色。此功能依赖uni-id[另见详情](https://uniapp.dcloud.io/uniCloud/uni-id)
需要应用关联[uniCloud](https://uniapp.dcloud.net.cn/uniCloud/README)服务空间并使用[uni-id](https://uniapp.dcloud.net.cn/uniCloud/uni-id)
> 需要在token内缓存角色权限才可使用,请参考:[缓存角色权限](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=cachepermissionintoken)
......@@ -29,7 +31,9 @@
## uniIDHasPermission
新增于`HBuilderX 3.1.15-alpha`,判断当前用户是否拥有某权限,注意:admin角色的用户拥有所有权限
新增于`HBuilderX 3.1.15`,判断当前用户是否拥有某权限,注意:admin角色的用户拥有所有权限。此功能依赖uni-id[另见详情](https://uniapp.dcloud.io/uniCloud/uni-id)
需要应用关联[uniCloud](https://uniapp.dcloud.net.cn/uniCloud/README)服务空间并使用[uni-id](https://uniapp.dcloud.net.cn/uniCloud/uni-id)
> 需要在token内缓存角色权限才可使用,请参考:[缓存角色权限](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=cachepermissionintoken)
......
......@@ -5,14 +5,16 @@
需要拦截的`api`名称,如:`uni.addInterceptor('request', OBJECT)` ,将拦截 `uni.request()`
注意:仅支持异步接口,如:`uni.setStorage(OBJECT)`,暂不支持同步接口如:`uni.setStorageSync(KEY,DATA)`
**OBJECT 参数说明**
|参数名 |类型 |必填 |默认值 |说明 |平台差异说明 |
|:- |:- |:- |:- |:- |:- |
|invoke |Function |否 | |拦截前触发 | |
|success |Function |否 | |成功回调拦截 | |
|fail |Function |否 | |失败回调拦截 | |
|complete |Function |否 | |完成回调拦截 | |
|参数名 |类型 |必填 |默认值 |说明 |平台差异说明 |
|:- |:- |:- |:- |:- |:- |
|invoke |Function |否 | |拦截前触发 | |
|success |Function |否 | |成功回调拦截 | |
|fail |Function |否 | |失败回调拦截 | |
|complete |Function |否 | |完成回调拦截 | |
**示例**
......
......@@ -48,7 +48,7 @@
* 组件和接口显示会根据设置的语言环境自动切换,未支持的系统语言环境会显示为英文。
* App-Android 平台设置新的语言后会自动重启应用。
* 框架内置如下语言
* 框架内置如下语言,如需自定义内容或增加其他语言参考:[自定义国际化内容](https://uniapp.dcloud.io/collocation/i18n?id=uni-framework)
* 英语 en
* 中文简体 zh-Hans
* 繁体 zh-Hant
......
......@@ -5,69 +5,56 @@
#### 创建应用
1.打开[Facebook开发者中心](http://developers.facebook.com/)
2.点击右上角"我的应用"
* 打开[Facebook开发者中心](http://developers.facebook.com/)
* 点击右上角"我的应用"
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/9e3ba994-95b0-46d6-9e40-0c18b9fac5d3.png)
3.进入应用管理界面,点击"创建应用"
* 进入应用管理界面,点击"创建应用"
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/0d96a58b-e31d-4f86-9372-dd84249a498b.png)
4.根据需要选择应用产品的类型(应用类型详见"详细了解应用类型"),然后点击继续
* 根据需要选择应用产品的类型(应用类型详见"详细了解应用类型"),然后点击继续
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/a940cfc2-8e8c-44cf-9334-56cb282d4f52.png)
5.填写应用信息
* 填写应用信息
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/57f5f5c0-27ca-4aa7-9e68-fb051c8afccb.png)
6.创建完成后即可获取应用的应用编号(即appID)
7.为应用添加登录功能
* 创建完成后即可获取应用的应用编号(即appID)
* 为应用添加登录功能
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/4e7ad147-e4ce-40eb-a1b0-2381bdc53813.png)
#### 设置登录-iOS
1.我的应用--设置--基本,选择添加平台,选择iOS
* 我的应用--设置--基本,选择添加平台,选择iOS
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/cebc70d2-da0e-4708-9d05-d5f5d80de1ca.png)
2.填写信息保存即可
* 填写信息保存即可
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/70038074-8c3a-4db8-99ab-49e14b951c79.png)
#### 设置登录-Android
我的应用--设置--基本,选择添加平台
* 我的应用--设置--基本,选择添加平台
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/a8fe2779-1142-452b-a4b0-f4bd61695770.png)
选择android平台,应用商店选择Google Play
* 选择android平台,应用商店选择Google Play
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/afa346b7-a001-47b1-9c7e-914074153ac3.png)
填写必要的包名和散列信息,类名是固定的。如图
* 填写必要的包名和散列信息,类名是固定的。如图
散列的获取方法,参考文档:
https://developers.facebook.com/docs/facebook-login/android 第六小节
如果获取到的散列位数不对,需要找台linux/mac 计算机。
使用下面的命令获取
keytool -exportcert -alias hbuilder -keystore ./HBuilder.keystore | openssl dgst -sha1 -binary | openssl base64
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/4c59adf0-cb40-41d7-95d4-e26102aeacd9.png)
......@@ -75,6 +62,5 @@ keytool -exportcert -alias hbuilder -keystore ./HBuilder.keystore | openssl dgst
#### 应用权限
使用Facebook登录需开启"public_profile"以及"email"的访问权限
点击"应用审核"-"权限和功能",开启"public_profile"以及"email"的高级访问权限
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/28dac1d2-f714-4477-a5c8-dd2e1b894894.png)
......@@ -6,41 +6,28 @@
#### Android开通步骤
2.1 打开Google 登录引导页
* 打开Google 登录引导页
网址: https://developers.google.com/identity/sign-in/android/sign-in?hl=zh-cn
2.2 选择项目配置
* 选择项目配置
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/636a9bd3-77d7-4539-b46c-0c798eb49350.png)
点击后出现项目与应用选择界面,
如果你有已创建过的Firebase项目,可以直接选择。
如果没有,可以选择新建一个Google Api 项目。
点击后出现项目与应用选择界面,如果你有已创建过的Firebase项目,可以直接选择。如果没有,可以选择新建一个Google Api 项目。
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/f206ec8a-c82d-41f4-9e6d-d838e21a4857.png)
选择项目后,在该项目下新建一个应用
* 选择项目后,在该项目下新建一个应用
选择应用平台 android
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/09c5a8aa-c698-4133-9a11-d73d59e37da5.png)
需要填写应用的包名和sha1指纹
指纹的获取方法在界面上有提示。按照提示操作即可。
需要填写应用的包名和sha1指纹,指纹的获取方法在界面上有提示。按照提示操作即可。
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/d14feca3-94b5-467e-b197-d98b866072bc.png)
点击创建,即可完成开通步骤。
#### iOS开通步骤
3.1 打开[Google登录iOS引导页](http://developers.google.com/identity/sign-in/ios/start-integrating?hl=zh-cn)
3.2 点击创建OAuth客户端ID,填写项目名称
* 打开[Google登录iOS引导页](http://developers.google.com/identity/sign-in/ios/start-integrating?hl=zh-cn)
* 点击创建OAuth客户端ID,填写项目名称
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/1978e9aa-5e11-4586-9caf-1c1b7c3e71bd.png)
3.3 选择iOS平台、填写BundleID后,点击CREATE,即可获取Client ID
* 选择iOS平台、填写BundleID后,点击CREATE,即可获取Client ID
![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/26045e0b-b6f0-4c22-aa61-0d63120e1a4b.png)
## 申请开通Paypal
* [登录/注册](https://www.paypal.com/c2/signin)
* 打开[paypal开发者中心](https://developer.paypal.com/developer/applications)
如图,依次选择My Apps & Credentials -> Live(如果创建沙箱环境点击Sandbox) -> Create App
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_develop_center.png)
* 输入App Name,点击Create App
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_create_app.png)
* 创建完成后,点击AppName
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_setup_app_info.png)
* 查看Client ID 以及 Secret
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_get_clientid.png)
* 添加return URL并保存(必须使用小写字母)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_add_returnurl.png)
* 勾选Accept payments 并点击Advanced options选择详情配置(点击保存后生效)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_accept_payments.png)
* 勾选Log in with PayPal 并点击Advanced options选择详情配置(点击保存后生效)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_log_in.png)
## 申请开通Stripe
* [登录/注册](https://dashboard.stripe.com/login)
* 进入主页后,点击顶部继续按钮
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_home_page.png)
* 完善公司信息
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_company_info.png)
* 完善信息后,回到首页即可在右侧查看密钥
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_get_publishkey.png)
## 概述
HBuilder|HBuilderX集成了常用的推送平台,包括个推推送和小米推送。
从HBuilderX1.7.2版本开始支持UniPush推送服务(支持华为、小米、OPPO、魅族厂商推送通道),解决APP离线时因为三方推送进程被杀而导致无法推送的问题,参考[UniPush使用指南](http://ask.dcloud.net.cn/article/35622)
**Push推送功能需配置SDK参数后提交云端打包后才能生效,如需真机运行生效请使用[自定义基座](http://ask.dcloud.net.cn/article/35115)**
### 使用须知
push是一个可用但不可依赖的功能。
- Android平台
Push推送通道不可依赖,Android rom厂商为了省电会禁止push进程开机自启、三方清理软件会杀掉push进程。不止是个推,所有非大厂的app,没有进入rom厂商和三方清理软件白名单的app,不管用哪个推送方案都可能会被杀。当然集成了小米推送后在小米手机上肯定不会被杀,但在其他平台被杀的概率可能更高。
本质上推送是一个有利于开发商但却很容易造成用户骚扰和费电的功能,所以大多数主流app里的push的实际用处都是拉激活的非实时活动推送。必要时要补充发短信通知的方式。
关于三方推送服务商,其实发展多年内后,技术、服务差距都不大,核心还在于用户量,因为集成的sdk越多,保活和看护机制越有效果。从个推、极光等公司在ipo时披露的数据来看,还是个推占据优势。
- iOS平台
手机用户有自主关闭APP推送的权利,如果被关闭自然无法收到push。
**可以参考[iOS平台检查是否关闭通知消息,并提醒用户开启通知消息](https://ask.dcloud.net.cn/article/35727)**
### 整体架构
![](http://www.dcloud.io/docs/a/push/architecture.png)
### 推送消息类型
通常推送消息分以下两种类型:
- 通知栏消息(推送通知)
UniPush推送服务定义好的推送样式、后续动作的推送方式,客户端接收到后显示在系统通知栏,用户点击通知栏消息启动APP(激活到前台)。
- 透传消息
即自定义消息,UniPush推送服务只负责消息传递,不做任何处理,客户端在接收到透传消息后需要自己去处理消息的展示方式或后续动作。
## 使用5+ API处理推送消息
uni-app应用中使用推送服务参考:[http://ask.dcloud.net.cn/article/35726](http://ask.dcloud.net.cn/article/35726)
### 获取APP终端标识
在应用安装后第一次运行时应该调用5+ API的[plus.push.getClientInfo](http://www.html5plus.org/doc/zh_cn/push.html#plus.push.getClientInfo)方法获取客户端标识,并将此标识提交到开发者的业务服务器进行注册设备,以便在用户登录时可绑定设备,实现向登录用户推送专属消息。
示例代码如下:
```JavaScript
document.addEventListener('plusready', function(){
// 页面加载时触发
var pinf = plus.push.getClientInfo();
var cid = pinf.clientid;//客户端标识
}, false );
```
**如果获取的cid为空,说明客户端向推送服务器注册还未完成,可以使用setTimeout延时重试。**
### 监听推送消息事件
通常在应用入口页面(首页)中调用5+ API的[plus.push.addEventListener](http://www.html5plus.org/doc/zh_cn/push.html#plus.push.addEventListener)方法监听消息事件,在回调函数中处理消息的响应业务逻辑,如下示例:
```JavaScript
//监听系统通知栏消息点击事件
plus.push.addEventListener('click', function(msg){
//处理点击消息的业务逻辑代码
}, false);
//监听接收透传消息事件
plus.push.addEventListener('receive', function(msg){
//处理透传消息的业务逻辑代码
}, false);
```
启动回调函数的参数msg为[PushMessage](http://www.html5plus.org/doc/zh_cn/push.html#plus.push.PushMessage)对象,保存消息的标题(title)、内容(content)、自定义数据(payload)等。
推送消息包括以下事件类型:
- click
用户点击系统通知栏中的消息,APP启动或者激活到前台运行,触发click事件。
- receive
客户端接收到透传消息时(在系统通知栏中不显示消息),触发receive事件。
**注意:特殊情况**
- Android平台
推送服务器下发的透传消息符合以下json格式:
```json
{title:"标题",content:"内容",payload:"自定义数据"}
```
时,会作为普通推送通知处理,在系统通知栏创建消息,点击消息激活APP触发"click"事件。
- iOS平台
如果应用在前台运行,并且监听了"receive"事件,此时接收到APNs通道下发的消息时,会触发"receive"事件。此时可在回调的参数PushMessage对象中获取aps属性值来判断是否是APNs下发的消息。
```
// 监听在线消息事件
plus.push.addEventListener( "receive", function( msg ) {
if ( msg.aps ) { // Apple APNS message
//APNS下发的消息,应用在前台
} else {
//其它情况接收消息
}
//其它逻辑
}, false );
```
### 通知栏消息操作
5+ Push模块还提供一系列API操作系统通知栏,解决比较少见的业务场景需求。
- 清空消息
5+ API提供[plus.push.clear]()方法可用于清空系统通知栏中属于当前应用的所有消息,示例代码如下:
```JavaScript
plus.push.clear();
```
- 创建本地消息
开发者在业务逻辑中如需创建本地消息可以调用[plus.push.createMessage](http://www.html5plus.org/doc/zh_cn/push.html#plus.push.createMessage)接口,可以指定消息的标题,显示消息的时间或者使用延迟时间。
示例代码如下:
```JavaScript
var options = {cover:false};
var str = dateToStr(new Date());
str += ": 欢迎使用Html5 Plus创建本地消息!";
plus.push.createMessage(str, "LocalMSG", options);
```
<a id="receive" />
**iOS平台创建本地消息也会触发监听的"receive"事件,此时需要添加特殊参数来标识本地创建的消息。**
```
// 监听在线消息事件
plus.push.addEventListener( "receive", function( msg ) {
if ( msg.aps ) { // Apple APNS message
//APNS下发的消息,应用在前台
} else if ( 'LocalMSG' == msg.payload ) { // 特殊payload标识本地创建的消息
//本地创建的消息,通常不需要处理
//注意:不要在这种情况下再此调用plus.push.createMessage,从而引起循环创建本地消息
} else {
//接收到在线透传消息
}
//其它逻辑
}, false );
```
- 获取所有消息
可以调用[plus.push.getAllMessage](http://www.html5plus.org/doc/zh_cn/push.html#plus.push.getAllMessage)获取系统通知栏中属于当前应用的所有消息,示例代码如下:
```JavaScript
var msgs = plus.push.getAllMessage();
for(var i in msgs){
var msg = msgs[i];
console.log( i+": "+msg.title+" - "+msg.content );
}
```
**iOS平台不支持获取系统通知栏消息,返回空数组。**
## 推送平台申请
使用推送前需要向推送平台申请应用,并获取推送参数(提交云端打包时需配置),如appid、appkey等。
### 个推推送
登录个推[消息推送开放平台](https://dev.getui.com/)
如果已经申请过个推的消息推送应用,打开“个推·消息推送”页面,在应用列表中找到申请的应用,点击“应用配置”打开应用信息页面,可获取个推的AppID、AppKey、AppSecret等信息。
如果没有申请过应用,打开“[应用管理](https://dev.getui.com/dev/#/appManage)”页面选择“创建应用”申请新应用,申请成功后再通过上面的方法获取AppID、AppKey、AppSecret等参数。
**个推推送平台相关问题可直接咨询个推客服,企业QQ:2880983159。也可以在ask中@[getui_johny](http://ask.dcloud.net.cn/people/getui_johny)**
### 小米推送
登录[小米开放平台](https://dev.mi.com/console/),进入“[管理控制台](https://dev.mi.com/console/man/)”页面,在“应用服务”栏选择“消息推送”,打开[推送运营平台](http://admin.xmpush.xiaomi.com/zh_CN/app/nav)
如果已经在小米开放平台申请应用,则在应用列表中点击相应应用的“应用信息”按钮,打开应用信息页面可查看小米推送的AppID、AppKey、AppSecret等信息;若应用没有启用推送服务,则点击“启用推送”按钮申请开通。
如果没有申请过应用,则点击页面左上角的“创建应用”按钮创建新应用,创建成功后再他通过上面的方法“启用推送”功能并获取小米推送的AppID、AppKey、AppSecret等参数。
**小米推送需要为Android和iOS平台分别创建两个应用**
## 云端打包配置
HBuilder|HBuilderX中提交云端打包前,需在manifest.json文件中配置Push推送模块的参数。
### 1. 模块配置、
打开应用的manifest.json文件,选择“模块权限配置”项,勾选“Push(消息推送)”,如下图所示:
![Push(消息推送)-模块权限配置](http://www.dcloud.io/docs/a/push/x_s1.png)
### 2. SDK参数配置
打开应用的manifest.json文件,选择“SDK配置”项,选择应用使用的推送平台,并输入从此推送平台申请获取的配置参数,如下图所示:
![Push(消息推送)-SDK配置](http://www.dcloud.io/docs/a/push/x_s2.png)
**Android平台云端打包时需要确认填写的app包名和在推送平台创建应用时填写的包名一致**
**iOS平台云端打包时需要确人打包填写的Bundle ID(Apple AppID)和提交给推送平台的APS证书内包含的AppID一致**
## 常见问题
**1.为什么真机运行时不能收到推送的消息**
答: 如果需要测试推送功能,需要使用HBuilder云打包生成安装包进行测试。
**2.推送消息到安卓平台为什么没有在消息中心中显示**
答: 如果推送到安卓平台的消息是透传消息,并且格式不符合规范则会触发监听页面的receive事件,消息不会进入消息中心。
**3. IOS平台本地创建本地消息会触发“receive”事件,如何和服务器发送的消息进行区分。**
答: 用户在创建IOS本地消息是可以在“payload”节点添加特殊标记对消息进行区分
**4. Android平台如何配置推送消息图标**
答:参考[https://ask.dcloud.net.cn/article/35537](https://ask.dcloud.net.cn/article/35537)
......@@ -273,7 +273,7 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**极米:** [极米官方app](https://sj.qq.com/myapp/detail.htm?apkName=com.xgimi.zhushou&info=FB45015C23ACF368D22855D6C4964312)[官网H5版](https://m.xgimi.com/)、微信小程序搜索“极米官方商城”、微信小程序搜索“极米care+”售后服务宣传
**货拉拉:** App部分栏目使用uni小程序sdk
**货拉拉:** App部分栏目使用[uni小程序SDK](https://nativesupport.dcloud.net.cn)
**叮咚买菜:** 微信小程序搜索 “叮咚买菜”、[公众号H5](http://wx.m.ddxq.mobi/#/)
......@@ -289,6 +289,7 @@ uni-app助力数百家单位快速上线**抗疫系统**,开源众多项目,
**快递100:** 微信、百度、头条、QQ小程序搜索“快递100”
**海康威视:** 海康互联App使用[uni小程序SDK](https://nativesupport.dcloud.net.cn)[App下载](https://www.me-app.net/Sentinels)
<!-- **达内在线:** 达内教育的在线培训App。[App官网下载](http://www.tmooc.cn/app/index.shtml) -->
......
......@@ -3,7 +3,7 @@
这个文件的作用包括:调用应用生命周期函数、配置全局样式、配置全局的存储globalData
应用生命周期仅可在`App.vue`中监听,在页面监听无效。
## 应用生命周期
## 应用生命周期@applifecycle
``uni-app`` 支持如下应用生命周期函数:
......
......@@ -5,4 +5,4 @@
* [uni.scss](collocation/uni-scss.md)
* [App.vue](collocation/App.md)
* [main.js](collocation/main.md)
* [plugin.json 生成小程序插件](collocation/miniprogram-plugin.md)
\ No newline at end of file
* [plugin.json 生成小程序插件](collocation/miniprogram-plugin.md)
......@@ -62,8 +62,8 @@ uni 统计配置项
|nvueCompiler|String|切换 nvue 编译模式,可选值,`weex` :老编译模式,`uni-app`: 新编译模式,默认为 `weex`[编译模式区别详情](http://ask.dcloud.net.cn/article/36074)|2.0.3+|
|nvueStyleCompiler|String|切换 nvue 样式编译模式,可选值,`weex` :老编译模式,`uni-app`: 新编译模式,默认为 `weex`[编译模式区别详情](https://ask.dcloud.net.cn/article/38751)|3.1.1+|
|renderer|String|可不加载基于 webview 的运行框架,减少包体积、提升启动速度。可选值 `native`| App-nvue 2.2.0+|
|compilerVersion|Number|编译器版本,可选值:2、3 默认 2 [详见](https://ask.dcloud.net.cn/article/36599)|HBuilderX alpha 2.4.4+或HBuilderX 2.5.0+|
|nvueLaunchMode|Number|Nvue 首页启动模式,在 compilerVersion 值为 3 时生效,可选值:normal、fast 默认 normal(HBuilderX alpha 2.4.4-2.4.9 固定为 fast) [详见](https://ask.dcloud.net.cn/article/36749)|2.5.0+|
|compilerVersion|Number|编译器版本,可选值:2、3 默认 2 [详见](https://ask.dcloud.net.cn/article/36599)|HBuilderX 2.5.0+|
|nvueLaunchMode|Number|Nvue 首页启动模式,在 compilerVersion 值为 3 时生效,可选值:normal、fast 默认 normal(HBuilderX 2.4.4-2.4.9 固定为 fast) [详见](https://ask.dcloud.net.cn/article/36749)|2.5.0+|
|nvue|Object|nvue 页面布局初始配置,[详见](/collocation/manifest?id=nvue)|2.0.3+|
|uniStatistics|Object|[App 是否开启 uni 统计,配置方法同全局配置](/collocation/manifest?id=uniStatistics)|2.2.3+|
......
......@@ -13,18 +13,19 @@ uni-app 通过在`package.json`文件中增加`uni-app`扩展节点,可实现
注意只能扩展web和小程序平台,不能扩展app打包。并且扩展小程序平台时只能基于指定的基准平台扩展子平台,不能扩展基准平台。基准平台详见下文。
package.json扩展配置用法(拷贝代码记得去掉注释!)
package.json扩展配置用法:
```json
{
/**
package.json其它原有配置
* package.json其它原有配置
* 拷贝代码后请去掉注释!
*/
"uni-app": {// 扩展配置
"scripts": {
"custom-platform": { //自定义编译平台配置,可通过cli方式调用
"title":"自定义扩展名称", // 在HBuilderX中会显示在 运行/发行 菜单中
"BROWSER":"", //运行到的目标浏览器,仅当UNI_PLATFORM为h5时有效
"browser":"", //运行到的目标浏览器,仅当UNI_PLATFORM为h5时有效
"env": {//环境变量
"UNI_PLATFORM": "", //基准平台
"MY_TEST": "", // ... 其他自定义环境变量
......@@ -43,7 +44,7 @@ package.json扩展配置用法(拷贝代码记得去掉注释!):
Tips:
- `UNI_PLATFORM`仅支持填写`uni-app`默认支持的基准平台,目前仅限如下枚举值:`h5``mp-weixin``mp-alipay``mp-baidu``mp-toutiao``mp-qq`
- `BROWSER` 仅在`UNI_PLATFORM``h5`时有效,目前仅限如下枚举值:`Chrome``Firefox``IE``Edge``Safari``HBuilderX`
- `browser` 仅在`UNI_PLATFORM``h5`时有效,目前仅限如下枚举值:`chrome``firefox``id``edge``safari``hbuilderx`
- `package.json`文件中不允许出现注释,否则扩展配置无效
- `vue-cli`需更新到最新版,HBuilderX需升级到 2.1.6+ 版本
......@@ -105,7 +106,7 @@ Tips:钉钉小程序编译目录依然是`mp-alipay`,需通过支付宝开
"scripts": {
"h5-weixin": {
"title":"微信服务号",
"BROWSER":"Chrome",
"browser":"chrome",
"env": {
"UNI_PLATFORM": "h5"
},
......
......@@ -330,6 +330,7 @@ uni-app 2.9+ 新增 leftWindow, topWindow, rightWindow 配置。用于解决宽
|onReachBottomDistance|Number|50|页面上拉触底事件触发时距页面底部距离,单位只支持px,详见[页面生命周期](/tutorial/page.html#lifecycle)||
|backgroundColorTop|HexColor|#ffffff|顶部窗口的背景色(bounce回弹区域)|仅 iOS 平台|
|backgroundColorBottom|HexColor|#ffffff|底部窗口的背景色(bounce回弹区域)|仅 iOS 平台|
|disableSwipeBack|Boolean|false|是否禁用滑动返回|仅 iOS 平台(HBuilder X 3.4.0+)|
|titleImage|String||导航栏图片地址(替换当前文字标题),支付宝小程序内必须使用https的图片链接地址|支付宝小程序、H5|
|transparentTitle|String|none|导航栏透明设置。支持 always 一直透明 / auto 滑动自适应 / none 不透明|支付宝小程序、H5、APP|
|titlePenetrate|String|NO|导航栏点击穿透|支付宝小程序、H5|
......
......@@ -19,7 +19,7 @@ banner或信息流广告展现场景非常灵活,常见的展现场景为:
|App|H5|微信小程序|支付宝小程序|百度小程序|字节跳动小程序|QQ小程序|快应用|360小程序|快手小程序|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|√(2.5.2+)|x|√|x|√|√|√|x|x|√|
|√(2.5.2+)|3.3.8+|√|x|√|√|√|x|x|√|
**开通配置广告**
......
......@@ -10,7 +10,7 @@
|type|String|default|按钮的样式类型|||
|plain|Boolean|false|按钮是否镂空,背景色透明|||
|disabled|Boolean|false|是否禁用|||
|loading|Boolean|false|名称前是否带 loading 图标||App-nvue 平台,在 ios 上为雪花,Android上为圆圈|
|loading|Boolean|false|名称前是否带 loading 图标||H5、App(App-nvue 平台,在 ios 上为雪花,Android上为圆圈)|
|form-type|String||用于 ``<form>`` 组件,点击分别会触发 ``<form>`` 组件的 submit/reset 事件|||
|open-type|String||开放能力|||
|hover-class|String|button-hover|指定按钮按下去的样式类。当 hover-class="none" 时,没有点击态效果||App-nvue 平台暂不支持|
......
......@@ -9,6 +9,7 @@
|type|String||指定 canvas 类型,支持 2d (2.9.0) 和 webgl|微信小程序 2.7.0+ 字节小程序1.78.0+|
|canvas-id|String||canvas 组件的唯一标识符||
|disable-scroll|Boolean|false|当在 canvas 中移动时且有绑定手势事件时,禁止屏幕滚动以及下拉刷新|字节跳动小程序与飞书小程序不支持|
|hidpi|Boolean|true|是否启用高清处理|H5 (HBuilder X 3.4.0+)、App-vue (HBuilder X 3.4.0+)|
|@touchstart|EventHandle||手指触摸动作开始|字节小程序1.78.0+|
|@touchmove|EventHandle||手指触摸后移动|字节小程序1.78.0+|
|@touchend|EventHandle||手指触摸动作结束|字节小程序1.78.0+|
......@@ -82,7 +83,7 @@ canvas的常用用途有图表和图片处理,在uni-app插件市场有大量
**nvue页面如何使用canvas**
HBuilderX 2.2.5(alpha)开始 nvue 页面支持 Canvas,支持 W3C WebGL API [WebGL 1.0](https://www.khronos.org/registry/webgl/specs/latest/1.0/)
HBuilderX 2.2.5 开始 nvue 页面支持 Canvas,支持 W3C WebGL API [WebGL 1.0](https://www.khronos.org/registry/webgl/specs/latest/1.0/)
示例工程地址:[NvueCanvasDemo](https://github.com/dcloudio/NvueCanvasDemo)
......
......@@ -89,9 +89,15 @@ uni-ui支持 HBuilderX直接新建项目模板、npm安装和单独导入个别
```
### 通过 `uni_modules` 导入全部组件
如果想一次把所有uni-ui组件导入到项目中,只需要导入一个 `uni-ui` 组件即可 [点击去导入](https://ext.dcloud.net.cn/plugin?id=55)
### npm安装 (不推荐)
`vue-cli` 项目中可以使用 `npm` 安装 `uni-ui` 库 ,或者直接在 `HBuilderX` 项目中使用 `npm` 。(不推荐后一种方式)
如果没有自动导入其他组件,可以在 uni-ui 组件目录上右键选择 `安装三方插件依赖` 即可。
### npm安装
`vue-cli` 项目中可以使用 `npm` 安装 `uni-ui` 库 ,或者直接在 `HBuilderX` 项目中使用 `npm`
> **注意**
> cli 项目默认是不编译 `node_modules` 下的组件的,导致条件编译等功能失效 ,导致组件异常
......@@ -119,8 +125,8 @@ uni-ui支持 HBuilderX直接新建项目模板、npm安装和单独导入个别
npm i sass-loader@10.1.1 -D 或 yarn add sass-loader@10.1.1 -D
```
> sass-loader 请使用低于 @11.0.0 的版本,[sass-loader@11.0.0 不支持 vue@2.6.12 ](https://stackoverflow.com/questions/66082397/typeerror-this-getoptions-is-not-a-function)
> 如果 `node` 版本小于 16 ,sass-loader 请使用低于 @11.0.0 的版本,[sass-loader@11.0.0 不支持 vue@2.6.12 ](https://stackoverflow.com/questions/66082397/typeerror-this-getoptions-is-not-a-function)
> 如果 `node` 版本大于 16 , `sass-loader` 建议使用 `v8.x` 版本
**安装 uni-ui**
......@@ -130,25 +136,6 @@ npm i @dcloudio/uni-ui 或 yarn add @dcloudio/uni-ui
``script`` 中引用组件:
```javascript
import {uniBadge} from '@dcloudio/uni-ui'
//import uniBadge from '@dcloudio/uni-ui/lib/uni-badge/uni-badge.vue' //也可使用此方式引入组件
export default {
components: {uniBadge}
}
```
``template`` 中使用组件:
```html
<uni-badge text="1"></uni-badge>
<uni-badge text="2" type="success" @click="bindClick"></uni-badge>
<uni-badge text="3" type="primary" :inverted="true"></uni-badge>
```
**配置easycom**
使用 `npm` 安装好 `uni-ui` 之后,需要配置 `easycom` 规则,让 `npm` 安装的组件支持 `easycom`
......@@ -174,20 +161,22 @@ export default {
```
**注意**
- `CLI` 引用方式, `H5` 端不支持在 `main.js` 中全局注册组件,如有需求请使用([easyCom](https://uniapp.dcloud.io/collocation/pages?id=easycom)) 的方式引用组件
- 使用 npm 安装的组件,默认情况下 babel-loader 会忽略所有 node_modules 中的文件 ,导致条件编译失效,需要通过配置 `vue.config.js` 解决:
```javascript
// 在根目录创建 vue.config.js 文件,并配置如下
module.exports = {
transpileDependencies: ['@dcloudio/uni-ui']
}
```
``template`` 中使用组件:
```html
<uni-badge text="1"></uni-badge>
<uni-badge text="2" type="success" @click="bindClick"></uni-badge>
<uni-badge text="3" type="primary" :inverted="true"></uni-badge>
```
**注意**
- uni-ui 是uni-app内置组件的扩展。注意与web开发不同,uni-ui不包括基础组件,它是基础组件的补充。web开发中有的开发者习惯用一个ui库完成所有开发,但在uni-app体系中,推荐开发者首先使用性能更高的基础组件,然后按需引入必要的扩展组件。
- `uni-ui` 不支持使用 `Vue.use()` 的方式安装
- uni-ui 现在只推荐使用 `easycom` ,如自己引用组件,可能会出现组件找不到的问题
- 使用 npm 安装的组件,默认情况下 babel-loader 会忽略所有 node_modules 中的文件 ,导致条件编译失效,需要通过配置 `vue.config.js` 解决:
```javascript
// 在根目录创建 vue.config.js 文件,并配置如下
module.exports = {
transpileDependencies: ['@dcloudio/uni-ui']
}
```
- uni-ui 是uni-app内置组件的扩展。注意与web开发不同,uni-ui不包括基础组件,它是基础组件的补充。web开发中有的开发者习惯用一个ui库完成所有开发,但在uni-app体系中,推荐开发者首先使用性能更高的基础组件,然后按需引入必要的扩展组件。
- `uni-ui` 不支持使用 `Vue.use()` 的方式安装
......@@ -35,7 +35,7 @@
|second |Number |0 |秒 |
|showDay |Boolean|true |是否显示天数 |
|showColon |Boolean|true |是否以冒号为分隔符 |
|start |Boolean|true |是否初始化组件后就开始倒计时|
|start |Boolean|true |是否初始化组件后就开始倒计时|
### Countdown Events
......@@ -44,6 +44,17 @@
|@timeup|倒计时时间到触发事件 |- |
### Countdown Methods
|事件称名 |说明 |返回值 |
|:-: |:-: |:-: |
|update |动态更新时间后,刷新组件显示 |- |
## 组件示例
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/countdown/countdown](https://hellouniapp.dcloud.net.cn/pages/extUI/countdown/countdown)
\ No newline at end of file
......@@ -140,9 +140,6 @@
};
</script>
<style lang="scss">
@import "@/common/uni-nvue.scss";
</style>
```
## API
......
......@@ -38,7 +38,6 @@ uni-list不包含下拉刷新和上拉翻页。上拉翻页另见组件:[uni-l
> - 支付宝小程序平台需要在支付宝小程序开发者工具里开启 component2 编译模式,开启方式: 详情 --> 项目配置 --> 启用 component2 编译
> - 如果需要修改 `switch`、`badge` 样式,请使用插槽自定义
> - 在 `HBuilderX` 低版本中,可能会出现组件显示 `undefined` 的问题,请升级最新的 `HBuilderX` 或者 `cli`
> - 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
### 基本用法
......
......@@ -23,6 +23,7 @@
|iconSize|Number|-|24|指定图标大小|
|status|String |more/loading/noMore|more|loading 的状态|
|showIcon|Boolean|-|true|是否显示 loading 图标|
|showText **[1.3.3新增]**|Boolean|-|true|是否显示文本|
|iconType|String|snow/circle/auto|auto|指定图标样式|
|color|String|-|#777777 |图标和文字颜色|
|contentText|Object|-|{contentdown: "上拉显示更多",contentrefresh: "正在加载...",contentnomore: "没有更多数据了"}|各状态文字说明 |
......
......@@ -6,14 +6,93 @@
导航栏组件,主要用于头部导航。
## 基本用法
> **注意事项**
> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
> - 组件需要依赖 `sass` 插件 ,请根据提示自行手动安装
> - 组件内部依赖 `'uni-icons'` 组件
> - 请勿在组件内部使用,宽度可能会发生错误
> - 当前组件不支持文字大小的修改 ,如有需要请使用深度选择器覆盖样式
``template`` 中使用组件
### 基本用法
```html
<uni-nav-bar left-icon="back" left-text="返回" right-text="菜单" title="导航栏组件"></uni-nav-bar>
<uni-nav-bar title="导航栏组件"></uni-nav-bar>
```
### 开启阴影
使用 `shadow` 属性开启导航栏阴影
Tips:
- nvue 下某些机型可能显示不正常 ,建议 nvue 下关闭阴影
```html
<uni-nav-bar shadow title="导航栏组件"></uni-nav-bar>
```
### 开启暗黑模式
使用 `dark` 属性开启导航栏的暗黑模式
Tips:
- 暗黑模式只会改变组件默认的前景色和背景色,如果设置自定义颜色,自定义颜色将优先显示
```html
<uni-nav-bar dark title="导航栏组件"></uni-nav-bar>
```
### 自定义颜色
使用 `color` 属性修改导航栏前景色(文字图标颜色)
使用 `background-color` 属性修改导航栏背景色
```html
<uni-nav-bar dark title="导航栏组件"></uni-nav-bar>
```
### 带左右文字
使用 `left-text` 属性设置导航栏左侧文字
使用 `right-text` 属性设置导航栏右侧文字
Tips:
- 图标依赖 `uni-icons` 组件 ,可用图标类型参考 [uni-icons 示例](https://hellouniapp.dcloud.net.cn/pages/extUI/icons/icons)
```html
<uni-nav-bar left-text="返回" right-text="设置" title="标题" />
```
### 带左右图标
使用 `left-icon` 属性设置导航栏左侧图标
使用 `right-icon` 属性设置导航栏右侧图标
Tips:
- 图标依赖 `uni-icons` 组件 ,可用图标类型参考 [uni-icons 示例](https://hellouniapp.dcloud.net.cn/pages/extUI/icons/icons)
- **right-text 和 right-icon 属性不能同时存在,如需都使用,请使用 right 插槽自定义**
```html
<uni-nav-bar left-icon="left" right-icon="cart" title="标题" />
```
### 自定义高度
使用 `height` 属性设置导航栏高度
Tips:
- 组件默认高度为44px
- 如使用 Number 类型传值默认单位为 px,使用 String 类型传值则必须带单位,如传值无效 ,则使用默认值
```html
<uni-nav-bar height="120rpx" title="自定义高度" />
```
## API
### NavBar Props
|属性名|类型|默认值 |说明|
......@@ -29,16 +108,24 @@
|statusBar|Boolean|false|是否包含状态栏|
|shadow|Boolean|false|导航栏下是否有阴影|
|border|Boolean|true|导航栏下是否有边框|
|height|Number/String|44|导航栏高度|
|dark|Boolean|false|导航栏开启暗黑模式|
|leftWidth|Number/String|120rpx|导航栏左侧插槽宽度|
|rightWidth|Number/String|120rpx|导航栏右侧插槽宽度|
**Tips**
- `leftWidth``rightWidth` 如无必要不需要设置
- `leftWidth``rightWidth` 如需设置 ,只有两个值相同,才能保证 `title` 居中 ,如设置值过大,需要注意到 `title` 被覆盖的可能
### NavBar Slots
开发者使用 NavBar 时,支持向 NavBar 里插入不同内容,以达到自定义的目的。
### NavBar Slots
支持向 NavBar 里插入不同内容,以达到自定义的目的。
|slot名 |说明|
|:-:|:-:|
|default|向导航栏中间插入 |
|left|向导航栏左侧插入 |
|right |向导航栏右侧插入 |
|default|向导航栏中间插入 |
```html
<uni-nav-bar>
......
......@@ -19,6 +19,7 @@
> - 使用 `npm` 方式引入组件,如果确认引用正确,但是提示未注册组件或显示不正常,请尝试重新编译项目
> - `uni-popup` 中尽量不要使用 `scroll-view` 嵌套过多的内容,可能会影响组件的性能,导致组件无法打开或者打开卡顿
> - `uni-popup` 不会覆盖原生 tabbar 和原生导航栏
> - app-vue 中组件无法遮盖 video ,ad 等原生组件 ,建议使用 nvue
> - 组件支持 nvue ,需要在 `manifest.json > app-plus` 节点下配置 `"nvueStyleCompiler" : "uni-app"`
### 基本用法
......@@ -104,7 +105,9 @@ export default {
|:-:|:-:|:-:|:-:|
|animation|Boolean|true|是否开启动画|
|type|String|'center'|弹出方式|
|mask-click|Boolean|true|蒙版点击是否关闭弹窗|
|mask-click **[即将废弃]**|Boolean|true|蒙版点击是否关闭弹窗|
|is-mask-click **[1.7.4新增]**|Boolean|true|蒙版点击是否关闭弹窗|
|mask-background-color **[1.7.4新增]**|rgba|rgba(0,0,0,0.4)|蒙版颜色,建议使用 rgba 颜色值|
|background-color|String|'none'|主窗口背景色|
|safe-area|Boolean|true|是否适配底部安全区|
......@@ -228,6 +231,8 @@ export default {
|mode|String|base| 对话框模式,可选值:base(提示对话框)/input(可输入对话框)|
|title|String|-|对话框标题|
|content|String|-|对话框内容,base模式下生效|
|confirmText **[1.7.4新增]**|String|-|定义确定按钮文本|
|cancelText **[1.7.4新增]**|String|-|定义取消按钮文本|
|value| String\Number|-|输入框默认值,input模式下生效|
|placeholder|String|-|输入框提示文字,input模式下生效|
|before-close|Boolean|false | 是否拦截按钮事件,如为true,则不会关闭对话框,关闭需要手动执行 uni-popup 的 close 方法|
......@@ -275,6 +280,57 @@ export default {
**Tips**
- share 分享组件,只是作为一个扩展示例,如果需要修改数据源,请到组件内修改
## 禁止滚动穿透
使用组件时,会发现内容部分滚动到底时,继续划动会导致底层页面的滚动,这就是滚动穿透。
但由于平台自身原因,除了h5平台外 ,其他平台都不能在在组件内禁止滚动穿透,所以在微信小程序、App 平台,页面内需要用户特殊处理一下
### 微信小程序/App
`微信小程序/App` 平台可使用 `page-meta` 组件动态修改页面样式 ,
需要在 data 中定义一个变量,用来表示 `uni-popup` 的开启关闭状态,并通过这个变量修改 `page-meta``overflow` 属性。
`uni-popup``@change` 事件中可以接受到 `uni-popup` 的开启关闭状态 ,并赋值给上面的变量
**下面是关键代码片段:**
```html
<template>
<page-meta :page-style="'overflow:'+(show?'hidden':'visible')"></page-meta>
<view class="container">
<!-- 普通弹窗 -->
<uni-popup ref="popup" background-color="#fff" @change="change">
<!-- ... -->
</uni-popup>
</view>
</template>
<script>
export default {
data() {
return {
show:false
}
},
methods: {
change(e) {
this.show = e.show
}
}
}
</script>
```
**Tips**
- h5 滚动穿透不需要处理
- wx、app 需要 使用 page-meta 组件配合阻止滚动穿透
- 注意 page-meta 组件,一个页面只能存在一个
- 其他平台无法阻止滚动穿透,建议使用 scroll-view 滚动 ,手动设置 overflow:hidden,同 page-meta 方法一致
## 组件示例
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/popup/popup](https://hellouniapp.dcloud.net.cn/pages/extUI/popup/popup)
\ No newline at end of file
......@@ -50,6 +50,7 @@ app端nvue专用组件。
- left-gap: [可选]左边cell和列表的间隙. 如果未指定 ,则对应 `0`
- right-gap: [可选]右边cell和列表的间隙. 如果未指定,则对应 `0`
<img src="https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-uni-app-doc/e78b5450-4f2e-11eb-b680-7980c8a877b8.png" />
- always-scrollable-vertical : `[可选]` 可选值为 true/ false,默认值为 false,iOS 平台,内容不满一屏无法触发下拉刷新时需要设置为true,因为默认子视图高度不超过父视图高度的时候 waterfall 不能滑动
其他支持的属性参见 `<list>` 组件属性部分
......
......@@ -12,7 +12,7 @@
|allow|String|用于为 [iframe](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/iframe) 指定其[特征策略](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/策略特征)|H5|
|sandbox|String|该属性对呈现在 [iframe](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/iframe) 框架中的内容启用一些额外的限制条件。|H5|
|webview-styles|Object|webview 的样式|App-vue|
|update-title|Boolean|是否自动更新当前页面标题。默认值:`true`|App-vue (3.4.0+)|
|update-title|Boolean|是否自动更新当前页面标题。默认值:`true`|App-vue (HBuilder X 3.3.8+)|
|@message|EventHandler|网页向应用 `postMessage` 时,会在特定时机(后退、组件销毁、分享)触发并收到消息。|H5 暂不支持(可以直接使用 [window.postMessage](https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage))|
|@onPostMessage|EventHandler|网页向应用实时 `postMessage`|App-nvue|
......
......@@ -252,7 +252,7 @@ vue页面在App端的渲染引擎默认是系统webview(不是手机自带浏
* 页面中引入自定义组件时,渲染的结果中外层会有一个 `template` 标签,这会导致部分选择器对应的样式匹配不上。
#### 360小程序开发注意 @mp-360
* HBuilderX 2.7.6+ alpha 版支持
* HBuilderX 2.7.6+ 版支持
* 默认为H5平台组件,如果需要360平台组件请使用 <se-...></se-...>,例如 `<se-video></se-video>`
* `<se-...></se-...>` 为360平台专有组件,不能跨平台,需要条件编译 `mp-360`
pages 配置
......@@ -268,7 +268,7 @@ pages 配置
#### 快应用开发注意@quickapp
* HBuilderX 2.7.12+ alpha 版支持
* HBuilderX 2.7.12+ 版支持
##### quickapp-webview
- 目前仅vivo oppo支持
......
# 更新日志(正式版)
---
#### 3.3.11.20220210
* 【uni-app】
+ H5平台 修复 3.3.9 引出的 uni.previewImage 预览图像无法拖动的Bug [详情](https://ask.dcloud.net.cn/question/138972)
+ App-Android平台 修复 3.3.10版本引出的 picker 组件样式错误的Bug [详情](https://ask.dcloud.net.cn/question/138748)
+ App-iOS平台 修复 3.3.9 版本引出的 nvue swiper-list 组件中的 list 组件设置 show-scrollbar 为 false 时吸顶效果异常的Bug [详情](https://ask.dcloud.net.cn/question/138944)
* 【App插件(含5+App和uni-app的App端)】
+ Android平台 修复 3.3.9 版本引出的 一键登录 同时自定义 logo 与 closeIcon 可能导致显示异常的Bug [详情](https://ask.dcloud.net.cn/question/137642)
+ iOS平台 修复 Downloader 下载图片文件可能失败的Bug [详情](https://ask.dcloud.net.cn/question/116101)
#### 3.3.10.20220124
* 【uni-app】
......
......@@ -42,8 +42,9 @@
* [Native.js](/tutorial/native-js.md)
* [renderjs](/tutorial/renderjs.md)
* [原生插件](https://nativesupport.dcloud.net.cn/NativePlugin/README)
* [App 打包](/tutorial/app-icons.md)
* [图标](/tutorial/app-icons.md)
* [App 打包](/tutorial/app-base.md)
* [基础配置](/tutorial/app-base.md)
* [图标配置](/tutorial/app-icons.md)
* [启动界面](/tutorial/app-splashscreen.md)
* [功能模块](/tutorial/app-modules.md)
* [Geolocation(定位)](/tutorial/app-geolocation.md)
......@@ -54,6 +55,8 @@
* [Paypal支付](/tutorial/app-payment-paypal.md)
* [Stripe支付](/tutorial/app-payment-stripe.md)
* [Google支付](/tutorial/app-payment-google.md)
* Push(消息推送)
* [UniPush](/tutorial/app-push-unipush.md)
* [Statistic(统计)](/tutorial/app-statistic.md)
* [友盟统计](/tutorial/app-statistic-umeng.md)
* [Google统计](/tutorial/app-statistic-google.md)
......
......@@ -23,7 +23,8 @@
```
+ 填写隐私协一定要结合实际使用的模块功能。填写相关隐私条款!不能含糊不清。模块收集了什么信息都要填写完整。否则影响上架!请参考当前文档中的`隐私政策注意事项`
+ 查看是否集成uni原生插件。有些权限或是违规获取可能是uni原生插件引发的。建议使用排除法删除插件重新打包检测
+ 你的APP上面排查点都符合要求。上架依然失败请向检测平台要求提供代码调用堆栈。请拿着堆栈信息去找管理人员反馈
+ 检查是否集成了fcm推送(包含unipush中的fcm)、google统计、google推送、google登录模块。由于这些模块都集成google的gms服务会提前获取android id导致无法在国内正常上架。打包时请在manifest.json配置中排除这些功能模块。
+ 你的APP上面排查点都符合要求。上架依然失败请向检测平台要求提供代码调用堆栈。请拿着堆栈信息去[ASK论坛](https://ask.dcloud.net.cn/explore/)发帖说明问题并@管理人员反馈
### 隐私政策注意事项
......@@ -116,8 +117,15 @@
#### 14、您的应用在后台状态下获取了用户的MAC信息,且未在应用内的隐私政策
+ 查看是否集成了UniPush
+ 如果集成UniPush请更新个推隐私协议条款!补充MAC信息[参考](https://ask.dcloud.net.cn/article/39484)
+ 没有集成UniPush请向检测平台获取java调用堆栈。拿着java调用堆栈找客服确认问题
+ 如果集成UniPush请更新个推隐私协议条款!重点是补充MAC信息描述[参考](https://ask.dcloud.net.cn/article/39484)
+ 没有集成UniPush请向检测平台获取java调用堆栈。拿到java调用堆栈在[ask论坛](https://ask.dcloud.net.cn/explore/)发帖咨询
#### 15、未经许可读取个人信息 获取ANDROID ID
+ 检查是否集成了fcm推送(包含unipush中的fcm)、google统计、google推送、google登录模块。
+ 如果集成了则不能国内上架!原因是集成这些模块会将google的GMS服务导入安装包中。启动会获取android id导致无法上架。
+ 检查uni-app项目在manifest.json将上诉模块去除重新打包上架
+ 没有集成这些模块可以向检测平台获取调用堆栈。拿到java调用堆栈在[ask论坛](https://ask.dcloud.net.cn/explore/)发帖咨询
#### 看不懂文档不知道如何修改?
......
HBuilderX中打开项目的manifest.json文件,在“基础配置”中可以设置App的应用名称、版本号等信息:
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/base.png)
<a id="appid"/>
### 应用标识
DCloud应用appid(简称appid)是由DCloud创建App项目时生成的唯一标识,关联DCloud云端服务,创建项目后会自动生成,不能随意变更。
> 注:这与各家小程序的appid、Apple的appid(bundle id)及其它三方SDK平台申请的appid不同,它们分别属于各自平台的appid体系
更多appid用途详见 [DCloud appid使用说明](https://ask.dcloud.net.cn/article/35907)
#### 本地离线打包
离线打包时需在原生工程中设置,Android平台参考 [Android Studio工程配置DCloud appid](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/android?id=appid),iOS平台参考 [XCode工程配置DCloud appid](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/ios?id=appid)
<a id="name"/>
### 应用名称
应用的名称,发行为App时作为应用桌面图标的名称,支持国际化时请参考 [manifest.json国际化](https://uniapp.dcloud.io/collocation/i18n?id=manifest)
#### 本地离线打包
离线打包时需在原生工程中设置,Android平台参考 [Android Studio工程配置应用名称](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/android?id=name),iOS平台参考 [XCode工程配置应用名称](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/ios?id=%e9%85%8d%e7%bd%ae%e5%ba%94%e7%94%a8%e5%90%8d%e7%a7%b0)
<a id="description"/>
### 应用描述
应用的描述信息,用于简单介绍应用情况,发行为App时不会使用。
<a id="versionname"/>
### 应用版本名称
应用显示的版本名称,可以使用任何字符串,推荐使用“.”分割的数字表示“主版本号.此版本号.编译版本号”,如“1.1.1234”。云端打包后设置为原生工程的应用版本名称:
- Android平台
应用清单文件(AndroidManifest.xml)中manifest节点的`android:versionName`属性值,安装到手机后可在“设置”->“应用管理”->“应用信息”中查看
- iOS平台
应用Info.plist文件中的`CFBundleShortVersionString`字段值,安装到手机后可连接到电脑在iTunes的应用列表中查看。提交AppStore审核时通常跟后台构建的版本号一致,审核失败后重新打包通常不需要修改版本名称。
> 在 App 中可通过 [plus.runtime.version](https://www.html5plus.org/doc/zh_cn/runtime.html#plus.runtime.version) 获取应用版本名称。
#### 本地离线打包
离线打包时需在原生工程中设置,Android平台参考 [Android Studio工程配置应用版本名称](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/android?id=versioncode),iOS平台参考 [XCode工程配置应用版本名称](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/ios?id=%e9%85%8d%e7%bd%ae%e5%ba%94%e7%94%a8%e7%89%88%e6%9c%ac%e5%90%8d%e7%a7%b0)
<a id="versioncode"/>
### 应用版本号
应用的内部版本号,必须使用整数,用于记录开发版本的,建议每次发布(云端打包)时更新为比上一次高。如:当前版本是100,下次发布就要大于100,比如101、102等。云端打包后设置为原生工程的应用版本号:
- Android平台
应用清单文件(AndroidManifest.xml)中manifest节点的`android:versionCode`属性值,安装时只能高版本的安装包覆盖升级低版本的安装包,提交各应用市场时也要求必须更新为比上次高的版本。
- iOS平台
应用Info.plist文件中的`CFBundleVersion`字段值。每次提交AppStore审核时都必须更新为比上一次高的版本号,审核失败后重新打包也需要更新版本号。
> 在 App 中可通过 [plus.runtime.versionCode](https://www.html5plus.org/doc/zh_cn/runtime.html#plus.runtime.versionCode) 获取应用版本名称。
#### 本地离线打包
离线打包时需在原生工程中设置,Android平台参考 [Android Studio工程配置应用版本名称](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/android?id=versionname),iOS平台参考 [XCode工程配置应用版本号](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/ios?id=%e9%85%8d%e7%bd%ae%e5%ba%94%e7%94%a8%e7%89%88%e6%9c%ac%e5%8f%b7)
App端定位模块封装系统自带的`系统定位`,及市场上主流的三方定位SDK,如`高德定位``百度定位`等,提供JS API统一调用定位功能。
> HBuilderX3.3.0开始独立出“系统定位”模块
|项目类型|API|
|:-|:-|
|uni-app|[uni.getLocation(OBJECT)](api/location/location?id=getlocation)|
|5+ App/Wap2App|[plus.geolocation.*](https://www.html5plus.org/doc/zh_cn/geolocation.html)
### 背景
使用定位功能需在项目manifest.json的“App模块配置”中勾选“Geolocation(定位)”,并根据项目实际需求勾选使用的三方定位SDK:
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/geolocation/modules.png)
从2021年初开始,高德、百度、腾讯等地图服务商更新了服务协议、开始实施商业授权机制,要求除公益App外所有使用地图相关功能(包括定位SDK、地图SDK、H5地图等)都需要获取地图服务商的商业授权。重点强调一下,免费应用同样需要商业授权,除非你的应用是公益类App,其它类型App都需要商业授权。
- 高德地图参考:[https://lbs.amap.com/upgrade](https://lbs.amap.com/upgrade)
- 百度地图参考:[https://lbsyun.baidu.com/cashier/auth](https://lbsyun.baidu.com/cashier/auth)
没有取得地图服务商授权的App可能会遇到定位或地图功能被停用、上架应用市场可能提示存在侵权的问题,因此需要向高德、百度等地图开放平台申请商业授权。
为了避免商业授权引起的问题,也可以只使用“系统定位”模块,“系统定位”在功能和机型适配上没有高德、百度等商业定位服务完善,需开发者根据实际情况选择。
### 系统定位
### 系统定位
系统定位调用的系统提供的定位服务,不同设备对定位功能支持的情况有所差异
> HBuilderX3.2.16开始独立出“系统定位”模块
使用`系统定位`需在“App模块配置”项的“Geolocation(定位)”下,勾选“系统定位”:
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/geolocation/system.png)
`系统定位`调用设备的操作系统提供的定位服务,只支持wgs84坐标系,不同设备对定位功能支持的情况有所差异。
#### iOS平台
由苹果公司提供定位服务,可以获取经纬度信息,也支持解析地址信息。即可以直接返回城市街道信息。
由苹果iOS系统提供定位服务,可以获取经纬度信息,支持解析地址信息,即可以直接返回城市街道信息。
#### Android平台
标准Android平台的定位服务是Google提供的,但需要手机内置GMS服务,连接Google服务器。国产手机大多不支持
只可以获取经纬度信息,不支持解析地址信息,即无法返回城市街道信息
主流国内手机厂商均自行提供了定位服务,但小众品牌可能不支持,主流品牌中较老的机型也不支持。如下Android手机厂商都支持系统定位:
标准Android系统的定位服务是Google提供的,但需要手机内置GMS服务,连接Google服务器。
国内主流手机厂商均自行提供了定位服务,但小众品牌可能不支持,主流品牌中较老的机型也不支持。如下Android手机厂商都支持`系统定位`
- 华为
- 小米
- Oppo
......@@ -33,7 +39,63 @@
在国外通常都是使用Google的GMS提供定位服务。
**注意:Android系统定位模块不支持位置解析服务,只可以获取经纬度信息,不支持解析地址信息。如需要根据经纬度获取城市街道信息,仍然需要请求高德、百度等商业服务**
**注意**
- 由于设备厂商适配的原因,在部分Android设备上定位服务可能不稳定,如需提升定位功能的稳定性建议使用`高德定位``百度定位`
- 本地离线打包参考[Android平台系统定位模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/androidModuleConfig/geolocation?id=%e7%b3%bb%e7%bb%9f%e5%ae%9a%e4%bd%8d)[iOS平台百度定位模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/iOSModuleConfig/geolocation?id=%e7%b3%bb%e7%bb%9f%e5%ae%9a%e4%bd%8d)
### 高德定位
> 需要向高德申请商业授权,参考:[商业授权相关说明](id=business),使用前需登录 [高德开放平台](https://lbs.amap.com/) 创建应用申请Key
使用`高德定位`需在“App模块配置”项的“Geolocation(定位)”下,勾选“高德定位”:
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/geolocation/amap.png)
#### 参数说明
- appkey_android
[高德开放平台](https://lbs.amap.com/)为Android平台申请的Key
- appkey_ios
[高德开放平台](https://lbs.amap.com/)为iOS平台申请的Key
**注意**
- 调用高德定位SDK提供的定位服务,仅支持gcj02坐标系,支持解析地址信息。
- 配置后需提交云端打包后才能生效,真机运行时请使用[自定义调试基座](https://ask.dcloud.net.cn/article/35115)
- 本地离线打包参考[Android平台高德定位模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/androidModuleConfig/geolocation?id=%e9%ab%98%e5%be%b7%e5%ae%9a%e4%bd%8d)[iOS平台高德定位模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/iOSModuleConfig/geolocation?id=%e9%ab%98%e5%be%b7%e5%ae%9a%e4%bd%8d)
### 百度定位
> 需要向百度申请商业授权,参考:[商业授权相关说明](id=business),使用前需登录 [百度地图开放平台](https://lbsyun.baidu.com/) 创建应用申请访问应用密钥(AK)
使用`高德定位`需在“App模块配置”项的“Geolocation(定位)”下,勾选“百度定位”:
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/geolocation/baidu.png)
#### 参数说明
- appkey_android
[百度地图开放平台](https://lbsyun.baidu.com/)为Android平台申请的访问应用密钥
- appkey_ios
[百度地图开放平台](https://lbsyun.baidu.com/)为iOS平台申请的访问应用密钥
**注意**
-调用百度定位SDK提供的定位服务,仅支持gcj02/bd09/bd09ll坐标系,支持解析地址信息。
- 配置后需提交云端打包后才能生效,真机运行时请使用[自定义调试基座](https://ask.dcloud.net.cn/article/35115)
- 本地离线打包参考[Android平台百度定位模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/androidModuleConfig/geolocation?id=%e7%99%be%e5%ba%a6%e5%ae%9a%e4%bd%8d)[iOS平台百度定位模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/iOSModuleConfig/geolocation?id=%e7%99%be%e5%ba%a6%e5%ae%9a%e4%bd%8d)
<a id="business"/>
### 商业授权相关说明
从2021年初开始,高德、百度、腾讯等地图服务商更新了服务协议、开始实施商业授权机制,要求除公益App外所有使用地图相关功能(包括定位SDK、地图SDK、H5地图等)都需要获取地图服务商的商业授权。重点强调一下,免费应用同样需要商业授权,除非你的应用是公益类App,其它类型App都需要商业授权。
- 高德地图参考:[https://lbs.amap.com/upgrade](https://lbs.amap.com/upgrade)
- 百度地图参考:[https://lbsyun.baidu.com/cashier/auth](https://lbsyun.baidu.com/cashier/auth)
没有取得地图服务商授权的App可能会遇到定位或地图功能被停用、上架应用市场可能提示存在侵权的问题,因此需要向高德、百度等地图开放平台申请商业授权。
为了避免商业授权引起的问题,如仅需获取wgs84坐标的情况下也可以只使用“系统定位”模块,“系统定位”在功能和机型适配上没有高德、百度等商业定位服务完善,需开发者根据实际情况选择。
打开项目的manifest.json文件,在“App图标配置”中可以设置App的桌面图标,推荐使用“自动生成图标”功能:
HBuilderX中打开项目的manifest.json文件,在“App图标配置”中可以设置App的桌面图标,推荐使用“自动生成图标”功能:
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/icons/auto.png)
如果不使用自动生成图标方式,可按下面文档分别配置Android和iOS平台的图标。
......@@ -68,21 +68,21 @@
|:-|:-|:-|
|iphone|对象,参考[iPhone图标源码参数](#iphone)|iPhone设备程序图标
|ipad|对象,参考[iPad图标源码参数](#ipad)|iPad设备程序图标|
|appstore|String|720P高分屏设备程序图标路径,分辨率要求1024x1024|
|appstore|String|App Store图标路径,分辨率要求1024x1024|
<a id="iphone"/>
iPhone图标源码参数
|属性名称|类型|说明|
|:-|:-|:-|
|app@2x|String|iPhone4S/5/6/7/8设备程序主图标,分辨率要求120x120|
|app@3x|String|iPhone6plus/7plus/8plus/X设备程序主图标,分辨率要求180x180|
|spotlight@2x|String|iPhone5/6/7/8设备Spotlight搜索图标,分辨率要求80x80|
|spotlight@3x|String|iPhone6plus/7plus/8plus/X设备Spotlight搜索图标,分辨率要求120x120|
|settings@2x|String|iPhone5/6/7/8设备Settings设置图标,分辨率要求58x58|
|settings@3x|String|iPhone6plus/7plus/8plus/X设备Settings设置图标,分辨率要求87x87|
|notification@2x|String|iPhone5/6/7/8设备通知栏图标,分辨率要求40x40|
|notification@3x|String|iPhone6plus/7plus/8plus/X设备通知栏图标,分辨率要求60x60|
|app@2x|String|iOS7+设备程序主图标,分辨率要求120x120|
|app@3x|String|iOS7+设备程序主图标,分辨率要求180x180|
|spotlight@2x|String|iOS7+设备Spotlight搜索图标,分辨率要求80x80|
|spotlight@3x|String|iOS7+设备Spotlight搜索图标,分辨率要求120x120|
|settings@2x|String|iOS7+设备Settings设置图标,分辨率要求58x58|
|settings@3x|String|iOS7+设备Settings设置图标,分辨率要求87x87|
|notification@2x|String|iOS7+设备通知栏图标,分辨率要求40x40|
|notification@3x|String|iOS7+设备通知栏图标,分辨率要求60x60|
<a id="ipad"/>
iPad图标源码参数
......@@ -91,7 +91,7 @@ iPad图标源码参数
|:-|:-|:-|
|app|String|iOS7+设备程序主图标,分辨率要求76x76|
|app@2x|String|iOS7+高分屏设备程序主图标,分辨率要求152x152|
|proapp@2x|String|iPad Pro设备程序主图标,分辨率要求167x167|
|proapp@2x|String|iOS9+ iPad Pro(12.9英寸)设备程序主图标,分辨率要求167x167|
|spotlight|String|iOS7+设备Spotlight搜索图标,分辨率要求40x40|
|spotlight@2x|String|iOS7+高分屏设备Spotlight搜索图标,分辨率要求80x80|
|settings|String|iOS5+设备Settings设置图标,分辨率要求29x29|
......@@ -118,5 +118,5 @@ iOS系统会缓存应用图标,需要重启手机新图标才能生效
ERROR ITMS-90717: "Invalid App Store Icon. The App Store Icon in the asset catalog in 'HBuilder.app' can't be transparent nor contain an alpha channel."
```
**解决方案**
生成png图标文件时去掉alpha通道,重新提云端打包
生成png图标文件时去掉alpha通道,重新提云端打包
#### 注意事项
1. 应苹果审核规范要求,应用中虚拟物品交易必须使用Apple应用内支付,实物才可使用第三方支付(支付宝、微信等)
2. 使用沙盒环境测试时每次调用支付接口需要换一个新的测试账号或商品,同一个账号多次购买同一个商品可能会没有回调
### 开通
- 登录[App Store Connect](https://appstoreconnect.apple.com/)签署《付费应用程序协议》
- 在App Store Connect中为 App 配置 App 内购买项目产品,参考[创建App内购买项目](https://help.apple.com/app-store-connect/#/devae49fb316),设置产品ID(productId)
#### 相关文档
使用前必读:[App内购买配置流程](https://help.apple.com/app-store-connect/#/devb57be10e7)
调试需要创建自定义基座.参考[自定义调试基座](https://ask.dcloud.net.cn/article/35115)
服务端防刷单参考[IAP支付防止刷单](https://www.jianshu.com/p/5cf686e92924)
更多信息详见苹果官方文档 [App 内购买项目配置流程](https://help.apple.com/app-store-connect/#/devb57be10e7)
#### 参考建议
1. 提前绑定支付方式可以有效避免丢单情况,示例:
`plus.runtime.openURL("https://apps.apple.com/account/billing"); //跳转AppStore绑定支付方式`
2. 在每个接口调用前后添加打点日志收集,以便快速定位问题
**注意**
- 提交 App Store 的 App 才能开通应用内支付,使用`苹果企业账号`发布的 App 不能开通使用
- 根据 App Store 审核指南条款 [3.1.1](https://developer.apple.com/cn/app-store/review/guidelines/#in-app-purchase) 要求,虚拟物品交易必须使用应用内支付,实物交易才可使用第三方支付(支付宝、微信等)
- 创建 App内购买项目的各项信息需要填写完整,保存后内购项目的状态是准备提交,当提交应用通过审核后,状态则变为已批准
- 正式上线前可在 Test Flight 平台添加 App Store Connect 用户,测试支付时可以使用此用户帐号
#### 丢单问题说明
通过和用户联调我们发现在调用支付接口后,如果用户未绑定支付方式此时会触发支付失败回调方法,实际上用户可以跳转 AppStrore 绑卡然后继续支付,之前的逻辑在回调失败方法中框架会关闭订单,用户付完钱在回到App中也不会触发成功回调,这样就造成了丢单,解决方法就是在调用支付接口时添加optimize: true参数,并标记 restoreFlag = true;,支付成功回调中清除标记 restoreFlag = false; 然后在支付失败回调中框架就不会关闭订单了,并在页面显示的时候通过标记判断是否需要调用 restoreComplateRequest 方法,如果用户跳转App Store绑定支付方式付款成功后回到 App 就可以通过 restoreComplateRequest 方法恢复之前支付的订单信息,解决丢单的问题;
#### 开发流程
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“Apple应用内支付”项
### 配置
打开项目的manifest.json文件,在“App模块配置”项的“Payment(支付)”下勾选“Apple应用内支付”:
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/iap_setup_manifest_info.png)
###### 获取支付渠道
> 提示:需提交云端打包后才能生效,真机运行时请使用[自定义调试基座](https://ask.dcloud.net.cn/article/35115);本地离线打包参考[Apple应用内支付模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/iOSModuleConfig/pay?id=%e8%8b%b9%e6%9e%9c%e5%ba%94%e7%94%a8%e5%86%85%e8%b4%ad%e6%94%af%e4%bb%98)
### 应用内发起支付
苹果应用内支付不需要从服务器生成订单,需在发起支付前调用[requestOrder](https://www.html5plus.org/doc/zh_cn/payment.html#plus.payment.PaymentChannel.requestOrder)获取订单信息。
#### 获取应用内支付对象
应用内支付通道标识为`appleiap`,调用[plus.payment.getChannels](https://www.html5plus.org/doc/zh_cn/payment.html#plus.payment.getChannels)获取应用内支付对象:
``` js
var iap = null;
plus.payment.getChannels(function(channels) {
for (var i in channels) {
var channel = channels[i];
var iap = null; //保存应用内支付对象
plus.payment.getChannels(function(channels){
for (var i in channels) {
var channel = channels[i];
// 获取 id 为 'appleiap' 的 channel
if (channel.id === 'appleiap') {
iap = channel;
}
}
}, function(e) {
console.log("获取iap支付通道失败:" + e.message);
if (channel.id === 'appleiap') {
iap = channel;
}
}
}, function(e){
console.log("获取iap支付通道失败:" + e.message);
});
```
###### 获取订单信息
#### 获取订单信息
发起支付前需调用[requestOrder](https://www.html5plus.org/doc/zh_cn/payment.html#plus.payment.PaymentChannel.requestOrder)传入产品ID(productId)获取订单信息:
``` js
// ids 为在苹果开发者后台配置的应用内购项目的标识集合
var ids = ['商品1', '商品2'];
// iap 为刚刚获取的`appleiap`支付通道
// ids 数组中的项为 App Store Connect 配置的内购买项目产品ID(productId)
var ids = ['商品ID 1', '商品ID 2'];
// iap 为应用内支付对象
iap.requestOrder(ids, function(e) {
// 获取订单信息成功回调方法
console.log('requestOrder success: ' + JSON.stringify(e));
}, function(e) {
console.log('requestOrder success: ' + JSON.stringify(e));
}, function(e) {
// 获取订单信息失败回调方法
console.log('requestOrder failed: ' + JSON.stringify(e));
console.log('requestOrder failed: ' + JSON.stringify(e));
});
```
###### 发起支付
* uni-app项目示例
#### 发起支付
- uni-app项目
调用 [uni.requestPayment(OBJECT)](https://uniapp.dcloud.io/api/plugins/payment?id=requestpayment) 发起支付,OBJECT参数中provider属性值固定为`appleiap`、orderInfo属性值为订单对象
- 5+ App项目
调用 [plus.payment.request(channel, orderInfo, successCB, errorCB)](https://www.html5plus.org/doc/zh_cn/payment.html#plus.payment.request) 发起支付, channel参数为应用内支付对象,orderInfo参数为订单对象
##### 订单对象参数说明
Object对象类型
| 属性 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| productid | String | 是 | App Store Connect 配置的内购买项目产品ID(productId) |
| username | String | 否 | 用户标识 |
| optimize | Boolean | 否 | 是否优化解决丢掉问题 |
##### 示例代码
- uni-app项目
``` js
var restoreFlag = true;
uni.requestPayment({
provider: 'appleiap',
orderInfo: {
productid: productId,
username: "appusername", // 用户标识
optimize: true // 设置 optimize: true 解决丢单问题
},
success: (e) => {
// 支付成功清除标记 restoreFlag = false
// 支付成功,result 为 IAP商品交易信息对象 IAPTransaction 需将返回的支付凭证传给后端进行二次认证
restoreFlag = false;
},
fail: (e) => {
// 支付失败的时候需要调用一下 restoreComplateRequest 方法
restoreComplateRequest()
},
complete: () => {
console.log("payment结束")
}
})
provider: 'appleiap',
orderInfo: {
productid: productId,
username: "appusername", // 用户标识
optimize: true // 设置 optimize: true 解决丢单问题
},
success: (e) => {
// 支付成功清除标记 restoreFlag = false
// 支付成功,result 为 IAP商品交易信息对象 IAPTransaction 需将返回的支付凭证传给后端进行二次认证
restoreFlag = false;
},
fail: (e) => {
// 支付失败的时候需要调用一下 restoreComplateRequest 方法
restoreComplateRequest();
},
complete: () => {
console.log("payment结束");
}
});
```
* 5+项目示例
- 5+ App项目
``` js
// restoreFlag 标记,用于判断在页面显示的时候是否需要调用 restoreComplateRequest 方法
var restoreFlag = true; // 调用支付接口时标记 restoreFlag = true , 实际应用请将标记存储在 storage 中
plus.payment.request(iap, {
productid: "商品id",
plus.payment.request(iap, {
productid: "商品id",
username: "appusername", // 用户标识
optimize: true // 设置 optimize: true 解决丢单问题
}, function(result) {
}, function(result){
restoreFlag = false; // 支付成功清除标记 restoreFlag = false
// 支付成功,result 为 IAP商品交易信息对象 IAPTransaction 需将返回的支付凭证传给后端进行二次认证
}, function(e) {
}, function(e){
// 支付失败的时候需要调用一下 restoreComplateRequest 方法
restoreComplateRequest()
restoreComplateRequest();
});
```
###### 恢复购买
#### 恢复购买
``` js
function restoreComplateRequest() {
iap.restoreComplateRequest({}, function(results) {
function restoreComplateRequest() {
iap.restoreComplateRequest({}, function(results){
// results 格式为数组存放恢复的IAP商品交易信息对象 IAPTransaction,需要将返回的支付凭证传给后端进行二次认证
});
});
}
```
此方法可获取
* 已购的非消耗性商品以及订阅商品
* 丢单的商品(所有类型)
`restoreComplateRequest`作用描述:
- 已购的非消耗性商品以及订阅商品
- 丢单的商品(所有类型)
注意事项:**丢单的消耗类型商品**在支付完成后,**首次**调用该接口可返回支付凭证
###### 丢单检测
* uni-app 在页面 onShow 方法中调用 restoreComplateRequest
#### 丢单检测
- uni-app项目
[页面生命周期](https://uniapp.dcloud.io/collocation/frame/lifecycle?id=%e9%a1%b5%e9%9d%a2%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f)函数 `onShow` 中调用 `restoreComplateRequest`
``` js
onShow() {
if(restoreFlag) {
restoreComplateRequest()
}
onShow() {
if(restoreFlag) {
restoreComplateRequest();
}
}
```
* 5+app 在 resume 回调中调用 restoreComplateRequest
- 5+ App项目
在监听页面 `resume` 事件回调中调用 `restoreComplateRequest`
``` js
document.addEventListener('resume',function(){
if(restoreFlag) {
restoreComplateRequest()
restoreComplateRequest();
}
},false);
```
#### 丢单问题说明
通过和用户联调我们发现在调用支付接口后,如果用户未绑定支付方式此时会触发支付失败回调方法,实际上用户可以跳转 AppStrore 绑卡然后继续支付,之前的逻辑在回调失败方法中框架会关闭订单,用户付完钱在回到App中也不会触发成功回调,这样就造成了丢单,解决方法就是在调用支付接口时添加optimize: true参数,并标记 restoreFlag = true;,支付成功回调中清除标记 restoreFlag = false; 然后在支付失败回调中框架就不会关闭订单了,并在页面显示的时候通过标记判断是否需要调用 restoreComplateRequest 方法,如果用户跳转App Store绑定支付方式付款成功后回到 App 就可以通过 restoreComplateRequest 方法恢复之前支付的订单信息,解决丢单的问题;
### 常见问题
- 使用沙盒环境测试时每次调用支付接口需要换一个新的测试账号或商品,同一个账号多次购买同一个商品可能会没有回调
- 服务端防刷单参考[IAP支付防止刷单](https://www.jianshu.com/p/5cf686e92924)
- 提前绑定支付方式可以有效避免丢单情况,示例:
`plus.runtime.openURL("https://apps.apple.com/account/billing"); //跳转AppStore绑定支付方式`
- 建议在每个接口调用前后添加打点日志收集,以便快速定位问题
## 申请开通支付宝支付
登录[支付宝开放平台](https://open.alipay.com/)
[创建应用](https://opendocs.alipay.com/open/200/105310)
[添加功能](https://opendocs.alipay.com/open/200/105310#%E6%B7%BB%E5%8A%A0%E5%BA%94%E7%94%A8%E5%8A%9F%E8%83%BD)
[开发设置](https://opendocs.alipay.com/open/200/105310#%E9%85%8D%E7%BD%AE%E5%BA%94%E7%94%A8%E7%8E%AF%E5%A2%83)
更多信息详见[支付宝官方文档](https://opendocs.alipay.com/open/204/105297/)
## 使用支付宝支付
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“支付宝支付”项
### 开通
- 登录 [支付宝开放平台](https://open.alipay.com/),进入控制台页面
- [创建移动应用](https://opendocs.alipay.com/open/200/105310),填写应用信息并提交审核
- 在应用详情页面的`能力列表`中添加`APP支付`功能,详情参考[添加应用功能](https://opendocs.alipay.com/open/200/105310#%E6%B7%BB%E5%8A%A0%E5%BA%94%E7%94%A8%E5%8A%9F%E8%83%BD)
- 进入开发设置完成加密方式、IP白名单等开发信息设置,详情参考[配置应用环境](https://opendocs.alipay.com/open/200/105310#%E9%85%8D%E7%BD%AE%E5%BA%94%E7%94%A8%E7%8E%AF%E5%A2%83)
- 添加功能和配置密钥后(获取公钥、私钥,用于服务器生成订单),将应用提交审核,详情参考[上线应用](https://opendocs.alipay.com/open/200/golive/)
- 应用上线后,完成签约才能在生产环境使用支付功能,详情参考[签约功能](https://opendocs.alipay.com/open/200/105314/)
更多信息详见支付宝官方文档 [App 支付接入准备](https://opendocs.alipay.com/open/204/105297/)
### 配置
打开项目的manifest.json文件,在“App模块配置”项的“Payment(支付)”下,勾选“支付宝支付”:
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/alipay_setup_manifest_info.png)
通过服务器生成支付订单,参考:
[生成支付订单示例(PHP)](https://github.com/dcloudio/H5P.Server/tree/master/payment/alipayrsa2)
[老版本"移动快捷支付"示例代码(PHP)](https://github.com/dcloudio/H5P.Server/tree/master/payment/alipay)
[生成支付订单示例(C#)](http://ask.dcloud.net.cn/article/197)
**注意**
- 支付宝支付没有绑定应用包名、签名信息,可以使用标准基座开发测试,正式发布前请提交云端打包并使用[自定义调试基座](https://ask.dcloud.net.cn/article/35115)
- 本地离线打包参考[Android平台支付宝模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/androidModuleConfig/pay?id=%e6%94%af%e4%bb%98%e5%ae%9d)[iOS平台支付宝模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/iOSModuleConfig/pay?id=%e6%94%af%e4%bb%98%e5%ae%9d)
### 服务器生成订单
在 App 端调用支付前,需在业务服务器生成支付订单,可参考:
- [生成支付订单示例(PHP)](https://github.com/dcloudio/H5P.Server/tree/master/payment/alipayrsa2)
- [老版本"移动快捷支付"示例代码(PHP)](https://github.com/dcloudio/H5P.Server/tree/master/payment/alipay)
- [生成支付订单示例(C#)](http://ask.dcloud.net.cn/article/197)
更多信息详见支付宝官方文档 [服务端接入流程](https://opendocs.alipay.com/open/204/01dcc0)
应用中调用支付功能(支付参数如下)
### 应用内发起支付
| 参数名称 | 参数说明 | 必须 |
|-------------|-------|-----|
| orderInfo | app 支付请求参数字符串,主要包含商户的订单信息,key=value 形式,以&连接。 | 是 |
- uni-app项目
调用 [uni.requestPayment(OBJECT)](https://uniapp.dcloud.io/api/plugins/payment?id=requestpayment) 发起支付,OBJECT参数中provider属性值固定为`alipay`、orderInfo属性值为订单对象
- 5+ App项目
调用 [plus.payment.request(channel, orderInfo, successCB, errorCB)](https://www.html5plus.org/doc/zh_cn/payment.html#plus.payment.request) 发起支付, channel参数为支付宝支付对象,orderInfo参数为订单对象
orderInfo 示例如下,参数说明见[请求参数说明](https://opendocs.alipay.com/open/204/105465/),orderInfo 的获取必须来源于服务端
#### 订单对象说明
支付宝支付订单对象为String类型,字符串数据格式为"application/x-www-form-urlencoded",即 key=value 形式,使用 & 符号连接。示例如下:
```
app_id=2015052600090779&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22seller_id%22%3A%22%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.02%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%22314VYGIAGG7ZOYY%22%7D&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA2&timestamp=2016-08-15%2012%3A12%3A15&version=1.0&sign=MsbylYkCzlfYLy9PeRwUUIg9nZPeN9SfXPNavUCroGKR5Kqvx0nEnd3eRmKxJuthNUx4ERCXe552EV9PfwexqW%2B1wbKOdYtDIb4%2B7PL3Pc94RZL0zKaWcaY3tSL89%2FuAVUsQuFqEJdhIukuKygrXucvejOUgTCfoUdwTi7z%2BZzQ%3D
```
* uni-app项目示例
更多信息详见支付宝官方文档 [APP支付请求参数说明](https://opendocs.alipay.com/open/204/105465/)
#### 示例代码
- uni-app项目
``` js
var orderInfo = ''; //从服务器获取的订单
uni.getProvider({
service: 'payment',
success: function (res) {
console.log(res.provider)
if (~res.provider.indexOf('alipay')) {
uni.requestPayment({
"provider": "alipay",
"orderInfo": orderInfo, //此处为服务器返回的订单信息字符串
success: function (res) {
var rawdata = JSON.parse(res.rawdata);
console.log("支付成功");
},
fail: function (err) {
console.log('支付失败:' + JSON.stringify(err));
}
})
}
}
service: 'payment',
success: function (res) {
console.log(res.provider)
if (~res.provider.indexOf('alipay')) {
uni.requestPayment({
"provider": "alipay", //固定值为"alipay"
"orderInfo": orderInfo, //此处为服务器返回的订单信息字符串
success: function (res) {
var rawdata = JSON.parse(res.rawdata);
console.log("支付成功");
},
fail: function (err) {
console.log('支付失败:' + JSON.stringify(err));
}
});
}
}
});
```
* 5+项目示例
- 5+ App项目
``` js
//获取支付渠道
var alipaySev = null;
plus.payment.getChannels(function(channels) {
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'alipay') {
alipaySev = channel;
var orderInfo = ''; //从服务器获取的订单
//获取支付宝支付对象
var alipaySev = null; // 支付宝支付对象
plus.payment.getChannels(function(channels){
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'alipay') {
alipaySev = channel;
}
}
}
}, function(e) {
console.log("获取支付渠道失败:" + e.message);
});
//发起支付
var statement = orderInfo; //此处为服务器返回的订单信息字符串
plus.payment.request(alipaySev, statement, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("支付成功");
}, function(e) {
console.log("支付失败:" + e.message);
//发起支付
plus.payment.request(alipaySev, orderInfo, function(result){
var rawdata = JSON.parse(result.rawdata);
console.log("支付成功");
}, function(e){
console.log("支付失败:" + JSON.stringify(e));
});
}, function(e){
console.log("获取支付渠道失败:" + JSON.stringify(e));
});
```
## 申请开通Paypal
[登录/注册](https://www.paypal.com/c2/signin)
### 开通
- 登录[paypal开发者中心](https://developer.paypal.com/developer/applications),创建应用
- 在 My Apps 中点击已创建的应用,获取ClientID(支付订单中需要)
- 添加return URL等相关配置,设置return URL时需注意:
+ 格式为“包名+://paypalpay”,必需全小写
+ 可添加多个return URL分别给Android和iOS平台使用
打开[paypal开发者中心](https://developer.paypal.com/developer/applications)
更多信息详见 [申请开通Paypal操作指南](https://uniapp.dcloud.io/app-payment-paypal-open)
如图,依次选择My Apps & Credentials -> Live(如果创建沙箱环境点击Sandbox) -> Create App
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_develop_center.png)
输入App Name,点击Create App
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_create_app.png)
### 配置
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“paypal支付”项并配置相关参数
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_setup_manifest_info.png)
创建完成后,点击AppName
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_setup_app_info.png)
**参数说明**
- returnURL_android
Android平台使用的return URL,必须与paypal开发者中心配置的值一致,否则无法调起支付
- returnURL_ios
iOS平台使用的return URL,必须与paypal开发者中心配置的值一致,否则无法调起支付
查看Client ID 以及 Secret
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_get_clientid.png)
> 提示:returnURL_android 和 returnURL_ios 可以相同,不相同时需要paypal开发者中心添加多个return URL
添加return URL并保存(必须使用小写字母)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_add_returnurl.png)
勾选Accept payments 并点击Advanced options选择详情配置(点击保存后生效)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_accept_payments.png)
### 服务器生成订单
在 App 端调用支付前,需在业务服务器生成支付订单并获取`orderId`,详情可参考paypal官方文档:[Create Order](https://developer.paypal.com/api/orders/v2/#orders_create)
勾选Log in with PayPal 并点击Advanced options选择详情配置(点击保存后生效)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_log_in.png)
------
### 应用内发起支付
## 使用Paypal支付
- uni-app项目
调用 [uni.requestPayment(OBJECT)](https://uniapp.dcloud.io/api/plugins/payment?id=requestpayment) 发起支付,OBJECT参数中provider属性值固定为`paypal`、orderInfo属性值为订单对象
- 5+ App项目
调用 [plus.payment.request(channel, orderInfo, successCB, errorCB)](https://www.html5plus.org/doc/zh_cn/payment.html#plus.payment.request) 发起支付, channel参数为paypal支付对象,orderInfo参数为订单对象
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“paypal支付”项并配置相关参数
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_setup_manifest_info.png)
配置说明:returnURL必须为paypal开发者中心配置的returnURL,否则无法调起支付
#### 订单对象参数说明
Object对象类型
| 属性 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| clientId | String | 是 | 客户端id,在paypal开发者中心创建应用时可获取 |
| currency | String | 否 | 币种,必须大写,取值参考paypal官方文档[Currency Codes](https://developer.paypal.com/docs/api/reference/currency-codes/) |
| environment | String | 是 | 运行环境,可取值sandbox/live,sandbox表示沙盒环境(用于开发测试),live表示线上环境(正式发布) |
| orderId | String | 是 | 订单id,服务器生成支付订单时可获取 |
| userAction | String | 否 | 按钮样式,可取值paynow/continue |
通过服务器生成支付订单并获取orderId(服务器获取订单信息详见[paypal API](https://developer.paypal.com/docs/api/orders/v2/))
应用中调用支付功能(支付参数如下)
| 参数名称 | 参数说明 | 必须 |
|-------------|-------|-----|
| clientId | 客户端id(获取方式详见paypal开通文档) | 是 |
| orderId | 订单id | 是 |
| environment | 运行环境(sandbox/live) |是 |
| userAction | 按钮样式(paynow/continue) | 否 |
| currency | [币种](https://developer.paypal.com/docs/api/reference/currency-codes/) (必须大写) | 否 |
* uni-app项目示例
#### 示例代码
- uni-app项目
``` js
//订单对象,从服务器获取
var orderInfo = {
"clientId": "clientId from paypal", //客户端id
"orderId": "orderId from server", //订单id
"userAction": "continue", // paynow/continue
"currency":"USD", // 币种
"environment":"sandbox", //运行环境 sandbox/live
};
uni.getProvider({
service: 'payment',
success: function (res) {
console.log(res.provider)
if (~res.provider.indexOf('paypal')) {
uni.requestPayment({
"provider": "paypal",
"orderInfo": {
"clientId": clientId, //客户端id
"orderId": orderId,//订单id
"userAction":"continue",// paynow/continue
"currency":"USD",//币种
"environment":"sandbox",//运行环境 sandbox/live
},
success: function (res) {
var rawdata = JSON.parse(res.rawdata);
console.log("orderId:" + rawdata.orderId);
},
fail: function (err) {
console.log('fail:' + JSON.stringify(err));
}
})
}
}
service: 'payment',
success: function (res) {
console.log(res.provider)
if (~res.provider.indexOf('paypal')) {
uni.requestPayment({
"provider": "paypal",
"orderInfo": orderInfo,
success: function (res) {
var rawdata = JSON.parse(res.rawdata);
console.log("orderId:" + rawdata.orderId);
},
fail: function (err) {
console.log('fail:' + JSON.stringify(err));
}
});
}
}
});
```
* 5+项目示例
``` js
- 5+ App项目
``` js
//订单对象,从服务器获取
var orderInfo = {
"clientId": "clientId from paypal", //客户端id
"orderId": "orderId from server", //订单id
"userAction":"continue", // paynow/continue
"currency":"USD", // 币种
"environment":"sandbox", //运行环境 sandbox/live
};
//获取支付渠道
var paypalSev = null;
plus.payment.getChannels(function(channels) {
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'paypal') {
paypalSev = channel;
plus.payment.getChannels(function(channels){
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'paypal') {
paypalSev = channel;
}
}
}
}, function(e) {
console.log("获取支付渠道失败:" + e.message);
});
//发起支付
var statement = {
"clientId": clientId, //客户端id
"orderId": orderId,//订单id
"userAction":"continue",// paynow/continue
"currency":"USD",//币种
"environment":"sandbox",//运行环境 sandbox/live
};
plus.payment.request(this.paypalSev, statement, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("orderId:" + rawdata.orderId);
}, function(e) {
console.log("支付失败:" + e.message);
//发起支付
plus.payment.request(paypalSev, orderInfo, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("支付成功");
}, function(e) {
console.log("支付失败:" + JSON.stringify(e));
});
}, function(e){
console.log("获取支付渠道失败:" + JSON.stringify(e));
});
```
应用发起支付完成后,返回订单id,服务器捕获或授权订单[详见paypal API](https://developer.paypal.com/docs/api/orders/v2/)
### 服务器授权
在App端发起支付完成后,返回订单id,并没有完成支付操作,需要在服务器授权或捕获订单完成扣款。
- 授权订单付款参考paypal官方文档:[Authorize payment for order](https://developer.paypal.com/api/orders/v2/#orders_authorize)
- 捕获订单付款参考paypal官方文档:[Capture payment for order](https://developer.paypal.com/api/orders/v2/#orders_capture)
## 申请开通Stripe
[登录/注册](https://dashboard.stripe.com/login)
### 开通
- [登录Stripe](https://dashboard.stripe.com/login)注册账号
* 注册账号后可获取开发测试的API密钥(公钥、私钥),注意:需[激活账户](https://dashboard.stripe.com/account/onboarding)获取正式的API密钥
* 设置[支付方式](https://dashboard.stripe.com/settings/payment_methods)
更多信息详见[申请开通Stripe操作指南](https://uniapp.dcloud.io/app-payment-stripe-open)
进入主页后,点击顶部继续按钮
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_home_page.png)
完善公司信息
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_company_info.png)
### 配置
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“paypal支付”项并配置相关参数
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_setup_manifest_info.png)
完善信息后,回到首页即可在右侧查看密钥
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_get_publishkey.png)
**参数说明**
- returnURL
Android平台使用,格式为"your-app://stripe"(示例 io.dcloud.test://stripe),'your-app'为应用的bundle id或其它自定义scheme,参考:[配置一个自定义页面内跳转协议 (URL Scheme)](https://ask.dcloud.net.cn/article/64)
### 服务器生成订单
在 App 端调用支付前,需在业务服务器生成[PaymentIntent](https://stripe.com/docs/api/payment_intents),详情可参考Stripe官方文档:[Add an endpoint](https://stripe.com/docs/payments/accept-a-payment?platform=android&ui=payment-sheet#add-server-endpoint)
------
激活账户前可通过POST请求Stripe官方沙盒服务器[https://stripe.com/docs/payments/accept-a-payment](https://stripe.com/docs/payments/accept-a-payment),生成测试PaymentIntent,示例如下:
## 使用Stripe支付
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“stripe支付”项并添加配置
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_setup_manifest_info.png)
配置说明:returnURL(只需配置iOS),格式为'your-app://stripe'(示例 hbuilder://stripe),'your-app'为应用的自定义scheme,参考:[配置一个自定义页面内跳转协议 (URL Scheme)](https://ask.dcloud.net.cn/article/64)
服务器生成支付订单[参考stripeAPI](https://stripe.com/docs/payments/accept-a-payment)
``` js
uni.request({
url: 'https://stripe-mobile-payment-sheet.glitch.me/checkout',//仅为示例
method: "POST",
success:(res) => {
``` js
uni.request({
url: 'https://stripe-mobile-payment-sheet.glitch.me/checkout',//仅为示例
method: "POST",
success:(res) => {
console.log("订单信息" + res.data);
var publishKey = res.data.publishableKey;
var paymentIntent = res.data.paymentIntent;
var customer = res.data.customer;
var ephemeralKey = res.data.ephemeralKey;
}
})
```
应用中调用支付功能(支付参数如下)
| 参数名称 | 参数说明 | 必须 |
|-------------|-------|-----|
| publishKey | 公钥(获取方式详见stripe开通文档) | 是 |
| paymentIntent | 订单信息 | 是 |
| merchantName | 商户名称 |是 |
| customer | 如果要设置支付方式供以后使用,则必须将它绑定到一个 Customer | 否 |
| ephemeralKey | EphemeralKey的作用是让 SDK 临时访问 Customer | 否 |
| isAllowDelay | 是否支持延迟支付,默认不支持(将 isAllowDelay 设置为 true 后可使用一些较慢的支付方式,例如 SEPA 借记和 Sofort 对于这些支付方式,只有当 PaymentSheet 完成后才能知道最终的付款状态是成功还是失败。如果您允许这样,则通知客户您已确认他们的订单,但收到付款后才能履行(例如,发货)订单。) | 否 |
}
});
```
### 应用内发起支付
- uni-app项目
调用 [uni.requestPayment(OBJECT)](https://uniapp.dcloud.io/api/plugins/payment?id=requestpayment) 发起支付,OBJECT参数中provider属性值固定为`stripe`、orderInfo属性值为订单对象
- 5+ App项目
调用 [plus.payment.request(channel, orderInfo, successCB, errorCB)](https://www.html5plus.org/doc/zh_cn/payment.html#plus.payment.request) 发起支付, channel参数为stripe支付对象,orderInfo参数为订单对象
注:customer与ephemeralKey必须成对出现,只传其一无效
* uni-app项目示例
``` js
uni.getProvider({
service: 'payment',
success: function(res) {
console.log(res);
if (~res.provider.indexOf('stripe')) {
uni.request({
url: 'https://stripe-mobile-payment-sheet.glitch.me/checkout',
method: "POST",
success: (res) => {
console.log(res.data);
uni.requestPayment({
#### 订单对象参数说明
Object对象类型
| 属性 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| customer | String | 否 | Stripe的[Customer](https://stripe.com/docs/api/customers)对象,如为同一用户执行定期重复性收款,并跟踪多笔收款 |
| ephemeralKey | String | 否 | Stripe的Customer Ephemeral Key,用于临时访问Customer |
| isAllowDelay | String | 否 | 是否支持延迟支付,默认不支持(将 isAllowDelay 设置为 true 后可使用一些较慢的支付方式,例如 SEPA 借记和 Sofort 对于这些支付方式,只有当 PaymentSheet 完成后才能知道最终的付款状态是成功还是失败。如果您允许这样,则通知客户您已确认他们的订单,但收到付款后才能履行(例如,发货)订单。) |
| merchantName | String | 是 | 商户名称 |
| paymentIntent | String | 是 | Stripe的[PaymentIntent](https://stripe.com/docs/api/payment_intents)对象,对应服务器生成的支付订单 |
| publishKey | String | 是 | 公钥,在Stripe注册账号后可获取 |
> 注意:customer与ephemeralKey必须成对出现,只传其一无效
#### 示例代码
- uni-app项目
``` js
//订单对象
var orderInfo = {
"customer": "Stripe的Customer", //Customer
"ephemeralKey": "Stripe的Customer Ephemeral Key", //临时访问Customer的Key
"isAllowDelay": true, //是否支持延迟支付 默认false
"merchantName": "DCloud", //商户名
"paymentIntent": "Stripe的PaymentIntent", //订单信息
"publishKey": "Public Key", //公钥
};
// 从Stripe测试服务器获取订单数据
uni.request({
url: 'https://stripe-mobile-payment-sheet.glitch.me/checkout',
method: "POST",
success: (res) => {
orderInfo = {
"customer": res.data.customer,
"ephemeralKey": res.data.ephemeralKey,
"isAllowDelay": true,
"merchantName": "DCloud",
"paymentIntent": res.data.paymentIntent,
"publishKey": res.data.publishableKey,
};
}
});
//...
//发起支付
uni.getProvider({
service: 'payment',
success: function(res) {
if (~res.provider.indexOf('stripe')) {
uni.requestPayment({
"provider": "stripe",
"orderInfo": {
"publishKey": res.data.publishableKey, //公钥
"paymentIntent": res.data.paymentIntent, //订单信息
"customer": res.data.customer, //支付方式等信息
"ephemeralKey": res.data.ephemeralKey, //信息key
"isAllowDelay": true, //是否支持延迟支付 默认false
"merchantName": "数字天堂", //商户名
},
"orderInfo": orderInfo,
success(res) {
console.log(res);
console.log("requestPayment Success: "+JSON.stringify(res));
},
fail(e) {
console.log(e);
console.log("requestPayment failed: "+JSON.stringify(e));
}
});
}
});
}
}
});
```
});
}
}
});
```
* 5+项目示例
``` js
//获取渠道
var stripeSev = null;
plus.payment.getChannels(function(channels) {
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'stripe') {
stripeSev = channel;
}
}
}, function(e) {
console.log("获取支付渠道失败:" + e.message);
});
//发起支付
var statement = {
"publishKey": publishKey, //公钥
"paymentIntent": paymentIntent,//订单加密信息
"merchantName":"数字天堂",//
"customer":customer,
"ephemeralKey":ephemeralKey,//
"isAllowDelay":true,//
};
plus.payment.request(stripeSev, statement, function(result) {
console.log("支付成功");
- 5+ App项目
``` js
//订单对象,从服务器获取
var orderInfo = {
"customer": "Stripe的Customer", //Customer
"ephemeralKey": "Stripe的Customer Ephemeral Key", //临时访问Customer的Key
"isAllowDelay": true, //是否支持延迟支付 默认false
"merchantName": "DCloud", //商户名
"paymentIntent": "Stripe的PaymentIntent", //订单信息
"publishKey": "Public Key", //公钥
};
//获取支付渠道
var stripeSev = null;
plus.payment.getChannels(function(channels){
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'stripe') {
stripeSev = channel;
}
}
//发起支付
plus.payment.request(stripeSev, orderInfo, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("支付成功");
}, function(e) {
console.log("支付失败:" + e.message);
console.log("支付失败:" + JSON.stringify(e));
});
```
}, function(e){
console.log("获取支付渠道失败:" + JSON.stringify(e));
});
```
......
## 申请开通微信支付
登录[微信开放平台](https://open.weixin.qq.com/),申请移动应用并开通支付功能,申请应用后可以获取 AppID
应用接入[微信商户平台](https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F),选择 App 支付
开通支付功能后可获取支付业务服务器配置数据:PARTNER(财付通商户号)、PARTNER_KEY(财付通密钥)、PAYSIGNKEY(支付签名密钥)
更多信息详见[移动应用开发](https://open.weixin.qq.com/cgi-bin/frame?t=home/app_tmpl&lang=zh_CN)
### 开通
- 登录[微信开放平台](https://open.weixin.qq.com/),添加移动应用并提交审核,审核通过后可获取应用ID(AppID,支付订单中需要使用)
- 在应用详情中`申请开通`微信支付功能,根据页面提示填写资料,提交审核
- 支付申请审核通过后将收到邮件,包括`商户号`(PartnerID,支付订单中需要使用)和`登录密码`
- 使用`商户号``登录密码`登录[微信商户平台](https://pay.weixin.qq.com/index.php/core/home/login),进入 “账户中心” > “API安全” > “设置APIv2密钥” 设置API密钥(用于服务器生成订单),详情参考[API证书及密钥](https://kf.qq.com/faq/180830UVRZR7180830Ij6ZZz.html)
## 使用微信支付
更多信息详见微信官方文档 [APP支付接入申请流程指引](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Pay/Vendor_Service_Center.html),服务器接入相关信息详见 [APP支付接入前准备](https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_5_1.shtml)
### 配置
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“微信支付”项
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/wxpay_setup_manifest_info.png)
通过服务器生成支付订单,参考:[微信支付示例(PHP)](https://github.com/dcloudio/H5P.Server/tree/master/payment/wxpayv3)
#### 参数说明
- appid
微信开放平台申请的应用ID(AppID)
- iOS平台通用链接(Universal Link)
在iOS平台微信支付使用的通用链接,必须与微信开放平台 “管理中心” > “应用详情” > “开发信息” 中的“Universal Links”项中配置一致,更多详情参考 [一键生成iOS通用链接](https://uniapp.dcloud.io/api/plugins/universal-links)
**注意**
- 配置后需提交云端打包后才能生效,真机运行时请使用[自定义调试基座](https://ask.dcloud.net.cn/article/35115)
- 本地离线打包参考[Android平台微信支付模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/androidModuleConfig/pay?id=%e5%be%ae%e4%bf%a1%e6%94%af%e4%bb%98)[iOS平台微信支付模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/iOSModuleConfig/pay?id=%e5%be%ae%e4%bf%a1%e6%94%af%e4%bb%98)
### 服务器生成订单
在 App 端调用支付前,需在业务服务器生成支付订单,可参考:
- [微信支付示例(PHP)](https://github.com/dcloudio/H5P.Server/tree/master/payment/wxpayv3)
更多信息详见微信支付官方文档 [APP支付统一下单](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1)
### 应用内发起支付
应用中调用支付功能(支付参数如下)
- uni-app项目
调用 [uni.requestPayment(OBJECT)](https://uniapp.dcloud.io/api/plugins/payment?id=requestpayment) 发起支付,OBJECT参数中provider属性值固定为`wxpay`、orderInfo属性值为订单对象
- 5+ App项目
调用 [plus.payment.request(channel, orderInfo, successCB, errorCB)](https://www.html5plus.org/doc/zh_cn/payment.html#plus.payment.request) 发起支付, channel参数为微信支付对象,orderInfo参数为订单对象
| 参数名称 | 参数说明 | 必须 |
|-------------|-------|-----|
| appid | 微信开放平台 - 应用 - AppId,注意和微信小程序、公众号 AppId 可能不一致 | 是 |
| noncestr | 随机字符串 | 是 |
| package | 固定值 |是 |
| partnerid | 微信支付商户号 | 是 |
| prepayid | 统一下单订单号 | 是 |
| timestamp | 时间戳(单位:秒) | 是 |
| sign | 签名,这里用的 MD5 签名 | 是 |
* uni-app项目示例
#### 订单对象参数说明
Object对象类型
| 属性 | 类型 | 必填 | 说明 |
| :--- | :--- | :--- | :--- |
| appid | String | 是 | 应用ID(AppID),请登录[微信开放平台](https://open.weixin.qq.com/)查看,注意与公众号的APPID不同 |
| partnerid | String | 是 | 微信支付分配的商户号(PartnerID)|
| prepayid | String | 是 | 预支付交易会话ID |
| package | String | 是 | 扩展字段,固定值"Sign=WXPay" |
| noncestr | String | 是 | 随机字符串,不长于32位 |
| timestamp | String | 是 | 时间戳,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数 |
| sign | String | 是 | 签名,详见[签名生成算法](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3) |
更多信息详见微信支付官方文档 [APP支付调起支付接口](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2)
#### 示例代码
- uni-app项目
``` js
//订单对象,从服务器获取
var orderInfo = {
"appid": "wx499********7c70e", // 应用ID(AppID)
"partnerid": "148*****52", // 商户号(PartnerID)
"prepayid": "wx202254********************fbe90000", // 预支付交易会话ID
"package": "Sign=WXPay", // 固定值
"noncestr": "c5sEwbaNPiXAF3iv", // 随机字符串
"timestamp": 1597935292, // 时间戳(单位:秒)
"sign": "A842B45937F6EFF60DEC7A2EAA52D5A0" // 签名,这里用的 MD5 签名
};
uni.getProvider({
service: 'payment',
success: function (res) {
console.log(res.provider)
if (~res.provider.indexOf('wxpay')) {
uni.requestPayment({
"provider": "wxpay",
"orderInfo": {
"appid": "wx499********7c70e", // 微信开放平台 - 应用 - AppId,注意和微信小程序、公众号 AppId 可能不一致
"noncestr": "c5sEwbaNPiXAF3iv", // 随机字符串
"package": "Sign=WXPay", // 固定值
"partnerid": "148*****52", // 微信支付商户号
"prepayid": "wx202254********************fbe90000", // 统一下单订单号
"timestamp": 1597935292, // 时间戳(单位:秒)
"sign": "A842B45937F6EFF60DEC7A2EAA52D5A0" // 签名,这里用的 MD5 签名
},
success: function (res) {
var rawdata = JSON.parse(res.rawdata);
console.log("支付成功");
},
fail: function (err) {
console.log('支付失败:' + JSON.stringify(err));
}
})
}
}
service: 'payment',
success: function (res) {
console.log(res.provider)
if (~res.provider.indexOf('wxpay')) {
uni.requestPayment({
"provider": "wxpay", //固定值为"wxpay"
"orderInfo": orderInfo,
success: function (res) {
var rawdata = JSON.parse(res.rawdata);
console.log("支付成功");
},
fail: function (err) {
console.log('支付失败:' + JSON.stringify(err));
}
});
}
}
});
```
* 5+项目示例
- 5+ App项目
``` js
//订单对象,从服务器获取
var orderInfo = {
"appid": "wx499********7c70e", // 应用ID(AppID)
"partnerid": "148*****52", // 商户号(PartnerID)
"prepayid": "wx202254********************fbe90000", // 预支付交易会话ID
"package": "Sign=WXPay", // 固定值
"noncestr": "c5sEwbaNPiXAF3iv", // 随机字符串
"timestamp": 1597935292, // 时间戳(单位:秒)
"sign": "A842B45937F6EFF60DEC7A2EAA52D5A0" // 签名,这里用的 MD5 签名
};
//获取支付渠道
var wxpaySev = null;
plus.payment.getChannels(function(channels) {
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'wxpay') {
wxpaySev = channel;
}
}
}, function(e) {
console.log("获取支付渠道失败:" + e.message);
});
//发起支付
var statement = {
"appid": "wx499********7c70e", // 微信开放平台 - 应用 - AppId,注意和微信小程序、公众号 AppId 可能不一致
"noncestr": "c5sEwbaNPiXAF3iv", // 随机字符串
"package": "Sign=WXPay", // 固定值
"partnerid": "148*****52", // 微信支付商户号
"prepayid": "wx202254********************fbe90000", // 统一下单订单号
"timestamp": 1597935292, // 时间戳(单位:秒)
"sign": "A842B45937F6EFF60DEC7A2EAA52D5A0" // 签名,这里用的 MD5 签名
};
plus.payment.request(wxpaySev, statement, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("支付成功");
}, function(e) {
console.log("支付失败:" + e.message);
plus.payment.getChannels(function(channels){
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'wxpay') {
wxpaySev = channel;
}
}
//发起支付
plus.payment.request(wxpaySev, orderInfo, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("支付成功");
}, function(e) {
console.log("支付失败:" + JSON.stringify(e));
});
}, function(e){
console.log("获取支付渠道失败:" + JSON.stringify(e));
});
```
......@@ -2,8 +2,8 @@ App端支付模块封装了市场上主流的三方支付平台SDK,提供JS AP
|项目类型|API|
|:-|:-|
|uni-app|[uni.requestPayment](/api/plugins/payment?id=requestpayment)|
|5+ App|[plus.payment.*](https://www.html5plus.org/doc/zh_cn/payment.html)
|uni-app|[uni.requestPayment(OBJECT)](api/plugins/payment?id=requestpayment)|
|5+ App/Wap2App|[plus.payment.*](https://www.html5plus.org/doc/zh_cn/payment.html)
如果服务端使用[uniCloud](https://uniapp.dcloud.io/uniCloud/README),官方提供了[uniPay](https://uniapp.dcloud.io/uniCloud/unipay)云端统一支付服务,极大提升支付业务的开发效率,强烈推荐给开发者使用,参考示例:[https://ext.dcloud.net.cn/plugin?id=1835](https://ext.dcloud.net.cn/plugin?id=1835)
......@@ -18,14 +18,14 @@ App端支付模块封装了市场上主流的三方支付平台SDK,提供JS AP
- 在客户端调用API进行支付
支持的三方支付平台:
- [Apple应用内支付](https://uniapp.dcloud.io/tutorial/app-payment-aip)
- [Apple应用内支付](https://uniapp.dcloud.io/app-payment-aip)
HBuilderX1.0.0+版本支持
- [支付宝支付](https://uniapp.dcloud.io/tutorial/app-payment-alipay)
- [微信支付](https://uniapp.dcloud.io/tutorial/app-payment-weixin)
- [Paypal支付](https://uniapp.dcloud.io/tutorial/app-payment-paypal)
- [支付宝支付](https://uniapp.dcloud.io/app-payment-alipay)
- [微信支付](https://uniapp.dcloud.io/app-payment-weixin)
- [Paypal支付](https://uniapp.dcloud.io/app-payment-paypal)
HBuilderX3.3.7+版本支持
- [Stripe支付](https://uniapp.dcloud.io/tutorial/app-payment-stripe)
- [Stripe支付](https://uniapp.dcloud.io/app-payment-stripe)
HBuilderX3.3.7+版本支持
- [Google支付](https://uniapp.dcloud.io/tutorial/app-payment-google)
- [Google支付](https://uniapp.dcloud.io/app-payment-google)
HBuilderX3.3.7+版本支持
### 开通
- 登录[DCloud开发者中心](https://dev.dcloud.net.cn/),通过实名认证后,可通过以下入口进入UniPush的Web控制台进行配置
+ HBuilderX中打开项目的manifest.json文件,在“App模块配置”项的“Push(消息推送)”->“UniPush”下点击`配置`
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/push/unipush-hx-config.png)
+ 登录[DCloud开发者中心](https://dev.dcloud.net.cn/),在“我创建的应用”列表中选择进入应用管理页面,点击左侧导航栏中的“Uni Push”
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/push/unipush-web-config.png)
- 在UniPush开通界面配置“Android包名”、“Android应用签名”、“iOS Bundle Id”等信息,点击“开通”
- 开通后可进行其它消息推送参数配置
+ Android平台
为了提升App离线送达率,建议配置厂商推送设置
+ iOS平台
需配置推送证书,在“UniPush”页面的“配置管理”->“应用配置”可上传推送证书
更多信息详见 [UniPush开通指南](https://ask.dcloud.net.cn/article/35716)
### 配置
在manifest.json文件“App模块配置”项的“Push(消息推送)”下,勾选“UniPush”
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/push/unipush-manifest.png)
**注意**
- UniPush模块需要开通后才能提交云端打包,否则会提示错误,如未开通UniPush不要勾选此模块
- UniPush推送功能需要提交云端打包后才能生效,真机运行时请使用[自定义调试基座](https://ask.dcloud.net.cn/article/35115)
- 本地离线打包参考[Android平台UniPush模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/androidModuleConfig/push)[iOS平台UniPush模块配置](https://nativesupport.dcloud.net.cn/AppDocs/usemodule/iOSModuleConfig/push)
### 使用UniPush
- **uni-app项目详细使用教程请参考 [统一推送UniPush](https://uniapp.dcloud.io/unipush)**
- **5+ App、Wap2App项目详细使用教程请参考 [UniPush使用指南](https://ask.dcloud.net.cn/article/35622)**
......@@ -10,7 +10,7 @@
- 不能在 style 中引入字体文件
- 不能使用百分比布局,如`width:100%`
- 不支持在css里写背景图`background-image`,但可以使用image组件和层级来实现类似web中的背景效果。因为原生开发本身也没有web这种背景图概念
- 使用`image`标签,支持使用base64
- 使用`image`标签,支持使用base64,不支持svg格式图片
- nvue 的各组件在安卓端默认是透明的,如果不设置`background-color`,可能会导致出现重影的问题
- 文字内容,必须只能在`text`组件下,`text`组件不能换行写内容,否则会出现无法去除的周边空白
- 只有`text`标签可以设置字体大小,字体颜色
......
......@@ -48,5 +48,4 @@ const package = require('packageName')
* 为多端兼容考虑,建议优先从 [uni-app插件市场](https://ext.dcloud.net.cn/) 获取插件。直接从 npm 下载库很容易只兼容H5端。
* 非 H5 端不支持使用含有 dom、window 等操作的 vue 组件和 js 模块,安装的模块及其依赖的模块使用的 API 必须是 uni-app 已有的 [API](/api/)(兼容小程序 API),比如:支持[高德地图微信小程序 SDK](https://www.npmjs.com/package/amap-wx)。类似[jQuery](https://www.npmjs.com/package/jquery) 等库只能用于H5端。
* node_modules 目录必须在项目根目录下。不管是cli项目还是HBuilderX创建的项目。
* 支持安装 mpvue 组件,但npm方式不支持小程序自定义组件(如 wxml格式的vant-weapp),使用小程序自定义组件请参考:[小程序组件支持](/tutorial/miniprogram-subject#小程序自定义组件支持)
* 关于ui库的获取,详见[多端UI库](https://ask.dcloud.net.cn/article/35489)
\ No newline at end of file
......@@ -436,7 +436,7 @@ uni-app自带的web-view组件,是页面中新插入的一个子webview。获
20. 目前不支持在 nvue 页面使用 `typescript/ts`。
21. nvue 页面关闭原生导航栏时,想要模拟状态栏,可以[参考文章](https://ask.dcloud.net.cn/article/35111)。但是,仍然强烈建议在 nvue 页面使用原生导航栏。nvue 的渲染速度再快,也没有原生导航栏快。原生排版引擎解析`json`绘制原生导航栏耗时很少,而解析 nvue 的 js 绘制整个页面的耗时要大的多,尤其在新页面进入动画期间,对于复杂页面,没有原生导航栏会在动画期间产生整个屏幕的白屏或闪屏。
<!-- ## 组件生命周期
## 组件生命周期@componentlifecycle
``uni-app`` 组件支持的生命周期,与vue标准组件的生命周期相同。这里没有页面级的onLoad等生命周期:
......@@ -449,4 +449,4 @@ uni-app自带的web-view组件,是页面中新插入的一个子webview。获
|beforeUpdate|数据更新时调用,发生在虚拟 DOM 打补丁之前。[详见](https://cn.vuejs.org/v2/api/#beforeUpdate)|仅H5平台支持||
|updated|由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。[详见](https://cn.vuejs.org/v2/api/#updated)|仅H5平台支持||
|beforeDestroy|实例销毁之前调用。在这一步,实例仍然完全可用。[详见](https://cn.vuejs.org/v2/api/#beforeDestroy)|||
|destroyed|Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。[详见](https://cn.vuejs.org/v2/api/#destroyed)||| -->
\ No newline at end of file
|destroyed|Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。[详见](https://cn.vuejs.org/v2/api/#destroyed)|||
\ No newline at end of file
......@@ -91,7 +91,7 @@ ES6 API 的支持,详见如下表格部分(`x` 表示不支持,无特殊
|getOwnPropertyNames|||||
|getOwnPropertySymbols||||&nbsp;|
|Other|iOS8|iOS9|iOS10|Android|
|Other|iOS8|iOS9|iOS10|Android<5|
|:-|:-|:-|:-|:-|
|Symbol|||||
|Set|||||
......
......@@ -242,7 +242,7 @@ vue 是单页面应用,使页面局部刷新,不用每次跳转页面都要
[uni-app 项目支持 vue 3.0介绍,及升级指南](https://ask.dcloud.net.cn/article/37834)
`HBuilderX 3.2.5-alpha`新增在App平台支持 vue 3.0,至此 `uni-app` 项目对 vue 3.0 的支持情况如下:
`HBuilderX 3.2.5`新增在App平台支持 vue 3.0,至此 `uni-app` 项目对 vue 3.0 的支持情况如下:
- H5/PC Web平台支持,编译器升级为`vite`
- 小程序平台:支持vue 3.0开发,编译器依然是 `webpack`,正在升级`vite`中。
......
......@@ -27,29 +27,27 @@
* [云存储](uniCloud/storage.md)
* [腾讯云自定义登录](uniCloud/authentication.md)
* [腾讯云权限管理](uniCloud/policy-tcb.md)
* [客户端sdk](uniCloud/client-sdk.md)
* [uni-id用户体系](uniCloud/uni-id.md)
* 扩展能力
* [uni一键登录](uniCloud/univerify.md)
* [发送短信](uniCloud/send-sms.md)
* [前端网页托管](uniCloud/hosting.md)
* Redis扩展库
* [简介](uniCloud/redis-introduction.md)
* [费用说明](uniCloud/redis-buy.md)
* [开发文档](uniCloud/redis.md)
* [日志输出](uniCloud/cf-logger.md)
* [客户端sdk](uniCloud/client-sdk.md)
* 增强开源库
* [uni-config-center 配置中心](https://ext.dcloud.net.cn/plugin?id=4425)
* [uni-starter](https://ext.dcloud.net.cn/plugin?id=5057)
* [uni-admin](uniCloud/admin.md)
* [uni-upgrade-center App升级中心](uniCloud/upgrade-center.md)
* [uni-cloud-router](uniCloud/uni-cloud-router.md)
* [unipay 统一支付](uniCloud/unipay.md)
* [发送短信](uniCloud/send-sms.md)
* [uni一键登录](uniCloud/univerify.md)
* [uSearch 云端一体搜索](https://ext.dcloud.net.cn/plugin?id=3851)
* [uni-captcha 图形验证码](https://ext.dcloud.net.cn/plugin?id=4048)
* [uni-sec-check 内容安全](https://ext.dcloud.net.cn/plugin?id=5460)
* [统一发行页面](https://uniapp.dcloud.io/m3w)
* [uniCloud响应体规范](uniCloud/unicloud-response-format.md)
* [前端网页托管](uniCloud/hosting.md)
* Redis扩展库
* [简介](uniCloud/redis-introduction.md)
* [费用说明](uniCloud/redis-buy.md)
* [开发文档](uniCloud/redis.md)
* [日志输出](uniCloud/cf-logger.md)
* [同时连多服务空间](uniCloud/init.md)
* [uni-cloud-router](uniCloud/uni-cloud-router.md)
* [案例](uniCloud/resource.md)
* [开发者使用反馈](uniCloud/feedback.md)
* [DCloud行业认证服务商](https://ask.dcloud.net.cn/article/39388)
......
......@@ -14,12 +14,76 @@
## 名词解释
- Ticket(票据):由云函数调用`createTicket`返回的票据,用于客户端使用票据进行登录操作
- Ticket(票据):由云函数调用`auth.createTicket`返回的票据,用于客户端使用票据进行登录操作
- 匿名登录:用户未进行登录操作的状态
- 短期访问令牌:用户身份的凭证(access token),调用`signInWithTicket`或者`linkAndRetrieveDataWithTicket`之后会自动进行存储
## uniCloud.customAuth()
## 云函数接口
### uniCloud.customAuth@cloud-custom-auth
**重要:自HBuilderX 2.9.12起,此接口由uniCloud.auth调整为uniCloud.customAuth,短时间内仍会兼容uniCloud.auth**
获取登录对象
**示例代码**
```js
const auth = uniCloud.customAuth()
```
### auth.createTicket@cloud-create-ticket
云端根据用户id创建票据用于客户端登录到对应的云厂商
**接口形式**
```js
auth.createTicket(String uid, Object options)
```
**参数说明**
|字段 |类型 |是否必填 |说明 |
|:-: |:-: |:-: |:-: |
|uid |string |是 |应用内的用户唯一id |
|options.refresh|number |否 |access_token的刷新时间,默认一小时 |
|options.expire |number |否 |access_token的过期时间 |
**示例代码**
```js
let uid = '123456';
const ticket = uniCloud.customAuth().createTicket(uid, {
refresh: 10 * 60 * 1000 // 每十分钟刷新一次登录态, 默认为一小时
});
```
### auth.getUserInfo@cloud-get-user-info
任何方式登录成功后,可以调用 `getUserInfo` 获得用户的身份信息。
**响应参数**
|字段 |类型 |是否必备 |说明 |
|:-: |:-: |:-: |:-: |
|uid |string |是 |用户在云厂商的唯一ID |
|customUserId |string |否 |用户使用自定义登录传入的用户Id |
**示例代码**
```js
const {
uid,
customUserId
} = await auth.getUserInfo()
```
## 客户端接口
### uniCloud.customAuth@custom-auth
**重要:自HBuilderX 2.9.12起,此接口由uniCloud.auth调整为uniCloud.customAuth,短时间内仍会兼容uniCloud.auth**
......@@ -42,9 +106,9 @@ const auth = uniCloud.customAuth()
auth.signInAnonymously()
``` -->
## auth.signInWithTicket()@signinwithticket
### auth.signInWithTicket@signinwithticket
使用,详细描述参考[登录流程](#cloudtoken)
使用云函数接口createTicket返回的票据进行登录,详细描述参考[登录流程](#cloudtoken)
**示例代码**
......@@ -58,7 +122,7 @@ auth.signInWithTicket('YourTicket').then(() => {
})
```
## auth.getLoginState()
### auth.getLoginState@get-login-state
开发者可以通过 `getLoginState()` 来获取当前的登录状态,调用 `getLoginState()` 后,SDK 会识别本地是否有登录状态,如果有,则会尝试刷新登录状态,若刷新登录状态成功,则会返回新的登录状态,否则返回 `undefined`
......@@ -74,16 +138,16 @@ auth.getLoginState().then(loginState => {
})
```
## auth.getUserInfo()
### auth.getUserInfo@get-user-info
任何方式登录成功后,可以调用 `getUserInfo` 获得用户的身份信息。
**响应参数**
|字段 |类型 |是否必备 |说明 |
|:-: |:-: |:-: |:-: |
|uid |string |是 |用户在云开发的唯一ID |
|customUserId |string |否 |用户使用自定义登录传入的用户Id |
|字段 |类型 |是否必备 |说明 |
|:-: |:-: |:-: |:-: |
|uid |string |是 |用户在云厂商的唯一ID |
|customUserId |string |否 |用户使用自定义登录传入的用户Id |
**示例代码**
......
......@@ -1140,7 +1140,7 @@ let res = await collection.where({name: dbCmd.eq('hey')}).update({
### 更新并返回更新后的数据@update-and-return
> 新增于HBuilderX 3.2.0-alpha
> 新增于HBuilderX 3.2.0
此接口仅会操作一条数据,有多条数据匹配的情况下会只更新匹配的第一条并返回
......@@ -1996,7 +1996,10 @@ exports.main = async (event) => {
db.collection('scores').aggregate()
```
**注意:聚合操作实例仅用于查询,不可执行增删改操作。在聚合操作实例上只能使用聚合操作方法,不能使用where/orderBy等基础方法,where需改为match,orderBy应使用sort实现,细节请阅读下方聚合操作文档。**
**注意:**
- 聚合操作实例仅用于查询,不可执行增删改操作。在聚合操作实例上只能使用聚合操作方法,不能使用where/orderBy等基础方法,where需改为match,orderBy应使用sort实现,细节请阅读下方聚合操作文档。
- 聚合操作在大数据量下性能不如简单查询,请根据自身业务选择合适的用法
云函数中使用时切勿复用aggregate实例,容易引发Bug。
......@@ -5609,7 +5612,7 @@ let res = await db.collection('sales').aggregate()
```js
{ _id: 1, sales: 5 }
{ _id: 2, sales: 1 }
{ _id: 3, sales: -6 }
{ _id: 3, sales: -4 }
```
#### ln
......
## 简介@intro
云函数是运行在云端的 `JavaScript` 代码,和普通的`Node.js`开发一样,熟悉`Node.js`的开发者可以直接上手
云函数是运行在云端的 `JavaScript` 代码,是基于 `Node.js` 的扩展
如下是将传入的两个参数求和并返回客户端的云函数代码示例:
在常规的 `Node API` 基础上,uniCloud的云函数环境内置了`uniCloud`对象,这个对象内置了网络、数据库等各种API。开发者未学习过 `Node.js` 也没有关系,只需要看uniCloud的文档,掌握这个`uniCloud`对象的API即可。
每个云函数是一个js包,在云函数被调用时,由serverless调度系统分配硬件资源启动一个node环境来运行这个云函数。
在HBuilderX中可以新建云函数。
![](https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/a18b3bb0-53d8-11eb-8ff1-d5dcf8779628.jpg)
新建的云函数是一个目录,其中有`index.js`入口文件。
一个最简单的云函数只需要这个`index.js`文件,在里面编写代码即可。
云函数的配置文件和npm规范相同,在云函数目录下可新建一个package.json来存放配置。uniCloud云函数扩展了package.json,增加了一些特有的配置项。[详见](/uniCloud/cf-functions?id=packagejson)
云函数中如果要使用其他服务(比如mysql数据库、redis等),可以按照nodejs的写法即可。但注意这些非uniCloud数据库和云函数运行环境不在一起,访问速度受影响。
云函数启动后环境会保留一段时间(如15分钟),超过保留期后若该云函数一直没有被再调用,那这个环境会被释放。
所以云函数有冷启动的概念,由于js环境的启动要比php和java更快,所以js适合serverless方式。
**注意事项**
- 不同项目使用同一个服务空间时,不可使用同名云函数,可以在uniCloud的web控制台手动删除重名云函数释放函数名。
- 在HBuilderX创建云函数时,如果新云函数与服务器上已存在同名云函数,会用新函数覆盖。
- 单个云函数大小限制为10M(包含node_modules)
- 云函数内使用commonjs规范,不可使用import、export,参考:[commonjs模块](http://nodejs.cn/api/modules.html#modules_modules_commonjs_modules)
- 服务商为阿里云时,暂不可使用相对路径读取文件(比如`fs.readFileSync('./info.txt')`),可以使用绝对路径`fs.readFileSync(path.resolve(__dirname,'./info.txt'))`
## 云函数的分类
云函数有若干子概念,包括 普通云函数、公共模块、clientDB的action云函数、uniCloud扩展库。
HBuilderX中uniCloud项目的云函数均为项目的uniCloud/cloudfunctions目录下,目录结构如下:
<pre v-pre="" data-lang="">
<code class="lang-" style="padding:0">
|——— cloudfunctions 云函数目录
| │───common 云函数公用模块目录 <a target="_blank" href="https://uniapp.dcloud.net.cn/uniCloud/cf-common">详情</a>
| | └──hello-common 云函数公用模块
| | │──index.js 公用模块代码
| | └──package.json 公用模块package.json
| │───uni-clientDB-actions
| │ └──new_action.js clientDB action代码 <a target="_blank" href="https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=action">详情</a>
| └───function-name 云函数目录
| │──index.js 云函数代码
| └──package.json 包含云函数的配置信息,如url化、定时设置、内存等内容 <a target="_blank" href="https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=packagejson">详情</a>
</code>
</pre>
- 公共模块用于不同的云函数抽取和共享相同代码,详见[公共模块文档](/uniCloud/cf-functions?id=公共模块)
- action云函数是为了弥补客户端直接操作数据库的局限而设计的,详见[clientDB action文档](/uniCloud/clientdb?id=action)
- uniCloud扩展库是为了裁剪和控制云函数体积而设计的,详见[uniCloud扩展库](/uniCloud/cf-functions?id=扩展库)
## 云函数的入参和返回值
### 入参
客户端请求云函数时,云函数通过入参接收客户端数据,通过头信息上下文获取客户端信息,经过业务逻辑处理后给客户端返回结果。
假使客户端代码调用云函数test,并传递了{a:1,b:2}的数据,
```js
// 客户端调用云函数并传递参数
uniCloud.callFunction({
name: 'test',
data: {a:1,b:2}
})
.then(res => {});
```
那么云函数侧的代码如下,将传入的两个参数求和并返回客户端:
```js
// 云函数index.js入口文件代码
'use strict';
exports.main = async (event, context) => {
//event为客户端上传的参数
return {
sum:event.a + event.b
}
sum:event.a + event.b
} // 通过return返回结果给客户端
}
```
云函数的传入参数有两个,一个是`event`对象,一个是`context`对象。`event`指的是触发云函数的事件,当客户端调用云函数时,`event`就是客户端调用云函数时传入的参数。`context` 对象包含了此处调用的调用信息和运行状态,可以用它来了解服务运行的情况。`uniCloud`会自动将客户端的操作系统(`os`)、运行平台(`platform`)、应用信息(`appid`)等注入`context`中,开发者可通过`context`获取每次调用的上下文,如下是一个示例:
云函数的传入参数有两个,一个是`event`对象,一个是`context`对象。
- `event`指的是触发云函数的事件,当客户端调用云函数时,`event`就是客户端调用云函数时传入的参数。
- `context` 对象包含了此处调用的调用信息和运行状态,可以用它来了解服务运行的情况。`uniCloud`会自动将客户端的操作系统(`os`)、运行平台(`platform`)、应用信息(`appid`)等注入`context`中,开发者可通过`context`获取每次调用的上下文。
如下是一个示例:
```js
'use strict';
......@@ -28,53 +100,27 @@ exports.main = async (event, context) => {
let spaceInfo = context.SPACEINFO // 当前环境信息 {spaceId:'xxx',provider:'tencent'}
// 以下四个属性只有使用uni-app以callFunction方式调用才能获取
let os = context.OS //客户端操作系统,返回值:android、ios 等
let platform = context.PLATFORM //运行平台,返回值为 mp-weixin、app-plus等
let platform = context.PLATFORM //运行平台,返回值为 mp-weixin、app-plus等。注意:vue3版本uni-app将app-plus修改为了app,此处为保证旧版本兼容性未进行统一,推荐后续在业务中都使用app作为客户端标识
let appid = context.APPID // manifest.json中配置的appid
let deviceId = context.DEVICEID // 客户端标识,新增于HBuilderX 3.1.0,同uni-app客户端getSystemInfo接口获取的deviceId
//... //其它业务代码
}
```
云函数url化的场景下无法获取`context.OS``context.PLATFORM``context.APPID``context.CLIENTUUID`
**注意:下面所有的“客户端”均是相对于云函数而言,如果你使用自己的服务器调用云函数此时客户端是指你的服务器**
>在云函数URL化的场景无法获取客户端平台信息,可以在调用依赖客户端平台的接口接口之前(推荐在云函数入口)通过修改context.PLATFORM手动传入客户端平台信息供其他插件(如:uni-id)使用
#### 获取用户token@client-token
如果客户端在storage内存储了uni_id_token,在使用callFunction请求云函数时会自动将此token传递到云端,云端可以通过以下方式获取
```js
'use strict';
exports.main = async (event, context) => {
context.PLATFORM = 'app-plus'
let token = event.uniIdToken // 客户端uni-id token
}
```
云函数中如果要使用其他服务(比如mysql数据库、redis等),可以按照nodejs的写法即可。但注意这些非uniCloud数据库和云函数运行环境不在一起,访问速度受影响。
**注意事项**
- 服务商为阿里云时,暂不可使用相对路径读取文件(比如`fs.readFileSync('./info.txt')`),可以使用绝对路径`fs.readFileSync(path.resolve(__dirname,'./info.txt'))`
- event大小不可超过100kb
## API列表
云函数支持nodejs和js的标准API,但除了标准API外,uniCloud扩展了一批新API,实际开发中更常用的是uniCloud的扩展API。见下:
|API |描述 |
|-- |-- |
|uniCloud.callFunction() |客户端调用云函数 [见下](uniCloud/cf-functions?id=clientcallfunction);云函数中调用另一个云函数 [见下](uniCloud/cf-functions?id=callbyfunction) |
|uniCloud.database() |云数据库对象 [详情](uniCloud/cf-database.md) |
|uniCloud.uploadFile() |云函数上传文件到云存储 [详情](uniCloud/storage?id=clouduploadfile) |
|uniCloud.downloadFile() |云函数下载云存储的文件到云函数运行环境 [详情](uniCloud/storage?id=clouddownloadfile) |
|uniCloud.deleteFile() |云函数删除云存储的文件 [详情](uniCloud/storage?id=clouddeletefile) |
|uniCloud.getTempFileURL() |获取云存储文件的临时路径 [详情](uniCloud/storage?id=cloudgettempfileurl) |
|uniCloud.httpclient |云函数中通过http连接其他系统 [见下](uniCloud/cf-functions?id=httpclient) |
|uniCloud.logger |云函数中打印日志到uniCloud日志记录系统(非HBuilderX控制台)[详情](uniCloud/cf-logger) |
|uniCloud.sendSms() |发送短信 [详见](uniCloud/send-sms.md) |
## 特殊属性
**注意:下面所有的“客户端”均是相对于云函数而言,如果你使用自己的服务器调用云函数此时客户端是指你的服务器**
### 获取客户端IP@clientip
#### 获取客户端IP@clientip
```js
'use strict';
......@@ -83,7 +129,7 @@ exports.main = async (event, context) => {
}
```
### 获取客户端user-agent@client-user-agent
#### 获取客户端user-agent@client-user-agent
```js
'use strict';
......@@ -92,7 +138,7 @@ exports.main = async (event, context) => {
}
```
### 获取服务空间信息@context-space-info
#### 获取服务空间信息@context-space-info
```js
'use strict';
......@@ -101,7 +147,7 @@ exports.main = async (event, context) => {
}
```
### 获取云函数调用来源@context-source
#### 获取云函数调用来源@context-source
```js
'use strict';
......@@ -115,9 +161,8 @@ exports.main = async (event, context) => {
}
```
### 其他客户端信息@client-info
#### 其他客户端信息@client-info
**注意:**
- 以下四个属性只有使用uni-app以callFunction方式调用才能获取,由客户端传递到云函数
- 实际业务中务必验证一下前端传来的数据的合法性
......@@ -125,19 +170,105 @@ exports.main = async (event, context) => {
'use strict';
exports.main = async (event, context) => {
let os = context.OS //客户端操作系统,返回值:android、ios 等
let platform = context.PLATFORM //运行平台,返回值为 mp-weixin、app-plus等
let platform = context.PLATFORM //运行平台,返回值为 mp-weixin、app-plus等。注意:vue3版本uni-app将app-plus修改为了app,此处为保证旧版本兼容性未进行统一,推荐后续在业务中都使用app作为客户端标识
let appid = context.APPID // manifest.json中配置的appid
let deviceId = context.DEVICEID // 客户端标识,新增于HBuilderX 3.1.0,同uni-app客户端getSystemInfo接口获取的deviceId
}
```
**注意事项**
- event大小不可超过100kb
- 云函数url化的场景下无法获取`context.OS``context.PLATFORM``context.APPID``context.DEVICEID`
>在云函数URL化的场景无法获取客户端平台信息,可以在调用依赖客户端平台的接口接口之前(推荐在云函数入口)通过修改context.PLATFORM手动传入客户端平台信息供其他插件(如:uni-id)使用
例:
```js
exports.main = async (event, context) => {
context.PLATFORM = 'app-plus'
}
```
### 返回格式-uniCloud响应体规范@resformat
云函数对返回结果没有强制约定,一般返回格式为json格式。
但为了方便拦截器统一处理返回值,捕获异常或弹框提示,uniCloud定义了`uniCloud响应体规范`,推荐开发者使用。
`uniCloud响应体规范`(uniCloud response format),是DCloud制定的、服务器给客户端返回json数据的一种建议格式。后续uni-id、uni-pay、clientDB等均会调整为此结构
**由来**
uniCloud服务器给客户端返回的数据格式是json,但json的格式具体是什么没有约定。比如返回错误码,是叫code还是叫errCode?错误内容是message还是errMsg?内容的国际化如何处理?
如果没有一套统一的格式,在客户端将无法编写有效的网络拦截器,无法统一处理错误。
同时如果不同的插件,云端返回的数据格式千差万别,那使用者整合这些插件也会非常麻烦。国际化更无法落地。
为此DCloud推出了`uniCloud响应体规范`
为尽可能的与uni-app前端的API错误回调风格接近,uniCloud响应体规范定义的云端返回信息内应包含`errCode``errMsg`,示例如下
```js
// 失败返回值
{
errCode: 'uni-id-account-banned',
errMsg: '账号被禁用'
}
// 成功返回值
{
errCode: 0,
errMsg: '登录成功',
uid: 'xxx' // 其他信息
}
```
- errCode
errCode在成功时应返回数字`0`,失败时应返回一个以插件id开头的“字符串”,每个单词以连字符(`-`)分割。做出这样的规定是为了防止不同插件之间出现重复错误码
`'uni-id-account-banned'`错误码为例,`uni-id`为插件id,`account-banned`为错误缩写。
如果业务开发的代码并不发布插件市场,那么为了避免下载了一个市场的插件产生冲突,推荐使用不包含“-”的字符串来做errCode(插件市场的所有插件ID必须包含“-”)。
后续uniCloud会提供自动根据errCode对errMsg进行国际化处理的功能,开发者仅需保证云函数返回值满足`uniCloud响应体规范`即可。
- errMsg
errMsg用于存放具体错误信息,包括展示给开发者、终端用户的错误信息
## uniCloud API列表
云函数支持js和nodejs的标准API,但除了标准API外,uniCloud扩展了一批新API,实际开发中更常用的是uniCloud的扩展API。见下:
|API |描述 |
|-- |-- |
|uniCloud.callFunction() |客户端调用云函数 [见下](uniCloud/cf-functions?id=clientcallfunction);云函数中调用另一个云函数 [见下](uniCloud/cf-functions?id=callbyfunction) |
|uniCloud.database() |云数据库对象 [详情](uniCloud/cf-database.md) |
|uniCloud.databaseJQL() |云函数中使用JQL语法操作数据库 [详见](uniCloud/jql-cloud.md),由扩展库提供 |
|uniCloud.redis() |使用redis [详见](uniCloud/redis.md),由扩展库提供 |
|uniCloud.uploadFile() |云函数上传文件到云存储 [详情](uniCloud/storage?id=clouduploadfile) |
|uniCloud.downloadFile() |云函数下载云存储的文件到云函数运行环境 [详情](uniCloud/storage?id=clouddownloadfile) |
|uniCloud.deleteFile() |云函数删除云存储的文件 [详情](uniCloud/storage?id=clouddeletefile) |
|uniCloud.getTempFileURL() |获取云存储文件的临时路径 [详情](uniCloud/storage?id=cloudgettempfileurl) |
|uniCloud.httpclient |云函数中通过http连接其他系统 [见下](uniCloud/cf-functions?id=httpclient) |
|uniCloud.logger |云函数中打印日志到uniCloud日志记录系统(非HBuilderX控制台)[详情](uniCloud/cf-logger) |
|uniCloud.customAuth() |使用云厂商自定义登录,仅腾讯云支持[详情](uniCloud/authentication.md?id=cloud-custom-auth) |
|uniCloud.sendSms() |发送短信 [详见](uniCloud/send-sms.md) |
|uniCloud.getPhoneNumber() |获取一键登录手机号 [详见](uniCloud/univerify.md?id=cloud) |
|uniCloud.init() |获取指定服务空间的uniCloud实例 [详见](uniCloud/uniCloud/concepts/space.md?id=multi-space) |
## 访问数据库
云函数中支持访问本服务空间下的数据库,调用方式详见[规范](uniCloud/cf-database.md)
云函数中支持访问本服务空间下的、或经授权的其他服务空间下的,数据库,调用方式详见[规范](uniCloud/cf-database.md)
## 访问HTTP服务@httpclient
## 访问其他HTTP服务@httpclient
`uniCloud`提供了`uniCloud.httpclient`供开发者使用。无需额外依赖,就可以请求任何 HTTP 和 HTTPS 协议的 Web 服务。`uniCloud.httpclient`返回的是一个[urllib实例](https://github.com/node-modules/urllib)
云函数中如需要请求其他http服务,则使用`uniCloud.httpclient`。无需额外依赖,就可以请求任何 HTTP 和 HTTPS 协议的 Web 服务。`uniCloud.httpclient`返回的是一个[urllib实例](https://github.com/node-modules/urllib)
**uniCloud.httpclient.request(URL,requestOptions)**
......@@ -262,12 +393,15 @@ Tips:
## 扩展库
uniCloud内置了一些扩展库,但是为了减小云函数体积,并不会对所有云函数默认开启。如需使用需要在云函数的package.json内的extensions字段下配置。
uniCloud的api中,有些api对应的实现,其源码体积较大,且这些功能并不是每一个云函数都会使用。为了方面开发者控制云函数的体积,设计了`uniCloud扩展库`的概念。
开发者可以在云函数目录下的package.json内的extensions字段下配置这个云函数引用哪些扩展库。未引用扩展库的,使用uniCloud相应api时会报错。
**目前支持的扩展库有以下几个**
<!-- - 用于在云函数内使用JQL语法操作数据库的JQL扩展库[uni-cloud-jql],参考:[JQL扩展库](uniCloud/jql-cloud.md) -->
- 用于在云函数内使用redis的redis扩展库[uni-cloud-redis],参考:[redis扩展库](uniCloud/redis.md)
- JQL扩展库[uni-cloud-jql]:用于在云函数内使用JQL语法操作数据库,详见:[JQL扩展库](uniCloud/jql-cloud.md)
- redis扩展库[uni-cloud-redis]:用于在云函数内使用redis,详见:[redis扩展库](uniCloud/redis.md)
以下是一个开启了Redis扩展库的云函数package.json示例,注意此文件不支持注释,下方示例中的注释仅为演示
......@@ -285,6 +419,8 @@ uniCloud内置了一些扩展库,但是为了减小云函数体积,并不会
## 客户端调用云函数@clientcallfunction
如需通过url访问云函数请参考:[云函数URL化](/uniCloud/http)
前端代码(H5前端、App、小程序),不再执行uni.request联网,而是通过`uniCloud.callFunction`调用云函数,`callFunction`定义如下:
#### 请求参数
......
......@@ -7,15 +7,15 @@ uniCloud分为客户端和云端两部分,有些接口名称相同,参数也
客户端API列表
|API |描述 |
|-- |-- |
|uniCloud.callFunction() |客户端调用云函数 [详情](https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=clientcallfunction) |
|uniCloud.database() |客户端访问云数据库,获取云数据库对象引用 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb) |
|uniCloud.uploadFile() |客户端直接上传文件到云存储 [详情](https://uniapp.dcloud.net.cn/uniCloud/storage?id=uploadfile) |
|uniCloud.getTempFileURL() |客户端获取云存储文件的临时路径 [详情](https://uniapp.dcloud.net.cn/uniCloud/storage?id=gettempfileurl) |
|uniCloud.chooseAndUploadFile() |客户端选择文件并上传 [详情](https://uniapp.dcloud.net.cn/uniCloud/storage?id=chooseanduploadfile) |
|uniCloud.getCurrentUserInfo() |获取当前用户信息 [详情](https://uniapp.dcloud.io/uniCloud/client-sdk?id=client-getcurrentuserinfo) |
|uniCloud.init() |同时使用多个服务空间时初始化额外服务空间 [详情](https://uniapp.dcloud.net.cn/uniCloud/init) |
|API |描述 |
|-- |-- |
|uniCloud.callFunction() |客户端调用云函数 [详情](https://uniapp.dcloud.net.cn/uniCloud/cf-functions?id=clientcallfunction) |
|uniCloud.database() |客户端访问云数据库,获取云数据库对象引用 [详情](https://uniapp.dcloud.net.cn/uniCloud/clientdb) |
|uniCloud.uploadFile() |客户端直接上传文件到云存储 [详情](https://uniapp.dcloud.net.cn/uniCloud/storage?id=uploadfile) |
|uniCloud.getTempFileURL() |客户端获取云存储文件的临时路径 [详情](https://uniapp.dcloud.net.cn/uniCloud/storage?id=gettempfileurl) |
|uniCloud.chooseAndUploadFile() |客户端选择文件并上传 [详情](https://uniapp.dcloud.net.cn/uniCloud/storage?id=chooseanduploadfile) |
|uniCloud.getCurrentUserInfo() |获取当前用户信息 [详情](#client-getcurrentuserinfo) |
|uniCloud.init() |同时使用多个服务空间时初始化额外服务空间 [详情](https://uniapp.dcloud.net.cn/uniCloud/init) |
### 获取当前用户信息getCurrentUserInfo@client-getcurrentuserinfo
......
## 云对象
> 新增于 HBuilderX 3.4.0
云对象本质上是对云函数的封装,和传统方式通过callFunction调用云函数相比,云对象写法更简单,调用更清晰。另外云对象默认支持[uniCloud响应体规范](uniCloud/cf-functions.md?id=resformat),对于满足规范的错误响应会在客户端自动抛出错误,开发者可以少写很多罗里吧嗦的判断。
以多action云函数为例,对比一下云对象和传统云函数
**传统callFunction方式代码如下:**
```js
// 传统方式调用云函数-云函数代码
// 云函数名:user-center
// 云函数入口index.js内容如下
'use strict';
exports.main = async (event, context) => {
const {
action,
params
} = event
switch(action) {
case 'updateUser': {
const {
nickname,
age
} = params
// 简化演示逻辑,此处不演示token校验
if(!nickname) {
return {
errCode: 'INVALID_NICKNAME',
errMsg: '昵称不正确'
}
}
return {
errCode: 0,
errMsg: '更新成功'
}
}
}
return {
errCode: 'ACTION_NOT_FOUND',
errMsg: `action[action] not found`
}
};
// 传统方式调用云函数-客户端代码
async function updateUser () {
try {
const res = uniCloud.callFunction({
name: 'user-center',
data: {
action: 'updateUser',
params: {
nickname: 'dc',
age: 10
}
}
})
const {
errCode,
errMsg
} = res.result
if(errCode) {
uni.showModal({
title: '更新失败',
content: errMsg,
showCancel: false
})
return
}
uni.showToast({
title: '更新成功'
})
} catch (e) {
uni.showModal({
title: '更新失败',
content: e.message,
showCancel: false
})
}
}
```
**使用云对象的写法如下:**
```js
// 使用云对象的写法-云对象代码
// 云对象名:user-center
// 云对象入口index.obj.js内容如下
module.exports = {
updateUser(nickname, age) {
if (!nickname) {
return {
errCode: 'INVALID_NICKNAME',
errMsg: '昵称不正确'
}
}
return {
errCode: 0,
errMsg: '更新成功'
}
}
}
// 使用云对象的写法-客户端代码
const userCenter = uniCloud.importObject('user-center')
async function updateUser () {
try {
const res = await userCenter.updateUser('dc', 10)
uni.showToast({
title: '更新成功'
})
} catch (e) {
// 此形式响应符合uniCloud响应体规范中的错误响应,自动抛出此错误
// {
// errCode: 'INVALID_NICKNAME',
// errMsg: '昵称不正确'
// }
uni.showModal({
title: '更新失败',
content: e.errMsg,
showCancel: false
})
}
}
```
可以看到大量的业务无关代码被简化掉,开发效率UP。此外通过`ObjectName.ActionName`的方式调用云函数和云端写法完全一致,心智负担大幅减小。请阅读以下内容深入了解云对象
## 规范
云对象和云函数都在cloudfunctions目录下,但是不同于云函数,云对象的入口为`index.obj.js`,而云函数则是`index.js`**为正确区分两者uniCloud做出了限制,云函数内不可存在index.obj.js,云对象内也不可存在index.js。**一个标准的云对象入口应导出一个对象,如下:
对象内每个键值对是一个action
```js
// user-center/index.obj.js
module.exports = {
updateUser: async function(nickname, age) {
console.log(nickname, age)
} // action updateUser
}
```
云对象也可以引用公共模块或者npm上的包,引用方式和云函数完全一致。
### 客户端调用@call-by-client
客户端通过`uniCloud.importObject`方法获取云对象的实例。用法如下
```js
const userCenter = uniCloud.importObject('user-center')
const res = await userCenter.updateUser('dc', 10) // 传入参数 nickname 和 age,参数和云对象内的action完全一致
```
### 客户端调用返回值@return-value
客户端拿到云对象的响应结果后,会自动进行结果的处理。
- 如果是正常的结果(errCode为假值[0, false, null, undefined, ...]或者结果内不含errCode)则将结果直接返回
- 如果是报错的结果(errCode为真值)将结果内的errCode和errMsg组合为错误对象抛出
- 如果是其他云函数未捕获的错误,直接将错误码和错误信息组合成错误对象抛出
前端抛出的错误对象上有以下属性
|属性名 |类型 |是否必备 |说明 |
|-- |-- |-- |-- |
|errCode |string&#124;number |否 |错误码 |
|errMsg |string |否 |错误信息 |
|requestId |string |否 |当前请求的requestId |
|detail |Object |否 |完成的错误响应(仅在响应符合uniCloud响应体规范时才有) |
详见以下示例:
```js
// user-center/index.obj.js
module.exports = {
updateUser: async function(nickname, age) {
if(!nickname) {
return {
errCode: 'INVALID_NICKNAME',
errMsg: '更新失败'
}
}
return {
errCode: 0,
errMsg: '更新成功'
}
}
}
// 客户端代码
const userCenter = uniCloud.importObject('user-center')
try {
// 不传username,云函数返回错误的响应
await userCenter.updateUser()
} catch (e) {
// e.errCode === 'INVALID_NICKNAME'
// e.errMsg === '更新失败'
// e.detail === {errCode: 'INVALID_NICKNAME',errMsg: '更新失败'}
// e.requestId === 'xxxx'
}
try {
const res = await userCenter.updateUser('dc', 10)
// res = {errCode: 0,errMsg: '更新成功'}
} catch (e) {}
```
`uniCloud`提供了一个 JSON 格式的文档型数据库,数据库中的每条记录都是一个 JSON 格式的对象。一个数据库可以有多个集合(相当于关系型数据中的表),集合可看做一个 JSON 数组,数组中的每个对象就是一条记录,记录的格式是 JSON 对象。
更多云数据库介绍参考[规范](uniCloud/cf-database)
更多云数据库介绍参考[规范](uniCloud/hellodb.md)
## 简介
一个服务空间对应一整套独立的云开发资源,包括数据库、存储空间、云函数等资源。服务空间之间彼此隔离。
每个服务空间都有一个全局唯一的space ID。
开发者可在 HBuilderX 中新建服务空间,如下:
- 通过 HBuilderX 中管理服务空间,包括新建服务空间和关联服务空间
HBuilderX 3.0起版本,在云函数目录 `uniCloud` 右键菜单创建服务空间
`uniCloud` 目录右键菜单中创建服务空间
<div align=center>
<img style="max-width:750px;" src="https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/b16f9740-4c05-11eb-8a36-ebb87efcf8c0.jpg"/>
</div>
创建服务空间后,在同样的 `uniCloud` 目录右键菜单中关联该服务空间。只有项目关联好服务空间后,才能上传云函数、操作服务空间下的数据库、存储等资源。
HBuilderX 3.0之前版本,在云函数目录 `cloudfunctions` 右键菜单创建服务空间
- 通过uniCloud的web控制台[https://unicloud.dcloud.net.cn](https://unicloud.dcloud.net.cn) 管理服务空间。
<div align=center>
<img style="max-width:750px;" src="https://img.cdn.aliyun.dcloud.net.cn/uni-app/uniCloud/unicloud-01.png"/>
</div>
web控制台可以新建、删除服务空间,管理线上的服务空间资源。
**服务空间数量限制**:每个DCloud开发者账户,腾讯云版提供1个免费服务空间,最多可创建49个收费服务空间。阿里云版最多可创建50个免费服务空间。
**新建服务空间注意**
- 第一次创建腾讯云服务空间时会为用户创建腾讯云账号并跳转到腾讯云实名界面,等待实名认证审核之后可以开通服务空间。若腾讯云实名认证提示身份证下已创建过多账户,则需要在腾讯云官网注销不用的账户。[详见](/uniCloud/faq?id=tencent-exceed-account-limit)
- 创建服务空间可能需要几十秒的时间,可以在web控制台查看是否创建完成。
## 多人协作@collaboration
一个服务空间只有一个创建者,但可以设置协作者。
项目涉及多人开发时,在[dev.dcloud.net.cn](https://dev.dcloud.net.cn)设置协作者(选择应用->设置项目成员),实现多人共同使用一个云服务空间。
协作者可以在HBuilderX和web控制台中操作被授权的服务空间,除了删除服务空间,其他功能均可正常操作。
授权步骤:
1. 在开发者中心`我创建的应用`列表页面选择特定的应用,如果应用过多可以使用AppId进行查找
![我创建的应用](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/865a0df3-3169-48df-8b4c-8acacf1a621f.jpg)
2. 在第一步选择的应用详情页面左侧菜单点击`项目成员管理`
3. 输入协作者邮箱并点击`添加协作者按钮`,下方会出现协作者权限配置界面
![项目成员管理](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/2e59ce9b-f202-4432-954c-d6182187ef94.jpg)
4. 勾选uniCloud并点击`设置授权服务空间`,在弹出界面勾选希望此协作者访问的服务空间
![设置授权服务空间](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/b3c234a7-e514-4b14-b33d-e7322130bd7d.jpg)
5. 点击第4步弹出界面的`保存按钮`以及第3步的`保存权限设置`按钮
6. 协作者如需在uni-app项目关联此服务空间,需要在项目的`manifest.json`内配置上共享的应用的AppId(需要在源码视图编辑manifest.json)
## 应用和服务空间的关系
每个uni-app应用都有一个appid,每个服务空间都有一个spaceid。
服务空间和手机端项目是多对多绑定关系。同DCloud账号下,一个应用可以关联到多个服务空间。一个服务空间也可以被多个项目访问。
### 多应用共用服务空间@multi-app
比如一个项目的用户端和管理端,在HBuilderX里可以创建成2个项目,但2个项目的服务空间可以指向一个,或者干脆把其中一个项目的服务空间绑定到另一个项目上。
[详见](https://ask.dcloud.net.cn/article/37949)
### 一个应用访问多个服务空间@multi-space
若应用仅连接一个服务空间,在HBuilderX中做好服务空间关联即可。开发者无需手动做初始化工作(可理解为类调用)。
```javascript
//项目仅连接了一个服务空间,则无需初始化
//可通过uniCloud直接调用云开发的API
uniCloud.callFunction()
uniCloud.uploadFile()
```
若一个应用需要同时连接更多服务空间,HBuilderX中无法绑定更多服务空间。此时需开发者在**客户端代码**中,手动调用初始化方法`uniCloud.init`,连接其他服务空间。
`uniCloud.init`方法会返回一个`uniCloud`实例,之后云函数API的调用都需要通过该`uniCloud`实例发起(类似实例调用)。
`uniCloud.init`方法定义如下:
```javascript
function init(options):uniCloud
```
`uniCloud.init`方法接受一个`options`参数,返回`uniCloud`实例,`uniCloud`实例可调用云函数、云存储相关API。
**注意**
- 云函数环境(仅腾讯云支持)仅能通过init返回同账号下其他的腾讯云服务空间实例。
- 客户端环境(腾讯云阿里云均支持)可以通过init返回本账号下任意云厂商服务空间实例
**options 参数说明**
|参数名 |类型 |必填 |默认值 |说明 |
|:-: |:-: |:-: |:-: |:-: |
|provider |String |是 |- |aliyun、tencent |
|spaceId |String |是 |- |服务空间ID,**注意是服务空间ID,不是服务空间名称** |
|clientSecret |String |是 |- |仅阿里云支持,可以在[uniCloud控制台](https://unicloud.dcloud.net.cn)服务空间列表中查看 |
|endpoint |String |否 |`https://api.bspapp.com` |服务空间地址,仅阿里云侧支持 |
**示例代码**
```javascript
//开发者创建了多个服务空间,则需手动初始化。注意这是前端代码,不是云函数代码
const myCloud = uniCloud.init({
provider: 'aliyun',
spaceId: 'xxxx-yyy',
clientSecret: 'xxxx'
});
//通过uniCloud实例调用云开发的API
myCloud.callFunction()
myCloud.uploadFile()
```
**Tips:**
或者在uniCloud的web控制台[https://unicloud.dcloud.net.cn](https://unicloud.dcloud.net.cn) 创建服务空间。
- 云函数会自动识别自己所属的服务空间,无需初始化。
- 腾讯云支持在云函数内初始化本账号下的其他服务空间
开发者需先为项目绑定服务空间,然后才能上传云函数、操作服务空间下的数据库、存储等资源。
uniCloud还支持跨服务空间的数据库访问,另见[文档](https://uniapp.dcloud.net.cn/uniCloud/hellodb?id=init-db)
\ No newline at end of file
......@@ -2,7 +2,7 @@
开发者应经常查阅自己的慢查询,修复问题,保证业务系统的健康稳定。
在数据库语句执行超过一定时间(**腾讯云为5秒,阿里云为1秒**)仍不能返回结果后,阿里云甚至会报错`operation exceeded time limit`
在数据库语句执行超过一定时间(**腾讯云为5秒,阿里云为1秒**)仍不能返回结果后,阿里云甚至会报错`operation exceeded time limit`**如果对数据库超时时间有更高的需求,建议使用腾讯云。**
这里介绍如何进行查询优化以避免此类问题。
......
......@@ -219,7 +219,7 @@ uniCloud的每个云函数是一个独立进程,不存在云函数级别的多
2. 将上述域名CNAME到`api.bspapp.com`
3. [自行初始化uniCloud](uniCloud/init.md)传入endpoint参数,其值为开通全球加速的自有域名
### 腾讯云提示当前实名主体已经有三个账号怎么办
### 腾讯云提示当前实名主体已经有三个账号怎么办@tencent-exceed-account-limit
开通腾讯云服务空间时实名认证提示实名主体已有三个账号,这往往是开发者在微信小程序开发工具里不小心开通了多个免费的小程序云,此时可以参考以下流程注销不用的账号:
......@@ -287,24 +287,7 @@ exports.main = async function(event){
### 授权其他用户访问服务空间@collaborator
开发期间经常需要多人共用同一个服务空间,此时可以在[DCloud开发者中心](https://dev.dcloud.net.cn/)将特定应用及其关联的服务空间共享给协作者,详细步骤如下
1. 在开发者中心`我创建的应用`列表页面选择特定的应用,如果应用过多可以使用AppId进行查找
![我创建的应用](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/865a0df3-3169-48df-8b4c-8acacf1a621f.jpg)
2. 在第一步选择的应用详情页面左侧菜单点击`项目成员管理`
3. 输入协作者邮箱并点击`添加协作者按钮`,下方会出现协作者权限配置界面
![项目成员管理](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/2e59ce9b-f202-4432-954c-d6182187ef94.jpg)
4. 勾选uniCloud并点击`设置授权服务空间`,在弹出界面勾选希望此协作者访问的服务空间
![设置授权服务空间](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-f184e7c3-1912-41b2-b81f-435d1b37c7b4/b3c234a7-e514-4b14-b33d-e7322130bd7d.jpg)
5. 点击第4步弹出界面的`保存按钮`以及第3步的`保存权限设置`按钮
6. 协作者如需在uni-app项目关联此服务空间,需要在项目的`manifest.json`内配置上共享的应用的AppId(需要在源码视图编辑manifest.json)
详见文档:[服务空间的多人协作](/uniCloud/concepts/space?id=collaboration)
### 如何使用promise/async/await@promise
......@@ -371,7 +354,7 @@ uniCloud客户端callFunction及数据库相关接口会返回Promise类型结
- bspapp.com,属于阿里云。如果该域名访问报错,说明阿里云serverless出故障了。
- tencentcloudapi.com,属于腾讯云。如果该域名访问报错,说明腾讯云serverless出故障了。
当然还有一种情况报错,其实是客户端的问题,包括浏览器的跨域问题,或者小程序的域名白名单问题,导致客户端无法连接uniCloud。这需要通过配置来解决,参考文档:[小程序和浏览器的域名访问配置](https://uniapp.dcloud.io/uniCloud/quickstart?id=%e5%b0%8f%e7%a8%8b%e5%ba%8f%e4%b8%ad%e4%bd%bf%e7%94%a8unicloud%e7%9a%84%e7%99%bd%e5%90%8d%e5%8d%95%e9%85%8d%e7%bd%ae)
当然还有一种情况报错,其实是客户端的问题,包括浏览器的跨域问题,或者小程序的域名白名单问题,导致客户端无法连接uniCloud。这需要通过配置来解决,参考文档:[小程序和浏览器的域名访问配置](https://uniapp.dcloud.io/uniCloud/quickstart?id=useinmp)
2. 通过测试系统判断故障点
- [hello uniCloud 阿里云版](https://hellounicloud.dcloud.net.cn/#/)
......@@ -387,7 +370,7 @@ uniCloud客户端callFunction及数据库相关接口会返回Promise类型结
**`operation exceeded time limit`、`云数据库执行时间超限`错误**
此错误一般由数据库操作超时引发,具体如何优化请参考:[性能优化](db-performance.md)
此错误一般由数据库操作超时引发,具体如何优化请参考:[性能优化](https://uniapp.dcloud.io/uniCloud/db-performance)
**使用事务时出现`WriteConflict`错误**
......
......@@ -104,25 +104,44 @@ exports.main = async (event, context) => {
};
```
**获取其他服务空间的数据库实例**
## 获取其他服务空间数据库实例@init-db
> 仅腾讯云在云函数内可用
如果当前应用仅使用一个服务空间,在HBuilderX中做好服务空间关联即可。获取当前空间的数据库实例时无需传递配置,直接调用database方法即可
接口形式:`uniCloud.database(Object DBOptions)`
```js
const db = uniCloud.database()
```
如果应用有连接其他服务空间数据库的需求,可以在获取database实例时传递对应服务空间的配置
> HBuilderX 3.2.11及更高版本支持客户端初始化其他服务空间database实例,此前仅腾讯云云函数环境支持。阿里云云函数环境不支持此用法。
调用`uniCloud.database()`时可以传入对应的服务空间信息(参数同uniCloud.init,参考:[uniCloud.init](uniCloud/init.md?id=init-unicloud))来获取指定服务空间的database实例。
**DBOptions参数说明**
**注意**
- 云函数环境(仅腾讯云支持)仅能通过init返回同账号下其他的腾讯云服务空间的数据库实例。
- 客户端环境(腾讯云阿里云均支持)可以通过init返回本账号下任意云厂商服务空间的数据库实例
|字段 |类型 |必填 |描述 |平台差异说明 |
|:-: |:-: |:-: |:-: |:-: |
|spaceId|String |否 |同一账号下的服务空间ID |仅腾讯云支持 |
**示例**
```js
// 如果ID为tcb-space-demo的服务空间也在你的账号下,可以通过这种方式访问tcb-space-demo的数据库。调用此接口的服务空间和tcb-space-demo对应的服务空间均为腾讯云才可以正常使用
const db = uniCloud.database({
spaceId: 'tcb-space-demo'
});
provider: 'tencent',
spaceId: 'xxx'
})
db.collection('uni-id-users').get()
```
**参数说明**
|参数名 |类型 |必填 |默认值 |说明 |
|:-: |:-: |:-: |:-: |:-: |
|provider |String |是 |- |aliyun、tencent |
|spaceId |String |是 |- |服务空间ID,**注意是服务空间ID,不是服务空间名称** |
|clientSecret |String |是 |- |仅阿里云支持,可以在[uniCloud控制台](https://unicloud.dcloud.net.cn)服务空间列表中查看 |
|endpoint |String |否 |`https://api.bspapp.com` |服务空间地址,仅阿里云侧支持 |
## 创建一个集合/数据表@createCollection
......
......@@ -17,7 +17,7 @@
## 操作步骤
### 设置云函数 HTTP 访问地址
### 设置云函数 HTTP 访问地址@set-path
1. 登录[uniCloud后台](https://unicloud.dcloud.net.cn/),选择需要管理的服务空间。
2. 单击左侧菜单栏【云函数】,进入云函数页面。
......@@ -31,7 +31,7 @@
- 阿里云使用默认域名时,在浏览器访问url化地址会触发下载。绑定自定义域名则无此问题
### 绑定自定义域名
### 绑定自定义域名@custom-domain
**2021年5月25日起腾讯云绑定域名CNAME记录值由默认域名调整为腾讯云给定的`CNAME域名`,已经绑定正常使用的域名无需调整**
......@@ -63,11 +63,11 @@
在阿里云申请的ssl证书包含一个pem文件和一个key文件,pem的文本内容为证书内容,key文件的内容为私钥
### 通过 HTTP URL 方式访问云函数
### 通过 HTTP URL 方式访问云函数@request-url
通过`https://${云函数Url化域名}/${path}`直接访问函数,其中`${path}`是配置的函数触发路径。
### 云函数的入参
### 云函数的入参@input
使用 HTTP 访问云函数时,HTTP 请求会被转化为特殊的结构体,称之为**集成请求**,结构如下:
......@@ -181,7 +181,7 @@ exports.main = function(event) {
```
### 云函数的返回值
### 云函数的返回值@output
云函数可以返回`string``object``number`等类型的数据,或者返回 [集成响应](#Integrationresponse),随后云接入会将返回值转化为正常的 HTTP 响应。
......
## 初始化uniCloud实例@init-unicloud
**若项目仅连接一个服务空间,`uniCloud`框架会自动绑定服务空间,开发者无需手动做初始化工作(可理解为类调用)。只有存在多服务空间时,才需要根据本文进行初始化**
```
//项目仅连接了一个服务空间,则无需初始化
//可通过uniCloud直接调用云开发的API
uniCloud.callFunction()
uniCloud.uploadFile()
```
若项目内需要使用多个服务空间,`uniCloud`无法自动绑定;需开发者在客户端代码中,手动调用初始化方法`uniCloud.init`,绑定服务空间。
`uniCloud.init`方法会返回一个`uniCloud`实例,之后云开发API的调用都需要通过该`uniCloud`实例发起(类似实例调用)。
`uniCloud.init`方法定义如下:
```
function init(options):uniCloud
```
`uniCloud.init`方法接受一个`options`参数,返回`uniCloud`实例,`uniCloud`实例可调用云函数、云存储相关API。
**options 参数说明**
|参数名 |类型 |必填 |默认值 |说明 |
|:-: |:-: |:-: |:-: |:-: |
|provider |String |是 |- |aliyun、tencent |
|spaceId |String |是 |- |服务空间ID,**注意是服务空间ID,不是服务空间名称** |
|clientSecret |String |是 |- |仅阿里云支持,可以在[uniCloud控制台](https://unicloud.dcloud.net.cn)服务空间列表中查看 |
|endpoint |String |否 |`https://api.bspapp.com` |服务空间地址,仅阿里云侧支持 |
**示例代码**
```javascript
//开发者创建了多个服务空间,则需手动初始化
const myCloud = uniCloud.init({
provider: 'aliyun',
spaceId: 'xxxx-yyy',
clientSecret: 'xxxx'
});
//通过uniCloud实例调用云开发的API
myCloud.callFunction()
myCloud.uploadFile()
```
**Tips:**
- 云函数会自动识别自己所属的服务空间,无需初始化。
- 腾讯云支持在云函数内初始化本账号下的其他服务空间
文档已迁移至:[一个应用访问多个服务空间](uniCloud/concepts/space.md?id=multi-space)
## 获取其他服务空间的database@init-db
> HBuilderX 3.2.11及更高版本支持客户端初始化其他服务空间database实例,此前仅腾讯云云函数环境支持。阿里云云函数环境不支持此用法。
调用`uniCloud.database()`时可以传入对应的服务空间信息(参数同uniCloud.init,参考:[uniCloud.init](uniCloud/init.md?id=init-unicloud))来获取指定服务空间的database实例。
**示例**
```js
const db = uniCloud.database({
provider: 'tencent',
spaceId: 'xxx'
})
db.collection('uni-id-users').get()
```
**参数说明**
|参数名 |类型 |必填 |默认值 |说明 |
|:-: |:-: |:-: |:-: |:-: |
|provider |String |是 |- |aliyun、tencent |
|spaceId |String |是 |- |服务空间ID,**注意是服务空间ID,不是服务空间名称** |
|clientSecret |String |是 |- |仅阿里云支持,可以在[uniCloud控制台](https://unicloud.dcloud.net.cn)服务空间列表中查看 |
|endpoint |String |否 |`https://api.bspapp.com` |服务空间地址,仅阿里云侧支持 |
文档已迁移至:[一个应用访问多个服务空间](uniCloud/hellodb.md?id=init-db)
......@@ -285,7 +285,7 @@ db.collection('user').where({
|DUPLICATE_KEY |索引冲突 |
|SYSTEM_ERROR |系统错误 |
如需自定义返回的err对象,可以在clientDB中挂一个[action云函数](uniCloud/database?id=action),在action云函数的`after`内用js修改返回结果,传入`after`内的result不带code和message。
如需自定义返回的err对象,可以在clientDB中挂一个[action云函数](#action),在action云函数的`after`内用js修改返回结果,传入`after`内的result不带code和message。
## 查询数据@query
......@@ -308,7 +308,7 @@ db.collection('user').where({
}
```
使用jql查询语法时,可以直接使用`student=='wang'`作为查询条件来查询students内包含wang的记录。
使用jql查询语法时,可以直接使用`students=='wang'`作为查询条件来查询students内包含wang的记录。
### 使用正则查询@regexp
......@@ -419,7 +419,7 @@ const res = await db.collection(order, 'book').get() // 将获取的order表的
"副表2字段名1": "xxx",
"副表2字段名2": "xxx",
}],
"_value": "主表字段原始值" // 使用副表foreignKey查询时会在关联的主表字段内以_value存储该字段的原始值,新增于HBuilderX 3.1.16-alpha
"_value": "主表字段原始值" // 使用副表foreignKey查询时会在关联的主表字段内以_value存储该字段的原始值,新增于HBuilderX 3.1.16
}
}
```
......@@ -1008,7 +1008,7 @@ db.collection(comment, user)
"副表2字段名1": "xxx",
"副表2字段名2": "xxx",
}],
"_value": "主表字段原始值" // 使用副表foreignKey查询时会在关联的主表字段内以_value存储该字段的原始值,新增于HBuilderX 3.1.16-alpha
"_value": "主表字段原始值" // 使用副表foreignKey查询时会在关联的主表字段内以_value存储该字段的原始值,新增于HBuilderX 3.1.16
}
}
```
......@@ -3285,7 +3285,7 @@ module.exports = {
目前JQL依赖了`uni-id`,uni-id 3.0.7及以上版本又依赖了`uni-config-center`,这两个公共模块是可以在action内使用的。
`HBuilderX 3.2.7-alpha`起,action内可使用任意公共模块。通过在要使用的公共模块的package.json内配置`"includeInClientDB":true`,可以将公共模块和JQL关联。
`HBuilderX 3.2.7`起,action内可使用任意公共模块。通过在要使用的公共模块的package.json内配置`"includeInClientDB":true`,可以将公共模块和JQL关联。
一个在JQL内使用的公共模块的package.json示例如下。
......
## 概述
选择阿里云作为服务商时,服务空间资源完全免费,每个账号最多允许创建50个服务空间。
选择阿里云作为服务商时,服务空间资源完全免费,每个账号最多允许创建50个服务空间。**阿里云目前处于公测阶段,如有正式业务对稳定性有较高要求建议使用腾讯云。**
选择腾讯云作为服务商时,可以创建一个免费的服务空间,资源详情参考[腾讯云免费额度](uniCloud/price?id=price-free);如想提升免费空间资源配额,或创建更多服务空间,则需付费购买。
......
......@@ -267,7 +267,7 @@ exports.main = async (event, context) => {
**断点调试**
> HBuilderX 3.2.10-alpha起支持
> HBuilderX 3.2.10 起支持
开启断点调试方式如下图所示,在HBuilderX内的uniCloud控制台点击虫子图标即可开启断点调试。
......@@ -328,7 +328,7 @@ exports.main = async (event, context) => {
**断点调试**
> HBuilderX 3.2.10-alpha起支持
> HBuilderX 3.2.10 起支持
开启断点调试方式如下图所示,在运行菜单选择`调试运行-本地云函数`即可。
......
......@@ -10,6 +10,7 @@
**注意:**
- 前端和云函数端,均有一个相同名称的api:`uniCloud.uploadFile`。请不要混淆。
- 前端还有一个`uni.uploadFile`的API,那个API用于连接非uniCloud的上传使用。请不要混淆。
- 腾讯云在权限为`非公有读`时,获取的带签名的链接(包括getTempFileURL接口返回的链接、web控制台文件详情页面看到的链接)有两个小时的有效期
文件上传成功后,系统会自动生成一个https链接或临时文件id,开发者应保存该文件地址供后续业务下载使用。
......
......@@ -151,7 +151,8 @@ exports.main = async (event, context) => {
"autoSetInviteCode": false, // 是否在用户注册时自动设置邀请码,默认不自动设置
"forceInviteCode": false, // 是否强制用户注册时必填邀请码,默认为false(需要注意的是目前只有短信验证码注册才可以填写邀请码),设置为true时需要在loginBySms时指定type为register来使用注册,登录时也要传入type为login
"removePermissionAndRoleFromToken": false, // 新增于uni-id 3.0.0版本,如果配置为false则自动缓存用户的角色、权限到token中,默认值为false。详细说明见https://uniapp.dcloud.io/uniCloud/uni-id?id=cache-permission-in-token
"app-plus": {
"preferedAppPlatform": "app", // 新增于uni-id 3.3.12,指定app端对应的PLATFORM名称,用于处理app-plus和app的兼容问题,详细说明见:https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=prefered-app-platform
"app": { // 此处需和preferedAppPlatform保持一致
"tokenExpiresIn": 2592000,
"oauth": {
// App微信登录所用到的appid、appsecret需要在微信开放平台获取,注意:不是公众平台而是开放平台
......@@ -243,6 +244,44 @@ const userSegment = token.split('.')[1]
const userInfo = atob(userSegment) // '{"uid":"61a593ba91a750000166f78d","role":["admin"],"permission":[],"iat":1638243365,"exp":1638250565}'
```
## preferedAppPlatform@prefered-app-platform
> 新增于uni-id 3.3.12
**前提介绍:**
uni-app vue2版本app端对应的platform为`app-plus`,uni-app vue3版本app端对应的platform为`app`。此改动引发了一些问题,比如在uni-id内使微信登录会无法匹配对应的平台导致登录报错。
由于uni-id将客户端平台存储在了数据库内(例如:app端微信登录的openid被存储为`wx_openid['app-plus']`),此问题无法平滑升级,因此对于新老项目建议分别处理。
### 旧项目的处理
旧项目建议将所有platform为app的场景统一为app-plus,即建议使用如下配置
```js
// 以下仅列出相关配置
{
"preferedAppPlatform": "app-plus", // uni-id内部会将收到的app平台全部转化为app-plus平台
"app-plus": { // 配置内的平台名称和preferedAppPlatform保持一致
"oauth": {}
}
}
```
### 新项目的处理
新项目建议将platform统一为app,即建议使用如下配置
```js
// 以下仅列出相关配置
{
"preferedAppPlatform": "app", // uni-id内部会将收到的app-plus平台全部转化为app平台
"app": { // 配置内的平台名称和preferedAppPlatform保持一致
"oauth": {}
}
}
```
# 用户角色权限@rbac
为什么需要角色权限管理?
......
## uniCloud响应体规范
uniCloud响应体规范(uniCloud response format),是DCloud官方制定的、服务器给客户端返回json数据的一种建议格式。后续uni-id、uni-pay、clientDB等均会调整为此结构
**由来**
uniCloud服务器给客户端返回的数据格式是json,但json的格式具体是什么没有约定。比如返回错误码,是叫code还是叫errCode?错误内容是message还是errMsg?内容的国际化如何处理?
如果没有一套统一的格式,在客户端将无法编写有效的网络拦截器,无法统一处理错误。
同时如果不同的插件,云端返回的数据格式千差万别,那使用者整合这些插件也会非常麻烦。国际化更无法落地。
为此DCloud推出了`uniCloud响应体规范`
为尽可能的与uni-app前端的API错误回调风格接近,uniCloud响应体规范定义的云端返回信息内应包含`errCode``errMsg`,示例如下
```js
// 失败返回值
{
errCode: 'uni-id-account-banned',
errMsg: '账号被禁用'
}
// 成功返回值
{
errCode: 0,
errMsg: '登录成功',
uid: 'xxx' // 其他信息
}
```
## errCode
errCode在成功时应返回数字`0`,失败时应返回一个以插件id开头的“字符串”,每个单词以连字符(`-`)分割。做出这样的规定是为了防止不同插件之间出现重复错误码
`'uni-id-account-banned'`错误码为例,`uni-id`为插件id,`account-banned`为错误缩写。
如果业务开发的代码并不发布插件市场,那么为了避免下载了一个市场的插件产生冲突,推荐使用不包含“-”的字符串来做errCode(插件市场的所有插件ID必须包含“-”)。
后续uniCloud会提供自动根据errCode对errMsg进行国际化处理的功能,开发者仅需保证云函数返回值满足`uniCloud响应体规范`即可。
## errMsg
errMsg用于存放具体错误信息,包括展示给开发者、终端用户的错误信息
<!-- 占位变量格式说明:
## 支持情况
1. 从xx版本开始,clientDB遵循该格式
2. 推荐开发者的云函数在返回json数据给客户端时也遵循这种格式。
3. uniCloud客户端sdk后续会提供callFunction及数据库操作的拦截器,开发者可以在拦截器内对特定的错误码进行处理。例如:在收到token过期的错误码时进行提示并跳转到登录页面
4. uniCloud admin和uni-starter等插件内置的网络拦截器也均将支持该格式。
历史兼容说明: -->
\ No newline at end of file
文档已迁移至:[/uniCloud/cf-functions?id=resformat](/uniCloud/cf-functions?id=resformat)
\ No newline at end of file
此差异已折叠。
......@@ -172,6 +172,9 @@ univerifyStyle 数据结构:
"icon": {
"path": "static/xxx.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
},
"closeIcon": {
"path": "static/xxx.png" // 自定义关闭按钮,仅支持本地图片。 HBuilderX3.3.7+版本支持
},
"phoneNum": {
"color": "#202020" // 手机号文字颜色 默认值:#202020
},
......
......@@ -276,6 +276,13 @@ uni-app.zh-Hans.json 文件
- pages.json,可以通过调用API来设置,例如更改标题 `uni.setNavigationBarTitle()`
- tabbar 不支持动态修改内容,但是可以通过自定义tabbar的方式,详情: [https://uniapp.dcloud.net.cn/collocation/pages?id=custom-tab-bar](https://uniapp.dcloud.net.cn/collocation/pages?id=custom-tab-bar)
## 双向文字流@bidi
中东语言的文字大多从右向左 (RTL) 书写。但是,一般而言,最常用的形式为双向 (bidi) 文字 - 混用从左向右和从右向左书写的文字。bidi 文字的一个示例是含有阿拉伯语和英语文字的段落。在 uni-app 中,nvue 页面和 vue 页面以不同的方式控制。
* nvue 页面使用平台原生控件渲染,文字的方向一定程度上可以根据语言自动切换。
* vue 页面使用 webveiw 渲染,文字方向需要开发者通过 css 样式进行控制:[unicode-bidi](https://developer.mozilla.org/en-US/docs/Web/CSS/unicode-bidi)[direction](https://developer.mozilla.org/en-US/docs/Web/CSS/direction)
## schema 国际化@schema
......@@ -376,3 +383,17 @@ HBuilderX 3.3 起,新建项目可以直接选择`hello i18n`模板,或者去
**注意:**
- Android 平台因原生层限制,将自动重启。其他平台均实时变化,包括已打开的所有页面
- iOS date 类型的 picker 因系统限制无法设置国际化,默认跟随系统语言
- iOS 新增框架语言需要配置 manifest.json -> app-plus -> locales ,例如: 增加日语 `ja`,详情见下面的 manifest.json 配置
```json
// manifest.json
{
"app-plus" : {
// 打包后生效
"locales": {
"ja": {}
}
}
}
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册