From b4e8cf40dfd6c4aa2dd8a320db6b47ebee6404d6 Mon Sep 17 00:00:00 2001 From: daodao97 Date: Fri, 19 Jun 2020 16:42:33 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=A2=9E=E5=8A=A0entity,remote=5Fmodel?= =?UTF-8?q?=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/_sidebar.md | 2 + docs/backend/remote_module.md | 23 +++++++++ docs/backend/scaffold_entity.md | 92 +++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 docs/backend/remote_module.md create mode 100644 docs/backend/scaffold_entity.md diff --git a/docs/_sidebar.md b/docs/_sidebar.md index d3e2c5f..f445f2d 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -8,6 +8,8 @@ * [表单详解](backend/form.md) * [列表详解](backend/list.md) * [按钮详解](backend/super-button.md) + * [脚手架实体](backend/scaffold_entity.md) + * [多模块模式](backend/remote_module.md) * [通用配置](backend/common-config.md) * [辅助函数](backend/functions.md) * 业务组件 diff --git a/docs/backend/remote_module.md b/docs/backend/remote_module.md new file mode 100644 index 0000000..5cf42e0 --- /dev/null +++ b/docs/backend/remote_module.md @@ -0,0 +1,23 @@ +绝大部分的前后端分离的后台构建中, 一般都是`一个前端`->`一个后端`的架构, 但是随着业务的发展会有以下现象 + +1. 后端代码越来越庞大 +2. 代码中各种 `Consumer`, `Process` +3. 过多的 `Worker + Process`会占用大量的机器资源, 单机内存,CPU有时告警的风险 +4. 服务职能不纯粹 +5. 等等等等 + +所以我们的服务一步步的变得膨胀, 变得不稳定, 是时候做出改变了 + +![Biv9dV](https://cdn.jsdelivr.net/gh/daodao97/FigureBed@master/uPic/Biv9dV.png) + +我们将一些业务边界比较明显, 比较独立的功能, 以微服务的方式拆分出去, 然后注册到主项目上去, 这样我们就可以达到, 既使用一套ui, 又进行服务拆分的目的啦. + +`remote_module`的注册也十分简单, `http://localhost:9528/system/#/cconf/cconf_website_config` 在站点管理中增加相应模块的配置即可 + +![1DIbj0](https://cdn.jsdelivr.net/gh/daodao97/FigureBed@master/uPic/1DIbj0.png) + +然后在`菜单管理`中, 增加相应的模块菜单即可使用啦. + +?> 注意 `remote_module` 必须基于`hyperf-admin/admin` 组件构建哦 + +?> 另外, 主的`HyperfAdmin`项目, 默认包含两个本地模块, `default`, `system` \ No newline at end of file diff --git a/docs/backend/scaffold_entity.md b/docs/backend/scaffold_entity.md new file mode 100644 index 0000000..9982b96 --- /dev/null +++ b/docs/backend/scaffold_entity.md @@ -0,0 +1,92 @@ +在脚手架一结中已经介绍, `Controller`中的`module_class`属性, 告诉了我们要操作的是 `mysql`的那张表, 那么如果当我们要管理的数据存储方式是`elasticsearch`, `mongo`, 甚至是三方服务的`api`时 , 该怎么办呢? + +此时, 我们抽象出了一个实体`entity`的概念, 源码见[这里](https://github.com/hyperf-admin/hyperf-admin/tree/master/src/base-utils/src/Scaffold/Entity), 实体接口如下 + +```php +interface EntityInterface +{ + public function create(array $data); + + public function set($id, array $data); + + public function get($id); + + public function delete($id); + + public function count($where); + + public function list($where, $attr = [], $page = 1, $size = 20); + + public function getPk(); + + public function isVersionEnable(); +} +``` + +实体接口定义了要操作对象的`CRUD`等必备接口, 然后针对不同数据源封装了`MysqlEntityAbstract`, `EsEntityAbstract`, `ApiEntityAbstract`等抽象类, 脚手架控制器中增加了`entity_class`属性 + +比如, 我们有一个`es` 的索引`goods`存放商品数据 + +```php +// es model +class EsGoods extend EsBaseModel +{ + // .... +} + +// entity +class EsGoodsEntity extend EsEntityAbstract +{ + // .... +} + +// 将实体注入进脚手架 +class GoodsController extend AdminAbstractController +{ + public $entity_class = EsGoodsEntity::class; +} +``` + +如上操作, 我们将可以通过脚手架完成`es`数据的管理, 而且, 所有的页面效果, 搜索支持等几乎与`mysql`无异. + +当然, 我们还可以继续简化以上操作 + +```php +// es model +class EsGoods extend EsBaseModel +{ + // .... +} + +// 将 model 注入进脚手架 +class GoodsController extend AdminAbstractController +{ + public $model_class = EsGoods::class; +} +``` + +(⊙o⊙)… $model_class 不是用来存放 mysql 模型名称的吗, 怎么放了 es 的 modle 名? 看如下源码 + +```php +public function getEntity() +{ + if ($this->entity_class) { + return make($this->entity_class); + } + if ($this->model_class && make($this->model_class) instanceof BaseModel) { + return new class ($this->model_class) extends MysqlEntityAbstract {}; + } + if ($this->model_class && make($this->model_class) instanceof EsBaseModel) { + return new class ($this->model_class) extends EsEntityAbstract {}; + } + + return null; +} +``` + +我们通过匿名类的方式动态生成实体, 进一步简化了操作, 但脚手架最终使用的还是`entity`对象 + +通过以上形式的抽象, 我们可以实现`ApiEntityAbstract`, `MongoEntityAbstract`, `RedisListEntityAbstract` 等等任意可以操作的数据源了, 而且使用上跟之前完全一样. 将所有数据源上的区别都隐藏在`***EntityAbstract` 中. + +看, 就是这么方便. +