💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
DMP将数据与数据库操作分离,使得开发人员只需要专注于数据的变化,而不需要去考虑数据如何与数据库进行交互。**各功能包管理自己的逻辑层。** logic类分为两大块:**敏捷方法**和**事件方法**。 **敏捷方法**,可用于controller或者其他logic类调用的public、protected方法。它们已经集成了常规的一些操作。很多时候常规操作并不能满足我们的需求,毕竟是逻辑层,需要的就是对基本数据的加工处理。那么这个时候我们就需要用到logic类的另一块内容了:事件方法。 **事件方法**,对于每一个敏捷方法,都包含有至少一个的事件方法。它们都是protected方法,使用方法是直接重载他们。事件方法的优势在于,你不需要在意操作的过程,而将注意力集中额外的处理数据的变化上。比如在添加之前需要设置一些默认数据,那么只需要在get敏捷方法的事件方法onGetAfter($item)中,对$item进行设置即可: ``` protected function onAddBefore(&$item): bool { $item["enable"] = true; } ``` > 逻辑层位置:应用目录/logic/功能块名/逻辑类 继承基本类framework\core\driver\Logic,它是一个抽象类,需要实现以下方法: * **modelClassPath(): ?array** 返回当前逻辑使用的model类路径。敏捷方法都通过这个方法获得model实例进行操作。 ## 敏捷方法: * **getStatement(): array** 逻辑申明,详细内容请查看下一级内容《逻辑申明》。 * **getSearchOperationFilter(): array** 指定查询操作符,**未指定的参数将无法筛选**,如果有外键关联查询,可通过.方式指定,比如:`"usertype.name"=>"="`,重载此方法,并返回一个数组。return一个键值对数组,字段名以及对应操作符。如:["title"=>"like"],如: ``` protected function getSearchOperationFilter() { return [ "name" => "like", "description" => "like", "parent_string" => "like%", "id"=>function($paramName,$value){return ["id","in",[1,2,3]];} //可以直接通过回调函数返回一个where数组或者字符串。 //id键值表示当查询中包含id字段时将会触发此条件。 ]; } ``` * **getFailMessage()** 获取失败信息,获取一次后该信息会失效。 * **protected function setFailMessage($message)** 设置失败消息。当logic内部发生错误时,用此方法将失败内容进行提示,此方法不影响返回结果,该return false的,还是要自己写。 * **protected function fail($message)** 操作失败的方法,当logic内部发生错误时,用此方法将失败内容进行提示,与setFailMessage($message)不同的是,这个方法会返回fanlse,可以在操作过程中直接return此方法。 * **get($pk, $field = "*")** 获取主体数据,返回的值为modelClassPath()方法指定的主体model返回记录。$pk参数指的标识值,不一定就是表里面的id值。指定标识列在model里设置$pk='openid'。支持事件:onGetBefore($pk, $model),onGetAfter(?array &$item),支持申明内容,已集成消息队列。 * **getRecord($pk, $field)** 获取数据记录请求的响应逻辑。这个方法可以用来返回数据库的记录数据。返回带关联数据等的情况建议通过get方法响应。支持事件:onGetRecordBefore($pk, $model),onGetRecordAfter($item),支持申明内容,集成消息队列。 * **add($item)** 数据添加操作,返回值是新添加数据的标识序列,这个标识序列不一定是表里的id列。指定标识列在model里设置$pk='openid'。额外数据操作,在事件方法里设置。 * **addAll(array $items)** 批量添加信息,一次性批量提交信息。它有一个对应的addAllBefore与addAllAfter事件,并支持申明内容。 * **edit($pk, $item)** 数据修改操作,返回值是编辑之后的操作结果或者它的后置操作事件onEditAfter所返回的内容,$pk参数指的标识值,不一定就是表里面的id值。指定标识列在model里设置$pk='openid',在此过程中,如果提供的id值没有对应的记录,则会返回false,并有fail消息"未找到记录"。额外数据操作,在事件方法里设置。 * **updateAll(array $pkAndValue)** 批量更新数据,根据键值对进行批量修改,数组的键为标识值。暂未支持事件,未支持申明内容,支持消息队列。 * **setEnable($pk, bool $enable)** 修改数据表enable字段。提供标识值与true或否。指定标识列在model里设置$pk='openid'。额外数据操作,在事件方法里设置。支持事件:onSetEnableAfter($result),支持申明内容,已集成消息队列。 * **setOrderNumber(array $pkAndValue)** 设置排序场景的响应逻辑,提供一个包含键为标识值,值为排序值的数组即可更新数据。支持事件:onSetOrderNumber(bool $result, array $requestItems),暂没有支持的申明内容,已集成消息队列。 * **delete($pk)** 删除数据,提供标识值,批量删除提供一个标识值的数组,返回删除主键与onDeleteAfter返回值的和。指定标识列在model里设置$pk='openid'。额外数据操作,在事件方法里设置。支持事件:onDeleteBefore、onDeleteAfter,支持申明内容,已集成消息队列。 **deleteBatch(array $where)** 根据指定条件批量删除数据,暂未支持事件,未支持申明内容,支持消息队列。 * **getList(int $currentPage, $searchKeyAndValue = [], $order = "", $pageSize = 0, $field = "")** 分页、查询、排序场景响应方法。返回为数组:["data":数据列表,"total":总记录数],控制层的doGetList调用的就是这个方法。支持事件:onGetListBefore(array $searchKeyAndValue),onGetListAfter(array &$list),支持申请内容,已集成消息队列。 * **protected function convertSearchParams($searchParams, $operationFilter = [])** 查询转换,将查询键值数组转化成TP查询器数组,这个方法一般不需要自己调用。 * **protected function getModelInstance($modelName = ""): \Think\Model** 获取一个关联model实例的对象。惰性获取。使用时不需要用变量保存,可以直接用。 ## 事件方法: * **protected function onGetListBefore(int $currentPage = 1, array $searchKeyAndValue = [], $order = "", $pageSize = 0, $field = "*")** getList前置操作,提交数据库查询前的操作。 * **protected function onGetListAfter(array &$list)** GetList后置事件方法。注意:不要在这里删除数据,否则可能与翻页不匹配。如果需要删除数据,建议在前置事件中操作或者删除完后再查询一遍。 * **protected function onGetAllListBefore(array $searchKeyAndValue,$order = "", $field = "*")** getAllList方法前置操作。提交数据库之前抛出。 * **protected function onGetAllListAfter(array &$items)** GetAllList后置事件方法。注意:不要在这里删除数据,否则可能与翻页不匹配。 * **protected function onAddBefore( $item):bool** 数据添加前置操作,$item:准备添加的数据内容,如果返回false,则添加会取消。对添加内容的预设值、强制对值设定可以放在这个方法里进行。比如: ``` protected function onAddBefore($item) { $item["enable"] = 1; $item["create_info"] = json_encode(LoginState::getCreateInfo()); $parent = $this->get($item["parent_id"]); $item["parent_string"] = $parent["parent_string"] . $parent["id"] . ","; return $item; } ``` * **protected function onAddAfter(bool $addResult, array $addItem)** 数据添加的后置操作,$addResult:添加结果,如果为false表示添加失败。$addItem:添加成功的数据行,addResult为false,此项则为空数组。 * **protected function onAddAllBefore(array &$items):bool** 批量添加的前置操作,同onAddBefore,只是在用来响应addAll方法。$items:准备添加的数据数组,这里是一个引用参数,修改会直接更改添加内容。 * **protected function onAddAllAfter(array $successPks, array $addItems)** 批量添加后置事件方法。同onAddAfter,只是在用来响应addAll方法。$successPks:添加成功的主键值。$addItems:之前准备添加的数据行,不管结果成功或者失败都返回。 * **protected function onEditBefore($pk, $original, $item):array** 数据修改前置操作,$pk:请求更新的数据标识。$original:当前数据库的原始数据。$item:准备修改的数据。 * **protected function onEditAfter($original, $result)** 数据修改后置操作,$original:修改成功前的原始数据。$result:修改成功的数据行。 * **protected function onGetBefore($id, framework\core\driver\Model &$modelInstance)** 获取数据的前置操作,$id:标识值,指定标识列在model里设置$pk='openid'。$modelInstance:查询实例,可以在这里直接利用TP的链式操作做查询的改变。model的with操作等可以在这里设置。 * **protected function onGetAfter(?array &$item)** 获取数据的后置操作,$items:准备返回的数据。父类对create_info与update_info进行json_decode,子类中使用parent::onGetAfter来使用。 * **protected function onDeleteBefore($pk, framework\core\driver\Model $modelInstance):bool** 数据删除的前置操作,$pk:标识值,指定标识列在model里设置$pk='openid'。$modelInstance:查询实例。返回true表示继续删除。返回false则取消操作,并会在消息队列中添加一个消息。 * **protected function onDeleteAfter($pk, array $deletedItems)** 删除操作后置事件方法。可用来在这里做关联删除或者写入日志等操作。,$pk:主键,提供数组表示批量删除。$deletedItems:已删除数据清单。二维数组。 * **protected function onGetRecordBefore($pk, framework\core\driver\Model &$model)** get信息记录前置操作。$pk:查询标识。$model:model实例。 * **protected function onGetRecordAfter(?array &$item)** get信息后置操作。$items:获取到的原始记录。 * **protected function onSetEnableAfter($result)** SetEnable后置操作。$result:请求的setenable是否操作成功。 * **protected function onSetOrderNumber(bool $result, array $requestItems)** setOrderNumber后置方法。$result 操作结果。true为成功,false为失败。$requestItems 请求设置数据,仅包含有id和ordernumber值。 ***** 另外设置有一个ApiLogic逻辑类,允许将这个逻辑类作为Api方式使用,某些模块直接实例化将不受控制。