diff --git a/docs/uniCloud/admin.md b/docs/uniCloud/admin.md
index deb7da6caf3cfc586534c891e1d0d1b424d61d00..2efaed15b080a29c9a89a65476e43ece9b001b9c 100644
--- a/docs/uniCloud/admin.md
+++ b/docs/uniCloud/admin.md
@@ -1,5 +1,24 @@
# uniCloud Admin
+## 文档修改
+
+- 看完文档,还是不知道作为插件作者,怎么开发一个插件。作为用户,怎么导入一个插件
+ >把你们之前做的某个功能,比如权限管理,作为插件,发布到市场。以这个例子为例,说明怎么开发插件,怎么导入插件
+
+- 用表格表示菜单配置
+
+新增页面,要讲清楚:
+1. 可以新增普通的页面,在前端callfunction,后台搭配云函数操作
+2. 可以使用uni-clientdb,在前端直接操作数据库,后台配置db schema进行权限和格式校验
+3. 可以使用云函数单文件路由,在项目中默认包含了一个uni-cloud-router的单文件路由,也可以使用插件市场的其他单文件路由
+
+
+## 代码
+
+1. 这里不应该是输入时校验,改成失焦时校验
+2. 这个界面不响应回车键
+3. 这里需要验证码啊,不然怎么商用?
+
### 什么是uniCloud Admin
uniCloud Admin,是基于uni-app和uniCloud的应用后台管理框架。
@@ -16,8 +35,7 @@ uniCloud Admin,是基于uni-app和uniCloud的应用后台管理框架。
- 顶部topWindow的设置:比如logo更换、右上角部分连接更换。详见项目根目录的`admin.config.js`文件
- 左侧leftWindow的菜单设置:菜单包括两类,一类是动态菜单,具备业务和权限功能,在数据库的`opendb-admin-menu`表中增加删除菜单;另一类是静态菜单,不会根据登录用户角色变化,在项目根目录的`admin.config.js`文件中配置
- 开发模式下的 debug 功能,帮助开发者及时发现报错和搜索错误信息,可在`admin.config.js`文件中配置
-
-### PC 宽屏和移动端上的 UI 表现
+g### PC 宽屏和移动端上的 UI 表现
@@ -115,17 +133,50 @@ $top-window-text-color: #999; /* 文字颜色 */
1. 通过 [admin.config.js](https://github.com/dcloudio/uni-template-admin/blob/master/admin.config.js) 配置侧边栏内容,侧边栏的菜单包括根据用户角色动态显示的动态菜单,和所有用户都能看到静态菜单。
+*菜单的属性*
+
+| 字段 | 类型 | 必填 | 描述 |
+|:-|:-|:-|:-|
+| \_id | Object ID | 是 | Id保持唯一 |
+| name | String | 是 | 菜单文字 |
+| icon | String | 否 | 菜单图标 |
+| url | String | 否 | 菜单对应的页面链接(只有没有子菜单的菜单项可以配置) |
+| children | Array | 否 | 子菜单,重复它的父菜单的数据结构 |
+
+静态菜单 secondaryMenus 配置如下:
+
```js
export default {
// 侧边栏
sideBar: {
// 配置静态菜单列表(放置在用户被授权的菜单列表下边)
- secondaryMenus: [
- {
- name: "404页面",
- url: "/pages/error/404",
- },
- ],
+ secondaryMenus: [{
+ _id: 'demo',
+ name: '系统设置',
+ icon: 'el-icon-menu',
+ children: [{
+ _id: 'table',
+ name: '用户',
+ url: '/pages/demo/table/table'
+ },{
+ _id: 'table',
+ name: '角色',
+ url: '/pages/demo/table/table'
+ },{
+ _id: 'table',
+ name: '权限',
+ url: '/pages/demo/table/table'
+ }]
+ }, {
+ _id: 'app',
+ name: '应用管理',
+ icon: 'el-icon-menu',
+ children: [{
+ _id: 'table',
+ name: '表格',
+ url: '/pages/demo/table/table'
+ }]
+ }],
},
};
```
@@ -161,7 +212,7 @@ $menu-text-color-actived: #409eff; /* 菜单激活前景色 */
> [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=%e6%9d%83%e9%99%90%e8%a1%a8)
3. 菜单表 `opendb-admin-menu`
| 字段 | 类型 | 必填 | 描述 |
- | ---------- | --------- | ---- | ------- |
+ |:-|:-|:-|:-|
| \_id | Object ID | 是 | 系统自动生成的 Id |
| name | String | 是 | 菜单文字 |
| icon | String | 否 | 菜单图标 |
@@ -192,9 +243,13 @@ $menu-text-color-actived: #409eff; /* 菜单激活前景色 */
### 新增页面
-在框架搭建好后,接下来就需要增加页面,实现功能,建议页面统一放在 ``pages`` 目录,以便管理。由于是云端一体的开发模式,简单的理解为,在前端实现页面和 *api 接口*,这里需要转换一下观念,api 也是在前端实现的。
+- 可以新增普通的页面,在前端callfunction,后台搭配云函数操作
+- 可以使用uni-clientdb,在前端直接操作数据库,后台配置db schema进行权限和格式校验
+- 可以使用云函数单文件路由,在项目中默认包含了一个uni-cloud-router的单文件路由,也可以使用插件市场的其他单文件路由
+
+建议页面统一放在 ``pages`` 目录,以便管理。由于是云端一体的开发模式,简单的理解为,在前端实现页面和 *api 接口*,这里需要转换一下观念,api 也是在前端实现的。
-以登录功能为例,以下是代码片段,完整代码见项目源码:
+以登录功能为例,这里使用的是 `可以新增普通的页面,在前端callfunction,后台搭配云函数操作` 和 `项目中默认的 uni-cloud-router 的单文件路由` 的方式新增页面,以下是代码片段,完整代码见项目源码:
1. 新增前端 vue 页面
@@ -282,9 +337,9 @@ module.exports = class UserService extends Service {
```
-### 关于uni-cloud-router的用法
-
+### 关于 uni-cloud-router 的用法
+> [详情](https://uniapp.dcloud.io/uniCloud/uni-cloud-router)
### 云函数
@@ -292,13 +347,6 @@ module.exports = class UserService extends Service {
> [详情](https://uniapp.dcloud.io/uniCloud/uni-clientDB)
-### admin 自带的组件
-
-- sidebar-item
-
-
-### 怎么开发一个插件
-
### 使用三方组件库
uniCloud Admin支持所有三方的Vue UI库,包括elementUI等非uni-app的UI库,但注意这些for h5的ui库只能在浏览器中使用,无法适配App和小程序,按如下操作。
diff --git a/docs/uniCloud/uni-cloud-router.md b/docs/uniCloud/uni-cloud-router.md
new file mode 100644
index 0000000000000000000000000000000000000000..1c9c74f2a27140687a8aa57a47a2f1f9e669ae8e
--- /dev/null
+++ b/docs/uniCloud/uni-cloud-router.md
@@ -0,0 +1,270 @@
+# uni-cloud-router
+
+> 基于 koa 风格的 uniCloud 云函数路由库,同时支持 uniCloud 客户端及 URL 化访问
+
+---
+
+- [云函数端](#云函数端)
+ - [安装](#安装)
+ - [目录结构](#目录结构)
+ - [控制器(Controller)](#控制器controller)
+ - [如何编写 Controller](#如何编写-controller)
+ - [获取请求参数](#获取请求参数)
+ - [调用 Service](#调用-service)
+ - [定制 URL 化返回的状态码](#定制-url-化返回的状态码)
+ - [服务(Service)](#服务service)
+ - [使用场景](#使用场景)
+ - [如何编写 Service](#如何编写-service)
+ - [使用 Service](#使用-service)
+ - [中间件(Middleware)](#中间件middleware)
+ - [开发中间件](#开发中间件)
+ - [使用中间件](#使用中间件)
+ - [Context](#context)
+ - [获取方式](#获取方式)
+- [客户端](#客户端)
+ - [发送请求](#发送请求)
+ - [返回结果](#返回结果)
+
+## 云函数端
+
+### 安装
+
+```bash
+npm install --save uni-cloud-router
+```
+
+### 目录结构
+
+```bash
+├── package.json
+├── index.js // 云函数入口文件
+├── config.js // 用于配置 router 应用根目录、中间件等
+├── controller // 用于解析用户的输入,处理后返回相应的结果
+| ├── user.js
+├── service (可选) //用于编写业务逻辑层,建议使用
+| ├── user.js
+```
+
+```js
+// index.js (通常无需改动)
+const Router = require('uni-cloud-router').Router // 引入 Router
+const router = new Router(require('./config.js')) // 根据 config 初始化 Router
+exports.main = async (event, context) => {
+ return router.serve(event, context) // 由 Router 接管云函数
+}
+```
+
+```js
+// config.js
+module.exports = {
+ debug: true, // 调试模式时,将返回 stack 错误堆栈
+ baseDir: __dirname, // 必选,应用根目录
+ middleware: [], // 自定义中间件
+}
+```
+
+```js
+// controller/user.js
+const uniID = require('uni-id')
+const Controller = require('uni-cloud-router').Controller
+// 必须继承 Controller
+module.exports = class UserController extends Controller {
+ async login() {
+ const { username, password } = this.ctx.data // 获取请求参数
+ // 使用 uni-id 登录
+ return uniID.login({
+ username,
+ password,
+ })
+ }
+}
+```
+
+### 控制器(Controller)
+
+负责解析用户的输入,处理后返回相应的结果。
+
+推荐 Controller 层主要对用户的请求参数进行处理(校验、转换),然后调用对应的 service 方法处理业务,得到业务结果后封装并返回:
+
+1. 获取用户传递过来的请求参数。
+2. 校验、组装参数。
+3. 调用 Service 进行业务处理,必要时处理转换 Service 的返回结果,让它适应用户的需求。
+4. 将结果响应给用户。
+
+#### 如何编写 Controller
+
+所有的 Controller 文件都必须放在 `controller` 目录下,可以支持多级目录,访问的时候可以通过目录名级联访问。
+
+```js
+// controller/post.js
+const Controller = require('uni-cloud-router').Controller
+// 必须继承 Controller 类
+module.exports = class PostController extends Controller {
+ async create() {
+ const { ctx, service } = this
+ // 校验参数
+ ctx.validate({
+ title: { type: 'string' },
+ content: { type: 'string' },
+ })
+ // 组装参数
+ const author = ctx.auth.uid
+ const post = Object.assign(ctx.data, { author })
+ // 调用 Service 进行业务处理
+ return service.post.create(post)
+ }
+}
+```
+
+定义的 Controller 类,会在每一个请求访问时实例化一个全新的对象,会有下面几个属性挂在 `this` 上。
+
+- `this.ctx`:当前请求的上下文对象的实例,通过它我们可以拿到各种便捷属性和方法。
+- `this.service`:应用定义的 service,通过它我们可以访问到抽象出的业务层,等同于 `this.ctx.service`。
+- `this.db`:等同于 `uniCloud.database()`。
+- `this.curl`:等同于 `uniCloud.httpclient.request`。
+- `this.throw`:抛出异常信息,等同于 `this.ctx.throw`。
+
+#### 获取请求参数
+
+通过在 Controller 上绑定的 Context 实例的 data 属性,获取请求发送过来的参数
+
+```js
+class PostController extends Controller {
+ async listPosts() {
+ const data = this.ctx.data
+ // {
+ // username: 'demo',
+ // password: 'demo',
+ // }
+ }
+}
+```
+
+#### 调用 Service
+
+通过 Service 层进行业务逻辑的封装,不仅能提高代码的复用性,同时可以让业务逻辑更好测试。
+
+Controller 中可以调用任何一个 Service 上的任何方法,同时 Service 是懒加载的,只有当访问到它的时候才会去实例化它。
+
+```js
+class PostController extends Controller {
+ async create() {
+ const { ctx, service } = this
+ const author = ctx.auth.uid
+ const post = Object.assign(ctx.data, { author })
+ // 调用 service 进行业务处理
+ return service.post.create(post)
+ }
+}
+```
+
+Service 的具体写法,请查看 [Service](#服务service) 章节。
+
+#### 定制 URL 化返回的状态码
+
+```js
+class PostController extends Controller {
+ async create() {
+ // 设置状态码为 201
+ this.ctx.status = 201 // 仅当使用 HTTP/HTTPS 请求时生效
+ }
+}
+```
+
+### 服务(Service)
+
+业务逻辑封装的一个抽象层,有以下几个好处:
+
+- 保持 Controller 中的逻辑更加简洁。
+- 保持业务逻辑的独立性,抽象出来的 Service 可以被多个 Controller 重复调用。
+- 将逻辑和展现分离,更容易编写测试用例。
+
+#### 使用场景
+
+- 复杂数据的处理,比如要展现的信息需要从数据库获取,还要经过一定的规则计算,才能返回用户显示。或者计算完成后,更新到数据库。
+- 第三方服务的调用,比如 微信模板消息推送 等。
+
+#### 如何编写 Service
+
+所有的 Service 文件都必须放在 `service` 目录下,可以支持多级目录,访问的时候可以通过目录名级联访问。
+
+```js
+// service/post.js
+const Service = require('uni-cloud-router').Service
+// 必须继承 Service
+module.exports = class PostService extends Service {
+ async create(data) {
+ return this.db.add(data)
+ }
+}
+```
+
+定义的 Service 类是懒加载的,只有当访问到它的时候才会去实例化它,会有下面几个属性挂在 `this` 上。
+
+- `this.ctx`:当前请求的上下文对象的实例,通过它我们可以拿到各种便捷属性和方法。
+- `this.service`:应用定义的 service,通过它我们可以访问到抽象出的业务层,等同于 `this.ctx.service`。
+- `this.db`:等同于 `uniCloud.database()`。
+- `this.curl`:等同于 `uniCloud.httpclient.request`。
+- `this.throw`:抛出异常信息,等同于 `this.ctx.throw`。
+
+#### 使用 Service
+
+[在 Controller 中调用 Service](#调用-service)
+
+### 中间件(Middleware)
+
+在路由请求前,后添加处理逻辑,实现一些特定功能,如:用户登录,权限校验等
+
+#### 开发中间件
+
+与 koa 保持一致,参考:[koa 中间件](https://demopark.github.io/koa-docs-Zh-CN/guide.html)
+
+```js
+// middleware/auth.js
+const uniID = require('uni-id')
+module.exports = (options) => {
+ // 初始化 uniID 配置
+ uniID.init(options)
+ // 返回中间件函数
+ return async function auth(ctx, next) {
+ // 校验 token
+ const auth = uniID.checkToken(ctx.event.uniIdToken)
+ if (auth.code) {
+ // 校验失败,抛出错误信息
+ throw { code: auth.code, message: auth.message }
+ }
+ ctx.auth = auth // 设置当前请求的 auth 对象
+ await next() // 执行后续中间件
+ }
+}
+```
+
+示例:
+
+- [uni-id 校验 token 中间件](https://github.com/dcloudio/uni-template-admin/blob/master/cloudfunctions-aliyun/uni-admin/middleware/auth.js)
+- [uni-id 校验 permission 中间件](https://github.com/dcloudio/uni-template-admin/blob/master/cloudfunctions-aliyun/uni-admin/middleware/permission.js)
+- [云函数 URL 化中间件](https://github.com/fxy060608/uni-cloud-router/blob/master/src/middleware/http.ts)
+
+#### 使用中间件
+
+1. 通过 config.js 配置
+
+```js
+const auth = require('./middleware/auth.js') // 引入 auth 中间件
+module.exports = {
+ debug: true, // 调试模式时,将返回 stack 错误堆栈
+ baseDir: __dirname, // 指定应用根目录
+ middleware: [
+ [
+ //数组格式,第一个元素为中间件,第二个元素为中间件生效规则配置
+ auth({ tokenSecret: 'tokenSecret-demo' }), // 注册中间件
+ { enable: true, ignore: /\/login$/ }, // 配置当前中间件生效规则,该规则表示以`/login`结尾的路由不会执行 auth 中间件校验 token
+ ],
+ ],
+}
+```
+
+2. 中间件配置项
+
+- enable 控制中间件是否开启。
+- match 设置
\ No newline at end of file