diff --git a/docs/_navbar.md b/docs/_navbar.md
index eb7cbc78d026107541767c5573f7d8cd52850ba5..36b629e8051845c74520c9d96f11c6b7b09c230e 100644
--- a/docs/_navbar.md
+++ b/docs/_navbar.md
@@ -1,7 +1,8 @@
* [介绍](README.md)
* [框架](collocation/pages.md)
* [组件](component/README.md)
-* [API](api/README.md)
+* [API](api/README.md)
+* [uniCloud](uniCloud/README.md)
* [其它规范](javascript:;)
- [App扩展规范HTML5 Plus](http://www.html5plus.org/doc/h5p.html)
- [微信小程序](https://developers.weixin.qq.com/miniprogram/dev/framework/)
diff --git a/docs/unicloud/README.md b/docs/unicloud/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..7a410b0e4c5fe1c24380e84863dd94a445450215
--- /dev/null
+++ b/docs/unicloud/README.md
@@ -0,0 +1,9 @@
+#### 介绍
+
+uniCloud是提供包括云函数、数据存储、文件存储等一整套后端服务,目前服务供应商为腾讯和阿里。开发者可以使用云开发来直接开发网站应用,在开发过程中即便需要后台服务也无需搭建服务器,可以直接使用云开发提供的云端能力。使用云开发后,后端和运维概念将被弱化,开发者无需再担心具体的后台资源及运维,只需使用平台提供的 API 进行核心业务开发,即可实现产品快速上线和迭代。
+
+云开发提供了完整的后台基础能力帮助开发者进行网站应用的开发,主要包括:
+
+- 云函数:在云端运行的代码,开发者只需编写自身业务逻辑代码。
+- 数据库:一个既可在网站应用前端操作,也能在云函数中读写的 JSON 数据库。
+- 存储:在应用前端直接上传或下载云端文件,并可在云开发控制台进行可视化管理。
diff --git a/docs/unicloud/_sidebar.md b/docs/unicloud/_sidebar.md
new file mode 100644
index 0000000000000000000000000000000000000000..fd72fc46b7b213925fa1e9597451785c1f190f13
--- /dev/null
+++ b/docs/unicloud/_sidebar.md
@@ -0,0 +1,87 @@
+* [什么是uniCloud](uniCloud/README.md)
+* [快速上手](uniCloud/quickstart.md)
+* 服务端sdk
+ * [身份认证](uniCloud/cf-authentication.md)
+ * [云函数](uniCloud/cf-functions.md)
+ * [数据库](uniCloud/cf-database.md)
+ * [云存储](uniCloud/cf-storage.md)
+* 客户端sdk
+ * [初始化](uniCloud/init.md)
+ * [云函数](uniCloud/functions.md)
+ * [云存储](uniCloud/storage.md)
+ * [登录授权](uniCloud/authentication.md)
+* 权限管理
+ * [腾讯云](uniCloud/policy-tcb.md)
+ * [阿里云](uniCloud/policy-ali.md)
+
+
\ No newline at end of file
diff --git a/docs/unicloud/authentication.md b/docs/unicloud/authentication.md
new file mode 100644
index 0000000000000000000000000000000000000000..0a62a5a6f9d3a9b917b29c1c5c8e8b14ff5d2654
--- /dev/null
+++ b/docs/unicloud/authentication.md
@@ -0,0 +1,209 @@
+**本章内容仅针对腾讯云开发,阿里侧暂不支持**
+
+## 获取登录对象
+
+**示例代码**
+
+```js
+const uniClient = uniCloud.init({
+ spaceId: 'xxxx-yyy'
+});
+
+let auth = uniClient.auth()
+```
+
+
+## 获取登录状态
+
+开发者可以通过 `getLoginState()` 来获取当前的登录状态,调用 `getLoginState()` 后,SDK 会识别本地是否有登录状态,如果有,则会尝试刷新登录状态,若刷新登录状态成功,则会返回新的登录状态,否则返回 `undefined`。
+
+**示例代码**
+
+```js
+const uniClient = uniCloud.init({
+ spaceId: 'xxxx-yyy'
+});
+uniClient.auth().getLoginState().then(loginState => {
+ if (loginState) {
+ // 登录态有效
+ } else {
+ // 没有登录态,或者登录态已经失效
+ }
+})
+```
+
+## 自定义登录
+
+`uniCloud`允许开发者使用特定的登录凭据`Ticket`对用户进行身份认证。开发者可以使用`服务端 SDK`来创建`Ticket`,并且将`token`传入到应用内,然后调用`signInWithTicket()`获得登录态。
+
+### 获取私钥文件
+
+登录腾讯云[云开发控制台](https://console.cloud.tencent.com/tcb),在[用户管理页面](https://console.cloud.tencent.com/tcb/user)中,点击“登录设置”,然后**生成并下载私钥**:
+
+**此处链接需替换为UniCloud链接【uniCloud替换标记】**
+
+![云开发下载私钥](https://main.qcloudimg.com/raw/e08751567a86afceda9e3e8536d37c52.png)
+
+**此处图片需替换为UniCloud图片【uniCloud替换标记】**
+
+### 使用云函数创建登录凭据
+
+获取私钥文件之后,重命名为`credentials.json`放在云函数同级目录即可
+
+`服务端 SDK`内置了生成`Ticket`的接口,开发者需要提供一个自定义的`customUserId`作为用户的唯一身份标识。`Ticket`有效期为**5分钟**,过期则失效。
+
+每个用户的`customUserId`不能相同,每次用户重新登录时,原有的登录态将会失效。
+
+```js
+let customUserId = '123456';
+
+const ticket = uniCloud.auth().createTicket(customUserId, {
+ refresh: 10 * 60 * 1000 // 每十分钟刷新一次登录态, 默认为一小时
+});
+// 然后把 ticket 发送给客户端
+```
+
+
+
+### 客户端上使用Ticket登录
+
+创建`Ticket`之后,开发者应将`Ticket`发送至客户端,然后使用`客户端SDK`提供的 `signInWithTicket()` 登录`UniCloud`:
+
+```js
+auth.signInWithTicket(ticket).then(() => {
+ // 登录成功
+})
+```
+
+## 获取用户信息
+
+任何方式登录成功后,可以调用 `getUserInfo` 获得用户的身份信息。
+
+**响应参数**
+
+|字段 |类型 |是否必备 |说明 |
+|:-: |:-: |:-: |:-: |
+|uid |string |是 |用户在云开发的唯一ID |
+|customUserId |string |否 |用户使用自定义登录传入的用户Id |
+
+**示例代码**
+```js
+const uniClient = uniCloud.init({
+ spaceId: 'xxxx-yyy'
+});
+
+const auth = uniClient.auth()
+auth.signInWithTicket('YourTicket').then(() => {
+ // 获取用户信息
+ return auth.getUserInfo()
+ })
+ .then(userInfo => {
+ //...
+ })
+```
+
+## 匿名登录
+uniCloud允许开发者使用匿名登录的方式进行静默授权,可以避免强制登录。在匿名状态下可正常的调用uniCloud的资源,开发者同时可以配合安全规则针对匿名用户制定对应的访问限制。
+
+### 开启匿名登录授权
+登录腾讯云[云开发控制台](https://console.cloud.tencent.com/tcb),在[用户管理页面](https://console.cloud.tencent.com/tcb/user)中,点击“登录设置”,然后在“匿名登录”一栏打开/关闭可用状态。
+
+**此处链接需替换为UniCloud链接【uniCloud替换标记】**
+
+### 客户端进行匿名登录
+```js
+const uniClient = uniCloud.init({
+ spaceId: 'xxxx-yyy'
+});
+const auth = uniClient.auth();
+await auth.signInAnonymously().catch(err=>{
+ // 登录失败会抛出错误
+});
+// 匿名登录成功检测登录状态isAnonymous字段为true
+const loginState = await auth.getLoginState();
+console.log(loginState.isAnonymous) // true
+```
+
+#### 匿名用户重新登录
+
+匿名用户如果要重新使用开发者提供的身份登录,可以调用`auth.signInWithTicket`来进行。[参考](#客户端上使用Ticket登录)
+
+#### 匿名用户转化为自定义用户
+目前UniCloud支持将匿名用户转化为自定义登录用户,此转正用户将会继承匿名用户在云端创建的资源,流程如下:
+1. 首先需要按照自定义登录的流程搭建获取自定义登录凭证`ticket`的服务;
+2. 客户端请求接口获取自定义登录凭证`ticket`。**请注意**,此`ticket`必须未注册过uniCloud,换句话说,匿名用户只能转化为新的uniCloud用户;
+3. 客户端调用`auth.linkAndRetrieveDataWithTicket`API,如下:
+```js
+// 调用此API之前需先请求接口获取到ticket
+auth.linkAndRetrieveDataWithTicket(ticket).then(res => {
+ // 转正成功
+}).catch(err => {
+ // 转正失败会抛出错误
+});
+```
+
+## 登录授权相关事件及钩子函数
+
+### Event: 'loginStateExpire'
+
+当登录态失效时,会触发这个事件,开发者可以在这个事件回调内,尝试重新登录 uniCloud。
+
+```js
+uniClient.on('loginStateExpire', () => {
+ // 尝试重新登录
+});
+```
+
+### Event: 'refreshAccessToken'
+
+JS SDK 会在登录态生效期间,自动刷新和维护短期访问令牌(access token),每次成功刷新时会触发此事件。
+
+对于两种登录态并存(uniCloud、自身业务登录态)的 Web 应用,这个事件可以用于同步登录态之间的状态。
+
+```js
+uniClient.on('refreshAccessToken', () => {
+ // 此时 uniCloud 短期访问令牌已经刷新,可以尝试刷新自身业务的登录态
+})
+```
+
+### Auth.shouldRefreshAccessToken(callback)
+
+`shouldRefreshAccessToken` 接收一个 `callback` 函数,并且会在刷新短期访问令牌前调用此 `callback` 函数,根据返回值决定是否要刷新短期访问令牌。
+
+对于两种登录态并存(uniCloud、自身业务登录态)的 Web 应用,可以在 `callback` 内判断自身业务登录态是否失效,从而决定是否续期 uniCloud 的短期访问令牌。
+
+```js
+auth.shouldRefreshAccessToken(() => {
+ if (/* 自身业务登录态还有效 */) {
+ return true;
+ } else {
+ return false;
+ }
+});
+```
+
diff --git a/docs/unicloud/cf-authentication.md b/docs/unicloud/cf-authentication.md
new file mode 100644
index 0000000000000000000000000000000000000000..be8a376fd0c35d82bfd381f7953301541394e555
--- /dev/null
+++ b/docs/unicloud/cf-authentication.md
@@ -0,0 +1,18 @@
+## 获取 auth 的引用
+
+```js
+const auth = uniCloud.auth();
+```
+
+#### 获取用户信息
+
+```js
+const {
+ uid, //云开发用户唯一ID
+ customUserId //自定义登录传入的用户Id
+} = auth.getUserInfo()
+```
+
+## 云函数生成登录凭证
+
+开发者可以使用云函数创建登录凭证,提供给客户端进行登录操作。[详见](uniCloud/authentication.md#自定义登录)
diff --git a/docs/unicloud/cf-database.md b/docs/unicloud/cf-database.md
new file mode 100644
index 0000000000000000000000000000000000000000..d66321420b648e7eef48fe1f9d2b988826808c87
--- /dev/null
+++ b/docs/unicloud/cf-database.md
@@ -0,0 +1,893 @@
+## 获取数据库的引用
+
+```js
+const db = uniCloud.database();
+```
+
+## 获取集合的引用
+
+```js
+// 获取 `user` 集合的引用
+const collection = db.collection('user');
+```
+
+### 集合 Collection
+
+通过 `db.collection(name)` 可以获取指定集合的引用,在集合上可以进行以下操作
+
+| 类型 | 接口 | 说明 |
+| -------- | ------- | ---------------------------------------------------------------------------------- |
+| 写 | add | 新增记录(触发请求) |
+| 计数 | count | 获取复合条件的记录条数 |
+| 读 | get | 获取集合中的记录,如果有使用 where 语句定义查询条件,则会返回匹配结果集 (触发请求) |
+| 引用 | doc | 获取对该集合中指定 id 的记录的引用 |
+| 查询条件 | where | 通过指定条件筛选出匹配的记录,可搭配查询指令(eq, gt, in, ...)使用 |
+| | skip | 跳过指定数量的文档,常用于分页,传入 offset |
+| | orderBy | 排序方式 |
+| | limit | 返回的结果集(文档数量)的限制,有默认值和上限值 |
+| | field | 指定需要返回的字段 |
+
+
+查询及更新指令用于在 `where` 中指定字段需满足的条件,指令可通过 `db.command` 对象取得。
+
+
+### 记录 Record / Document
+
+通过 `db.collection(collectionName).doc(docId)` 可以获取指定集合上指定 id 的记录的引用,在记录上可以进行以下操作
+
+| 接口 | 说明 |
+| ---- | ------ |
+| 写 | set | 覆写记录 |
+| | update | 局部更新记录(触发请求) |
+| | remove | 删除记录(触发请求) |
+| 读 | get | 获取记录(触发请求) |
+
+
+### 查询筛选指令 Query Command
+
+以下指令挂载在 `db.command` 下
+
+| 类型 | 接口 | 说明 |
+| -------- | ---- | ---------------------------------- |
+| 比较运算 | eq | 字段 == |
+| | neq | 字段 != |
+| | gt | 字段 > |
+| | gte | 字段 >= |
+| | lt | 字段 < |
+| | lte | 字段 <= |
+| | in | 字段值在数组里 |
+| | nin | 字段值不在数组里 |
+| 逻辑运算 | and | 表示需同时满足指定的所有条件 |
+| | or | 表示需同时满足指定条件中的至少一个 |
+
+
+### 字段更新指令 Update Command
+
+以下指令挂载在 `db.command` 下
+
+| 类型 | 接口 | 说明 |
+| ---- | ------- | -------------------------------- |
+| 字段 | set | 设置字段值 |
+| | remove | 删除字段 |
+| | inc | 加一个数值,原子自增 |
+| | mul | 乘一个数值,原子自乘 |
+| | push | 数组类型字段追加尾元素,支持数组 |
+| | pop | 数组类型字段删除尾元素,支持数组 |
+| | shift | 数组类型字段删除头元素,支持数组 |
+| | unshift | 数组类型字段追加头元素,支持数组 |
+
+
+## 支持的数据类型
+
+数据库提供以下几种数据类型:
+* String:字符串
+* Number:数字
+* Object:对象
+* Array:数组
+* Bool:布尔值
+* GeoPoint:地理位置点
+* GeoLineStringL: 地理路径
+* GeoPolygon: 地理多边形
+* GeoMultiPoint: 多个地理位置点
+* GeoMultiLineString: 多个地理路径
+* GeoMultiPolygon: 多个地理多边形
+* Date:时间
+* Null
+
+以下对几个特殊的数据类型做个补充说明
+1. 时间 Date
+
+ Date 类型用于表示时间,精确到毫秒,可以用 JavaScript 内置 Date 对象创建。需要特别注意的是,用此方法创建的时间是客户端时间,不是服务端时间。如果需要使用服务端时间,应该用 API 中提供的 serverDate 对象来创建一个服务端当前时间的标记,当使用了 serverDate 对象的请求抵达服务端处理时,该字段会被转换成服务端当前的时间,更棒的是,我们在构造 serverDate 对象时还可通过传入一个有 offset 字段的对象来标记一个与当前服务端时间偏移 offset 毫秒的时间,这样我们就可以达到比如如下效果:指定一个字段为服务端时间往后一个小时。
+
+ 那么当我们需要使用客户端时间时,存放 Date 对象和存放毫秒数是否是一样的效果呢?不是的,我们的数据库有针对日期类型的优化,建议大家使用时都用 Date 或 serverDate 构造时间对象。
+
+ ```js
+ //服务端当前时间
+ new db.serverDate()
+ ```
+
+ ```js
+ //服务端当前时间加1S
+ new db.serverDate({
+ offset: 1000
+ })
+ ```
+
+2. 地理位置
+
+参考:[GEO地理位置](#GEO地理位置)
+
+3. Null
+
+ Null 相当于一个占位符,表示一个字段存在但是值为空。
+
+
+## 新增文档
+
+方法1: collection.add(data)
+
+示例:
+
+| 参数 | 类型 | 必填 | 说明 |
+| ---- | ------ | ---- | ---------------------------------------- |
+| data | object | 是 | {_id: '10001', 'name': 'Ben'} _id 非必填 |
+
+```js
+collection.add({
+ name: 'Ben'
+}).then((res) => {
+
+});
+```
+
+方法2: collection.doc().set(data)
+
+也可通过 `set` 方法新增一个文档,需先取得文档引用再调用 `set` 方法。
+如果文档不存在,`set` 方法会创建一个新文档。
+
+```js
+collection.doc().set({
+ name: "Hey"
+});
+```
+
+## 查询文档
+
+支持 `where()`、`limit()`、`skip()`、`orderBy()`、`get()`、`update()`、`field()`、`count()` 等操作。
+
+只有当调用`get()` `update()`时才会真正发送请求。
+注:默认取前100条数据,最大取前100条数据。
+
+### 添加查询条件
+collection.where()
+参数
+
+设置过滤条件
+where 可接收对象作为参数,表示筛选出拥有和传入对象相同的 key-value 的文档。比如筛选出所有类型为计算机的、内存为 8g 的商品:
+
+```js
+db.collection('goods').where({
+ category: 'computer',
+ type: {
+ memory: 8,
+ }
+})
+```
+
+如果要表达更复杂的查询,可使用高级查询指令,比如筛选出所有内存大于 8g 的计算机商品:
+```js
+const _ = db.command // 取指令
+db.collection('goods').where({
+ category: 'computer',
+ type: {
+ memory: _.gt(8), // 表示大于 8
+ }
+})
+```
+
+### 获取查询数量
+collection.count()
+
+参数
+```js
+db.collection('goods').where({
+ category: 'computer',
+ type: {
+ memory: 8,
+ }
+}).count().then(function(res) {
+
+})
+```
+
+响应参数
+
+| 字段 | 类型 | 必填 | 说明 |
+| --------- | ------- | ---- | ------------------------ |
+| code | string | 否 | 状态码,操作成功则不返回 |
+| message | string | 否 | 错误描述 |
+| total | Integer | 否 | 计数结果 |
+| requestId | string | 否 | 请求序列号,用于错误排查 |
+
+
+
+### 设置记录数量
+collection.limit()
+
+参数说明
+
+| 参数 | 类型 | 必填 | 说明 |
+| ----- | ------- | ---- | -------------- |
+| value | Integer | 是 | 限制展示的数值 |
+
+使用示例
+
+```js
+collection.limit(1).get().then(function(res) {
+
+});
+```
+
+### 设置起始位置
+collection.skip()
+
+参数说明
+
+| 参数 | 类型 | 必填 | 说明 |
+| ----- | ------- | ---- | -------------- |
+| value | Integer | 是 | 跳过展示的数据 |
+
+使用示例
+
+```js
+collection.skip(4).get().then(function(res) {
+
+});
+```
+
+### 对结果排序
+collection.orderBy()
+
+参数说明
+
+| 参数 | 类型 | 必填 | 说明 |
+| --------- | ------ | ---- | ----------------------------------- |
+| field | string | 是 | 排序的字段 |
+| orderType | string | 是 | 排序的顺序,升序(asc) 或 降序(desc) |
+
+使用示例
+
+```js
+collection.orderBy("name", "asc").get().then(function(res) {
+
+});
+```
+
+### 指定返回字段
+
+collection.field()
+
+参数说明
+
+| 参数 | 类型 | 必填 | 说明 |
+| ---- | ------ | ---- | --------------------------------------- |
+| - | object | 是 | 要过滤的字段,不返回传false,返回传true |
+
+使用示例
+
+```js
+collection.field({ 'age': true })
+```
+备注:只能指定要返回的字段或者不要返回的字段。即{'a': true, 'b': false}是一种错误的参数格式
+
+### 查询指令
+#### eq
+
+表示字段等于某个值。`eq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`。
+
+比如筛选出所有自己发表的文章,除了用传对象的方式:
+
+```js
+const myOpenID = 'xxx'
+db.collection('articles').where({
+ _openid: myOpenID
+})
+```
+
+还可以用指令:
+
+```js
+const _ = db.command
+const myOpenID = 'xxx'
+db.collection('articles').where({
+ _openid: _.eq(openid)
+})
+```
+
+注意 `eq` 指令比对象的方式有更大的灵活性,可以用于表示字段等于某个对象的情况,比如:
+
+```js
+// 这种写法表示匹配 stat.publishYear == 2018 且 stat.language == 'zh-CN'
+db.collection('articles').where({
+ stat: {
+ publishYear: 2018,
+ language: 'zh-CN'
+ }
+})
+// 这种写法表示 stat 对象等于 { publishYear: 2018, language: 'zh-CN' }
+const _ = db.command
+db.collection('articles').where({
+ stat: _.eq({
+ publishYear: 2018,
+ language: 'zh-CN'
+ })
+})
+```
+
+#### neq
+
+字段不等于。`neq` 指令接受一个字面量 (literal),可以是 `number`, `boolean`, `string`, `object`, `array`。
+
+如筛选出品牌不为 X 的计算机:
+
+```js
+const _ = db.command
+db.collection('goods').where({
+ category: 'computer',
+ type: {
+ brand: _.neq('X')
+ },
+})
+```
+
+#### gt
+
+字段大于指定值。
+
+如筛选出价格大于 2000 的计算机:
+
+```js
+const _ = db.command
+db.collection('goods').where({
+ category: 'computer',
+ price: _.gt(2000)
+})
+```
+
+#### gte
+
+字段大于或等于指定值。
+
+#### lt
+
+字段小于指定值。
+
+#### lte
+
+字段小于或等于指定值。
+
+#### in
+
+字段值在给定的数组中。
+
+筛选出内存为 8g 或 16g 的计算机商品:
+
+```js
+const _ = db.command
+db.collection('goods').where({
+ category: 'computer',
+ type: {
+ memory: _.in([8, 16])
+ }
+})
+```
+
+#### nin
+
+字段值不在给定的数组中。
+
+筛选出内存不是 8g 或 16g 的计算机商品:
+
+```js
+const _ = db.command
+db.collection('goods').where({
+ category: 'computer',
+ type: {
+ memory: _.nin([8, 16])
+ }
+})
+```
+
+#### and
+
+表示需同时满足指定的两个或以上的条件。
+
+如筛选出内存大于 4g 小于 32g 的计算机商品:
+
+流式写法:
+```js
+const _ = db.command
+db.collection('goods').where({
+ category: 'computer',
+ type: {
+ memory: _.gt(4).and(_.lt(32))
+ }
+})
+```
+
+前置写法:
+```js
+const _ = db.command
+db.collection('goods').where({
+ category: 'computer',
+ type: {
+ memory: _.and(_.gt(4), _.lt(32))
+ }
+})
+```
+
+#### or
+
+表示需满足所有指定条件中的至少一个。如筛选出价格小于 4000 或在 6000-8000 之间的计算机:
+
+流式写法:
+```js
+const _ = db.command
+db.collection('goods').where({
+ category: 'computer',
+ type: {
+ price:_.lt(4000).or(_.gt(6000).and(_.lt(8000)))
+ }
+})
+```
+
+前置写法:
+```js
+const _ = db.command
+db.collection('goods').where({
+ category: 'computer',
+ type: {
+ price: _.or(_.lt(4000), _.and(_.gt(6000), _.lt(8000)))
+ }
+})
+```
+
+如果要跨字段 “或” 操作:(如筛选出内存 8g 或 cpu 3.2 ghz 的计算机)
+
+```js
+const _ = db.command
+db.collection('goods').where(_.or(
+ {
+ type: {
+ memory: _.gt(8)
+ }
+ },
+ {
+ type: {
+ cpu: 3.2
+ }
+ }
+))
+```
+
+### 正则表达式查询
+
+#### db.RegExp
+
+根据正则表达式进行筛选
+
+例如下面可以筛选出 `version` 字段开头是 "数字+s" 的记录,并且忽略大小写:
+```js
+// 可以直接使用正则表达式
+db.collection('articles').where({
+ version: /^\ds/i
+})
+
+// 或者
+db.collection('articles').where({
+ version: new db.RegExp({
+ regex: '^\\ds' // 正则表达式为 /^\ds/,转义后变成 '^\\ds'
+ options: 'i' // i表示忽略大小写
+ })
+})
+```
+
+## 删除文档
+方式1 通过指定文档ID
+
+collection.doc(_id).remove()
+
+```js
+// 清理全部数据
+collection.get()
+ .then((res) => {
+ const promiseList = res.data.map(document => {
+ return collection.doc(document.id).remove();
+ });
+ Promise.all(promiseList);
+ })
+ .catch((e) => {
+
+ });
+```
+
+方式2 条件查找文档然后直接批量删除
+
+collection.where().remove()
+
+```js
+// 删除字段a的值大于2的文档
+collection.where({
+ a: _.gt(2)
+}).remove().then(function(res) {
+
+})
+```
+
+## 更新文档
+
+### 更新指定文档
+
+collection.doc().update()
+
+```js
+collection.doc('doc-id').update({
+ name: "Hey"
+});
+```
+
+### 更新文档,如果不存在则创建
+collection.doc().set()
+
+```js
+collection.doc('doc-id').set({
+ name: "Hey"
+}).then(function(res) {
+
+});
+```
+
+### 批量更新文档
+collection.update()
+
+```js
+collection.where({name: _.eq('hey')}).update({
+ age: 18,
+}).then(function(res) {
+
+});
+```
+
+### 更新指令
+
+#### set
+
+更新指令。用于设定字段等于指定值。这种方法相比传入纯 JS 对象的好处是能够指定字段等于一个对象:
+
+```js
+// 以下方法只会更新 property.location 和 property.size,如果 property 对象中有
+db.collection('photo').doc('doc-id').update({
+ data: {
+ property: {
+ location: 'guangzhou',
+ size: 8
+ }
+ }
+}).then(function(res) {
+
+})
+```
+
+#### inc
+
+更新指令。用于指示字段自增某个值,这是个原子操作,使用这个操作指令而不是先读数据、再加、再写回的好处是:
+
+1. 原子性:多个用户同时写,对数据库来说都是将字段加一,不会有后来者覆写前者的情况
+2. 减少一次网络请求:不需先读再写
+
+之后的 mul 指令同理。
+
+如给收藏的商品数量加一:
+
+```js
+const _ = db.command
+
+db.collection('user').where({
+ _openid: 'my-open-id'
+}).update({
+ count: {
+ favorites: _.inc(1)
+ }
+}).then(function(res) {
+
+})
+```
+
+#### mul
+
+更新指令。用于指示字段自乘某个值。
+
+
+#### remove
+
+更新指令。用于表示删除某个字段。如某人删除了自己一条商品评价中的评分:
+
+```js
+const _ = db.command
+db.collection('comments').doc('comment-id').update({
+ rating: _.remove()
+}).then(function(res) {
+
+})
+
+```
+
+#### push
+向数组尾部追加元素,支持传入单个元素或数组
+
+```js
+const _ = db.command
+
+db.collection('comments').doc('comment-id').update({
+ // users: _.push('aaa')
+ users: _.push(['aaa', 'bbb'])
+}).then(function(res) {
+
+})
+
+```
+
+#### pop
+删除数组尾部元素
+
+```js
+const _ = db.command
+
+db.collection('comments').doc('comment-id').update({
+ users: _.pop()
+}).then(function(res) {
+
+})
+```
+#### unshift
+向数组头部添加元素,支持传入单个元素或数组。使用同push
+#### shift
+删除数组头部元素。使用同pop
+
+
+## GEO地理位置
+
+注意:**如果需要对类型为地理位置的字段进行搜索,一定要建立地理位置索引**。
+
+### GEO数据类型
+
+#### Point
+
+用于表示地理位置点,用经纬度唯一标记一个点,这是一个特殊的数据存储类型。
+
+签名:`Point(longitude: number, latitude: number)`
+
+示例:
+```js
+new db.Geo.Point(longitude, latitude)
+```
+
+#### LineString
+
+用于表示地理路径,是由两个或者更多的 `Point` 组成的线段。
+
+签名:`LineString(points: Point[])`
+
+示例:
+
+```js
+new db.Geo.LineString([
+ new db.Geo.Point(lngA, latA),
+ new db.Geo.Point(lngB, latB),
+ // ...
+])
+```
+
+#### Polygon
+
+用于表示地理上的一个多边形(有洞或无洞均可),它是由一个或多个**闭环** `LineString` 组成的几何图形。
+
+由一个环组成的 `Polygon` 是没有洞的多边形,由多个环组成的是有洞的多边形。对由多个环(`LineString`)组成的多边形(`Polygon`),第一个环是外环,所有其他环是内环(洞)。
+
+签名:`Polygon(lines: LineString[])`
+
+示例:
+
+```js
+new db.Geo.Polygon([
+ new db.Geo.LineString(...),
+ new db.Geo.LineString(...),
+ // ...
+])
+```
+
+#### MultiPoint
+
+用于表示多个点 `Point` 的集合。
+
+签名:`MultiPoint(points: Point[])`
+
+示例:
+
+```js
+new db.Geo.MultiPoint([
+ new db.Geo.Point(lngA, latA),
+ new db.Geo.Point(lngB, latB),
+ // ...
+])
+```
+
+#### MultiLineString
+
+用于表示多个地理路径 `LineString` 的集合。
+
+签名:`MultiLineString(lines: LineString[])`
+
+示例:
+
+```js
+new db.Geo.MultiLineString([
+ new db.Geo.LineString(...),
+ new db.Geo.LineString(...),
+ // ...
+])
+```
+
+
+#### MultiPolygon
+
+用于表示多个地理多边形 `Polygon` 的集合。
+
+签名:`MultiPolygon(polygons: Polygon[])`
+
+示例:
+
+```js
+new db.Geo.MultiPolygon([
+ new db.Geo.Polygon(...),
+ new db.Geo.Polygon(...),
+ // ...
+])
+```
+
+### GEO操作符
+
+#### geoNear
+
+按从近到远的顺序,找出字段值在给定点的附近的记录。
+
+签名:
+```js
+db.command.geoNear(options: IOptions)
+
+interface IOptions {
+ geometry: Point // 点的地理位置
+ maxDistance?: number // 选填,最大距离,米为单位
+ minDistance?: number // 选填,最小距离,米为单位
+}
+```
+
+
+示例:
+
+```js
+db.collection('user').where({
+ location: db.command.geoNear({
+ geometry: new db.Geo.Point(lngA, latA),
+ maxDistance: 1000,
+ minDistance: 0
+ })
+})
+```
+
+#### geoWithin
+
+找出字段值在指定 Polygon / MultiPolygon 内的记录,无排序
+
+签名:
+
+```js
+db.command.geoWithin(IOptions)
+
+interface IOptions {
+ geometry: Polygon | MultiPolygon // 地理位置
+}
+```
+
+示例:
+
+```js
+// 一个闭合的区域
+const area = new Polygon([
+ new LineString([
+ new Point(lngA, latA),
+ new Point(lngB, latB),
+ new Point(lngC, latC),
+ new Point(lngA, latA)
+ ]),
+])
+
+// 搜索 location 字段在这个区域中的 user
+db.collection('user').where({
+ location: db.command.geoWithin({
+ geometry: area
+ })
+})
+```
+
+#### geoIntersects
+
+找出字段值和给定的地理位置图形相交的记录
+
+签名:
+
+```js
+db.command.geoIntersects(IOptions)
+
+interface IOptions {
+ geometry: Point | LineString | MultiPoint | MultiLineString | Polygon | MultiPolygon // 地理位置
+}
+```
+
+示例:
+
+```js
+// 一条路径
+const line = new LineString([
+ new Point(lngA, latA),
+ new Point(lngB, latB)
+])
+
+// 搜索 location 与这条路径相交的 user
+db.collection('user').where({
+ location: db.command.geoIntersects({
+ geometry: line
+ })
+})
+```
+
+## 数据库实时推送
+
+监听指定集合中符合查询条件的文档,通过onchange回调获得文档的变化详情
+(where参数为查询条件 参考 [查询文档](#查询文档))
+
+```js
+ const uniClient = uniCloud.init({
+ spaceId: 'YourSpaceId
+ });
+ const db = uniClient.database();
+ const _ = db.command
+ const collection = db.collection('collName') // collName 需填当前服务空间下集合名称
+
+ let ref = collection.where({ test: _.gt(0) }).watch({
+ onChange: snapshot => {
+ console.log("收到snapshot**********", snapshot)
+ },
+ onError: error => {
+ console.log("收到error**********", error)
+ }
+ })
+```
+
+单个doc的监听,也可以采用doc('docId').watch()形式
+```js
+ let ref = collection.doc('one docId').watch({
+ onChange: snapshot => {
+ console.log("收到snapshot**********", snapshot)
+ },
+ onError: error => {
+ console.log("收到error**********", error)
+ }
+ })
+```
+
+手动关闭监听,当前监听将不再收到推送
+```js
+ ref.close()
+```
+
diff --git a/docs/unicloud/cf-functions.md b/docs/unicloud/cf-functions.md
new file mode 100644
index 0000000000000000000000000000000000000000..2c28534ffa8a3d75143e127d7718ec5aff92d22d
--- /dev/null
+++ b/docs/unicloud/cf-functions.md
@@ -0,0 +1,33 @@
+## 执行函数
+
+- 接口名称:callFunction(object)
+- 接口功能:远程调用云函数。
+
+### 请求参数
+
+| 字段 | 类型 | 必填| 说明 |
+| --- | --- | --- | --- |
+| name | string | 是 | 云函数名称。|
+| data | object | 否 | 云函数参数。|
+| callback| function| 否 | 回调函数。 |
+
+### 响应参数
+
+| 字段 | 类型 | 必填| 说明 |
+| --- | --- | --- | --- |
+| code | string| 否 | 状态码,操作成功则不返回。|
+| message | string| 否 | 错误描述。 |
+| result | object| 否 | 云函数执行结果。 |
+| requestId | string| 否 | 请求序列号,用于错误排查。|
+
+### 示例代码
+
+```javascript
+//promise
+uniCloud.callFunction({
+ name: "test",
+ data: { a: 1 }
+}).then((res) => {
+
+});
+```
\ No newline at end of file
diff --git a/docs/unicloud/cf-storage.md b/docs/unicloud/cf-storage.md
new file mode 100644
index 0000000000000000000000000000000000000000..d64b01c69416b0826d6a12d297090df8055cb587
--- /dev/null
+++ b/docs/unicloud/cf-storage.md
@@ -0,0 +1,139 @@
+## 上传文件
+- 接口名称: uploadFile
+- 接口功能:上传文件至云开发存储服务。
+- 阿里云暂不支持此接口
+
+### 请求参数
+
+| 字段 | 类型 | 必填 | 说明|
+| --- | --- | --- | --- |
+| cloudPath | string | 是 | 文件的绝对路径,包含文件名。例如 foo/bar.jpg、foo/bar/baz.jpg 等。[查看详情](https://cloud.tencent.com/document/product/436/13324) 。 |
+| fileContent | fs.ReadStream | 是 | buffer或要上传的文件 [可读流](https://nodejs.org/api/stream.html#stream_class_stream_readable) 。|
+
+### 响应参数
+
+| 字段 | 类型 | 必填 | 说明|
+| --- | --- | --- | --- |
+| code | string | 否 | 状态码,操作成功则不返回。 |
+| message | string | 否 | 错误描述。 |
+| fileID | fileID | 是 | 文件唯一 ID,用来访问文件,建议存储起来。 |
+| requestId | string | 否 | 请求序列号,用于错误排查。 |
+
+### 示例代码
+
+```javascript
+const fs = require("fs");
+
+let result = await uniCloud.uploadFile({
+ cloudPath: "test-admin.jpeg",
+ fileContent: fs.createReadStream(`${__dirname}/cos.jpeg`)
+});
+```
+
+## 获取文件下载链接
+- 接口名称:getTempFileURL
+- 接口功能:获取已上传至云开发的文件的访问链接。
+
+### 请求参数
+
+| 字段 | 类型 | 必填 | 说明 |
+| --- | --- | --- | --- |
+| fileList | <Array>.string | 是 | 要下载的文件 ID 组成的数组。 |
+
+fileList
+
+| 字段 | 类型 | 必填 | 说明
+| --- | --- | --- | --- |
+| fileID | string | 是 | 文件 ID。 |
+| maxAge | Integer | 是 | 文件链接有效期。 |
+
+### 响应参数
+
+| 字段 | 类型 | 必填 | 说明
+| --- | --- | --- | --- |
+| code | string | 否 | 状态码,操作成功则为 SUCCESS。 |
+| message | string | 否 | 错误描述。 |
+| fileList | <Array>.object | 否 | 存储下载链接的数组。 |
+| requestId | string | 否 | 请求序列号,用于错误排查。 |
+
+fileList
+
+| 字段 | 类型 | 必填 | 说明 |
+| --- | --- | --- | --- |
+| code | string | 否 | 删除结果,成功为 SUCCESS。 |
+| fileID | string | 是 | 文件 ID。 |
+| tempFileURL | string | 是 | 文件访问链接。 |
+
+### 示例代码
+
+```javascript
+let result = await uniCloud.getTempFileURL({
+ fileList: ['cloud://test-28farb/a.png']
+});
+```
+
+## 删除文件
+
+接口名称:deleteFile
+接口功能:删除云端文件。
+
+### 请求参数
+
+| 字段 | 类型 | 必填 | 说明 |
+| --- | --- | --- | --- |
+| fileList | <Array>.string | 是 | 要删除的文件 ID 组成的数组。 |
+
+### 响应参数
+
+| 字段 | 类型 | 必填 | 说明 |
+| --- | --- | --- | --- |
+| code | string | 否 | 状态码,操作成功则不返回。 |
+| message | string | 否 | 错误描述 |
+| fileList | <Array>.object | 否 | 删除结果组成的数组。 |
+| requestId | string | 否 | 请求序列号,用于错误排查。 |
+
+fileList
+
+| 字段 | 类型 | 必填 | 说明 |
+| --- | --- | --- | --- |
+| code | string | 否 | 删除结果,成功为SUCCESS。 |
+| fileID | string | 是 | 文件 ID。 |
+
+### 示例代码
+
+```javascript
+let result = await uniCloud.deleteFile({
+ fileList: [
+ "cloud://test-28farb/a.png"
+ ]
+});
+```
+
+## 下载文件
+- 接口名称:downloadFile
+- 接口功能:下载已上传至云开发的文件至本地(默认本地根目录/root)。
+
+### 请求参数
+
+| 字段 | 类型 | 必填 | 说明 |
+| --- | --- | --- | --- |
+| fileID | string | 是 | 要下载的文件的 ID。 |
+| tempFilePath | string | 否 | 下载的文件要存储的位置。 |
+
+### 响应参数
+
+| 字段 | 类型 | 必填 | 说明 |
+| --- | --- | --- | --- |
+| code | string | 否 | 状态码,操作成功则不返回。 |
+| message | string | 否 | 错误描述。 |
+| fileContent | Buffer | 否 | 下载的文件的内容。如果传入 tempFilePath 则不返回该字段。 |
+| requestId | string | 否 | 请求序列号,用于错误排查。 |
+
+### 示例代码
+
+```javascript
+let result = await uniCloud.downloadFile({
+ fileID: "cloud://aa-99j9f/my-photo.png",
+ // tempFilePath: '/tmp/test/storage/my-photo.png'
+});
+```
\ No newline at end of file
diff --git a/docs/unicloud/functions.md b/docs/unicloud/functions.md
new file mode 100644
index 0000000000000000000000000000000000000000..7561dc1fa480a5ae4f0b7b1cd2b58c3698861751
--- /dev/null
+++ b/docs/unicloud/functions.md
@@ -0,0 +1,39 @@
+## callFunction(object)
+
+调用云函数
+
+#### 请求参数
+
+|字段 |类型 |必填 |说明 |
+|:-: |:-: |:-: |:-: |
+|name |String |是 |云函数名称|
+|data |Object |否 |云函数参数|
+
+#### 响应参数
+
+|字段 |类型 |说明 |
+|:-: |:-: |:-: |
+|code |String |状态码,操作成功则不返回 |
+|message |String |错误描述 |
+|result |Object |云函数执行结果 |
+|requestId |String |请求序列号,用于错误排查 |
+
+#### 示例代码
+
+```javascript
+// promise
+uniClient.callFunction({
+ name: 'test',
+ data: { a: 1 }
+ })
+ .then(res => {});
+
+// callback
+uniClient.callFunction({
+ name: 'test',
+ data: { a: 1 },
+ success(){},
+ fail(){},
+ complete(){}
+});
+```
diff --git a/docs/unicloud/init.md b/docs/unicloud/init.md
new file mode 100644
index 0000000000000000000000000000000000000000..74978f5a5f468e7169928824c50a6dbc1a91de1c
--- /dev/null
+++ b/docs/unicloud/init.md
@@ -0,0 +1,31 @@
+#### uniCloud.init(Object initOptions)
+
+服务空间初始化,返回uniCloud实例。调用云资源之前必须调用此方法。
+
+**在一个项目只对应一个服务空间的情况下,会自动执行初始化操作用户无需再次执行。后续开发者可以直接使用uniCloud.callFunction等API**
+
+**initOptions 参数说明**
+
+|参数名 |类型 |必填 |默认值 |说明 |平台差异说明 |
+|:-: |:-: |:-: |:-: |:-: |:-: |
+|provider |String |是 |- |选择服务供应商(可选值tencent,aliyun) | |
+|spaceId |String |是 |- |服务空间id | |
+|clientSecret |String |阿里云必填 |- |服务空间secret key |仅阿里云侧支持 |
+|endpoint |String |否 |https://api.bspapp.com |服务空间地址 |仅阿里云侧支持 |
+|autoSignIn |Boolean|否 |true |是否自动匿名登录 |仅腾讯云侧支持 |
+|debugFunction|Boolean|否 |true |是否启用云函数日志输出 |仅开发阶段生效,平台支持:APP、H5(使用`HBuilderX`内置浏览器获得更好的调试体验) |
+
+**示例**
+
+```javascript
+const uniClient = uniCloud.init({
+ provider: 'tencent',
+ spaceId: 'xxxx-yyy',
+ clientSecret: 'xxxx',
+ endpoint: 'https://api.bspapp.com'
+});
+```
+
+**注意**
+
+- 服务提供商为腾讯云时,需要开发者手动去管理控制台开启匿名登录才可以操作云函数[详情](/uniCloud/authentication#匿名登录)
\ No newline at end of file
diff --git a/docs/unicloud/policy-ali.md b/docs/unicloud/policy-ali.md
new file mode 100644
index 0000000000000000000000000000000000000000..ce258d87ec36f4ebca0e6c963a6cd880909e184b
--- /dev/null
+++ b/docs/unicloud/policy-ali.md
@@ -0,0 +1,48 @@
+## 简介
+
+云开发提供了一套简明易懂的JSON语法用来控制**客户端**对资源的访问,类似于身份验证体系里的IAM或者网络权限中的ACL。您可以在控制台上通过修改默认权限规则来管理数据表的权限。
+
+**注意**
+
+- 权限控制仅针对客户端
+
+**阿里云侧目前实现为由开发者自行控制登录状态,所以auth相关的权限判断条件不会生效**
+
+## 云数据库
+
+开发者可以在uniCloud控制台设置数据库权限,如下图所示
+
+**此处需补充uniCloud控制台截图【uniCloud替换标记】**
+
+**目前实现端上不可直接访问数据库,推荐将数据表权限设置为以下形式**
+
+```
+{
+ "db": {
+ "*": {
+ ".read": false,
+ ".write": false,
+ "*": false
+ }
+ }
+}
+```
+
+## 云存储
+
+阿里侧端上直接上传文件到云存储的功能正在完善中,开发者可以先将云存储配置为客户端不可读写
+
+**权限配置示例**
+
+```
+{
+ "file": {
+ "*": {
+ "*": false
+ }
+ }
+}
+```
+
+
+
diff --git a/docs/unicloud/policy-tcb.md b/docs/unicloud/policy-tcb.md
new file mode 100644
index 0000000000000000000000000000000000000000..4642a150931a19367dd032e773566f1b986e4349
--- /dev/null
+++ b/docs/unicloud/policy-tcb.md
@@ -0,0 +1,162 @@
+## 简介
+
+为了保护用户的数据安全,云开发提供更灵活、可扩展、更细粒度的安全规则能力,开发者可以在云后台或者小程序开发工具上自定义安全规则,限制**客户端**对数据库的访问权限。本文档主要介绍如何配置安全规则以及表达式的相关说明。
+
+安全规则本身不收费,但是安全规则额外的数据访问会统计到计费中。
+
+**注意**
+
+- `get`函数会产生额外的数据访问。
+- 指定文档ID查询的所有写操作会产生一次数据访问。
+- 权限控制仅针对客户端
+
+## 安全规则示例
+
+**规则示例**
+
+```
+//云数据库
+{
+ "read": "auth.uid==doc._openid",
+ "write": "doc.name=='zzz'"
+}
+
+//云存储
+{
+ "read": true,
+ "write": "resource.openid == auth.uid"
+}
+```
+
+以上 json 配置中解释如下:
+
+- key:指用户的操作类型。
+- value:指一个表达式。
+
+## 操作类型
+
+- [云数据库操作类型](#云数据库操作类型)
+- [云存储操作类型](#云存储操作类型)
+
+## 表达式
+
+表达式是伪代码的语句,配置的时候不能过长。
+
+### 变量
+
+**全局变量**
+
+|变量名 |类型 |说明 |
+|:-: |:-: |:-: |
+|auth |object |用户登录信息,字段说明参见下文 |
+|now |number |当前时间 |
+|doc |any |文档数据或查询条件 |
+
+**auth**
+
+|字段名 |类型 |说明 |
+|:-: |:-: |:-: |
+|loginType|string |登录方式,取值为ANONYMOUS(匿名登录)、CUSTOM(自定义登录) |
+|uid |string |用户唯一 ID(对应数据库文档的doc._openid、云存储的resource.openid),见下面示例|
+
+```
+//云数据库
+{
+ "read": "auth.uid == doc._openid", //仅创建者可读
+ "write": "auth.uid == doc._openid" //仅创建者可写
+}
+
+//云存储
+{
+ "read": "resource.openid == auth.uid", //仅创建者可读
+ "write": "resource.openid == auth.uid" //仅创建者可写
+}
+```
+
+### 运算符
+
+|运算符 |说明 |示例 |示例解释(集合查询) |
+|:-: |:-: |:-: |:-: |
+|== |等于 |auth.uid == 'zzz' |用户的 uid 为 zzz |
+|!= |不等于 |auth.uid != 'zzz' |用户的 uid 不为 zzz |
+|> |大于 |doc.age>10 |查询条件的 age 属性大于10 |
+|>= |大于等于 |doc.age>=10 |查询条件的 age 属性大于等于10 |
+|< |小于 |doc.age>10 |查询条件的 age 属性小于10 |
+|<= |小于等于 |doc.age>=10 |查询条件的 age 属性小于等于10 |
+|in |存在于集合中 |auth.uid in ['zzz','aaa'] |用户的 uid 是['zzz','aaa']中的一个 |
+|!(xx in [])|不存在于集合中,使用 in 的方式描述 !(a in [1,2,3]) |!(auth.uid in ['zzz','aaa']) |用户的 uid 不是['zzz','aaa']中的任何一个 |
+|&& |与 |auth.uid == 'zzz' && doc.age>10 |用户的 uid 为 zzz 并且查询条件的 age 属性大于10 |
+||| |或者 |auth.uid == 'zzz' || doc.age>10 |用户的 uid 为 zzz 或者查询条件的 age 属性大于10 |
+|. |对象元素访问符 |auth.uid |用户的 uid |
+|[] |数组访问符属性 |get('database.collection_a.user')[auth.uid] == 'zzz' |collection_a集合中id为user的文档,key 为用户 uid 的属性值为 zzz|
+
+**注意**
+
+- 比较运算符的右值必须为数值。
+
+### 函数
+
+#### get
+
+目前仅支持`get`函数,唯一的参数必须为`database.集合名称.文档id`。通过访问其它文档的数据来判断用户操作是否符合安全规则。
+
+**使用示例**
+
+```
+{
+ "read":"get('xxxx')[auth.uid] in [1,2,3]",
+ "delete":"get('xxxx')[auth.uid] == 1 && doc.user in ['ersed','sfsdf'] "
+}
+```
+
+**注意**
+
+- 一个表达式最多可以有3个get函数。
+- 最多可以访问2个不同的文档。
+- 不允许嵌套调用,例如:get("xxxx").prop[get("xxxxx").zzzz];
+
+
+## 云数据库
+
+### 配置说明
+
+开发者可以在uniCloud控制台设置数据库权限
+
+**步骤**
+
+1.
+2.
+3.
+
+**此处需补充uniCloud控制台截图【uniCloud替换标记】**
+
+### 云数据库操作类型
+
+|操作类型 |说明 |默认值 |
+|:-: |:-: |:-: |
+|read |读文档 |false |
+|write |写文档,可以细分为 create、update、delete|false |
+|create |新建文档 |无 |
+|update |更新文档 |无 |
+|delete |删除文档 |无 |
+
+## 云存储
+
+### 配置说明
+
+开发者可以在uniCloud控制台设置云存储权限
+
+**步骤**
+
+1.
+2.
+3.
+
+**此处需补充uniCloud控制台截图【uniCloud替换标记】**
+
+### 云存储操作类型
+
+|操作类型 |说明 |默认值 |
+|:-: |:-: |:-: |
+|read |读取文件,例如:download |- |
+|write |上传/覆盖文件,删除文件 |- |
\ No newline at end of file
diff --git a/docs/unicloud/quickstart.md b/docs/unicloud/quickstart.md
new file mode 100644
index 0000000000000000000000000000000000000000..5e66a721c899deb547893f0855eb7ea19bcb0733
--- /dev/null
+++ b/docs/unicloud/quickstart.md
@@ -0,0 +1,7 @@
+## 通过HBuilderX创建云开发项目
+
+**此处需配合HBuilderX截图进行说明【uniCloud替换标记】**
+
+**注意**
+
+- 服务提供商为腾讯云时,需要开发者手动去管理控制台开启匿名登录[详情](/uniCloud/authentication#匿名登录)
\ No newline at end of file
diff --git a/docs/unicloud/storage.md b/docs/unicloud/storage.md
new file mode 100644
index 0000000000000000000000000000000000000000..842284d5c8b6df125db8d7003a585e9e4367d8ad
--- /dev/null
+++ b/docs/unicloud/storage.md
@@ -0,0 +1,203 @@
+## uploadFile(Object uploadOptions)
+
+上传文件到云存储
+
+#### 请求参数
+
+|参数名 |类型 |必填 |默认值 |说明 |平台差异说明 |
+|:-: |:-: |:-: |:-: |:-: |:-: |
+|cloudPath |String |是 |- |文件的绝对路径,包含文件名 |仅腾讯云侧支持 |
+|filePath |String |是 |- |要上传的文件对象 | |
+|onUploadProgress |Function |否 |- |上传进度回调 |仅腾讯云侧支持 |
+
+**注意**
+
+- `cloudPath` 为文件的绝对路径,包含文件名 foo/bar.jpg、foo/bar/baz.jpg 等,不能包含除[0-9 , a-z , A-Z]、/、!、-、\_、.、、\*和中文以外的字符,使用 / 字符来实现类似传统文件系统的层级结构。[查看详情](https://cloud.tencent.com/document/product/436/13324)
+
+#### 响应参数
+
+|字段 |类型 |说明 |
+|:-: |:-: |:-: |
+|code |String |状态码,操作成功则不返回 |
+|message |String |错误描述 |
+|fileID |String |文件唯一 ID,用来访问文件,建议存储起来 |
+|requestId |String |请求序列号,用于错误排查 |
+
+#### 示例代码
+
+```javascript
+uni.chooseImage({
+ count: 1,
+ success(res) {
+ console.log(res);
+ if (res.tempFilePaths.length > 0) {
+ let filePath = res.tempFilePaths[0]
+ //进行上传操作
+
+ // promise
+ const result = await uniClient.uploadFile({
+ cloudPath: 'test-admin.jpeg',
+ filePath: filePath,
+ onUploadProgress: function(progressEvent) {
+ console.log(progressEvent);
+ var percentCompleted = Math.round(
+ (progressEvent.loaded * 100) / progressEvent.total
+ );
+ }
+ });
+
+ // callback
+ uniClient.uploadFile({
+ cloudPath: 'test-admin.jpeg',
+ filePath: filePath,
+ onUploadProgress: function(progressEvent) {
+ console.log(progressEvent);
+ var percentCompleted = Math.round(
+ (progressEvent.loaded * 100) / progressEvent.total
+ );
+ },
+ success() {},
+ fail() {},
+ complete() {}
+ });
+
+ }
+ }
+});
+
+```
+
+**注意**
+
+- 为了提高文件上传性能,文件上传方式为直接上传到对象存储,为了防止在使用过程中出现 CORS 报错,需要到 Web 控制台/用户管理/登录设置选项中设置安全域名。如果已有域名出现 CORS 报错,请删除安全域名,重新添加。
+- 阿里云返回的fileID为链接形式
+
+## getTempFileURL(Object getTempFileURLOptions)
+
+获取文件临时下载链接,**仅腾讯云支持**
+
+#### 请求参数
+
+|字段 |类型 |必填 |默认值 |说明 |平台差异说明 |
+|:-: |:-: |:-: |:-: |:-: |:-: |
+|fileList |<Array>.String,Object|是 |- |要获取下载链接的文件 ID 组成的数组 |仅腾讯云支持 |
+
+**fileList**
+
+|字段 |类型 |必填 |说明 |
+|:-: |:-: |:-: |:-: |
+|fileID |String |是 |文件 ID |
+|maxAge |Number |是 |文件链接有效期,单位:秒 |
+
+#### 响应参数
+
+|字段 |类型 |说明 |
+|:-: |:-: |:-: |
+|code |String |状态码,操作成功则为 SUCCESS |
+|message |String |错误描述 |
+|fileList |<Array>.Object |存储下载链接的数组 |
+|requestId |String |请求序列号,用于错误排查 |
+
+**fileList**
+
+|字段 |类型 |说明 |
+|:-: |:-: |:-: |
+|fileID |String |文件 ID |
+|tempFileURL|String |文件访问链接 |
+
+#### 示例代码
+
+```javascript
+// promise
+uniClient.getTempFileURL({
+ fileList: ['cloud://test-28farb/a.png']
+ })
+ .then(res => {});
+
+// callback
+uniClient.getTempFileURL({
+ fileList: ['cloud://test-28farb/a.png'],
+ success() {},
+ fail() {},
+ complete() {}
+});
+```
+
+## deleteFile(Object deleteFileOptions)
+
+删除云端文件
+
+#### 请求参数
+
+|字段 |类型 |必填 |说明 |
+|:-: |:-: |---- |:-: |
+|fileList |<Array>.String |是 |要删除的文件 ID 组成的数组,**阿里云只支持一次删除一个文件**|
+
+#### 响应参数
+
+|字段 |类型 |必填 |说明 |
+|:-: |:-: |:-: |:-: |
+|code |String |否 |状态码,操作成功则不返回 |
+|message |String |否 |错误描述 |
+|fileList |<Array>.Object |否 |删除结果组成的数组 |
+|requestId |String |否 |请求序列号,用于错误排查 |
+
+**fileList**
+
+|字段 |类型 |必填 |说明 |
+|:-: |:-: |:-: |:-: |
+|code |String |否 |删除结果,成功为 SUCCESS |
+|fileID |String |是 |文件 ID |
+
+#### 示例代码
+
+```javascript
+// promise
+uniClient
+ .deleteFile({
+ fileList: ['cloud://jimmytest-088bef/1534576354877.jpg']
+ })
+ .then(res => {});
+
+// callback
+uniClient.deleteFile(
+ {
+ fileList: ['cloud://jimmytest-088bef/1534576354877.jpg'],
+ success(){},
+ fail(){},
+ complete(){}
+ }
+);
+```
+
+